diff --git a/definitions/bip122-000000000019d6689c085ae165831e93/bitcoind.test.ts b/definitions/bip122-000000000019d6689c085ae165831e93/bitcoind.test.ts index 83a3fa1..3c33176 100644 --- a/definitions/bip122-000000000019d6689c085ae165831e93/bitcoind.test.ts +++ b/definitions/bip122-000000000019d6689c085ae165831e93/bitcoind.test.ts @@ -1,5 +1,5 @@ import { afterAll, beforeAll, describe, expect, it } from '@jest/globals'; -import { KarfiaAgentContainer, KarfiaContainer, KarfiaTestcontainers } from 'karfia-testcontainers'; +import { KarfiaContainer, KarfiaTestcontainers } from 'karfia-testcontainers'; import waitForExpect from 'wait-for-expect'; import definition from './bitcoind.json'; @@ -141,60 +141,3 @@ describe('bitcoind', () => { }); }); }); - -describe('karfia-agent', () => { - let agent: KarfiaAgentContainer; - - beforeAll(() => { - agent = testcontainers.getKarfiaAgent(); - }); - - it('should get karfia-agent/deployment', async () => { - const result = await agent.getDeployment(); - expect(result).toMatchObject({ - deploymentId: testcontainers.getDeploymentId(), - definitionId: definition.id, - caip2: definition.caip2, - name: definition.name, - }); - }); - - it('should get karfia-agent/definition', async () => { - const result = await agent.getDefinition(); - const expected = { - ...definition, - $schema: undefined, - }; - delete expected.$schema; - expect(result).toMatchObject(expected); - }); - - it('should get karfia-agent/probes/startup', async () => { - const response = await agent.probe('startup'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - ok: true, - }); - }); - - it('should get karfia-agent/probes/liveness', async () => { - const response = await agent.probe('liveness'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - ok: true, - }); - }); - - it('should get karfia-agent/probes/readiness', async () => { - const response = await agent.probe('readiness'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - containers: { - bitcoind: { - ok: true, - }, - }, - ok: true, - }); - }); -}); diff --git a/definitions/bip122-0f9188f13cb7b2c71f2a335e3a4fc328/bitcoind.test.ts b/definitions/bip122-0f9188f13cb7b2c71f2a335e3a4fc328/bitcoind.test.ts index 2e391b9..a447d12 100644 --- a/definitions/bip122-0f9188f13cb7b2c71f2a335e3a4fc328/bitcoind.test.ts +++ b/definitions/bip122-0f9188f13cb7b2c71f2a335e3a4fc328/bitcoind.test.ts @@ -1,5 +1,5 @@ import { afterAll, beforeAll, describe, expect, it } from '@jest/globals'; -import { KarfiaAgentContainer, KarfiaContainer, KarfiaTestcontainers } from 'karfia-testcontainers'; +import { KarfiaContainer, KarfiaTestcontainers } from 'karfia-testcontainers'; import definition from './bitcoind.json'; @@ -116,60 +116,3 @@ describe('bitcoind', () => { }); }); }); - -describe('karfia-agent', () => { - let agent: KarfiaAgentContainer; - - beforeAll(() => { - agent = testcontainers.getKarfiaAgent(); - }); - - it('should get karfia-agent/deployment', async () => { - const result = await agent.getDeployment(); - expect(result).toMatchObject({ - deploymentId: testcontainers.getDeploymentId(), - definitionId: definition.id, - caip2: definition.caip2, - name: definition.name, - }); - }); - - it('should get karfia-agent/definition', async () => { - const result = await agent.getDefinition(); - const expected = { - ...definition, - $schema: undefined, - }; - delete expected.$schema; - expect(result).toMatchObject(expected); - }); - - it('should get karfia-agent/probes/startup', async () => { - const response = await agent.probe('startup'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - ok: true, - }); - }); - - it('should get karfia-agent/probes/liveness', async () => { - const response = await agent.probe('liveness'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - ok: true, - }); - }); - - it('should get karfia-agent/probes/readiness', async () => { - const response = await agent.probe('readiness'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - containers: { - bitcoind: { - ok: true, - }, - }, - ok: true, - }); - }); -}); diff --git a/definitions/bip122-279b1a87aedc7b9471d4ad4e5f12967a/defid-jellyfish.test.ts b/definitions/bip122-279b1a87aedc7b9471d4ad4e5f12967a/defid-jellyfish.test.ts index b0f9dc3..e0e88cb 100644 --- a/definitions/bip122-279b1a87aedc7b9471d4ad4e5f12967a/defid-jellyfish.test.ts +++ b/definitions/bip122-279b1a87aedc7b9471d4ad4e5f12967a/defid-jellyfish.test.ts @@ -1,5 +1,5 @@ import { afterAll, beforeAll, describe, expect, it } from '@jest/globals'; -import { KarfiaAgentContainer, KarfiaContainer, KarfiaTestcontainers } from 'karfia-testcontainers'; +import { KarfiaContainer, KarfiaTestcontainers } from 'karfia-testcontainers'; import definition from './defid-jellyfish.json'; @@ -57,63 +57,3 @@ describe('defid + whale', () => { }); }); }); - -describe('karfia-agent', () => { - let agent: KarfiaAgentContainer; - - beforeAll(() => { - agent = testcontainers.getKarfiaAgent(); - }); - - it('should get karfia-agent/deployment', async () => { - const result = await agent.getDeployment(); - expect(result).toMatchObject({ - deploymentId: testcontainers.getDeploymentId(), - definitionId: definition.id, - caip2: definition.caip2, - name: definition.name, - }); - }); - - it('should get karfia-agent/definition', async () => { - const result = await agent.getDefinition(); - const expected = { - ...definition, - $schema: undefined, - }; - delete expected.$schema; - expect(result).toMatchObject(expected); - }); - - it('should get karfia-agent/probes/startup', async () => { - const response = await agent.probe('startup'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - ok: true, - }); - }); - - it('should get karfia-agent/probes/liveness', async () => { - const response = await agent.probe('liveness'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - ok: true, - }); - }); - - it('should get karfia-agent/probes/readiness', async () => { - const response = await agent.probe('readiness'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - containers: { - defid: { - ok: true, - }, - whale: { - ok: true, - }, - }, - ok: true, - }); - }); -}); diff --git a/definitions/bip122-279b1a87aedc7b9471d4ad4e5f12967a/defid.test.ts b/definitions/bip122-279b1a87aedc7b9471d4ad4e5f12967a/defid.test.ts index 27ca299..3bcc9d7 100644 --- a/definitions/bip122-279b1a87aedc7b9471d4ad4e5f12967a/defid.test.ts +++ b/definitions/bip122-279b1a87aedc7b9471d4ad4e5f12967a/defid.test.ts @@ -1,5 +1,5 @@ import { afterAll, beforeAll, describe, expect, it } from '@jest/globals'; -import { KarfiaAgentContainer, KarfiaContainer, KarfiaTestcontainers } from 'karfia-testcontainers'; +import { KarfiaContainer, KarfiaTestcontainers } from 'karfia-testcontainers'; import definition from './defid.json'; @@ -315,60 +315,3 @@ describe('defid', () => { }); }); }); - -describe('karfia-agent', () => { - let agent: KarfiaAgentContainer; - - beforeAll(() => { - agent = testcontainers.getKarfiaAgent(); - }); - - it('should get karfia-agent/deployment', async () => { - const result = await agent.getDeployment(); - expect(result).toMatchObject({ - deploymentId: testcontainers.getDeploymentId(), - definitionId: definition.id, - caip2: definition.caip2, - name: definition.name, - }); - }); - - it('should get karfia-agent/definition', async () => { - const result = await agent.getDefinition(); - const expected = { - ...definition, - $schema: undefined, - }; - delete expected.$schema; - expect(result).toMatchObject(expected); - }); - - it('should get karfia-agent/probes/startup', async () => { - const response = await agent.probe('startup'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - ok: true, - }); - }); - - it('should get karfia-agent/probes/liveness', async () => { - const response = await agent.probe('liveness'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - ok: true, - }); - }); - - it('should get karfia-agent/probes/readiness', async () => { - const response = await agent.probe('readiness'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - containers: { - defid: { - ok: true, - }, - }, - ok: true, - }); - }); -}); diff --git a/definitions/bip122-d744db74fb70ed42767ae028a129365f/defid-jellyfish.test.ts b/definitions/bip122-d744db74fb70ed42767ae028a129365f/defid-jellyfish.test.ts index ae0f065..616381a 100644 --- a/definitions/bip122-d744db74fb70ed42767ae028a129365f/defid-jellyfish.test.ts +++ b/definitions/bip122-d744db74fb70ed42767ae028a129365f/defid-jellyfish.test.ts @@ -65,44 +65,8 @@ describe('karfia-agent', () => { agent = testcontainers.getKarfiaAgent(); }); - it('should get karfia-agent/deployment', async () => { - const result = await agent.getDeployment(); - expect(result).toMatchObject({ - deploymentId: testcontainers.getDeploymentId(), - definitionId: definition.id, - caip2: definition.caip2, - name: definition.name, - }); - }); - - it('should get karfia-agent/definition', async () => { - const result = await agent.getDefinition(); - const expected = { - ...definition, - $schema: undefined, - }; - delete expected.$schema; - expect(result).toMatchObject(expected); - }); - - it('should get karfia-agent/probes/startup', async () => { - const response = await agent.probe('startup'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - ok: true, - }); - }); - - it('should get karfia-agent/probes/liveness', async () => { - const response = await agent.probe('liveness'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - ok: true, - }); - }); - - it('should get karfia-agent/probes/readiness', async () => { - const response = await agent.probe('readiness'); + it('should Probe.Readiness', async () => { + const response = await agent.probe('Readiness'); expect(response.status).toStrictEqual(200); expect(await response.json()).toMatchObject({ containers: { diff --git a/definitions/eip155-1337/ganache.test.ts b/definitions/eip155-1337/ganache.test.ts index 593024a..d5ea544 100644 --- a/definitions/eip155-1337/ganache.test.ts +++ b/definitions/eip155-1337/ganache.test.ts @@ -1,93 +1,34 @@ import { afterAll, beforeAll, describe, expect, it } from '@jest/globals'; -import { KarfiaAgentContainer, KarfiaContainer, KarfiaTestcontainers } from 'karfia-testcontainers'; +import { KarfiaContainer, KarfiaTestcontainers } from 'karfia-testcontainers'; import definition from './ganache.json'; -describe('testcontainers', () => { - let testcontainers: KarfiaTestcontainers; +let testcontainers: KarfiaTestcontainers; - beforeAll(async () => { - testcontainers = await KarfiaTestcontainers.start(definition); - }); - - afterAll(async () => { - await testcontainers.stop(); - }); - - describe('ganache', () => { - let ganache: KarfiaContainer; - - beforeAll(() => { - ganache = testcontainers.getContainer('ganache'); - }); +beforeAll(async () => { + testcontainers = await KarfiaTestcontainers.start(definition); +}); - it('should rpc(eth_blockNumber)', async () => { - const response = await ganache.rpc({ - method: 'eth_blockNumber', - }); +afterAll(async () => { + await testcontainers.stop(); +}); - expect(response.status).toStrictEqual(200); +describe('ganache', () => { + let ganache: KarfiaContainer; - expect(await response.json()).toMatchObject({ - result: '0x0', - }); - }); + beforeAll(() => { + ganache = testcontainers.getContainer('ganache'); }); - describe('karfia-agent', () => { - let agent: KarfiaAgentContainer; - - beforeAll(() => { - agent = testcontainers.getKarfiaAgent(); - }); - - it('should get karfia-agent/deployment', async () => { - const result = await agent.getDeployment(); - expect(result).toMatchObject({ - deploymentId: testcontainers.getDeploymentId(), - definitionId: definition.id, - caip2: definition.caip2, - name: definition.name, - }); - }); - - it('should get karfia-agent/definition', async () => { - const result = await agent.getDefinition(); - const expected = { - ...definition, - $schema: undefined, - }; - delete expected.$schema; - expect(result).toMatchObject(expected); - }); - - it('should get karfia-agent/probes/startup', async () => { - const response = await agent.probe('startup'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - ok: true, - }); + it('should rpc(eth_blockNumber)', async () => { + const response = await ganache.rpc({ + method: 'eth_blockNumber', }); - it('should get karfia-agent/probes/liveness', async () => { - const response = await agent.probe('liveness'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - ok: true, - }); - }); + expect(response.status).toStrictEqual(200); - it('should get karfia-agent/probes/readiness', async () => { - const response = await agent.probe('readiness'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - containers: { - ganache: { - ok: true, - }, - }, - ok: true, - }); + expect(await response.json()).toMatchObject({ + result: '0x0', }); }); }); diff --git a/definitions/eip155-31337/hardhat.test.ts b/definitions/eip155-31337/hardhat.test.ts index 1066273..acd3821 100644 --- a/definitions/eip155-31337/hardhat.test.ts +++ b/definitions/eip155-31337/hardhat.test.ts @@ -1,93 +1,34 @@ import { afterAll, beforeAll, describe, expect, it } from '@jest/globals'; -import { KarfiaAgentContainer, KarfiaContainer, KarfiaTestcontainers } from 'karfia-testcontainers'; +import { KarfiaContainer, KarfiaTestcontainers } from 'karfia-testcontainers'; import definition from './hardhat.json'; -describe('testcontainers', () => { - let testcontainers: KarfiaTestcontainers; +let testcontainers: KarfiaTestcontainers; - beforeAll(async () => { - testcontainers = await KarfiaTestcontainers.start(definition); - }); - - afterAll(async () => { - await testcontainers.stop(); - }); - - describe('hardhat', () => { - let hardhat: KarfiaContainer; - - beforeAll(() => { - hardhat = testcontainers.getContainer('hardhat'); - }); +beforeAll(async () => { + testcontainers = await KarfiaTestcontainers.start(definition); +}); - it('should rpc(eth_blockNumber)', async () => { - const response = await hardhat.rpc({ - method: 'eth_blockNumber', - }); +afterAll(async () => { + await testcontainers.stop(); +}); - expect(response.status).toStrictEqual(200); +describe('hardhat', () => { + let hardhat: KarfiaContainer; - expect(await response.json()).toMatchObject({ - result: '0x0', - }); - }); + beforeAll(() => { + hardhat = testcontainers.getContainer('hardhat'); }); - describe('karfia-agent', () => { - let agent: KarfiaAgentContainer; - - beforeAll(() => { - agent = testcontainers.getKarfiaAgent(); - }); - - it('should get karfia-agent/deployment', async () => { - const result = await agent.getDeployment(); - expect(result).toMatchObject({ - deploymentId: testcontainers.getDeploymentId(), - definitionId: definition.id, - caip2: definition.caip2, - name: definition.name, - }); - }); - - it('should get karfia-agent/definition', async () => { - const result = await agent.getDefinition(); - const expected = { - ...definition, - $schema: undefined, - }; - delete expected.$schema; - expect(result).toMatchObject(expected); - }); - - it('should get karfia-agent/probes/startup', async () => { - const response = await agent.probe('startup'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - ok: true, - }); + it('should rpc(eth_blockNumber)', async () => { + const response = await hardhat.rpc({ + method: 'eth_blockNumber', }); - it('should get karfia-agent/probes/liveness', async () => { - const response = await agent.probe('liveness'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - ok: true, - }); - }); + expect(response.status).toStrictEqual(200); - it('should get karfia-agent/probes/readiness', async () => { - const response = await agent.probe('readiness'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - containers: { - hardhat: { - ok: true, - }, - }, - ok: true, - }); + expect(await response.json()).toMatchObject({ + result: '0x0', }); }); }); diff --git a/definitions/solana-00000000000000000000000000000000/solana-test-validator.test.ts b/definitions/solana-00000000000000000000000000000000/solana-test-validator.test.ts index fc8d7f0..19bc318 100644 --- a/definitions/solana-00000000000000000000000000000000/solana-test-validator.test.ts +++ b/definitions/solana-00000000000000000000000000000000/solana-test-validator.test.ts @@ -1,93 +1,34 @@ import { afterAll, beforeAll, describe, expect, it } from '@jest/globals'; -import { KarfiaAgentContainer, KarfiaContainer, KarfiaTestcontainers } from 'karfia-testcontainers'; +import { KarfiaContainer, KarfiaTestcontainers } from 'karfia-testcontainers'; import definition from './solana-test-validator.json'; -describe('testcontainers', () => { - let testcontainers: KarfiaTestcontainers; +let testcontainers: KarfiaTestcontainers; - beforeAll(async () => { - testcontainers = await KarfiaTestcontainers.start(definition); - }); - - afterAll(async () => { - await testcontainers.stop(); - }); - - describe('solana-test-validator', () => { - let validator: KarfiaContainer; - - beforeAll(() => { - validator = testcontainers.getContainer('solana-test-validator'); - }); +beforeAll(async () => { + testcontainers = await KarfiaTestcontainers.start(definition); +}); - it('should rpc(getBlockHeight)', async () => { - const response = await validator.rpc({ - method: 'getBlockHeight', - }); +afterAll(async () => { + await testcontainers.stop(); +}); - expect(response.status).toStrictEqual(200); +describe('solana-test-validator', () => { + let validator: KarfiaContainer; - expect(await response.json()).toMatchObject({ - result: 0, - }); - }); + beforeAll(() => { + validator = testcontainers.getContainer('solana-test-validator'); }); - describe('karfia-agent', () => { - let agent: KarfiaAgentContainer; - - beforeAll(() => { - agent = testcontainers.getKarfiaAgent(); - }); - - it('should get karfia-agent/deployment', async () => { - const result = await agent.getDeployment(); - expect(result).toMatchObject({ - deploymentId: testcontainers.getDeploymentId(), - definitionId: definition.id, - caip2: definition.caip2, - name: definition.name, - }); - }); - - it('should get karfia-agent/definition', async () => { - const result = await agent.getDefinition(); - const expected = { - ...definition, - $schema: undefined, - }; - delete expected.$schema; - expect(result).toMatchObject(expected); - }); - - it('should get karfia-agent/probes/startup', async () => { - const response = await agent.probe('startup'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - ok: true, - }); + it('should rpc(getBlockHeight)', async () => { + const response = await validator.rpc({ + method: 'getBlockHeight', }); - it('should get karfia-agent/probes/liveness', async () => { - const response = await agent.probe('liveness'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - ok: true, - }); - }); + expect(response.status).toStrictEqual(200); - it('should get karfia-agent/probes/readiness', async () => { - const response = await agent.probe('readiness'); - expect(response.status).toStrictEqual(200); - expect(await response.json()).toMatchObject({ - containers: { - 'solana-test-validator': { - ok: true, - }, - }, - ok: true, - }); + expect(await response.json()).toMatchObject({ + result: 0, }); }); }); diff --git a/packages/karfia-agent/package.json b/packages/karfia-agent/package.json index fb3089c..921dba4 100644 --- a/packages/karfia-agent/package.json +++ b/packages/karfia-agent/package.json @@ -11,7 +11,8 @@ "build:docker": "docker buildx build --progress=plain -t ghcr.io/fuxingloh/karfia-agent:$(node -p \"require('./package.json').version\") -f Dockerfile ../../", "clean": "tsc --build --clean", "lint": "eslint .", - "push:docker": "docker buildx build --progress=plain -t ghcr.io/fuxingloh/karfia-agent:$(node -p \"require('./package.json').version\") -f Dockerfile ../../ --output type=registry --platform linux/amd64,linux/arm64" + "push:docker": "docker buildx build --progress=plain -t ghcr.io/fuxingloh/karfia-agent:$(node -p \"require('./package.json').version\") -f Dockerfile ../../ --output type=registry --platform linux/amd64,linux/arm64", + "test": "jest" }, "lint-staged": { "*": [ @@ -22,6 +23,9 @@ "prettier --write" ] }, + "jest": { + "preset": "@workspace/jest-preset" + }, "dependencies": { "@trpc/server": "^10.45.2", "ajv": "^8.13.0", @@ -31,6 +35,7 @@ "zod": "^3.23.8" }, "devDependencies": { + "@workspace/jest-preset": "workspace:*", "@workspace/tsconfig": "workspace:*" } } diff --git a/packages/karfia-agent/routers/_app.ts b/packages/karfia-agent/routers/_app.ts index 7521c6c..2616d51 100644 --- a/packages/karfia-agent/routers/_app.ts +++ b/packages/karfia-agent/routers/_app.ts @@ -1,8 +1,10 @@ -import { router } from '../trpc'; +import { createCallerFactory, router } from '../trpc'; import { agentRouter } from './agent'; import { probesRouter } from './probes'; export const appRouter = router({ - probes: probesRouter, - agent: agentRouter, + Probes: probesRouter, + Agent: agentRouter, }); + +export const createCaller = createCallerFactory(appRouter); diff --git a/packages/karfia-agent/routers/agent.test.ts b/packages/karfia-agent/routers/agent.test.ts new file mode 100644 index 0000000..a12faa5 --- /dev/null +++ b/packages/karfia-agent/routers/agent.test.ts @@ -0,0 +1,87 @@ +import { randomBytes } from 'node:crypto'; + +import { expect, it } from '@jest/globals'; +import { KarfiaDefinition } from 'karfia-definition'; + +import { createCaller } from './_app'; + +const definition: KarfiaDefinition = { + id: 'bip122:0f9188f13cb7b2c71f2a335e3a4fc328/bitcoind:25.1', + caip2: 'bip122:0f9188f13cb7b2c71f2a335e3a4fc328', + name: 'Bitcoin Regtest', + environment: { + RPC_USER: { + type: 'Value', + value: 'agent', + }, + RPC_PASSWORD: { + type: 'Value', + value: 'agent', + }, + }, + containers: { + bitcoind: { + image: 'docker.io/kylemanna/bitcoind@sha256:1492fa0306cb7eb5de8d50ba60367cff8d29b00b516e45e93e05f8b54fa2970e', + source: 'https://github.com/kylemanna/docker-bitcoind', + endpoints: { + rpc: { + port: 8332, + protocol: 'HTTP JSON-RPC 2.0', + authorization: { + type: 'HttpBasic', + username: 'RPC_USER', + password: 'RPC_PASSWORD', + }, + probes: { + readiness: { + method: 'getblockchaininfo', + params: [], + match: { + result: { + type: 'object', + properties: { + blocks: { + type: 'number', + }, + }, + required: ['blocks'], + }, + }, + }, + }, + }, + }, + resources: { + cpu: 0.25, + memory: 256, + }, + environment: { + REGTEST: '1', + RPCUSER: 'RPC_USER', + RPCPASSWORD: 'RPC_PASSWORD', + }, + }, + }, +}; + +const deploymentId = randomBytes(8).toString('hex'); + +const caller = createCaller({ + definition: definition, + deploymentId: deploymentId, +}); + +it('should call Agent.GetDeployment', async () => { + const result = await caller.Agent.GetDeployment(); + expect(result).toStrictEqual({ + caip2: 'bip122:0f9188f13cb7b2c71f2a335e3a4fc328', + definitionId: 'bip122:0f9188f13cb7b2c71f2a335e3a4fc328/bitcoind:25.1', + deploymentId: deploymentId, + name: 'Bitcoin Regtest', + }); +}); + +it('should call Agent.GetDefinition', async () => { + const result = await caller.Agent.GetDefinition(); + expect(result).toEqual(JSON.parse(JSON.stringify(definition))); +}); diff --git a/packages/karfia-agent/routers/agent.ts b/packages/karfia-agent/routers/agent.ts index dfc7dec..b58433d 100644 --- a/packages/karfia-agent/routers/agent.ts +++ b/packages/karfia-agent/routers/agent.ts @@ -3,7 +3,7 @@ import { z } from 'zod'; import { publicProcedure, router } from '../trpc'; export const agentRouter = router({ - getDefinition: publicProcedure + GetDefinition: publicProcedure .meta({ openapi: { method: 'GET', path: '/definition', tags: ['agent'] } }) .input(z.void()) .output( @@ -19,7 +19,7 @@ export const agentRouter = router({ .query(async ({ ctx }) => { return ctx.definition; }), - getDeployment: publicProcedure + GetDeployment: publicProcedure .meta({ openapi: { method: 'GET', path: '/deployment', tags: ['agent'] } }) .input(z.void()) .output( diff --git a/packages/karfia-agent/routers/probes.ts b/packages/karfia-agent/routers/probes.ts index ef92397..7ed0a4e 100644 --- a/packages/karfia-agent/routers/probes.ts +++ b/packages/karfia-agent/routers/probes.ts @@ -23,17 +23,17 @@ const probeProcedure = publicProcedure.input(z.void()).output( ); export const probesRouter = router({ - probeStartup: probeProcedure + ProbeStartup: probeProcedure .meta({ openapi: { method: 'GET', path: '/probes/startup', tags: ['probes'] } }) .query(async ({ ctx }) => { return query(ctx.definition, ProbeType.startup); }), - probeLiveness: probeProcedure + ProbeLiveness: probeProcedure .meta({ openapi: { method: 'GET', path: '/probes/liveness', tags: ['probes'] } }) .query(async ({ ctx }) => { return query(ctx.definition, ProbeType.liveness); }), - probeReadiness: probeProcedure + ProbeReadiness: probeProcedure .meta({ openapi: { method: 'GET', path: '/probes/readiness', tags: ['probes'] } }) .query(async ({ ctx }) => { return query(ctx.definition, ProbeType.readiness); diff --git a/packages/karfia-agent/trpc.ts b/packages/karfia-agent/trpc.ts index 62bf32f..f21185c 100644 --- a/packages/karfia-agent/trpc.ts +++ b/packages/karfia-agent/trpc.ts @@ -6,4 +6,7 @@ import type { Context } from './routers/_context'; const t = initTRPC.meta().context().create(); export const router = t.router; + +export const createCallerFactory = t.createCallerFactory; + export const publicProcedure = t.procedure; diff --git a/packages/karfia-testcontainers/index.test.ts b/packages/karfia-testcontainers/index.test.ts new file mode 100644 index 0000000..fbd0bd7 --- /dev/null +++ b/packages/karfia-testcontainers/index.test.ts @@ -0,0 +1,158 @@ +import { afterAll, beforeAll, describe, expect, it } from '@jest/globals'; + +import { KarfiaAgentContainer, KarfiaContainer, KarfiaTestcontainers } from './index'; + +const definition = { + id: 'bip122:0f9188f13cb7b2c71f2a335e3a4fc328/bitcoind:25.1', + caip2: 'bip122:0f9188f13cb7b2c71f2a335e3a4fc328', + name: 'Bitcoin Regtest', + environment: { + RPC_USER: { + type: 'Value', + value: 'karfia', + }, + RPC_PASSWORD: { + type: 'Value', + value: 'karfia', + }, + }, + containers: { + bitcoind: { + image: 'docker.io/kylemanna/bitcoind@sha256:1492fa0306cb7eb5de8d50ba60367cff8d29b00b516e45e93e05f8b54fa2970e', + source: 'https://github.com/kylemanna/docker-bitcoind', + endpoints: { + rpc: { + port: 8332, + protocol: 'HTTP JSON-RPC 2.0', + authorization: { + type: 'HttpBasic', + username: 'RPC_USER', + password: 'RPC_PASSWORD', + }, + probes: { + readiness: { + method: 'getblockchaininfo', + params: [], + match: { + result: { + type: 'object', + properties: { + blocks: { + type: 'number', + }, + }, + required: ['blocks'], + }, + }, + }, + }, + }, + }, + resources: { + cpu: 0.25, + memory: 256, + }, + environment: { + REGTEST: '1', + RPCUSER: 'RPC_USER', + RPCPASSWORD: 'RPC_PASSWORD', + }, + }, + }, +}; + +let testcontainers: KarfiaTestcontainers; + +beforeAll(async () => { + testcontainers = await KarfiaTestcontainers.start(definition); +}); + +afterAll(async () => { + await testcontainers.stop(); +}); + +describe('container', () => { + let container: KarfiaContainer; + + beforeAll(() => { + container = testcontainers.getContainer('bitcoind'); + }); + + it('should get rpc port', async () => { + const port = container.getHostPort('rpc'); + expect(port).toStrictEqual(expect.any(Number)); + }); + + it('should rpc getblockchaininfo', async () => { + const response = await container.rpc({ + method: 'getblockchaininfo', + }); + + expect(response.status).toStrictEqual(200); + + expect(await response.json()).toMatchObject({ + result: { + bestblockhash: '0f9188f13cb7b2c71f2a335e3a4fc328bf5beb436012afca590b1a11466e2206', + chain: 'regtest', + blocks: 0, + }, + }); + }); +}); + +describe('karfia-agent', () => { + let agent: KarfiaAgentContainer; + + beforeAll(() => { + agent = testcontainers.getKarfiaAgent(); + }); + + it('should call GET /deployment', async () => { + const result = await agent.getDeployment(); + expect(result).toMatchObject({ + deploymentId: testcontainers.getDeploymentId(), + definitionId: definition.id, + caip2: definition.caip2, + name: definition.name, + }); + }); + + it('should call GET /definition', async () => { + const result = await agent.getDefinition(); + const expected = { + ...definition, + $schema: undefined, + }; + delete expected.$schema; + expect(result).toMatchObject(expected); + }); + + it('should call GET /probes/startup', async () => { + const response = await agent.probe('startup'); + expect(response.status).toStrictEqual(200); + expect(await response.json()).toMatchObject({ + ok: true, + }); + }); + + it('should call GET /probes/liveness', async () => { + const response = await agent.probe('liveness'); + expect(response.status).toStrictEqual(200); + expect(await response.json()).toMatchObject({ + ok: true, + }); + }); + + it('should call GET /probes/readiness', async () => { + const response = await agent.probe('readiness'); + expect(response.status).toStrictEqual(200); + expect(await response.json()).toMatchObject({ + containers: { + bitcoind: { + ok: true, + }, + }, + ok: true, + }); + }); +}); diff --git a/packages/karfia-testcontainers/package.json b/packages/karfia-testcontainers/package.json index 8081957..6e9bb4d 100644 --- a/packages/karfia-testcontainers/package.json +++ b/packages/karfia-testcontainers/package.json @@ -15,7 +15,7 @@ "build": "tsc --project tsconfig.build.json", "clean": "tsc --build --clean", "lint": "eslint .", - "test": "jest --passWithNoTests" + "test": "jest" }, "lint-staged": { "*": [ diff --git a/packages/karfia-testcontainers/turbo.json b/packages/karfia-testcontainers/turbo.json index b723a1a..c72ef91 100644 --- a/packages/karfia-testcontainers/turbo.json +++ b/packages/karfia-testcontainers/turbo.json @@ -2,6 +2,10 @@ "$schema": "https://turbo.build/schema.json", "extends": ["//"], "pipeline": { + "test": { + "inputs": ["tsconfig.json", "./**/*.ts", "./**/*.test.ts"], + "dependsOn": ["karfia-agent#build:docker", "^build"] + }, "build": { "inputs": ["tsconfig.json", "tsconfig.build.json", "./**/*.ts"], "outputs": ["./**/*.js", "./**/*.d.ts", "./**/*.d.ts.map"], diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index f9dfc43..9a7b1c5 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -177,6 +177,9 @@ importers: specifier: ^3.23.8 version: 3.23.8 devDependencies: + '@workspace/jest-preset': + specifier: workspace:* + version: link:../../workspace/jest-preset '@workspace/tsconfig': specifier: workspace:* version: link:../../workspace/tsconfig @@ -251,7 +254,7 @@ importers: version: 9.1.0(eslint@8.57.0) eslint-plugin-import: specifier: ^2.29.1 - version: 2.29.1(@typescript-eslint/parser@7.9.0)(eslint@8.57.0) + version: 2.29.1(@typescript-eslint/parser@7.10.0)(eslint@8.57.0) eslint-plugin-no-only-tests: specifier: ^3.1.0 version: 3.1.0 @@ -265,8 +268,8 @@ importers: specifier: ^15.3.0 version: 15.3.0 typescript-eslint: - specifier: ^7.9.0 - version: 7.9.0(eslint@8.57.0)(typescript@5.4.5) + specifier: ^7.10.0 + version: 7.10.0(eslint@8.57.0)(typescript@5.4.5) workspace/jest-preset: {} @@ -1346,8 +1349,8 @@ packages: '@types/yargs-parser': 21.0.3 dev: true - /@typescript-eslint/eslint-plugin@7.9.0(@typescript-eslint/parser@7.9.0)(eslint@8.57.0)(typescript@5.4.5): - resolution: {integrity: sha512-6e+X0X3sFe/G/54aC3jt0txuMTURqLyekmEHViqyA2VnxhLMpvA6nqmcjIy+Cr9tLDHPssA74BP5Mx9HQIxBEA==} + /@typescript-eslint/eslint-plugin@7.10.0(@typescript-eslint/parser@7.10.0)(eslint@8.57.0)(typescript@5.4.5): + resolution: {integrity: sha512-PzCr+a/KAef5ZawX7nbyNwBDtM1HdLIT53aSA2DDlxmxMngZ43O8SIePOeX8H5S+FHXeI6t97mTt/dDdzY4Fyw==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: '@typescript-eslint/parser': ^7.0.0 @@ -1358,11 +1361,11 @@ packages: optional: true dependencies: '@eslint-community/regexpp': 4.10.0 - '@typescript-eslint/parser': 7.9.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/scope-manager': 7.9.0 - '@typescript-eslint/type-utils': 7.9.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/utils': 7.9.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.9.0 + '@typescript-eslint/parser': 7.10.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.10.0 + '@typescript-eslint/type-utils': 7.10.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.10.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.10.0 eslint: 8.57.0 graphemer: 1.4.0 ignore: 5.3.1 @@ -1373,8 +1376,8 @@ packages: - supports-color dev: false - /@typescript-eslint/parser@7.9.0(eslint@8.57.0)(typescript@5.4.5): - resolution: {integrity: sha512-qHMJfkL5qvgQB2aLvhUSXxbK7OLnDkwPzFalg458pxQgfxKDfT1ZDbHQM/I6mDIf/svlMkj21kzKuQ2ixJlatQ==} + /@typescript-eslint/parser@7.10.0(eslint@8.57.0)(typescript@5.4.5): + resolution: {integrity: sha512-2EjZMA0LUW5V5tGQiaa2Gys+nKdfrn2xiTIBLR4fxmPmVSvgPcKNW+AE/ln9k0A4zDUti0J/GZXMDupQoI+e1w==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -1383,10 +1386,10 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/scope-manager': 7.9.0 - '@typescript-eslint/types': 7.9.0 - '@typescript-eslint/typescript-estree': 7.9.0(typescript@5.4.5) - '@typescript-eslint/visitor-keys': 7.9.0 + '@typescript-eslint/scope-manager': 7.10.0 + '@typescript-eslint/types': 7.10.0 + '@typescript-eslint/typescript-estree': 7.10.0(typescript@5.4.5) + '@typescript-eslint/visitor-keys': 7.10.0 debug: 4.3.4 eslint: 8.57.0 typescript: 5.4.5 @@ -1394,16 +1397,16 @@ packages: - supports-color dev: false - /@typescript-eslint/scope-manager@7.9.0: - resolution: {integrity: sha512-ZwPK4DeCDxr3GJltRz5iZejPFAAr4Wk3+2WIBaj1L5PYK5RgxExu/Y68FFVclN0y6GGwH8q+KgKRCvaTmFBbgQ==} + /@typescript-eslint/scope-manager@7.10.0: + resolution: {integrity: sha512-7L01/K8W/VGl7noe2mgH0K7BE29Sq6KAbVmxurj8GGaPDZXPr8EEQ2seOeAS+mEV9DnzxBQB6ax6qQQ5C6P4xg==} engines: {node: ^18.18.0 || >=20.0.0} dependencies: - '@typescript-eslint/types': 7.9.0 - '@typescript-eslint/visitor-keys': 7.9.0 + '@typescript-eslint/types': 7.10.0 + '@typescript-eslint/visitor-keys': 7.10.0 dev: false - /@typescript-eslint/type-utils@7.9.0(eslint@8.57.0)(typescript@5.4.5): - resolution: {integrity: sha512-6Qy8dfut0PFrFRAZsGzuLoM4hre4gjzWJB6sUvdunCYZsYemTkzZNwF1rnGea326PHPT3zn5Lmg32M/xfJfByA==} + /@typescript-eslint/type-utils@7.10.0(eslint@8.57.0)(typescript@5.4.5): + resolution: {integrity: sha512-D7tS4WDkJWrVkuzgm90qYw9RdgBcrWmbbRkrLA4d7Pg3w0ttVGDsvYGV19SH8gPR5L7OtcN5J1hTtyenO9xE9g==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -1412,8 +1415,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/typescript-estree': 7.9.0(typescript@5.4.5) - '@typescript-eslint/utils': 7.9.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/typescript-estree': 7.10.0(typescript@5.4.5) + '@typescript-eslint/utils': 7.10.0(eslint@8.57.0)(typescript@5.4.5) debug: 4.3.4 eslint: 8.57.0 ts-api-utils: 1.3.0(typescript@5.4.5) @@ -1422,13 +1425,13 @@ packages: - supports-color dev: false - /@typescript-eslint/types@7.9.0: - resolution: {integrity: sha512-oZQD9HEWQanl9UfsbGVcZ2cGaR0YT5476xfWE0oE5kQa2sNK2frxOlkeacLOTh9po4AlUT5rtkGyYM5kew0z5w==} + /@typescript-eslint/types@7.10.0: + resolution: {integrity: sha512-7fNj+Ya35aNyhuqrA1E/VayQX9Elwr8NKZ4WueClR3KwJ7Xx9jcCdOrLW04h51de/+gNbyFMs+IDxh5xIwfbNg==} engines: {node: ^18.18.0 || >=20.0.0} dev: false - /@typescript-eslint/typescript-estree@7.9.0(typescript@5.4.5): - resolution: {integrity: sha512-zBCMCkrb2YjpKV3LA0ZJubtKCDxLttxfdGmwZvTqqWevUPN0FZvSI26FalGFFUZU/9YQK/A4xcQF9o/VVaCKAg==} + /@typescript-eslint/typescript-estree@7.10.0(typescript@5.4.5): + resolution: {integrity: sha512-LXFnQJjL9XIcxeVfqmNj60YhatpRLt6UhdlFwAkjNc6jSUlK8zQOl1oktAP8PlWFzPQC1jny/8Bai3/HPuvN5g==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: typescript: '*' @@ -1436,8 +1439,8 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/types': 7.9.0 - '@typescript-eslint/visitor-keys': 7.9.0 + '@typescript-eslint/types': 7.10.0 + '@typescript-eslint/visitor-keys': 7.10.0 debug: 4.3.4 globby: 11.1.0 is-glob: 4.0.3 @@ -1449,27 +1452,27 @@ packages: - supports-color dev: false - /@typescript-eslint/utils@7.9.0(eslint@8.57.0)(typescript@5.4.5): - resolution: {integrity: sha512-5KVRQCzZajmT4Ep+NEgjXCvjuypVvYHUW7RHlXzNPuak2oWpVoD1jf5xCP0dPAuNIchjC7uQyvbdaSTFaLqSdA==} + /@typescript-eslint/utils@7.10.0(eslint@8.57.0)(typescript@5.4.5): + resolution: {integrity: sha512-olzif1Fuo8R8m/qKkzJqT7qwy16CzPRWBvERS0uvyc+DHd8AKbO4Jb7kpAvVzMmZm8TrHnI7hvjN4I05zow+tg==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 dependencies: '@eslint-community/eslint-utils': 4.4.0(eslint@8.57.0) - '@typescript-eslint/scope-manager': 7.9.0 - '@typescript-eslint/types': 7.9.0 - '@typescript-eslint/typescript-estree': 7.9.0(typescript@5.4.5) + '@typescript-eslint/scope-manager': 7.10.0 + '@typescript-eslint/types': 7.10.0 + '@typescript-eslint/typescript-estree': 7.10.0(typescript@5.4.5) eslint: 8.57.0 transitivePeerDependencies: - supports-color - typescript dev: false - /@typescript-eslint/visitor-keys@7.9.0: - resolution: {integrity: sha512-iESPx2TNLDNGQLyjKhUvIKprlP49XNEK+MvIf9nIO7ZZaZdbnfWKHnXAgufpxqfA0YryH8XToi4+CjBgVnFTSQ==} + /@typescript-eslint/visitor-keys@7.10.0: + resolution: {integrity: sha512-9ntIVgsi6gg6FIq9xjEO4VQJvwOqA3jaBFQJ/6TK5AvEup2+cECI6Fh7QiBxmfMHXU0V0J4RyPeOU1VDNzl9cg==} engines: {node: ^18.18.0 || >=20.0.0} dependencies: - '@typescript-eslint/types': 7.9.0 + '@typescript-eslint/types': 7.10.0 eslint-visitor-keys: 3.4.3 dev: false @@ -2564,7 +2567,7 @@ packages: - supports-color dev: false - /eslint-module-utils@2.8.1(@typescript-eslint/parser@7.9.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): + /eslint-module-utils@2.8.1(@typescript-eslint/parser@7.10.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0): resolution: {integrity: sha512-rXDXR3h7cs7dy9RNpUlQf80nX31XWJEyGq1tRMo+6GsO5VmTe4UTwtmonAD4ZkAsrfMVDA2wlGJ3790Ys+D49Q==} engines: {node: '>=4'} peerDependencies: @@ -2585,7 +2588,7 @@ packages: eslint-import-resolver-webpack: optional: true dependencies: - '@typescript-eslint/parser': 7.9.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.10.0(eslint@8.57.0)(typescript@5.4.5) debug: 3.2.7 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 @@ -2593,7 +2596,7 @@ packages: - supports-color dev: false - /eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.9.0)(eslint@8.57.0): + /eslint-plugin-import@2.29.1(@typescript-eslint/parser@7.10.0)(eslint@8.57.0): resolution: {integrity: sha512-BbPC0cuExzhiMo4Ff1BTVwHpjjv28C5R+btTOGaCRC7UEz801up0JadwkeSk5Ued6TG34uaczuVuH6qyy5YUxw==} engines: {node: '>=4'} peerDependencies: @@ -2603,7 +2606,7 @@ packages: '@typescript-eslint/parser': optional: true dependencies: - '@typescript-eslint/parser': 7.9.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.10.0(eslint@8.57.0)(typescript@5.4.5) array-includes: 3.1.8 array.prototype.findlastindex: 1.2.5 array.prototype.flat: 1.3.2 @@ -2612,7 +2615,7 @@ packages: doctrine: 2.1.0 eslint: 8.57.0 eslint-import-resolver-node: 0.3.9 - eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.9.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) + eslint-module-utils: 2.8.1(@typescript-eslint/parser@7.10.0)(eslint-import-resolver-node@0.3.9)(eslint@8.57.0) hasown: 2.0.2 is-core-module: 2.13.1 is-glob: 4.0.3 @@ -5529,8 +5532,8 @@ packages: possible-typed-array-names: 1.0.0 dev: false - /typescript-eslint@7.9.0(eslint@8.57.0)(typescript@5.4.5): - resolution: {integrity: sha512-7iTn9c10teHHCys5Ud/yaJntXZrjt3h2mrx3feJGBOLgQkF3TB1X89Xs3aVQ/GgdXRAXpk2bPTdpRwHP4YkUow==} + /typescript-eslint@7.10.0(eslint@8.57.0)(typescript@5.4.5): + resolution: {integrity: sha512-thO8nyqptXdfWHQrMJJiJyftpW8aLmwRNs11xA8pSrXneoclFPstQZqXvDWuH1WNL4CHffqHvYUeCHTit6yfhQ==} engines: {node: ^18.18.0 || >=20.0.0} peerDependencies: eslint: ^8.56.0 @@ -5539,9 +5542,9 @@ packages: typescript: optional: true dependencies: - '@typescript-eslint/eslint-plugin': 7.9.0(@typescript-eslint/parser@7.9.0)(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/parser': 7.9.0(eslint@8.57.0)(typescript@5.4.5) - '@typescript-eslint/utils': 7.9.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/eslint-plugin': 7.10.0(@typescript-eslint/parser@7.10.0)(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/parser': 7.10.0(eslint@8.57.0)(typescript@5.4.5) + '@typescript-eslint/utils': 7.10.0(eslint@8.57.0)(typescript@5.4.5) eslint: 8.57.0 typescript: 5.4.5 transitivePeerDependencies: diff --git a/workspace/eslint-config/package.json b/workspace/eslint-config/package.json index db146d0..0e3a83e 100644 --- a/workspace/eslint-config/package.json +++ b/workspace/eslint-config/package.json @@ -10,6 +10,6 @@ "eslint-plugin-simple-import-sort": "^12.1.0", "eslint-plugin-unused-imports": "^3.2.0", "globals": "^15.3.0", - "typescript-eslint": "^7.9.0" + "typescript-eslint": "^7.10.0" } } diff --git a/workspace/tsconfig/tsconfig.json b/workspace/tsconfig/tsconfig.json index f7949d2..4e451c8 100644 --- a/workspace/tsconfig/tsconfig.json +++ b/workspace/tsconfig/tsconfig.json @@ -19,6 +19,7 @@ "preserveWatchOutput": true, "skipLibCheck": true, "strict": true, - "resolveJsonModule": true + "resolveJsonModule": true, + "types": ["node"] } }