@@ -23,9 +23,10 @@ func TestContext2Apply_actions(t *testing.T) {
2323 module map [string ]string
2424 mode plans.Mode
2525 prevRunState * states.State
26- events []providers.InvokeActionEvent
26+ events func ( req providers. InvokeActionRequest ) []providers.InvokeActionEvent
2727 callingInvokeReturnsDiagnostics func (providers.InvokeActionRequest ) tfdiags.Diagnostics
28- planOpts * PlanOpts
28+
29+ planOpts * PlanOpts
2930
3031 expectInvokeActionCalled bool
3132 expectInvokeActionCalls []providers.InvokeActionRequest
@@ -160,23 +161,79 @@ resource "test_object" "a" {
160161` ,
161162 },
162163 expectInvokeActionCalled : true ,
163- events : []providers.InvokeActionEvent {
164- providers.InvokeActionEvent_Completed {
165- Diagnostics : tfdiags.Diagnostics {
166- tfdiags .Sourceless (
167- tfdiags .Error ,
168- "test case for failing" ,
169- "this simulates a provider failing" ,
170- ),
164+ events : func (req providers.InvokeActionRequest ) []providers.InvokeActionEvent {
165+ return []providers.InvokeActionEvent {
166+ providers.InvokeActionEvent_Completed {
167+ Diagnostics : tfdiags.Diagnostics {
168+ tfdiags .Sourceless (
169+ tfdiags .Error ,
170+ "test case for failing" ,
171+ "this simulates a provider failing" ,
172+ ),
173+ },
171174 },
172- },
175+ }
173176 },
174177
175178 expectDiagnostics : tfdiags.Diagnostics {
176179 tfdiags .Sourceless (
177180 tfdiags .Error ,
178- "test case for failing" ,
179- "this simulates a provider failing" ,
181+ "Failed to apply actions before test_object.a" ,
182+ "An error occured while invoking action action.act_unlinked.hello: test case for failing: this simulates a provider failing\n " ,
183+ ),
184+ },
185+ },
186+
187+ "before_create failing with successfully completed actions" : {
188+ module : map [string ]string {
189+ "main.tf" : `
190+ action "act_unlinked" "hello" {}
191+ action "act_unlinked" "world" {}
192+ action "act_unlinked" "failure" {
193+ config {
194+ attr = "failure"
195+ }
196+ }
197+ resource "test_object" "a" {
198+ lifecycle {
199+ action_trigger {
200+ events = [before_create]
201+ actions = [action.act_unlinked.hello, action.act_unlinked.world, action.act_unlinked.failure]
202+ }
203+ }
204+ }
205+ ` ,
206+ },
207+ expectInvokeActionCalled : true ,
208+ events : func (req providers.InvokeActionRequest ) []providers.InvokeActionEvent {
209+ if ! req .PlannedActionData .IsNull () && req .PlannedActionData .GetAttr ("attr" ).AsString () == "failure" {
210+ return []providers.InvokeActionEvent {
211+ providers.InvokeActionEvent_Completed {
212+ Diagnostics : tfdiags.Diagnostics {
213+ tfdiags .Sourceless (
214+ tfdiags .Error ,
215+ "test case for failing" ,
216+ "this simulates a provider failing" ,
217+ ),
218+ },
219+ },
220+ }
221+ } else {
222+ return []providers.InvokeActionEvent {
223+ providers.InvokeActionEvent_Completed {},
224+ }
225+ }
226+ },
227+
228+ expectDiagnostics : tfdiags.Diagnostics {
229+ tfdiags .Sourceless (
230+ tfdiags .Error ,
231+ "Failed to apply actions before test_object.a" ,
232+ `An error occured while invoking action action.act_unlinked.failure: test case for failing: this simulates a provider failing
233+ The following actions were successfully invoked:
234+ - action.act_unlinked.hello
235+ - action.act_unlinked.world
236+ As the resource did not change, these actions will be re-invoked in the next apply.` ,
180237 ),
181238 },
182239 },
@@ -208,8 +265,104 @@ resource "test_object" "a" {
208265 expectDiagnostics : tfdiags.Diagnostics {
209266 tfdiags .Sourceless (
210267 tfdiags .Error ,
211- "test case for failing" ,
212- "this simulates a provider failing before the action is invoked" ,
268+ "Failed to apply actions before test_object.a" ,
269+ "An error occured while invoking action action.act_unlinked.hello: test case for failing: this simulates a provider failing before the action is invoked\n " ,
270+ ),
271+ },
272+ },
273+
274+ "after_create failing" : {
275+ module : map [string ]string {
276+ "main.tf" : `
277+ action "act_unlinked" "hello" {}
278+ resource "test_object" "a" {
279+ lifecycle {
280+ action_trigger {
281+ events = [after_create]
282+ actions = [action.act_unlinked.hello]
283+ }
284+ }
285+ }
286+ ` ,
287+ },
288+ expectInvokeActionCalled : true ,
289+ events : func (req providers.InvokeActionRequest ) []providers.InvokeActionEvent {
290+ return []providers.InvokeActionEvent {
291+ providers.InvokeActionEvent_Completed {
292+ Diagnostics : tfdiags.Diagnostics {
293+ tfdiags .Sourceless (
294+ tfdiags .Error ,
295+ "test case for failing" ,
296+ "this simulates a provider failing" ,
297+ ),
298+ },
299+ },
300+ }
301+ },
302+
303+ expectDiagnostics : tfdiags.Diagnostics {
304+ tfdiags .Sourceless (
305+ tfdiags .Error ,
306+ "Failed to apply actions after test_object.a" ,
307+ `An error occured while invoking action action.act_unlinked.hello: test case for failing: this simulates a provider failing
308+
309+ The following actions were not yet invoked:
310+ - action.act_unlinked.hello
311+ These actions will not be triggered in the next apply, please run "terraform invoke" to invoke them.` ,
312+ ),
313+ },
314+ },
315+
316+ "after_create failing with successfully completed actions" : {
317+ module : map [string ]string {
318+ "main.tf" : `
319+ action "act_unlinked" "hello" {}
320+ action "act_unlinked" "world" {}
321+ action "act_unlinked" "failure" {
322+ config {
323+ attr = "failure"
324+ }
325+ }
326+ resource "test_object" "a" {
327+ lifecycle {
328+ action_trigger {
329+ events = [after_create]
330+ actions = [action.act_unlinked.hello, action.act_unlinked.world, action.act_unlinked.failure]
331+ }
332+ }
333+ }
334+ ` ,
335+ },
336+ expectInvokeActionCalled : true ,
337+ events : func (req providers.InvokeActionRequest ) []providers.InvokeActionEvent {
338+ if ! req .PlannedActionData .IsNull () && req .PlannedActionData .GetAttr ("attr" ).AsString () == "failure" {
339+ return []providers.InvokeActionEvent {
340+ providers.InvokeActionEvent_Completed {
341+ Diagnostics : tfdiags.Diagnostics {
342+ tfdiags .Sourceless (
343+ tfdiags .Error ,
344+ "test case for failing" ,
345+ "this simulates a provider failing" ,
346+ ),
347+ },
348+ },
349+ }
350+ } else {
351+ return []providers.InvokeActionEvent {
352+ providers.InvokeActionEvent_Completed {},
353+ }
354+ }
355+ },
356+
357+ expectDiagnostics : tfdiags.Diagnostics {
358+ tfdiags .Sourceless (
359+ tfdiags .Error ,
360+ "Failed to apply actions after test_object.a" ,
361+ `An error occured while invoking action action.act_unlinked.failure: test case for failing: this simulates a provider failing
362+
363+ The following actions were not yet invoked:
364+ - action.act_unlinked.failure
365+ These actions will not be triggered in the next apply, please run "terraform invoke" to invoke them.` ,
213366 ),
214367 },
215368 },
@@ -242,7 +395,7 @@ resource "test_object" "a" {
242395 tfdiags .Sourceless (
243396 tfdiags .Error ,
244397 "test case for failing" ,
245- "this simulates a provider failing before the action is invoked " ,
398+ "this simulates a provider failing" ,
246399 ),
247400 }
248401 }
@@ -251,10 +404,14 @@ resource "test_object" "a" {
251404 expectDiagnostics : tfdiags.Diagnostics {
252405 tfdiags .Sourceless (
253406 tfdiags .Error ,
254- "test case for failing" ,
255- "this simulates a provider failing before the action is invoked" ,
407+ "Failed to apply actions before test_object.a" ,
408+ `An error occured while invoking action action.act_unlinked.failure: test case for failing: this simulates a provider failing
409+ The following actions were successfully invoked:
410+ - action.act_unlinked.hello
411+ As the resource did not change, these actions will be re-invoked in the next apply.` ,
256412 ),
257413 },
414+
258415 // We expect two calls but not the third one, because the second action fails
259416 expectInvokeActionCalls : []providers.InvokeActionRequest {{
260417 ActionType : "act_unlinked" ,
@@ -305,7 +462,7 @@ resource "test_object" "a" {
305462 tfdiags .Sourceless (
306463 tfdiags .Error ,
307464 "test case for failing" ,
308- "this simulates a provider failing before the action is invoked " ,
465+ "this simulates a provider failing" ,
309466 ),
310467 }
311468 }
@@ -314,8 +471,11 @@ resource "test_object" "a" {
314471 expectDiagnostics : tfdiags.Diagnostics {
315472 tfdiags .Sourceless (
316473 tfdiags .Error ,
317- "test case for failing" ,
318- "this simulates a provider failing before the action is invoked" ,
474+ "Failed to apply actions before test_object.a" ,
475+ `An error occured while invoking action action.act_unlinked.failure: test case for failing: this simulates a provider failing
476+ The following actions were successfully invoked:
477+ - action.act_unlinked.hello
478+ As the resource did not change, these actions will be re-invoked in the next apply.` ,
319479 ),
320480 },
321481 // We expect two calls but not the third one, because the second action fails
@@ -524,8 +684,8 @@ resource "test_object" "a" {
524684 defaultEvents = append (defaultEvents , providers.InvokeActionEvent_Completed {})
525685
526686 events := defaultEvents
527- if len ( tc .events ) > 0 {
528- events = tc .events
687+ if tc .events != nil {
688+ events = tc .events ( req )
529689 }
530690
531691 return providers.InvokeActionResponse {
@@ -571,7 +731,6 @@ resource "test_object" "a" {
571731 },
572732 },
573733 },
574-
575734 Unlinked : & providers.UnlinkedAction {},
576735 },
577736 },
0 commit comments