diff --git a/.github/workflows/go.yml b/.github/workflows/go.yml index 10da6c7..607ab3c 100644 --- a/.github/workflows/go.yml +++ b/.github/workflows/go.yml @@ -19,7 +19,7 @@ jobs: go-version: '1.22' - name: Unit Test - run: make unit-tests + run: make unit-tests-ci - name: e2e Test run: make ci-e2e diff --git a/Makefile b/Makefile index 9d25036..593b6f5 100644 --- a/Makefile +++ b/Makefile @@ -21,9 +21,13 @@ up: ## run all applications in stack docker compose up -d .PHONY: unit-tests -unit-tests: ## run unit tests without e2e-tests directory.. +unit-tests: ## run unit tests without e2e-tests directory. go test -race -count=1 `go list ./... | grep -v e2e-tests` +.PHONY: unit-tests-ci +unit-tests-ci: ## run unit tests without e2e-tests directory (multiple times to find race conditions). + go test -race -count=50 -failfast `go list ./... | grep -v e2e-tests` + .PHONY: ci-e2e ci-e2e: up go run ./e2e-tests/scripts/wait-ready/main.go -addr=':80;:8081;:8082' @@ -40,4 +44,4 @@ tests-e2e: ## run end to end tests vendor-licenses: ## report vendor licenses - go-licenses report ./cmd/api --template licenses.tpl > licenses.json 2> licenses-errors \ No newline at end of file + go-licenses report ./cmd/api --template licenses.tpl > licenses.json 2> licenses-errors diff --git a/internal/websocket/common/hub_pool_test.go b/internal/websocket/common/hub_pool_test.go index 403fd82..b340a5e 100644 --- a/internal/websocket/common/hub_pool_test.go +++ b/internal/websocket/common/hub_pool_test.go @@ -54,10 +54,15 @@ func TestCreateRemoveConcurrently(t *testing.T) { hubs := &sync.Map{} wg := sync.WaitGroup{} - wg.Add(channelsNo * clientsPerChannel) + // First we create `channelsNo` goroutines. Each of them creates `clientsPerChannel` sub-goroutines. + // This gives us `channelsNo*clientsPerChannel` sub go-routines and `channelsNo` parent goroutines. + // Each of them will call `wg.Done() once and we can't progress until all of them are done. + wg.Add(channelsNo*clientsPerChannel + channelsNo) + for i := 0; i < channelsNo; i++ { channelID := fmt.Sprintf("channel-%d", i) go func() { + defer wg.Done() for j := 0; j < clientsPerChannel; j++ { c, h := hp.registerClient(channelID, &websocket.Conn{}) hubs.Store(h, struct{}{}) @@ -70,7 +75,6 @@ func TestCreateRemoveConcurrently(t *testing.T) { hubs.Store(h, struct{}{}) }() } - wg.Wait() for c, hub := range hp.hubs {