diff --git a/internal/stacks/stackruntime/internal/stackeval/applying_test.go b/internal/stacks/stackruntime/internal/stackeval/applying_test.go index a55d7092f3..59ba8d18cd 100644 --- a/internal/stacks/stackruntime/internal/stackeval/applying_test.go +++ b/internal/stacks/stackruntime/internal/stackeval/applying_test.go @@ -10,6 +10,7 @@ import ( "strings" "sync" "testing" + "time" "github.com/davecgh/go-spew/spew" "github.com/google/go-cmp/cmp" @@ -128,6 +129,7 @@ func TestApply_componentOrdering(t *testing.T) { }, nil }, }, + PlanTimestamp: time.Now().UTC(), }) outp, outpTester := testPlanOutput(t) @@ -287,6 +289,7 @@ func TestApply_componentOrdering(t *testing.T) { }, nil }, }, + PlanTimestamp: time.Now().UTC(), }) outp, outpTester := testPlanOutput(t) diff --git a/internal/stacks/stackruntime/internal/stackeval/diagnostics_test.go b/internal/stacks/stackruntime/internal/stackeval/diagnostics_test.go index d9bc3b9778..2bbee476a5 100644 --- a/internal/stacks/stackruntime/internal/stackeval/diagnostics_test.go +++ b/internal/stacks/stackruntime/internal/stackeval/diagnostics_test.go @@ -5,6 +5,7 @@ package stackeval import ( "testing" + "time" "github.com/google/go-cmp/cmp" "github.com/zclconf/go-cty/cty" @@ -64,6 +65,7 @@ func TestNamedPromisesPlan(t *testing.T) { }, ), }, + PlanTimestamp: time.Now().UTC(), }) // We don't actually really care about the plan here. We just want the diff --git a/internal/stacks/stackruntime/internal/stackeval/main.go b/internal/stacks/stackruntime/internal/stackeval/main.go index 5efc35b178..6d4ceaa728 100644 --- a/internal/stacks/stackruntime/internal/stackeval/main.go +++ b/internal/stacks/stackruntime/internal/stackeval/main.go @@ -91,12 +91,8 @@ type mainPlanning struct { opts PlanOpts prevState *stackstate.State - // This is a utility for unit tests that want to encourage stable output - // to assert against. Not for real use. - forcePlanTimestamp *time.Time - // This is the plan timestamp that will be used for the plan if forcePlanTimestamp is not set. - planTimestamp *time.Time + planTimestamp time.Time } type mainApplying struct { @@ -131,9 +127,9 @@ func NewForPlanning(config *stackconfig.Config, prevState *stackstate.State, opt return &Main{ config: config, planning: &mainPlanning{ - opts: opts, - prevState: prevState, - forcePlanTimestamp: opts.ForcePlanTimestamp, + opts: opts, + prevState: prevState, + planTimestamp: opts.PlanTimestamp, }, providerFactories: opts.ProviderFactories, providerTypes: make(map[addrs.Provider]*ProviderType), @@ -611,20 +607,7 @@ func (m *Main) PlanTimestamp() time.Time { return m.applying.plan.PlanTimestamp } if m.planning != nil { - if m.planning.forcePlanTimestamp != nil { - return *m.planning.forcePlanTimestamp - } - - if m.planning.planTimestamp != nil { - return *m.planning.planTimestamp - } - - // We have not yet set the planTimestamp, so we set it now - now := time.Now().UTC() - m.mu.Lock() - defer m.mu.Unlock() - m.planning.planTimestamp = &now - return now + return m.planning.planTimestamp } // This is the default case, we are not planning / applying diff --git a/internal/stacks/stackruntime/internal/stackeval/planning.go b/internal/stacks/stackruntime/internal/stackeval/planning.go index 3a20b9a814..8811d282fd 100644 --- a/internal/stacks/stackruntime/internal/stackeval/planning.go +++ b/internal/stacks/stackruntime/internal/stackeval/planning.go @@ -20,10 +20,7 @@ type PlanOpts struct { ProviderFactories ProviderFactories - // ForcePlanTimestamp, if not nil, will force the plantimestamp function - // to return the given time instead of whatever real time the plan was - // started. This is here for unit testing only. - ForcePlanTimestamp *time.Time + PlanTimestamp time.Time } // Plannable is implemented by objects that can participate in planning. diff --git a/internal/stacks/stackruntime/internal/stackeval/planning_test.go b/internal/stacks/stackruntime/internal/stackeval/planning_test.go index b9f8c4236d..8f0b30949c 100644 --- a/internal/stacks/stackruntime/internal/stackeval/planning_test.go +++ b/internal/stacks/stackruntime/internal/stackeval/planning_test.go @@ -10,6 +10,7 @@ import ( "path/filepath" "strings" "testing" + "time" "github.com/davecgh/go-spew/spew" "github.com/google/go-cmp/cmp" @@ -158,7 +159,8 @@ func TestPlanning_DestroyMode(t *testing.T) { }, } main := NewForPlanning(cfg, priorState, PlanOpts{ - PlanningMode: plans.DestroyMode, + PlanningMode: plans.DestroyMode, + PlanTimestamp: time.Now().UTC(), ProviderFactories: ProviderFactories{ addrs.NewBuiltInProvider("test"): func() (providers.Interface, error) { return &providerTesting.MockProvider{ @@ -368,6 +370,7 @@ func TestPlanning_RequiredComponents(t *testing.T) { }, nil }, }, + PlanTimestamp: time.Now().UTC(), }) cmpA := stackaddrs.AbsComponent{ @@ -596,7 +599,8 @@ func TestPlanning_DeferredChangesPropagation(t *testing.T) { cfg := testStackConfig(t, "planning", "deferred_changes_propagation") main := NewForPlanning(cfg, stackstate.NewState(), PlanOpts{ - PlanningMode: plans.NormalMode, + PlanningMode: plans.NormalMode, + PlanTimestamp: time.Now().UTC(), InputVariableValues: map[stackaddrs.InputVariable]ExternalInputValue{ // This causes the first component to have a module whose // instance count isn't known yet. @@ -745,6 +749,7 @@ func TestPlanning_RemoveDataResource(t *testing.T) { main := NewForPlanning(cfg, stackstate.NewState(), PlanOpts{ PlanningMode: plans.NormalMode, ProviderFactories: providerFactories, + PlanTimestamp: time.Now().UTC(), }) outp, outpTest := testPlanOutput(t) main.PlanAll(ctx, outp) @@ -801,6 +806,7 @@ func TestPlanning_RemoveDataResource(t *testing.T) { main := NewForPlanning(cfg, state, PlanOpts{ PlanningMode: plans.NormalMode, ProviderFactories: providerFactories, + PlanTimestamp: time.Now().UTC(), }) outp, outpTest := testPlanOutput(t) main.PlanAll(ctx, outp) @@ -883,7 +889,8 @@ func TestPlanning_RemoveDataResource(t *testing.T) { func TestPlanning_PathValues(t *testing.T) { cfg := testStackConfig(t, "planning", "path_values") main := NewForPlanning(cfg, stackstate.NewState(), PlanOpts{ - PlanningMode: plans.NormalMode, + PlanningMode: plans.NormalMode, + PlanTimestamp: time.Now().UTC(), }) inPromisingTask(t, func(ctx context.Context, t *testing.T) { @@ -1009,6 +1016,7 @@ func TestPlanning_LocalsDataSource(t *testing.T) { main := NewForPlanning(cfg, stackstate.NewState(), PlanOpts{ PlanningMode: plans.NormalMode, ProviderFactories: providerFactories, + PlanTimestamp: time.Now().UTC(), }) comp2Addr := stackaddrs.AbsComponentInstance{ diff --git a/internal/stacks/stackruntime/plan.go b/internal/stacks/stackruntime/plan.go index a9afc72f41..9d20bd4e76 100644 --- a/internal/stacks/stackruntime/plan.go +++ b/internal/stacks/stackruntime/plan.go @@ -40,12 +40,17 @@ func Plan(ctx context.Context, req *PlanRequest, resp *PlanResponse) { var errored, applyable bool + planTimestamp := time.Now().UTC() + if req.ForcePlanTimestamp != nil { + planTimestamp = *req.ForcePlanTimestamp + } + main := stackeval.NewForPlanning(req.Config, req.PrevState, stackeval.PlanOpts{ PlanningMode: req.PlanMode, InputVariableValues: req.InputValues, ProviderFactories: req.ProviderFactories, - ForcePlanTimestamp: req.ForcePlanTimestamp, + PlanTimestamp: planTimestamp, }) main.AllowLanguageExperiments(req.ExperimentsAllowed) main.PlanAll(ctx, stackeval.PlanOutput{