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" : `
@@ -2511,6 +2563,7 @@ lifecycle {
25112563 InvokeActionFn : invokeActionFn ,
25122564 }
25132565
2566+ hookCapture := actionHookCapture {}
25142567 ctx := testContext2 (t , & ContextOpts {
25152568 Providers : map [addrs.Provider ]providers.Factory {
25162569 addrs .NewDefaultProvider ("test" ): testProviderFuncFixed (testProvider ),
@@ -2521,6 +2574,9 @@ lifecycle {
25212574 Hostname : addrs .DefaultProviderRegistryHost ,
25222575 }: testProviderFuncFixed (ecosystem ),
25232576 },
2577+ Hooks : []Hook {
2578+ & hookCapture ,
2579+ },
25242580 })
25252581
25262582 // Just a sanity check that the module is valid
@@ -2587,6 +2643,119 @@ lifecycle {
25872643 }
25882644 }
25892645 }
2646+
2647+ if tc .assertHooks != nil {
2648+ tc .assertHooks (t , hookCapture )
2649+ }
25902650 })
25912651 }
25922652}
2653+
2654+ var _ Hook = (* actionHookCapture )(nil )
2655+
2656+ type actionHookCapture struct {
2657+ startActionHooks []HookActionIdentity
2658+ completeActionHooks []HookActionIdentity
2659+ }
2660+
2661+ func (a * actionHookCapture ) PreApply (HookResourceIdentity , addrs.DeposedKey , plans.Action , cty.Value , cty.Value ) (HookAction , error ) {
2662+ return HookActionContinue , nil
2663+ }
2664+
2665+ func (a * actionHookCapture ) PostApply (HookResourceIdentity , addrs.DeposedKey , cty.Value , error ) (HookAction , error ) {
2666+ return HookActionContinue , nil
2667+ }
2668+
2669+ func (a * actionHookCapture ) PreDiff (HookResourceIdentity , addrs.DeposedKey , cty.Value , cty.Value ) (HookAction , error ) {
2670+ return HookActionContinue , nil
2671+ }
2672+
2673+ func (a * actionHookCapture ) PostDiff (HookResourceIdentity , addrs.DeposedKey , plans.Action , cty.Value , cty.Value ) (HookAction , error ) {
2674+ return HookActionContinue , nil
2675+ }
2676+
2677+ func (a * actionHookCapture ) PreProvisionInstance (HookResourceIdentity , cty.Value ) (HookAction , error ) {
2678+ return HookActionContinue , nil
2679+ }
2680+
2681+ func (a * actionHookCapture ) PostProvisionInstance (HookResourceIdentity , cty.Value ) (HookAction , error ) {
2682+ return HookActionContinue , nil
2683+ }
2684+
2685+ func (a * actionHookCapture ) PreProvisionInstanceStep (HookResourceIdentity , string ) (HookAction , error ) {
2686+ return HookActionContinue , nil
2687+ }
2688+
2689+ func (a * actionHookCapture ) PostProvisionInstanceStep (HookResourceIdentity , string , error ) (HookAction , error ) {
2690+ return HookActionContinue , nil
2691+ }
2692+
2693+ func (a * actionHookCapture ) ProvisionOutput (HookResourceIdentity , string , string ) {}
2694+
2695+ func (a * actionHookCapture ) PreRefresh (HookResourceIdentity , addrs.DeposedKey , cty.Value ) (HookAction , error ) {
2696+ return HookActionContinue , nil
2697+ }
2698+
2699+ func (a * actionHookCapture ) PostRefresh (HookResourceIdentity , addrs.DeposedKey , cty.Value , cty.Value ) (HookAction , error ) {
2700+ return HookActionContinue , nil
2701+ }
2702+
2703+ func (a * actionHookCapture ) PreImportState (HookResourceIdentity , string ) (HookAction , error ) {
2704+ return HookActionContinue , nil
2705+ }
2706+
2707+ func (a * actionHookCapture ) PostImportState (HookResourceIdentity , []providers.ImportedResource ) (HookAction , error ) {
2708+ return HookActionContinue , nil
2709+ }
2710+
2711+ func (a * actionHookCapture ) PrePlanImport (HookResourceIdentity , cty.Value ) (HookAction , error ) {
2712+ return HookActionContinue , nil
2713+ }
2714+
2715+ func (a * actionHookCapture ) PostPlanImport (HookResourceIdentity , []providers.ImportedResource ) (HookAction , error ) {
2716+ return HookActionContinue , nil
2717+ }
2718+
2719+ func (a * actionHookCapture ) PreApplyImport (HookResourceIdentity , plans.ImportingSrc ) (HookAction , error ) {
2720+ return HookActionContinue , nil
2721+ }
2722+
2723+ func (a * actionHookCapture ) PostApplyImport (HookResourceIdentity , plans.ImportingSrc ) (HookAction , error ) {
2724+ return HookActionContinue , nil
2725+ }
2726+
2727+ func (a * actionHookCapture ) PreEphemeralOp (HookResourceIdentity , plans.Action ) (HookAction , error ) {
2728+ return HookActionContinue , nil
2729+ }
2730+
2731+ func (a * actionHookCapture ) PostEphemeralOp (HookResourceIdentity , plans.Action , error ) (HookAction , error ) {
2732+ return HookActionContinue , nil
2733+ }
2734+
2735+ func (a * actionHookCapture ) PreListQuery (HookResourceIdentity , cty.Value ) (HookAction , error ) {
2736+ return HookActionContinue , nil
2737+ }
2738+
2739+ func (a * actionHookCapture ) PostListQuery (HookResourceIdentity , plans.QueryResults , int64 ) (HookAction , error ) {
2740+ return HookActionContinue , nil
2741+ }
2742+
2743+ func (a * actionHookCapture ) StartAction (identity HookActionIdentity ) (HookAction , error ) {
2744+ a .startActionHooks = append (a .startActionHooks , identity )
2745+ return HookActionContinue , nil
2746+ }
2747+
2748+ func (a * actionHookCapture ) ProgressAction (HookActionIdentity , string ) (HookAction , error ) {
2749+ return HookActionContinue , nil
2750+ }
2751+
2752+ func (a * actionHookCapture ) CompleteAction (identity HookActionIdentity , _ error ) (HookAction , error ) {
2753+ a .completeActionHooks = append (a .completeActionHooks , identity )
2754+ return HookActionContinue , nil
2755+ }
2756+
2757+ func (a * actionHookCapture ) Stopping () {}
2758+
2759+ func (a * actionHookCapture ) PostStateUpdate (* states.State ) (HookAction , error ) {
2760+ return HookActionContinue , nil
2761+ }
0 commit comments