From a6f65ef99fe48a29a5c8fcc90136d50cfb9ca4cf Mon Sep 17 00:00:00 2001 From: Ladd Date: Wed, 25 Dec 2024 17:24:18 -0600 Subject: [PATCH] successful tests with multiple rhizome nodes --- __tests__/{run.ts => run/001-single-node.ts} | 26 +-------- __tests__/run/002-two-nodes.ts | 61 ++++++++++++++++++++ util/app.ts | 34 +++++++++++ 3 files changed, 98 insertions(+), 23 deletions(-) rename __tests__/{run.ts => run/001-single-node.ts} (51%) create mode 100644 __tests__/run/002-two-nodes.ts create mode 100644 util/app.ts diff --git a/__tests__/run.ts b/__tests__/run/001-single-node.ts similarity index 51% rename from __tests__/run.ts rename to __tests__/run/001-single-node.ts index 73133c8..03dcc48 100644 --- a/__tests__/run.ts +++ b/__tests__/run/001-single-node.ts @@ -1,30 +1,10 @@ -import Debug from 'debug'; -import {RhizomeNode, RhizomeNodeConfig} from "../src/node"; -import {TypedCollection} from '../src/typed-collection'; -const debug = Debug('test:run'); - -type User = { - id?: string; - name: string; - nameLong?: string; - email?: string; - age: number; -}; - -class App extends RhizomeNode { - constructor(config?: Partial) { - super(config); - const users = new TypedCollection("users"); - users.rhizomeConnect(this); - } -} +import {App} from "../../util/app"; describe('Run', () => { let app: App; beforeAll(async () => { app = new App({ - // TODO expose more conveniently as test config options httpPort: 5000, httpEnable: true, requestBindPort: 5001, @@ -34,12 +14,12 @@ describe('Run', () => { }); afterAll(async () => { - debug('attempting to stop app'); await app.stop(); }); it('can put a new user', async () => { - const res = await fetch('http://localhost:5000/users', { + const {httpAddr, httpPort} = app.config; + const res = await fetch(`http://${httpAddr}:${httpPort}/users`, { method: 'PUT', headers: {'Content-Type': 'application/json'}, body: JSON.stringify({ diff --git a/__tests__/run/002-two-nodes.ts b/__tests__/run/002-two-nodes.ts new file mode 100644 index 0000000..8cd125f --- /dev/null +++ b/__tests__/run/002-two-nodes.ts @@ -0,0 +1,61 @@ +import {App} from '../../util/app'; + +describe('Run', () => { + const apps: App[] = []; + + beforeAll(async () => { + apps[0] = new App({ + httpEnable: true, + }); + apps[1] = new App({ + httpEnable: true, + }); + + await Promise.all(apps.map((app) => app.start())); + }); + + afterAll(async () => { + await Promise.all(apps.map((app) => app.stop())); + }); + + it('can create a record on node 0 and read it on node 1', async () => { + const res = await fetch(`${apps[0].apiUrl}/users`, { + method: 'PUT', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({ + name: "Peon", + id: "peon-1", + age: 263 + }) + }); + const data = await res.json(); + expect(data).toMatchObject({ + properties: { + name: "Peon", + id: "peon-1", + age: 263 + } + }); + + await new Promise((resolve) => setTimeout(resolve, 500)); + + const res2 = await fetch(`${apps[0].apiUrl}/users`, { + method: 'PUT', + headers: {'Content-Type': 'application/json'}, + body: JSON.stringify({ + name: "Peon", + id: "peon-1", + age: 263 + }) + }); + const data2 = await res2.json(); + expect(data2).toMatchObject({ + properties: { + name: "Peon", + id: "peon-1", + age: 263 + } + }); + + }); +}); diff --git a/util/app.ts b/util/app.ts new file mode 100644 index 0000000..51c583c --- /dev/null +++ b/util/app.ts @@ -0,0 +1,34 @@ +import {RhizomeNode, RhizomeNodeConfig} from "../src/node"; +import {TypedCollection} from "../src/typed-collection"; + +type User = { + id?: string; + name: string; + nameLong?: string; + email?: string; + age: number; +}; + +const start = 5000; +const range = 5000; +const getRandomPort = () => Math.floor(start + range * Math.random()); + +export class App extends RhizomeNode { + apiUrl: string; + + constructor(config?: Partial) { + // Randomizing ports to try to avoid collisions between tests. + super({ + publishBindPort: getRandomPort(), + requestBindPort: getRandomPort(), + httpPort: getRandomPort(), + ...config, + }); + + const users = new TypedCollection("users"); + users.rhizomeConnect(this); + + this.apiUrl = `http://${this.config.httpAddr}:${this.config.httpPort}`; + } +} +