Atlas › Test
panic_propagates
Exact test identity: go.temporal.io/server/common/testing/await/TestRequire_FailureScenarios/panic_propagates
- Package
go.temporal.io/server/common/testing/await
- Suite / test hierarchy
TestRequire_FailureScenarios/panic_propagates
- Test
panic_propagates
- Introduced at
- require_ctx.go ×2 Frontier kind: Joint frontier
- Covered ranges
- 23
- Covered lines
- 80
- Covered files
- 3
Covered source
Expand a file to inspect source; the > gutter marks covered lines.
go.temporal.io/server/common/testing/await/require_ctx.go 60 covered LOC · 19 ranges
Open complete file
20
const defaultSoftDeadlockTimeout = 30 * time.Second
21
23
>
if s := os.Getenv(softDeadlockTimeoutEnvVar); s != "" {
24
if d, err := time.ParseDuration(s); err == nil {
25
return d
26
}
27
}
29
}
30
54
// Pass the *await.T to require.*/assert.* — failures cause a retry, not a
55
// test failure. Use t.Context() inside the callback to honor the timeout.
56
>
func Require(ctx context.Context, tb testing.TB, condition func(*T), timeout, pollInterval time.Duration) {
require_ctx.go
57
>
tb.Helper()
58
>
run(ctx, tb, condition, legacyConfig(timeout, pollInterval, ""), "Require", requireMisuseHint, true)
59
>
}
60
61
// Requiref is like [Require] but adds a formatted message to the timeout
74
misuseHint string,
75
cancellable bool,
77
>
tb.Helper()
78
>
79
>
// Skip if the test already failed — no point polling.
80
>
if tb.Failed() {
81
tb.Logf("%s: skipping (test already failed)", funcName)
82
return
83
}
84
// Guard: context.WithDeadline panics on a nil parent.
86
tb.Fatalf("%s: nil context", funcName)
87
return
88
}
89
91
>
92
>
// Cap at the parent context's deadline if it's earlier than our timeout.
93
>
if parentDeadline, hasDeadline := parentCtx.Deadline(); hasDeadline && parentDeadline.Before(deadline) {
94
deadline = parentDeadline
95
}
97
// Cap at the test's deadline if it's earlier than our deadline.
98
// Ideally, the parent context already accounts for the test's deadline - but we are being defensive.
99
>
if d, ok := tb.(interface{ Deadline() (time.Time, bool) }); ok {
require_ctx.go
100
>
if testDeadline, hasDeadline := d.Deadline(); hasDeadline && testDeadline.Before(deadline) {
require_ctx.go
101
deadline = testDeadline
102
}
103
}
104
106
>
awaitCtx, awaitCancel := context.WithDeadline(parentCtx, deadline)
107
>
defer awaitCancel()
108
>
109
>
report := timeoutReport{effectiveTimeout: effectiveTimeout}
110
>
111
>
for {
112
>
// Parent context was canceled while we were sleeping (not our deadline).
113
>
if err := awaitCtx.Err(); err != nil && !deadlineReached(deadline) {
114
report.reportAttemptErrors(tb)
115
tb.Fatalf("%s: context canceled before condition was satisfied: %v", funcName, err)
117
}
118
120
>
121
>
// Per-attempt context: bounded by the configured attempt timeout and
122
>
// further capped by the overall awaitCtx.
123
>
attemptCtx, attemptCancel := context.WithTimeout(awaitCtx, cfg.attemptTimeout)
124
>
t := &T{tb: tb, ctx: attemptCtx}
125
>
126
>
// Run attempt.
127
>
res := runAttempt(t, condition, attemptCancel, funcName, cancellable)
128
>
attemptCancel()
129
>
if res.panicVal != nil {
131
}
132
if res.deadlocked {
211
funcName string,
212
cancellable bool,
214
>
done := make(chan attemptResult, 1)
215
>
216
>
go func() {
217
>
completed := false
218
>
defer func() {
221
done <- attemptResult{stopped: true}
222
return
223
}
225
>
return
226
}
227
// recover returned nil: either normal return (completed=true) or
229
done <- attemptResult{stopped: !completed}
230
}()
232
>
completed = true
233
}()
234
236
>
// Soft phase: wait for the condition, our soft timer, or parent cancel.
require_ctx.go
237
>
softTimer := time.NewTimer(softDeadlockTimeout())
238
>
defer softTimer.Stop()
239
>
240
>
select {
242
>
return r
243
case <-softTimer.C:
244
// Soft deadlock: log a warning.
go.temporal.io/server/common/testing/await/config.go 17 covered LOC · 3 ranges
Open complete file
17
}
18
20
>
return config{
21
>
attemptTimeout: envDuration(attemptTimeoutEnvVar, 10*time.Second) * debug.TimeoutMultiplier,
22
>
}
23
>
}
24
25
>
func legacyConfig(timeout, pollInterval time.Duration, timeoutMsg string) config {
config.go
26
>
cfg := newConfig()
27
>
cfg.totalTimeout = timeout
28
>
cfg.pollInterval = pollInterval
29
>
cfg.timeoutMsg = timeoutMsg
30
>
return cfg
31
>
}
32
33
>
func envDuration(name string, fallback time.Duration) time.Duration {
config.go
34
>
if s := os.Getenv(name); s != "" {
35
>
if d, err := time.ParseDuration(s); err == nil && d > 0 {
36
>
return d
37
>
}
38
}
39
return fallback
go.temporal.io/server/common/testing/await/report.go 3 covered LOC · 1 range
Open complete file
28
}
29
30
>
func (r *timeoutReport) nextPoll() {
report.go
31
>
r.attempts++
32
>
}
33
34
func (r *timeoutReport) recordErrors(errors []string) {