Skip to content

Commit

Permalink
chore: Fix flaky TS tests (#1877)
Browse files Browse the repository at this point in the history
Fixes #1875

Attempting to reduce flakiness - still getting some errors I can't quite
pinpoint every now and then but seems like an improvement
  • Loading branch information
msfstef authored Oct 22, 2024
1 parent 3bdf6b6 commit 67cecba
Show file tree
Hide file tree
Showing 8 changed files with 80 additions and 23 deletions.
8 changes: 4 additions & 4 deletions .github/workflows/ts_test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@ name: TS tests

on:
push:
branches: ['main']
branches: ["main"]
pull_request:

permissions:
Expand Down Expand Up @@ -47,7 +47,7 @@ jobs:
- uses: actions/setup-node@v4
with:
node-version: 20
cache: 'pnpm'
cache: "pnpm"
- run: pnpm install --frozen-lockfile
- run: pnpm -r --filter "$(jq '.name' -r package.json)^..." build
- run: pnpm run stylecheck
Expand All @@ -69,7 +69,7 @@ jobs:
- uses: erlef/setup-beam@v1
with:
version-type: strict
version-file: '.tool-versions'
version-file: ".tool-versions"
- uses: pnpm/action-setup@v4
with:
version: 9
Expand Down Expand Up @@ -105,7 +105,7 @@ jobs:
mix run --no-halt &
wait-on: |
http://localhost:3000
http-get://localhost:3000/v1/health
tail: true
log-output-resume: stderr
Expand Down
6 changes: 6 additions & 0 deletions integration-tests/tests/_macros.luxinc
Original file line number Diff line number Diff line change
Expand Up @@ -31,11 +31,17 @@
[shell pg_lifecycle]
# This timeout is needed until https://github.com/electric-sql/electric/issues/1632 is fixed.
!docker stop -t 1 $pg_container_name
?$PS1

[shell pg]
??database system is shut down
[sleep 1]
[endmacro]

[macro resume_pg]
[shell pg_lifecycle]
!docker start $pg_container_name
?$PS1

[shell pg]
!docker attach $pg_container_name
Expand Down
12 changes: 7 additions & 5 deletions packages/react-hooks/test/react-hooks.test.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -119,11 +119,13 @@ describe(`useShape`, () => {
// Add an item.
const [id2] = await insertIssues({ title: `other row` })

await waitFor(() =>
expect(result.current.data).toEqual([
{ id: id, title: `test row` },
{ id: id2, title: `other row` },
])
await waitFor(
() =>
expect(result.current.data).toEqual([
{ id: id, title: `test row` },
{ id: id2, title: `other row` },
]),
{ timeout: 4000 }
)
})

Expand Down
29 changes: 26 additions & 3 deletions packages/react-hooks/test/support/global-setup.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { GlobalSetupContext } from 'vitest/node'
import { FetchError } from '@electric-sql/client'
import { makePgClient } from './test-helpers'

const url = process.env.ELECTRIC_URL ?? `http://localhost:3000`
Expand All @@ -22,13 +21,37 @@ declare module 'vitest' {
}
}

function waitForElectric(url: string): Promise<void> {
return new Promise<void>((resolve, reject) => {
const timeout = setTimeout(
() => reject(`Timed out waiting for Electric to be active`),
10000
)

const tryHealth = async () =>
fetch(`${url}/v1/health`)
.then(async (res): Promise<void> => {
if (!res.ok) return tryHealth()
const { status } = (await res.json()) as { status: string }
if (status !== `active`) return tryHealth()
clearTimeout(timeout)
resolve()
})
.catch((err) => {
clearTimeout(timeout)
reject(err)
})

return tryHealth()
})
}

/**
* Global setup for the test suite. Validates that our server is running, and creates and tears down a
* special schema in Postgres to ensure clean slate between runs.
*/
export default async function ({ provide }: GlobalSetupContext) {
const response = await fetch(url)
if (!response.ok) throw FetchError.fromResponse(response, url)
await waitForElectric(url)

const client = makePgClient()
await client.connect()
Expand Down
2 changes: 1 addition & 1 deletion packages/react-hooks/test/support/test-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const testWithIssuesTable = testWithDbClient.extend<{
clearIssuesShape: ClearIssuesShapeFn
}>({
issuesTableSql: async ({ dbClient, task }, use) => {
const tableName = `"issues for ${task.id}"`
const tableName = `"issues for ${task.id}_${Math.random().toString(16)}"`
await dbClient.query(`
DROP TABLE IF EXISTS ${tableName};
CREATE TABLE ${tableName} (
Expand Down
13 changes: 8 additions & 5 deletions packages/typescript-client/test/integration.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -92,13 +92,16 @@ describe(`HTTP Sync`, () => {
}, 1000)
})

// first request was -1, second should be something else
expect(urlsRequested).toHaveLength(3)
// first request was -1, last requests should be live ones
const numRequests = urlsRequested.length
expect(numRequests).toBeGreaterThan(2)
expect(urlsRequested[0].searchParams.get(`offset`)).toBe(`-1`)
expect(urlsRequested[0].searchParams.has(`live`)).false
expect(urlsRequested[2].searchParams.get(`offset`)).not.toBe(`-1`)
expect(urlsRequested[2].searchParams.has(`live`)).true
expect(urlsRequested[2].searchParams.has(`cursor`)).true
expect(urlsRequested[numRequests - 1].searchParams.get(`offset`)).not.toBe(
`-1`
)
expect(urlsRequested[numRequests - 1].searchParams.has(`live`)).true
expect(urlsRequested[numRequests - 1].searchParams.has(`cursor`)).true

// first request comes back immediately and is up to date, second one
// should hang while waiting for updates
Expand Down
29 changes: 26 additions & 3 deletions packages/typescript-client/test/support/global-setup.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
import type { GlobalSetupContext } from 'vitest/node'
import { FetchError } from '../../src/error'
import { makePgClient } from './test-helpers'

const url = process.env.ELECTRIC_URL ?? `http://localhost:3000`
Expand All @@ -22,13 +21,37 @@ declare module 'vitest' {
}
}

function waitForElectric(url: string): Promise<void> {
return new Promise<void>((resolve, reject) => {
const timeout = setTimeout(
() => reject(`Timed out waiting for Electric to be active`),
10000
)

const tryHealth = async () =>
fetch(`${url}/v1/health`)
.then(async (res): Promise<void> => {
if (!res.ok) return tryHealth()
const { status } = (await res.json()) as { status: string }
if (status !== `active`) return tryHealth()
clearTimeout(timeout)
resolve()
})
.catch((err) => {
clearTimeout(timeout)
reject(err)
})

return tryHealth()
})
}

/**
* Global setup for the test suite. Validates that our server is running, and creates and tears down a
* special schema in Postgres to ensure clean slate between runs.
*/
export default async function ({ provide }: GlobalSetupContext) {
const response = await fetch(url)
if (!response.ok) throw FetchError.fromResponse(response, url)
await waitForElectric(url)

const client = makePgClient()
await client.connect()
Expand Down
4 changes: 2 additions & 2 deletions packages/typescript-client/test/support/test-context.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ export const testWithIssuesTable = testWithDbClient.extend<{
clearIssuesShape: ClearIssuesShapeFn
}>({
issuesTableSql: async ({ dbClient, task }, use) => {
const tableName = `"issues for ${task.id}"`
const tableName = `"issues for ${task.id}_${Math.random().toString(16)}"`
await dbClient.query(`
DROP TABLE IF EXISTS ${tableName};
CREATE TABLE ${tableName} (
Expand Down Expand Up @@ -124,7 +124,7 @@ export const testWithMultitypeTable = testWithDbClient.extend<{
tableUrl: string
}>({
tableSql: async ({ dbClient, task }, use) => {
const tableName = `"multitype table for ${task.id}"`
const tableName = `"multitype table for ${task.id}_${Math.random().toString(16)}"`

await dbClient.query(`
DROP TABLE IF EXISTS ${tableName};
Expand Down

0 comments on commit 67cecba

Please sign in to comment.