confluentinc / confluentinc/vscode

Mocha test flake: `docker/containers.ts waitForServiceHealthCheck`: `should retry failed requests and eventually succeed`

Open
#2,921 0 comments 0 reactions 1 assignee Claimed by @jlrobins View on GitHub
testing
Dominant language
TypeScript
Stars
34
Forks
17
Avg merge
1d 22h
Merged PRs (30d)
8

Description

Successful test:
```
docker/containers.ts waitForServiceHealthCheck
2025-10-21T18:33:07.714Z [info] [docker.containers] Starting TestService health check at http://localhost:9090/health
2025-10-21T18:33:07.715Z [info] [docker.containers] TestService health check request failed: Connection refused, retrying...
2025-10-21T18:33:08.715Z [info] [docker.containers] TestService health check succeeded
✔ should retry failed requests and eventually succeed (1002ms)
```

Failed test:
```
docker/containers.ts waitForServiceHealthCheck
2025-10-21T18:25:32.462Z [info] [docker.containers] Starting TestService health check at http://localhost:9090/health
2025-10-21T18:25:32.463Z [info] [docker.containers] TestService health check request failed: Connection refused, retrying...
2025-10-21T18:25:32.465Z [warning] [viewProviders.resources] No connection row found for connectionId { connectionId: 'vscode-local-connection' }
2025-10-21T18:25:32.536Z [error] [docker.eventListener] stream from event response is null
2025-10-21T18:25:33.464Z [info] [docker.containers] TestService health check request failed: Cannot read properties of undefined (reading 'ok'), retrying...
2025-10-21T18:25:33.552Z [error] [errors] Error: docker ping --> ResponseError: Response returned an error code {
errorType: 'ResponseError',
errorMessage: 'Response returned an error code',
errorStack: 'ResponseError: Response returned an error code\n' +
'\tat SystemApi.request (/Users/dshoup/Dev/confluent_dev/vscode/out/src/clients/docker/runtime.js:143:11)\n' +
'\tat async SystemApi.systemPingRaw (/Users/dshoup/Dev/confluent_dev/vscode/out/src/clients/docker/apis/SystemApi.js:146:22)\n' +
'\tat async SystemApi.systemPing (/Users/dshoup/Dev/confluent_dev/vscode/out/src/clients/docker/apis/SystemApi.js:166:22)\n' +
'\tat async Object.isDockerAvailable (/Users/dshoup/Dev/confluent_dev/vscode/out/src/docker/configs.js:45:18)\n' +
'\tat async _EventListener.listenForEvents (/Users/dshoup/Dev/confluent_dev/vscode/out/src/docker/eventListener.js:81:28)'
}
2025-10-21T18:25:33.552Z [warning] [viewProviders.resources] No connection row found for connectionId { connectionId: 'vscode-local-connection' }
2025-10-21T18:25:34.469Z [info] [docker.containers] TestService health check request failed: Cannot read properties of undefined (reading 'ok'), retrying...
2025-10-21T18:25:35.474Z [info] [docker.containers] TestService health check request failed: Cannot read properties of undefined (reading 'ok'), retrying...
2025-10-21T18:25:36.476Z [info] [docker.containers] TestService health check request failed: Cannot read properties of undefined (reading 'ok'), retrying...
2025-10-21T18:25:37.479Z [warning] [docker.containers] TestService health check timed out after 5s
1) should retry failed requests and eventually succeed
0 passing (8s)
1 failing
1) docker/containers.ts waitForServiceHealthCheck
should retry failed requests and eventually succeed:

AssertionError [ERR_ASSERTION]: Health check should eventually succeed

false !== true

+ expected - actual

-false
+true

at Context. (out/src/docker/containers.test.js:216:23)
```

Theory: because of the fact that `waitForServiceHealthCheck` uses `globalThis.fetch`, and the test is stubbing it and not using sinon [Fake timers](https://sinonjs.org/releases/latest/fake-timers/), I think some other fetch is happening during the actual 1sec backoff before the second attempt.
- failed test case:
```
fetch call 1: TestService health check failed, retrying
fetch call 2: unrelated background fetch request, { ok: true, status: 200 } returned
fetch call 3: TestService doesn't have any stubbed responses to work off of, so response is undefined and failures ensue
(continue failing)
```
- successful test case:
```
fetch call 1: TestService health check failed, retrying
fetch call 2: TestService health check happy
fetch call 3: unrelated background fetch request, normal behavior maybe
```

Proposed fix:
- make a small utility function like `containerFetch()` in a standalone file in https://github.com/confluentinc/vscode/tree/main/src/docker that effectively wraps `fetch` and replace the current fetch behavior: https://github.com/confluentinc/vscode/blob/1629eceb289e5fb36476e9768ded69a078ea45a0/src/docker/containers.ts#L160-L163
- update `fetchStub` to stub that new function instead of `globalThis.fetch` https://github.com/confluentinc/vscode/blob/1629eceb289e5fb36476e9768ded69a078ea45a0/src/docker/containers.test.ts#L227
- bonus: use fake timers instead of waiting the ~1sec for the retry

(This is similar to the [fsWrappers.ts](https://github.com/confluentinc/vscode/blob/main/src/utils/fsWrappers.ts) approach, but different intent since the `fs` functions just can't be stubbed directly. In this case we're just guarding against other fetch calls happening in unrelated parts of the codebase.)

Contributor guide

Open the contributing guide

Assessment

This issue has not been assessed yet.

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.