Skip to content

Adopting synctest for concurrent component testing #10

@danielorbach

Description

@danielorbach

Testing concurrent component lifecycles currently relies on an improvised collection of sleep-based synchronization, timeout constants, and manual coordination primitives. This approach is brittle, timing-dependent, and difficult to reason about. As components grow more complex and tests multiply, these weaknesses compound.

Go 1.24 introduced the testing/synctest package, which provides a controlled environment for testing concurrent code. By intercepting time-based operations and goroutine scheduling, synctest eliminates nondeterministic timing behavior and allows tests to deterministically advance through concurrent scenarios. This is particularly valuable for lifecycle management where we must verify correct sequencing of startup, shutdown, and cleanup phases.

The current test suite uses SyncTimeout constants and scattered synchronization logic that makes tests slower than necessary and occasionally flaky. Adopting synctest would allow us to remove arbitrary delays, make tests run faster, and most importantly, provide deterministic verification of concurrent behavior. When a lifecycle spawns child goroutines with L.Fork() or L.Go(), tests could advance time predictably and verify ordering guarantees without races or timeouts.

This migration touches the core testing patterns throughout the repository. Every test that exercises lifecycle concurrency, graceful shutdown, or cleanup ordering would benefit from synctest's controlled execution model. The work involves identifying timing-dependent tests, refactoring them to use synctest primitives, and establishing patterns that future tests can follow.

Acceptance Criteria

  • Tests using sleep-based synchronization are refactored to use synctest
  • Lifecycle tests verify concurrent behavior deterministically
  • Test execution time decreases due to eliminated sleeps
  • Documentation demonstrates synctest patterns for component testing
  • SyncTimeout and similar timing constants are removed or minimized

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions