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