backend/remote: test new options and modes
Tests for -refresh=false, -refresh-only, and -replace, as well as tests to ensure we error appropriately on mismatched API versions.
This commit is contained in:
parent
eb1f113693
commit
ab5fec9aec
|
@ -279,6 +279,45 @@ func TestRemote_applyWithoutRefresh(t *testing.T) {
|
|||
|
||||
op, configCleanup, done := testOperationApply(t, "./testdata/apply")
|
||||
defer configCleanup()
|
||||
defer done(t)
|
||||
|
||||
op.PlanRefresh = false
|
||||
op.Workspace = backend.DefaultStateName
|
||||
|
||||
run, err := b.Operation(context.Background(), op)
|
||||
if err != nil {
|
||||
t.Fatalf("error starting operation: %v", err)
|
||||
}
|
||||
|
||||
<-run.Done()
|
||||
if run.Result != backend.OperationSuccess {
|
||||
t.Fatalf("operation failed: %s", b.CLI.(*cli.MockUi).ErrorWriter.String())
|
||||
}
|
||||
if run.PlanEmpty {
|
||||
t.Fatalf("expected plan to be non-empty")
|
||||
}
|
||||
|
||||
// We should find a run inside the mock client that has refresh set
|
||||
// to false.
|
||||
runsAPI := b.client.Runs.(*mockRuns)
|
||||
if got, want := len(runsAPI.runs), 1; got != want {
|
||||
t.Fatalf("wrong number of runs in the mock client %d; want %d", got, want)
|
||||
}
|
||||
for _, run := range runsAPI.runs {
|
||||
if diff := cmp.Diff(false, run.Refresh); diff != "" {
|
||||
t.Errorf("wrong Refresh setting in the created run\n%s", diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemote_applyWithoutRefreshIncompatibleAPIVersion(t *testing.T) {
|
||||
b, bCleanup := testBackendDefault(t)
|
||||
defer bCleanup()
|
||||
|
||||
op, configCleanup, done := testOperationApply(t, "./testdata/apply")
|
||||
defer configCleanup()
|
||||
|
||||
b.client.SetFakeRemoteAPIVersion("2.3")
|
||||
|
||||
op.PlanRefresh = false
|
||||
op.Workspace = backend.DefaultStateName
|
||||
|
@ -293,10 +332,82 @@ func TestRemote_applyWithoutRefresh(t *testing.T) {
|
|||
if run.Result == backend.OperationSuccess {
|
||||
t.Fatal("expected apply operation to fail")
|
||||
}
|
||||
if !run.PlanEmpty {
|
||||
t.Fatalf("expected plan to be empty")
|
||||
}
|
||||
|
||||
errOutput := output.Stderr()
|
||||
if !strings.Contains(errOutput, "refresh is currently not supported") {
|
||||
t.Fatalf("expected a refresh error, got: %v", errOutput)
|
||||
if !strings.Contains(errOutput, "Planning without refresh is not supported") {
|
||||
t.Fatalf("expected a not supported error, got: %v", errOutput)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemote_applyWithRefreshOnly(t *testing.T) {
|
||||
b, bCleanup := testBackendDefault(t)
|
||||
defer bCleanup()
|
||||
|
||||
op, configCleanup, done := testOperationApply(t, "./testdata/apply")
|
||||
defer configCleanup()
|
||||
defer done(t)
|
||||
|
||||
op.PlanMode = plans.RefreshOnlyMode
|
||||
op.Workspace = backend.DefaultStateName
|
||||
|
||||
run, err := b.Operation(context.Background(), op)
|
||||
if err != nil {
|
||||
t.Fatalf("error starting operation: %v", err)
|
||||
}
|
||||
|
||||
<-run.Done()
|
||||
if run.Result != backend.OperationSuccess {
|
||||
t.Fatalf("operation failed: %s", b.CLI.(*cli.MockUi).ErrorWriter.String())
|
||||
}
|
||||
if run.PlanEmpty {
|
||||
t.Fatalf("expected plan to be non-empty")
|
||||
}
|
||||
|
||||
// We should find a run inside the mock client that has refresh-only set
|
||||
// to true.
|
||||
runsAPI := b.client.Runs.(*mockRuns)
|
||||
if got, want := len(runsAPI.runs), 1; got != want {
|
||||
t.Fatalf("wrong number of runs in the mock client %d; want %d", got, want)
|
||||
}
|
||||
for _, run := range runsAPI.runs {
|
||||
if diff := cmp.Diff(true, run.RefreshOnly); diff != "" {
|
||||
t.Errorf("wrong RefreshOnly setting in the created run\n%s", diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemote_applyWithRefreshOnlyIncompatibleAPIVersion(t *testing.T) {
|
||||
b, bCleanup := testBackendDefault(t)
|
||||
defer bCleanup()
|
||||
|
||||
op, configCleanup, done := testOperationApply(t, "./testdata/apply")
|
||||
defer configCleanup()
|
||||
|
||||
b.client.SetFakeRemoteAPIVersion("2.3")
|
||||
|
||||
op.PlanMode = plans.RefreshOnlyMode
|
||||
op.Workspace = backend.DefaultStateName
|
||||
|
||||
run, err := b.Operation(context.Background(), op)
|
||||
if err != nil {
|
||||
t.Fatalf("error starting operation: %v", err)
|
||||
}
|
||||
|
||||
<-run.Done()
|
||||
output := done(t)
|
||||
if run.Result == backend.OperationSuccess {
|
||||
t.Fatal("expected apply operation to fail")
|
||||
}
|
||||
if !run.PlanEmpty {
|
||||
t.Fatalf("expected plan to be empty")
|
||||
}
|
||||
|
||||
errOutput := output.Stderr()
|
||||
if !strings.Contains(errOutput, "Refresh-only mode is not supported") {
|
||||
t.Fatalf("expected a not supported error, got: %v", errOutput)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -375,6 +486,79 @@ func TestRemote_applyWithTargetIncompatibleAPIVersion(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestRemote_applyWithReplace(t *testing.T) {
|
||||
b, bCleanup := testBackendDefault(t)
|
||||
defer bCleanup()
|
||||
|
||||
op, configCleanup, done := testOperationApply(t, "./testdata/apply")
|
||||
defer configCleanup()
|
||||
defer done(t)
|
||||
|
||||
addr, _ := addrs.ParseAbsResourceInstanceStr("null_resource.foo")
|
||||
|
||||
op.ForceReplace = []addrs.AbsResourceInstance{addr}
|
||||
op.Workspace = backend.DefaultStateName
|
||||
|
||||
run, err := b.Operation(context.Background(), op)
|
||||
if err != nil {
|
||||
t.Fatalf("error starting operation: %v", err)
|
||||
}
|
||||
|
||||
<-run.Done()
|
||||
if run.Result != backend.OperationSuccess {
|
||||
t.Fatal("expected plan operation to succeed")
|
||||
}
|
||||
if run.PlanEmpty {
|
||||
t.Fatalf("expected plan to be non-empty")
|
||||
}
|
||||
|
||||
// We should find a run inside the mock client that has the same
|
||||
// refresh address we requested above.
|
||||
runsAPI := b.client.Runs.(*mockRuns)
|
||||
if got, want := len(runsAPI.runs), 1; got != want {
|
||||
t.Fatalf("wrong number of runs in the mock client %d; want %d", got, want)
|
||||
}
|
||||
for _, run := range runsAPI.runs {
|
||||
if diff := cmp.Diff([]string{"null_resource.foo"}, run.ReplaceAddrs); diff != "" {
|
||||
t.Errorf("wrong ReplaceAddrs in the created run\n%s", diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemote_applyWithReplaceIncompatibleAPIVersion(t *testing.T) {
|
||||
b, bCleanup := testBackendDefault(t)
|
||||
defer bCleanup()
|
||||
|
||||
op, configCleanup, done := testOperationApply(t, "./testdata/apply")
|
||||
defer configCleanup()
|
||||
|
||||
b.client.SetFakeRemoteAPIVersion("2.3")
|
||||
|
||||
addr, _ := addrs.ParseAbsResourceInstanceStr("null_resource.foo")
|
||||
|
||||
op.ForceReplace = []addrs.AbsResourceInstance{addr}
|
||||
op.Workspace = backend.DefaultStateName
|
||||
|
||||
run, err := b.Operation(context.Background(), op)
|
||||
if err != nil {
|
||||
t.Fatalf("error starting operation: %v", err)
|
||||
}
|
||||
|
||||
<-run.Done()
|
||||
output := done(t)
|
||||
if run.Result == backend.OperationSuccess {
|
||||
t.Fatal("expected apply operation to fail")
|
||||
}
|
||||
if !run.PlanEmpty {
|
||||
t.Fatalf("expected plan to be empty")
|
||||
}
|
||||
|
||||
errOutput := output.Stderr()
|
||||
if !strings.Contains(errOutput, "Planning resource replacements is not supported") {
|
||||
t.Fatalf("expected a not supported error, got: %v", errOutput)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemote_applyWithVariables(t *testing.T) {
|
||||
b, bCleanup := testBackendDefault(t)
|
||||
defer bCleanup()
|
||||
|
|
|
@ -788,6 +788,7 @@ func (m *mockRuns) Create(ctx context.Context, options tfe.RunCreateOptions) (*t
|
|||
HasChanges: false,
|
||||
Permissions: &tfe.RunPermissions{},
|
||||
Plan: p,
|
||||
ReplaceAddrs: options.ReplaceAddrs,
|
||||
Status: tfe.RunPending,
|
||||
TargetAddrs: options.TargetAddrs,
|
||||
}
|
||||
|
@ -804,6 +805,14 @@ func (m *mockRuns) Create(ctx context.Context, options tfe.RunCreateOptions) (*t
|
|||
r.IsDestroy = *options.IsDestroy
|
||||
}
|
||||
|
||||
if options.Refresh != nil {
|
||||
r.Refresh = *options.Refresh
|
||||
}
|
||||
|
||||
if options.RefreshOnly != nil {
|
||||
r.RefreshOnly = *options.RefreshOnly
|
||||
}
|
||||
|
||||
w, ok := m.client.Workspaces.workspaceIDs[options.Workspace.ID]
|
||||
if !ok {
|
||||
return nil, tfe.ErrResourceNotFound
|
||||
|
|
|
@ -284,6 +284,45 @@ func TestRemote_planWithoutRefresh(t *testing.T) {
|
|||
|
||||
op, configCleanup, done := testOperationPlan(t, "./testdata/plan")
|
||||
defer configCleanup()
|
||||
defer done(t)
|
||||
|
||||
op.PlanRefresh = false
|
||||
op.Workspace = backend.DefaultStateName
|
||||
|
||||
run, err := b.Operation(context.Background(), op)
|
||||
if err != nil {
|
||||
t.Fatalf("error starting operation: %v", err)
|
||||
}
|
||||
|
||||
<-run.Done()
|
||||
if run.Result != backend.OperationSuccess {
|
||||
t.Fatalf("operation failed: %s", b.CLI.(*cli.MockUi).ErrorWriter.String())
|
||||
}
|
||||
if run.PlanEmpty {
|
||||
t.Fatal("expected a non-empty plan")
|
||||
}
|
||||
|
||||
// We should find a run inside the mock client that has refresh set
|
||||
// to false.
|
||||
runsAPI := b.client.Runs.(*mockRuns)
|
||||
if got, want := len(runsAPI.runs), 1; got != want {
|
||||
t.Fatalf("wrong number of runs in the mock client %d; want %d", got, want)
|
||||
}
|
||||
for _, run := range runsAPI.runs {
|
||||
if diff := cmp.Diff(false, run.Refresh); diff != "" {
|
||||
t.Errorf("wrong Refresh setting in the created run\n%s", diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemote_planWithoutRefreshIncompatibleAPIVersion(t *testing.T) {
|
||||
b, bCleanup := testBackendDefault(t)
|
||||
defer bCleanup()
|
||||
|
||||
op, configCleanup, done := testOperationPlan(t, "./testdata/plan")
|
||||
defer configCleanup()
|
||||
|
||||
b.client.SetFakeRemoteAPIVersion("2.3")
|
||||
|
||||
op.PlanRefresh = false
|
||||
op.Workspace = backend.DefaultStateName
|
||||
|
@ -298,10 +337,82 @@ func TestRemote_planWithoutRefresh(t *testing.T) {
|
|||
if run.Result == backend.OperationSuccess {
|
||||
t.Fatal("expected plan operation to fail")
|
||||
}
|
||||
if !run.PlanEmpty {
|
||||
t.Fatalf("expected plan to be empty")
|
||||
}
|
||||
|
||||
errOutput := output.Stderr()
|
||||
if !strings.Contains(errOutput, "refresh is currently not supported") {
|
||||
t.Fatalf("expected a refresh error, got: %v", errOutput)
|
||||
if !strings.Contains(errOutput, "Planning without refresh is not supported") {
|
||||
t.Fatalf("expected not supported error, got: %v", errOutput)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemote_planWithRefreshOnly(t *testing.T) {
|
||||
b, bCleanup := testBackendDefault(t)
|
||||
defer bCleanup()
|
||||
|
||||
op, configCleanup, done := testOperationPlan(t, "./testdata/plan")
|
||||
defer configCleanup()
|
||||
defer done(t)
|
||||
|
||||
op.PlanMode = plans.RefreshOnlyMode
|
||||
op.Workspace = backend.DefaultStateName
|
||||
|
||||
run, err := b.Operation(context.Background(), op)
|
||||
if err != nil {
|
||||
t.Fatalf("error starting operation: %v", err)
|
||||
}
|
||||
|
||||
<-run.Done()
|
||||
if run.Result != backend.OperationSuccess {
|
||||
t.Fatalf("operation failed: %s", b.CLI.(*cli.MockUi).ErrorWriter.String())
|
||||
}
|
||||
if run.PlanEmpty {
|
||||
t.Fatal("expected a non-empty plan")
|
||||
}
|
||||
|
||||
// We should find a run inside the mock client that has refresh-only set
|
||||
// to true.
|
||||
runsAPI := b.client.Runs.(*mockRuns)
|
||||
if got, want := len(runsAPI.runs), 1; got != want {
|
||||
t.Fatalf("wrong number of runs in the mock client %d; want %d", got, want)
|
||||
}
|
||||
for _, run := range runsAPI.runs {
|
||||
if diff := cmp.Diff(true, run.RefreshOnly); diff != "" {
|
||||
t.Errorf("wrong RefreshOnly setting in the created run\n%s", diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemote_planWithRefreshOnlyIncompatibleAPIVersion(t *testing.T) {
|
||||
b, bCleanup := testBackendDefault(t)
|
||||
defer bCleanup()
|
||||
|
||||
op, configCleanup, done := testOperationPlan(t, "./testdata/plan")
|
||||
defer configCleanup()
|
||||
|
||||
b.client.SetFakeRemoteAPIVersion("2.3")
|
||||
|
||||
op.PlanMode = plans.RefreshOnlyMode
|
||||
op.Workspace = backend.DefaultStateName
|
||||
|
||||
run, err := b.Operation(context.Background(), op)
|
||||
if err != nil {
|
||||
t.Fatalf("error starting operation: %v", err)
|
||||
}
|
||||
|
||||
<-run.Done()
|
||||
output := done(t)
|
||||
if run.Result == backend.OperationSuccess {
|
||||
t.Fatal("expected plan operation to fail")
|
||||
}
|
||||
if !run.PlanEmpty {
|
||||
t.Fatalf("expected plan to be empty")
|
||||
}
|
||||
|
||||
errOutput := output.Stderr()
|
||||
if !strings.Contains(errOutput, "Refresh-only mode is not supported") {
|
||||
t.Fatalf("expected not supported error, got: %v", errOutput)
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -414,6 +525,79 @@ func TestRemote_planWithTargetIncompatibleAPIVersion(t *testing.T) {
|
|||
}
|
||||
}
|
||||
|
||||
func TestRemote_planWithReplace(t *testing.T) {
|
||||
b, bCleanup := testBackendDefault(t)
|
||||
defer bCleanup()
|
||||
|
||||
op, configCleanup, done := testOperationPlan(t, "./testdata/plan")
|
||||
defer configCleanup()
|
||||
defer done(t)
|
||||
|
||||
addr, _ := addrs.ParseAbsResourceInstanceStr("null_resource.foo")
|
||||
|
||||
op.ForceReplace = []addrs.AbsResourceInstance{addr}
|
||||
op.Workspace = backend.DefaultStateName
|
||||
|
||||
run, err := b.Operation(context.Background(), op)
|
||||
if err != nil {
|
||||
t.Fatalf("error starting operation: %v", err)
|
||||
}
|
||||
|
||||
<-run.Done()
|
||||
if run.Result != backend.OperationSuccess {
|
||||
t.Fatal("expected plan operation to succeed")
|
||||
}
|
||||
if run.PlanEmpty {
|
||||
t.Fatalf("expected plan to be non-empty")
|
||||
}
|
||||
|
||||
// We should find a run inside the mock client that has the same
|
||||
// refresh address we requested above.
|
||||
runsAPI := b.client.Runs.(*mockRuns)
|
||||
if got, want := len(runsAPI.runs), 1; got != want {
|
||||
t.Fatalf("wrong number of runs in the mock client %d; want %d", got, want)
|
||||
}
|
||||
for _, run := range runsAPI.runs {
|
||||
if diff := cmp.Diff([]string{"null_resource.foo"}, run.ReplaceAddrs); diff != "" {
|
||||
t.Errorf("wrong ReplaceAddrs in the created run\n%s", diff)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemote_planWithReplaceIncompatibleAPIVersion(t *testing.T) {
|
||||
b, bCleanup := testBackendDefault(t)
|
||||
defer bCleanup()
|
||||
|
||||
op, configCleanup, done := testOperationPlan(t, "./testdata/plan")
|
||||
defer configCleanup()
|
||||
|
||||
b.client.SetFakeRemoteAPIVersion("2.3")
|
||||
|
||||
addr, _ := addrs.ParseAbsResourceInstanceStr("null_resource.foo")
|
||||
|
||||
op.ForceReplace = []addrs.AbsResourceInstance{addr}
|
||||
op.Workspace = backend.DefaultStateName
|
||||
|
||||
run, err := b.Operation(context.Background(), op)
|
||||
if err != nil {
|
||||
t.Fatalf("error starting operation: %v", err)
|
||||
}
|
||||
|
||||
<-run.Done()
|
||||
output := done(t)
|
||||
if run.Result == backend.OperationSuccess {
|
||||
t.Fatal("expected plan operation to fail")
|
||||
}
|
||||
if !run.PlanEmpty {
|
||||
t.Fatalf("expected plan to be empty")
|
||||
}
|
||||
|
||||
errOutput := output.Stderr()
|
||||
if !strings.Contains(errOutput, "Planning resource replacements is not supported") {
|
||||
t.Fatalf("expected not supported error, got: %v", errOutput)
|
||||
}
|
||||
}
|
||||
|
||||
func TestRemote_planWithVariables(t *testing.T) {
|
||||
b, bCleanup := testBackendDefault(t)
|
||||
defer bCleanup()
|
||||
|
|
|
@ -200,7 +200,7 @@ func testServer(t *testing.T) *httptest.Server {
|
|||
// Respond to pings to get the API version header.
|
||||
mux.HandleFunc("/api/v2/ping", func(w http.ResponseWriter, r *http.Request) {
|
||||
w.Header().Set("Content-Type", "application/json")
|
||||
w.Header().Set("TFP-API-Version", "2.3")
|
||||
w.Header().Set("TFP-API-Version", "2.4")
|
||||
})
|
||||
|
||||
// Respond to the initial query to read the hashicorp org entitlements.
|
||||
|
|
Loading…
Reference in New Issue