Skip to content

Commit 39d1293

Browse files
authored
actions: consider event type when comparing action triggers (#37733)
1 parent c4a7f00 commit 39d1293

File tree

2 files changed

+173
-2
lines changed

2 files changed

+173
-2
lines changed

internal/plans/action_invocation.go

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,8 @@ func (t *LifecycleActionTrigger) Equals(other ActionTrigger) bool {
7979

8080
return t.TriggeringResourceAddr.Equal(o.TriggeringResourceAddr) &&
8181
t.ActionTriggerBlockIndex == o.ActionTriggerBlockIndex &&
82-
t.ActionsListIndex == o.ActionsListIndex
82+
t.ActionsListIndex == o.ActionsListIndex &&
83+
t.ActionTriggerEvent == o.ActionTriggerEvent
8384
}
8485

8586
func (t *LifecycleActionTrigger) Less(other ActionTrigger) bool {
@@ -93,7 +94,8 @@ func (t *LifecycleActionTrigger) Less(other ActionTrigger) bool {
9394
t.ActionTriggerBlockIndex < o.ActionTriggerBlockIndex) ||
9495
(t.TriggeringResourceAddr.Equal(o.TriggeringResourceAddr) &&
9596
t.ActionTriggerBlockIndex == o.ActionTriggerBlockIndex &&
96-
t.ActionsListIndex < o.ActionsListIndex)
97+
t.ActionsListIndex < o.ActionsListIndex &&
98+
t.ActionTriggerEvent < o.ActionTriggerEvent)
9799
}
98100

99101
type InvokeActionTrigger struct{}

internal/terraform/context_apply_action_test.go

