Files
tasks/common/testing/testhooks/test_impl_test.go
Stephan BehnkeandGitHub e267d540bd panic test hooks if not enabled (#8726)
## What changed?

Changed use of `testhooks`'s `Set` to be runtime error instead of
compile time error.

It still ensures that the default impl (used in `go build` artifacts
without `test_dep` tag) is the noop impl.

## Why?

When running a functional test via plain `go test` it will fail, as the
`test_dep` build flag is required. It is required to prevent
accidentally using the default/noop implementation of the `testhooks`
package which allows injecting custom behavior into production code from
tests.

But requiring `test_dep` to run any test adds friction: CLI invocations
need to specify it manually, editor setups need to be adjusted, AI
agents need to be instructed. That's a high price to pay for a test
helper that is used fairly sparsely.

## How did you test it?
- [ ] built
- [x] run locally and tested manually
- [x] covered by existing tests
- [x] added new unit test(s)
- [ ] added new functional test(s)


Functional test without testhook:
```
% go test ./tests -run "OwnershipLostErrorSuite" -count=1 .
ok  	go.temporal.io/server/tests	7.062s
```

Functional test with testhook and build tag:
```
% go test ./tests -run "TestUpdateWorkflowSuite" -tags test_dep -count=1 .
ok  	go.temporal.io/server/tests	36.975s
```

Functional test with testhook but no build tag:
```
% go test ./tests -run "TestUpdateWorkflowSuite" -count=1 .
...
noop_impl.go:39: test panicked: testhooks.Set called but TestHooks are not enabled: use -tags=test_dep when running `go test`
                    goroutine 33293 [running]:
                    runtime/debug.Stack()
...
FAIL
FAIL	go.temporal.io/server/tests	57.128s
FAIL
```
2025-12-09 17:43:36 +00:00

53 lines
1.1 KiB
Go

//go:build test_dep
package testhooks
import (
"testing"
"github.com/stretchr/testify/require"
)
func TestGet(t *testing.T) {
th := NewTestHooks()
t.Run("returns false for unset key", func(t *testing.T) {
_, ok := Get[int](th, MatchingDisableSyncMatch)
require.False(t, ok)
})
t.Run("returns set value", func(t *testing.T) {
cleanup := Set(th, MatchingDisableSyncMatch, 42)
defer cleanup()
v, ok := Get[int](th, MatchingDisableSyncMatch)
require.True(t, ok)
require.Equal(t, 42, v)
})
t.Run("cleanup removes value", func(t *testing.T) {
cleanup := Set(th, MatchingDisableSyncMatch, 42)
cleanup()
_, ok := Get[int](th, MatchingDisableSyncMatch)
require.False(t, ok)
})
}
func TestCall(t *testing.T) {
th := NewTestHooks()
t.Run("does nothing for unset key", func(t *testing.T) {
Call(th, MatchingDisableSyncMatch) // should not panic
})
t.Run("calls set function", func(t *testing.T) {
called := false
cleanup := Set(th, MatchingDisableSyncMatch, func() { called = true })
defer cleanup()
Call(th, MatchingDisableSyncMatch)
require.True(t, called)
})
}