The test hanging issue is caused by config state pollution that only occurs when running the full test suite (100+ non-BDD tests + BDD tests together). When BDD tests run in isolation, config isolation works correctly.
When running go test -v -run "TestReverseProxyModuleBDD":
🔍 DEBUG: iHaveAReverseProxyWithSpecificCacheTTLConfigured() starting (Cache TTL behavior scenario)
🔍 DEBUG: Set CacheTTL=1s (Cache TTL behavior signature)
...
🔍 DEBUG: cachedResponsesAgeBeyondTTL reading CacheTTL=1s, will sleep for 1.5s
Result: Correctly uses 1s CacheTTL, sleeps for 1.5s, test completes quickly.
When running go test -v . (all 175+ tests):
🔍 DEBUG: iHaveAReverseProxyWithSpecificCacheTTLConfigured() starting (Cache TTL behavior scenario)
🔍 DEBUG: Set CacheTTL=1s (Cache TTL behavior signature)
...
🔍 DEBUG: After setupApplicationWithConfig, ctx.config.CacheTTL=5m0s
...
🔍 DEBUG: cachedResponsesAgeBeyondTTL reading CacheTTL=5m0s, will sleep for 5m0.5s
Result: CacheTTL changes from 1s to 5m0s (300s), causing 5-minute sleep and test timeout.
All isolation tests pass, confirming:
- Module instances are isolated ✅
- Config struct pointers are isolated ✅
- BDD context instances are isolated ✅
resetContext()properly clears state ✅
The config is being modified inside setupApplicationWithConfig() between setting the config and reading it back. Specifically:
- Scenario sets
ctx.config.CacheTTL = 1 * time.Second - Calls
setupApplicationWithConfig() - After the call,
ctx.config.CacheTTL = 300 * time.Second
The config pointer (ctx.config) stays the same, but the object it points to is being modified.
When all tests run together, one of the 100+ non-BDD tests:
- Creates a global or static config with CacheTTL=300s (or 120s)
- This config is cached or stored somewhere in the modular framework
- When
setupApplicationWithConfig()callsctx.app.Init(), the framework's config loading mechanism somehow merges or overwrites the BDD test's config with the cached config
Debug logs show the modification happens during setupApplicationWithConfig():
🔍 DEBUG: Set CacheTTL=1s (Cache TTL behavior signature)
🔍 DEBUG: ctx.config pointer = 0x14000a002c8
... (setupApplicationWithConfig() runs)
🔍 DEBUG: After setupApplicationWithConfig, ctx.config.CacheTTL=5m0s
Files that set CacheTTL to 300 seconds:
bdd_caching_tenant_test.go:42-iHaveAReverseProxyWithCachingEnabled()- Response caching scenario (now 337s)bdd_tenant_caching_override_test.go:161- Another test
Files that set CacheTTL to 120 seconds:
config_merge_test.go:34module_test.go:812
- Investigate the modular framework's config loading mechanism to understand how it handles config sections during
Init() - Check if there's a config cache or global registry that's polluting state
- Add deep copy logic to ensure config structs are never shared between test runs
- Fix
setupApplicationWithConfig()to ensure the config passed in is the config that gets used
Use shorter CacheTTL values in all tests (< 5 seconds) to prevent timeouts even if config bleeding occurs.