Lines changed: 169 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import (
77
"path/filepath"
88
"testing"
99

10+
"github.com/google/go-cmp/cmp"
1011
"github.com/hashicorp/hcl/v2"
1112
"github.com/zclconf/go-cty/cty"
1213

@@ -39,6 +40,8 @@ func TestContextApply_actions(t *testing.T) {
3940
expectInvokeActionCallsAreUnordered bool
4041
expectDiagnostics func(m *configs.Config) tfdiags.Diagnostics
4142
ignoreWarnings bool
43+
44+
assertHooks func(*testing.T, actionHookCapture)
4245
}{
4346
"before_create triggered": {
4447
module: map[string]string{
@@ -74,6 +77,55 @@ resource "test_object" "a" {
7477
expectInvokeActionCalled: true,
7578
},
7679

80+
"before and after created triggered": {
81+
module: map[string]string{
82+
"main.tf": `
83+
action "action_example" "hello" {}
84+
resource "test_object" "a" {
85+
lifecycle {
86+
action_trigger {
87+
events = [before_create,after_create]
88+
actions = [action.action_example.hello]
89+
}
90+
}
91+
}
92+
`,
93+
},
94+
expectInvokeActionCalled: true,
95+
assertHooks: func(t *testing.T, capture actionHookCapture) {
96+
if len(capture.startActionHooks) != 2 {
97+
t.Error("expected 2 start action hooks")
98+
}
99+
if len(capture.completeActionHooks) != 2 {
100+
t.Error("expected 2 complete action hooks")
101+
}
102+
103+
evaluateHook := func(got HookActionIdentity, wantAddr string, wantEvent configs.ActionTriggerEvent) {
104+
trigger := got.ActionTrigger.(*plans.LifecycleActionTrigger)
105+
106+
if trigger.ActionTriggerEvent != wantEvent {
107+
t.Errorf("wrong event, got %s, want %s", trigger.ActionTriggerEvent, wantEvent)
108+
}
109+
if diff := cmp.Diff(got.Addr.String(), wantAddr); len(diff) > 0 {
110+
t.Errorf("wrong address: %s", diff)
111+
}
112+
}
113+
114+
// the before should have happened first, and the order should
115+
// be correct.
116+
117+
beforeStart := capture.startActionHooks[0]
118+
beforeComplete := capture.completeActionHooks[0]
119+
evaluateHook(beforeStart, "action.action_example.hello", configs.BeforeCreate)
120+
evaluateHook(beforeComplete, "action.action_example.hello", configs.BeforeCreate)
121+
122+
afterStart := capture.startActionHooks[1]
123+
afterComplete := capture.completeActionHooks[1]
124+
evaluateHook(afterStart, "action.action_example.hello", configs.AfterCreate)
125+
evaluateHook(afterComplete, "action.action_example.hello", configs.AfterCreate)
126+
},
127+
},
128+
77129
"before_update triggered": {
78130
module: map[string]string{
79131
"main.tf": `
@@ -2551,6 +2603,7 @@ lifecycle {
25512603
InvokeActionFn: invokeActionFn,
25522604
}
25532605

2606+
hookCapture := actionHookCapture{}
25542607
ctx := testContext2(t, &ContextOpts{
25552608
Providers: map[addrs.Provider]providers.Factory{
25562609
addrs.NewDefaultProvider("test"): testProviderFuncFixed(testProvider),
@@ -2561,6 +2614,9 @@ lifecycle {
25612614
Hostname: addrs.DefaultProviderRegistryHost,
25622615
}: testProviderFuncFixed(ecosystem),
25632616
},
2617+
Hooks: []Hook{
2618+
&hookCapture,
2619+
},
25642620
})
25652621

25662622
// Just a sanity check that the module is valid
@@ -2627,6 +2683,119 @@ lifecycle {
26272683
}
26282684
}
26292685
}
2686+
2687+
if tc.assertHooks != nil {
2688+
tc.assertHooks(t, hookCapture)
2689+
}
26302690
})
26312691
}
26322692
}
2693+
2694+
var _ Hook = (*actionHookCapture)(nil)
2695+
2696+
type actionHookCapture struct {
2697+
startActionHooks []HookActionIdentity
2698+
completeActionHooks []HookActionIdentity
2699+
}
2700+
2701+
func (a *actionHookCapture) PreApply(HookResourceIdentity, addrs.DeposedKey, plans.Action, cty.Value, cty.Value) (HookAction, error) {
2702+
return HookActionContinue, nil
2703+
}
2704+
2705+
func (a *actionHookCapture) PostApply(HookResourceIdentity, addrs.DeposedKey, cty.Value, error) (HookAction, error) {
2706+
return HookActionContinue, nil
2707+
}
2708+
2709+
func (a *actionHookCapture) PreDiff(HookResourceIdentity, addrs.DeposedKey, cty.Value, cty.Value) (HookAction, error) {
2710+
return HookActionContinue, nil
2711+
}
2712+
2713+
func (a *actionHookCapture) PostDiff(HookResourceIdentity, addrs.DeposedKey, plans.Action, cty.Value, cty.Value) (HookAction, error) {
2714+
return HookActionContinue, nil
2715+
}
2716+
2717+
func (a *actionHookCapture) PreProvisionInstance(HookResourceIdentity, cty.Value) (HookAction, error) {
2718+
return HookActionContinue, nil
2719+
}
2720+
2721+
func (a *actionHookCapture) PostProvisionInstance(HookResourceIdentity, cty.Value) (HookAction, error) {
2722+
return HookActionContinue, nil
2723+
}
2724+
2725+
func (a *actionHookCapture) PreProvisionInstanceStep(HookResourceIdentity, string) (HookAction, error) {
2726+
return HookActionContinue, nil
2727+
}
2728+
2729+
func (a *actionHookCapture) PostProvisionInstanceStep(HookResourceIdentity, string, error) (HookAction, error) {
2730+
return HookActionContinue, nil
2731+
}
2732+
2733+
func (a *actionHookCapture) ProvisionOutput(HookResourceIdentity, string, string) {}
2734+
2735+
func (a *actionHookCapture) PreRefresh(HookResourceIdentity, addrs.DeposedKey, cty.Value) (HookAction, error) {
2736+
return HookActionContinue, nil
2737+
}
2738+
2739+
func (a *actionHookCapture) PostRefresh(HookResourceIdentity, addrs.DeposedKey, cty.Value, cty.Value) (HookAction, error) {
2740+
return HookActionContinue, nil
2741+
}
2742+
2743+
func (a *actionHookCapture) PreImportState(HookResourceIdentity, string) (HookAction, error) {
2744+
return HookActionContinue, nil
2745+
}
2746+
2747+
func (a *actionHookCapture) PostImportState(HookResourceIdentity, []providers.ImportedResource) (HookAction, error) {
2748+
return HookActionContinue, nil
2749+
}
2750+
2751+
func (a *actionHookCapture) PrePlanImport(HookResourceIdentity, cty.Value) (HookAction, error) {
2752+
return HookActionContinue, nil
2753+
}
2754+
2755+
func (a *actionHookCapture) PostPlanImport(HookResourceIdentity, []providers.ImportedResource) (HookAction, error) {
2756+
return HookActionContinue, nil
2757+
}
2758+
2759+
func (a *actionHookCapture) PreApplyImport(HookResourceIdentity, plans.ImportingSrc) (HookAction, error) {
2760+
return HookActionContinue, nil
2761+
}
2762+
2763+
func (a *actionHookCapture) PostApplyImport(HookResourceIdentity, plans.ImportingSrc) (HookAction, error) {
2764+
return HookActionContinue, nil
2765+
}
2766+
2767+
func (a *actionHookCapture) PreEphemeralOp(HookResourceIdentity, plans.Action) (HookAction, error) {
2768+
return HookActionContinue, nil
2769+
}
2770+
2771+
func (a *actionHookCapture) PostEphemeralOp(HookResourceIdentity, plans.Action, error) (HookAction, error) {
2772+
return HookActionContinue, nil
2773+
}
2774+
2775+
func (a *actionHookCapture) PreListQuery(HookResourceIdentity, cty.Value) (HookAction, error) {
2776+
return HookActionContinue, nil
2777+
}
2778+
2779+
func (a *actionHookCapture) PostListQuery(HookResourceIdentity, plans.QueryResults, int64) (HookAction, error) {
2780+
return HookActionContinue, nil
2781+
}
2782+
2783+
func (a *actionHookCapture) StartAction(identity HookActionIdentity) (HookAction, error) {
2784+
a.startActionHooks = append(a.startActionHooks, identity)
2785+
return HookActionContinue, nil
2786+
}
2787+
2788+
func (a *actionHookCapture) ProgressAction(HookActionIdentity, string) (HookAction, error) {
2789+
return HookActionContinue, nil
2790+
}
2791+
2792+
func (a *actionHookCapture) CompleteAction(identity HookActionIdentity, _ error) (HookAction, error) {
2793+
a.completeActionHooks = append(a.completeActionHooks, identity)
2794+
return HookActionContinue, nil
2795+
}
2796+
2797+
func (a *actionHookCapture) Stopping() {}
2798+
2799+
func (a *actionHookCapture) PostStateUpdate(*states.State) (HookAction, error) {
2800+
return HookActionContinue, nil
2801+
}

0 commit comments

Comments
 (0)