Skip to content
Merged
Show file tree
Hide file tree
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions backend/remote/backend_common.go
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,10 @@ func (b *Remote) costEstimate(stopCtx, cancelCtx context.Context, op *backend.Op
b.CLI.Output(b.Colorize().Color("Waiting for cost estimate to complete..." + elapsed + "\n"))
}
continue
case "skipped_due_to_targeting": // TEMP: not available in the go-tfe library yet; will update this to be tfe.CostEstimateSkippedDueToTargeting once that's available.
Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We're planning to submit this tfe.CostEstimateSkippedDueToTargeting upstream to go-tfe asynchronously from getting this PR in. Will update this to use the named constant in a subsequent PR once it's included in a go-tfe release.

b.CLI.Output("Not available for this plan, because it was created with the -target option.")
b.CLI.Output("\n------------------------------------------------------------------------")
return nil
case tfe.CostEstimateErrored:
return fmt.Errorf(msgPrefix + " errored.")
case tfe.CostEstimateCanceled:
Expand Down
11 changes: 11 additions & 0 deletions backend/remote/backend_mock.go
Original file line number Diff line number Diff line change
Expand Up @@ -696,6 +696,11 @@ type mockRuns struct {
client *mockClient
runs map[string]*tfe.Run
workspaces map[string][]*tfe.Run

// If modifyNewRun is non-nil, the create method will call it just before
// saving a new run in the runs map, so that a calling test can mimic
// side-effects that a real server might apply in certain situations.
modifyNewRun func(client *mockClient, options tfe.RunCreateOptions, run *tfe.Run)
}

func newMockRuns(client *mockClient) *mockRuns {
Expand Down Expand Up @@ -780,6 +785,12 @@ func (m *mockRuns) Create(ctx context.Context, options tfe.RunCreateOptions) (*t
w.CurrentRun = r
}

if m.modifyNewRun != nil {
// caller-provided callback may modify the run in-place to mimic
// side-effects that a real server might take in some situations.
m.modifyNewRun(m.client, options, r)
}

m.runs[r.ID] = r
m.workspaces[options.Workspace.ID] = append(m.workspaces[options.Workspace.ID], r)

Expand Down
32 changes: 31 additions & 1 deletion backend/remote/backend_plan_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -270,6 +270,29 @@ func TestRemote_planWithTarget(t *testing.T) {
b, bCleanup := testBackendDefault(t)
defer bCleanup()

// When the backend code creates a new run, we'll tweak it so that it
// has a cost estimation object with the "skipped_due_to_targeting" status,
// emulating how a real server is expected to behave in that case.
b.client.Runs.(*mockRuns).modifyNewRun = func(client *mockClient, options tfe.RunCreateOptions, run *tfe.Run) {
const fakeID = "fake"
// This is the cost estimate object embedded in the run itself which
// the backend will use to learn the ID to request from the cost
// estimates endpoint. It's pending to simulate what a freshly-created
// run is likely to look like.
run.CostEstimate = &tfe.CostEstimate{
ID: fakeID,
Status: "pending",
}
// The backend will then use the main cost estimation API to retrieve
// the same ID indicated in the object above, where we'll then return
// the status "skipped_due_to_targeting" to trigger the special skip
// message in the backend output.
client.CostEstimates.estimations[fakeID] = &tfe.CostEstimate{
ID: fakeID,
Status: "skipped_due_to_targeting",
}
}

op, configCleanup := testOperationPlan(t, "./testdata/plan")
defer configCleanup()

Expand All @@ -291,6 +314,13 @@ func TestRemote_planWithTarget(t *testing.T) {
t.Fatalf("expected plan to be non-empty")
}

// testBackendDefault above attached a "mock UI" to our backend, so we
// can retrieve its non-error output via the OutputWriter in-memory buffer.
gotOutput := b.CLI.(*cli.MockUi).OutputWriter.String()
if wantOutput := "Not available for this plan, because it was created with the -target option."; !strings.Contains(gotOutput, wantOutput) {
t.Errorf("missing message about skipped cost estimation\ngot:\n%s\nwant substring: %s", gotOutput, wantOutput)
}

// We should find a run inside the mock client that has the same
// target address we requested above.
runsAPI := b.client.Runs.(*mockRuns)
Expand All @@ -303,7 +333,7 @@ func TestRemote_planWithTarget(t *testing.T) {
}

if !strings.Contains(run.Message, "using -target") {
t.Fatalf("incorrrect Message on the created run: %s", run.Message)
t.Errorf("incorrect Message on the created run: %s", run.Message)
}
}
}
Expand Down