Skip to content

Commit

Permalink
feat: test all composedb url combinations during tests
Browse files Browse the repository at this point in the history
  • Loading branch information
smrz2001 committed Nov 28, 2023
1 parent 437b696 commit 21eebd7
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 24 deletions.
16 changes: 10 additions & 6 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,7 @@ Eventually we expect the `js-ceramic` repo/process to be renamed to `js-composed

Tests are run in CI via the build docker image. However locally its useful to be able to run the tests without doing an image build.
There are some helpful scripts in this repo to make testing locally possible:

```bash
# Create the network
kubectl apply -f networks/basic-rust.yaml

Expand All @@ -73,15 +73,19 @@ There are some helpful scripts in this repo to make testing locally possible:
# We `source` the script so it can export the env vars.
source ./port-forward.sh

# Run cargo test locally using the newly exported env vars.
# Optionally you can use `make test`
cd test-suite && pnpm run start

# This will run "fast" tests locally using the newly exported env vars.
cd suite
pnpm run test --testPathPattern fast
```
>NOTE: The port-forward script will leave `kubectl` process running in the background to forward the ports.
The script kills those processes and creates new ones. However if you need you can kill them directly.
The script should be run anytime a pod in the network restarts.


You can also run these tests against durable infrastructure (e.g. QA):
```bash
cd suite
DURABLE_ENV=qa DOTENV_CONFIG_PATH=./env/.env."$DURABLE_ENV" pnpm run test --testPathPattern fast
```
### Visualizing Topology

When debugging a test failure it can be helpful to visualize the current network topology.
Expand Down
2 changes: 1 addition & 1 deletion suite/Dockerfile
Original file line number Diff line number Diff line change
Expand Up @@ -21,4 +21,4 @@ ENV DOTENV_CONFIG_PATH "./env/.env.dev"
# Select all tests by default
ENV TEST_SELECTOR "."

ENTRYPOINT ["/app/entrypoint.sh", "run", "test", "--runInBand", "--reporters", "default", "--setupFiles", "dotenv/config", "--testPathPattern", "$TEST_SELECTOR"]
ENTRYPOINT ["/app/entrypoint.sh", "run", "test", "--testPathPattern", "$TEST_SELECTOR"]
2 changes: 1 addition & 1 deletion suite/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
"type": "module",
"scripts": {
"build": "tsc",
"test": "NODE_OPTIONS=--experimental-vm-modules jest"
"test": "NODE_OPTIONS=--experimental-vm-modules jest --runInBand --reporters default --setupFiles dotenv/config"
},
"devDependencies": {
"@skypack/package-check": "^0.2.2",
Expand Down
42 changes: 26 additions & 16 deletions suite/src/__tests__/fast/update.test.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
import { CeramicApi, SyncOptions } from '@ceramicnetwork/common'
import CeramicClient from '@ceramicnetwork/http-client'
import { TileDocument } from '@ceramicnetwork/stream-tile'
import {afterAll, beforeAll, describe, expect, test} from '@jest/globals'
import { afterAll, beforeAll, describe, expect, test } from '@jest/globals'

import * as helpers from '../../utils/dynamoDbHelpers.js'
import { utilities } from '../../utils/common.js'
Expand All @@ -20,60 +20,70 @@ describe('update', () => {
beforeAll(async () => await helpers.createAnchorTable())
afterAll(async () => await helpers.cleanup())

const firstRwUrl = ComposeDbUrls[0]
// Run tests with each node being the node where a stream is created
generateUrlCombinations(ComposeDbUrls).forEach(testUpdate)
})

function generateUrlCombinations(urls: string[]): string[][] {
return urls.map((_, index) => [...urls.slice(index), ...urls.slice(0, index)])
}

function testUpdate(composeDbUrls: string[]) {
console.log(`test update with urls: ${composeDbUrls}`)
const firstNodeUrl = composeDbUrls[0]
const content = { step: 0 }
let firstCeramic: CeramicClient.CeramicClient
let firstTile: TileDocument

// Create and update on first node
test(`create stream on ${firstRwUrl}`, async () => {
firstCeramic = await newCeramic(firstRwUrl)
test(`create stream on ${firstNodeUrl}`, async () => {
firstCeramic = await newCeramic(firstNodeUrl)
firstTile = await TileDocument.create(firstCeramic as CeramicApi, content, metadata, {
anchor: false,
})
console.log(
`Created stream on ${firstRwUrl}: ${firstTile.id.toString()} with step ${content.step}`
`Created stream on ${firstNodeUrl}: ${firstTile.id.toString()} with step ${content.step}`,
)
})

test(`update stream on ${firstRwUrl}`, async () => {
test(`update stream on ${firstNodeUrl}`, async () => {
content.step++
await firstTile.update(content, undefined, { anchor: false })
console.log(
`Updated stream on ${firstRwUrl}: ${firstTile.id.toString()} with step ${content.step}`
`Updated stream on ${firstNodeUrl}: ${firstTile.id.toString()} with step ${content.step}`,
)
})

// Test load, update, and sync on subsequent node(s)
// Skip first url because it was already handled in the previous tests
for (let idx = 1; idx < ComposeDbUrls.length; idx++) {
const apiUrl = ComposeDbUrls[idx]
for (let idx = 1; idx < composeDbUrls.length; idx++) {
const apiUrl = composeDbUrls[idx]
let tile: TileDocument
test(`load stream on ${apiUrl}`, async () => {
await delay(5)
const ceramic = await newCeramic(apiUrl)
console.log(
`Loading stream ${firstTile.id.toString()} on ${apiUrl} with step ${content.step}`
`Loading stream ${firstTile.id.toString()} on ${apiUrl} with step ${content.step}`,
)
tile = await TileDocument.load(ceramic, firstTile.id)
expect(tile.content).toEqual(content)
console.log(
`Loaded stream on ${apiUrl}: ${firstTile.id.toString()} successfully with step ${
content.step
}`
}`,
)
})
test(`sync stream on ${apiUrl}`, async () => {
const isFinalWriter = idx == ComposeDbUrls.length - 1
const isFinalWriter = idx == composeDbUrls.length - 1
// Update the content as we iterate through the list of node URLs so that each step includes some change
// from the previous step.
content.step++
// Update on first node and wait for update to propagate to other nodes via pubsub
// Only anchor on the final write to avoid writes conflicting with anchors.
console.log(
`Updating stream ${firstTile.id.toString()} on ${firstRwUrl} so we can sync it on ${apiUrl} with step ${
`Updating stream ${firstTile.id.toString()} on ${firstNodeUrl} so we can sync it on ${apiUrl} with step ${
content.step
}`
}`,
)
await firstTile.update(content, undefined, { anchor: isFinalWriter })
console.log(`Updating complete, sleeping 5 seconds before syncing`)
Expand All @@ -84,7 +94,7 @@ describe('update', () => {
console.log(
`Synced stream on ${apiUrl}: ${firstTile.id.toString()} successfully with step ${
content.step
}`
}`,
)

if (isFinalWriter) {
Expand All @@ -93,4 +103,4 @@ describe('update', () => {
}
})
}
})
}

0 comments on commit 21eebd7

Please sign in to comment.