Skip to content

Commit 8b0ccce

Browse files
authored
actions: fix race condition in tests and capture errors from hooks (#37759)
1 parent d6865bf commit 8b0ccce

File tree

2 files changed

+30
-9
lines changed

2 files changed

+30
-9
lines changed

internal/terraform/context_apply_action_test.go

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ package terraform
55

66
import (
77
"path/filepath"
8+
"sync"
89
"testing"
910

1011
"github.com/google/go-cmp/cmp"
@@ -2603,7 +2604,7 @@ lifecycle {
26032604
InvokeActionFn: invokeActionFn,
26042605
}
26052606

2606-
hookCapture := actionHookCapture{}
2607+
hookCapture := newActionHookCapture()
26072608
ctx := testContext2(t, &ContextOpts{
26082609
Providers: map[addrs.Provider]providers.Factory{
26092610
addrs.NewDefaultProvider("test"): testProviderFuncFixed(testProvider),
@@ -2694,10 +2695,17 @@ lifecycle {
26942695
var _ Hook = (*actionHookCapture)(nil)
26952696

26962697
type actionHookCapture struct {
2698+
mu *sync.Mutex
26972699
startActionHooks []HookActionIdentity
26982700
completeActionHooks []HookActionIdentity
26992701
}
27002702

2703+
func newActionHookCapture() actionHookCapture {
2704+
return actionHookCapture{
2705+
mu: &sync.Mutex{},
2706+
}
2707+
}
2708+
27012709
func (a *actionHookCapture) PreApply(HookResourceIdentity, addrs.DeposedKey, plans.Action, cty.Value, cty.Value) (HookAction, error) {
27022710
return HookActionContinue, nil
27032711
}
@@ -2781,6 +2789,8 @@ func (a *actionHookCapture) PostListQuery(HookResourceIdentity, plans.QueryResul
27812789
}
27822790

27832791
func (a *actionHookCapture) StartAction(identity HookActionIdentity) (HookAction, error) {
2792+
a.mu.Lock()
2793+
defer a.mu.Unlock()
27842794
a.startActionHooks = append(a.startActionHooks, identity)
27852795
return HookActionContinue, nil
27862796
}
@@ -2790,6 +2800,8 @@ func (a *actionHookCapture) ProgressAction(HookActionIdentity, string) (HookActi
27902800
}
27912801

27922802
func (a *actionHookCapture) CompleteAction(identity HookActionIdentity, _ error) (HookAction, error) {
2803+
a.mu.Lock()
2804+
defer a.mu.Unlock()
27932805
a.completeActionHooks = append(a.completeActionHooks, identity)
27942806
return HookActionContinue, nil
27952807
}

internal/terraform/node_action_trigger_instance_apply.go

Lines changed: 17 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -136,9 +136,12 @@ func (n *nodeActionTriggerApplyInstance) Execute(ctx EvalContext, wo walkOperati
136136
ActionTrigger: ai.ActionTrigger,
137137
}
138138

139-
ctx.Hook(func(h Hook) (HookAction, error) {
139+
diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) {
140140
return h.StartAction(hookIdentity)
141-
})
141+
}))
142+
if diags.HasErrors() {
143+
return diags
144+
}
142145

143146
// We don't want to send the marks, but all marks are okay in the context
144147
// of an action invocation. We can't reuse our ephemeral free value from
@@ -153,28 +156,34 @@ func (n *nodeActionTriggerApplyInstance) Execute(ctx EvalContext, wo walkOperati
153156
respDiags := n.AddSubjectToDiagnostics(resp.Diagnostics)
154157
diags = diags.Append(respDiags)
155158
if respDiags.HasErrors() {
156-
ctx.Hook(func(h Hook) (HookAction, error) {
159+
diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) {
157160
return h.CompleteAction(hookIdentity, respDiags.Err())
158-
})
161+
}))
159162
return diags
160163
}
161164

162165
if resp.Events != nil { // should only occur in misconfigured tests
163166
for event := range resp.Events {
164167
switch ev := event.(type) {
165168
case providers.InvokeActionEvent_Progress:
166-
ctx.Hook(func(h Hook) (HookAction, error) {
169+
diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) {
167170
return h.ProgressAction(hookIdentity, ev.Message)
168-
})
171+
}))
172+
if diags.HasErrors() {
173+
return diags
174+
}
169175
case providers.InvokeActionEvent_Completed:
170176
// Enhance the diagnostics
171177
diags = diags.Append(n.AddSubjectToDiagnostics(ev.Diagnostics))
172-
ctx.Hook(func(h Hook) (HookAction, error) {
178+
diags = diags.Append(ctx.Hook(func(h Hook) (HookAction, error) {
173179
return h.CompleteAction(hookIdentity, ev.Diagnostics.Err())
174-
})
180+
}))
175181
if ev.Diagnostics.HasErrors() {
176182
return diags
177183
}
184+
if diags.HasErrors() {
185+
return diags
186+
}
178187
default:
179188
panic(fmt.Sprintf("unexpected action event type %T", ev))
180189
}

0 commit comments

Comments
 (0)