From 03472aa75a62d5851b6f04d0fa031e8d69e67176 Mon Sep 17 00:00:00 2001 From: Peter Somogyvari Date: Sat, 20 Jul 2024 21:41:49 -0700 Subject: [PATCH] test(cmd-api-server): migrate import from github test to Jest 1. Also two more test cases been migrated. 2. A bug has been fixed in the test tooling package where the keychain vault container helper class was not passing in the publish all ports configuration option correctly. This would normally deserve it's own commit but this bug has been caught in other similar classes at least 3 times in the recent weeks so it's not really worth the attention anymore so I'll just include it in this commit so that we save some time on reviewer attention and CI resource usage. Signed-off-by: Peter Somogyvari --- .github/workflows/ci.yaml | 2 +- .taprc | 3 - jest.config.js | 3 - .../plugin-import-from-github.test.ts | 135 +++++++------ .../plugin-import-without-install.test.ts | 188 ++++++++---------- .../integration/remote-plugin-imports.test.ts | 174 ++++++++-------- .../cactus-keychain-vault-server.ts | 11 +- 7 files changed, 257 insertions(+), 259 deletions(-) diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index 8fbb46a768..72afeafdeb 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -438,7 +438,7 @@ jobs: JEST_TEST_COVERAGE_PATH: ./code-coverage-ts/cactus-cmd-api-server JEST_TEST_CODE_COVERAGE_ENABLED: true TAPE_TEST_PATTERN: >- - --files={./packages/cactus-cmd-api-server/src/test/typescript/integration/plugin-import-from-github.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/integration/plugin-import-without-install.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/integration/remote-plugin-imports.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/unit/config/self-signed-certificate-generator/certificates-work-for-mutual-tls.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/unit/config/self-signed-certificate-generator/generates-working-certificates.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/unit/grpc-js-proto-loader-client-healthcheck.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/unit/grpc-proto-gen-ts-client-healthcheck.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/unit/grpc-proto-gen-ts-client-m-tls-enabled.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/unit/plugins/install-basic-plugin-consortium-manual.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/unit/plugins/install-basic-plugin-keychain-memory.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/unit/plugins/install-basic-plugin-ledger-connector-fabric-0-7-0.test.ts} + --files={./packages/cactus-cmd-api-server/src/test/typescript/unit/config/self-signed-certificate-generator/certificates-work-for-mutual-tls.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/unit/config/self-signed-certificate-generator/generates-working-certificates.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/unit/grpc-js-proto-loader-client-healthcheck.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/unit/grpc-proto-gen-ts-client-healthcheck.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/unit/grpc-proto-gen-ts-client-m-tls-enabled.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/unit/plugins/install-basic-plugin-consortium-manual.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/unit/plugins/install-basic-plugin-keychain-memory.test.ts,./packages/cactus-cmd-api-server/src/test/typescript/unit/plugins/install-basic-plugin-ledger-connector-fabric-0-7-0.test.ts} TAPE_TEST_RUNNER_DISABLED: false runs-on: ubuntu-22.04 steps: diff --git a/.taprc b/.taprc index 3c1f271bc3..577a6bafe3 100644 --- a/.taprc +++ b/.taprc @@ -52,9 +52,6 @@ files: - ./packages/cactus-test-tooling/src/test/typescript/integration/besu/besu-test-ledger/constructor-validates-options.test.ts - ./packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/get-single-status-endpoint.test.ts - ./packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/openapi/openapi-validation.test.ts - - ./packages/cactus-cmd-api-server/src/test/typescript/integration/remote-plugin-imports.test.ts - - ./packages/cactus-cmd-api-server/src/test/typescript/integration/plugin-import-from-github.test.ts - - ./packages/cactus-cmd-api-server/src/test/typescript/integration/plugin-import-without-install.test.ts - ./packages/cactus-cmd-api-server/src/test/typescript/unit/plugins/install-basic-plugin-keychain-memory.test.ts - ./packages/cactus-cmd-api-server/src/test/typescript/unit/plugins/install-basic-plugin-ledger-connector-fabric-0-7-0.test.ts - ./packages/cactus-cmd-api-server/src/test/typescript/unit/plugins/install-basic-plugin-consortium-manual.test.ts diff --git a/jest.config.js b/jest.config.js index cb07630cb3..da76fc78fb 100644 --- a/jest.config.js +++ b/jest.config.js @@ -65,9 +65,6 @@ module.exports = { `./packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/get-single-status-endpoint.test.ts`, `./packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/get--status-endpoint-invalid.test.ts`, `./packages/cactus-test-plugin-htlc-eth-besu/src/test/typescript/integration/plugin-htlc-eth-besu/openapi/openapi-validation.test.ts`, - `./packages/cactus-cmd-api-server/src/test/typescript/integration/remote-plugin-imports.test.ts`, - `./packages/cactus-cmd-api-server/src/test/typescript/integration/plugin-import-from-github.test.ts`, - `./packages/cactus-cmd-api-server/src/test/typescript/integration/plugin-import-without-install.test.ts`, `./packages/cactus-cmd-api-server/src/test/typescript/unit/plugins/install-basic-plugin-keychain-memory.test.ts`, `./packages/cactus-cmd-api-server/src/test/typescript/unit/plugins/install-basic-plugin-ledger-connector-fabric-0-7-0.test.ts`, `./packages/cactus-cmd-api-server/src/test/typescript/unit/plugins/install-basic-plugin-consortium-manual.test.ts`, diff --git a/packages/cactus-cmd-api-server/src/test/typescript/integration/plugin-import-from-github.test.ts b/packages/cactus-cmd-api-server/src/test/typescript/integration/plugin-import-from-github.test.ts index 4445c7aa68..a94485b18a 100644 --- a/packages/cactus-cmd-api-server/src/test/typescript/integration/plugin-import-from-github.test.ts +++ b/packages/cactus-cmd-api-server/src/test/typescript/integration/plugin-import-from-github.test.ts @@ -1,86 +1,91 @@ -import path from "path"; -import test, { Test } from "tape-promise/tape"; -import { v4 as uuidv4 } from "uuid"; -import { readFile } from "fs/promises"; -import { LogLevelDesc } from "@hyperledger/cactus-common"; +import { randomUUID } from "node:crypto"; +import path from "node:path"; +import { readFile } from "node:fs/promises"; + +import "jest-extended"; +import { LoggerProvider, LogLevelDesc } from "@hyperledger/cactus-common"; import { PluginImportAction, PluginImportType, } from "@hyperledger/cactus-core-api"; -import { - ApiServer, - AuthorizationProtocol, - ConfigService, -} from "../../../main/typescript/public-api"; +import { ConfigService } from "../../../main/typescript/config/config-service"; +import { AuthorizationProtocol } from "../../../main/typescript/config/authorization-protocol"; +import { ApiServer } from "../../../main/typescript/api-server"; -const logLevel: LogLevelDesc = "TRACE"; +describe("ApiServer", () => { + let apiServer: ApiServer; + + const logLevel: LogLevelDesc = "INFO"; + + const log = LoggerProvider.getOrCreate({ + label: "plugin-import-from-github.test.ts", + level: logLevel, + }); -test("can install plugins at runtime with specified version based on imports", async (t: Test) => { const pluginsPath = path.join( __dirname, "../../../../../../", // walk back up to the project root ".tmp/test/test-cmd-api-server/plugin-import-from-github_test/", // the dir path from the root - uuidv4(), // then a random directory to ensure proper isolation + randomUUID(), // then a random directory to ensure proper isolation ); const pluginManagerOptionsJson = JSON.stringify({ pluginsPath }); - const configService = new ConfigService(); - const apiServerOptions = await configService.newExampleConfig(); - apiServerOptions.pluginManagerOptionsJson = pluginManagerOptionsJson; - apiServerOptions.authorizationProtocol = AuthorizationProtocol.NONE; - apiServerOptions.configFile = ""; - apiServerOptions.apiCorsDomainCsv = "*"; - apiServerOptions.apiPort = 0; - apiServerOptions.cockpitPort = 0; - apiServerOptions.grpcPort = 0; - apiServerOptions.crpcPort = 0; - apiServerOptions.apiTlsEnabled = false; - apiServerOptions.plugins = [ - { - packageName: "@hyperledger/cactus-dummy-package", - type: PluginImportType.Local, - action: PluginImportAction.Install, - options: { - instanceId: uuidv4(), - keychainId: uuidv4(), - logLevel, - packageSrc: - "https://gitpkg.now.sh/hyperledger/cactus/packages/cactus-cmd-api-server/src/test/resources/cactus-dummy-package?main", - }, - }, - ]; - const config = await configService.newExampleConfigConvict(apiServerOptions); - - const apiServer = new ApiServer({ - config: config.getProperties(), + afterAll(async () => { + await apiServer.shutdown(); }); - const startResponse = apiServer.start(); - await t.doesNotReject( - startResponse, - "failed to start API server with dynamic plugin imports configured for it...", - ); - t.ok(startResponse, "startResponse truthy OK"); + it("can install plugins at runtime from GitHub", async () => { + const apiSrvOpts = await configService.newExampleConfig(); + apiSrvOpts.pluginManagerOptionsJson = pluginManagerOptionsJson; + apiSrvOpts.authorizationProtocol = AuthorizationProtocol.NONE; + apiSrvOpts.configFile = ""; + apiSrvOpts.apiCorsDomainCsv = "*"; + apiSrvOpts.apiPort = 0; + apiSrvOpts.cockpitPort = 0; + apiSrvOpts.grpcPort = 0; + apiSrvOpts.crpcPort = 0; + apiSrvOpts.apiTlsEnabled = false; + apiSrvOpts.plugins = [ + { + packageName: "@hyperledger/cactus-dummy-package", + type: PluginImportType.Local, + action: PluginImportAction.Install, + options: { + instanceId: randomUUID(), + keychainId: randomUUID(), + logLevel, + packageSrc: + "https://gitpkg.now.sh/hyperledger/cactus/packages/cactus-cmd-api-server/src/test/resources/cactus-dummy-package?main", + }, + }, + ]; + const config = await configService.newExampleConfigConvict(apiSrvOpts); - const packageFilePath = path.join( - pluginsPath, - apiServerOptions.plugins[0].options.instanceId, - "node_modules", - `${apiServerOptions.plugins[0].packageName}`, - "package.json", - ); + apiServer = new ApiServer({ + config: config.getProperties(), + }); - const pkgJsonStr = await readFile(packageFilePath, "utf-8"); - const { name, version } = JSON.parse(pkgJsonStr); + const startPromise = apiServer.start(); + await expect(startPromise).toResolve(); + await expect(startPromise).toBeTruthy(); + await expect((await startPromise).addressInfoApi).toBeTruthy(); + await expect((await startPromise).addressInfoCrpc).toBeTruthy(); + await expect((await startPromise).addressInfoGrpc).toBeTruthy(); - t.comment(name); - t.comment(version); - t.strictEquals( - name, - apiServerOptions.plugins[0].packageName, - `Package name strictly equal to ${apiServerOptions.plugins[0].packageName}`, - ); + const packageFilePath = path.join( + pluginsPath, + apiSrvOpts.plugins[0].options.instanceId, + "node_modules", + `${apiSrvOpts.plugins[0].packageName}`, + "package.json", + ); + + const pkgJsonStr = await readFile(packageFilePath, "utf-8"); + const { name, version } = JSON.parse(pkgJsonStr); - test.onFinish(() => apiServer.shutdown()); + log.debug("installed package name on file-system:", name); + log.debug("installed package version on file-system:", version); + expect(name).toEqual(apiSrvOpts.plugins[0].packageName); + }); }); diff --git a/packages/cactus-cmd-api-server/src/test/typescript/integration/plugin-import-without-install.test.ts b/packages/cactus-cmd-api-server/src/test/typescript/integration/plugin-import-without-install.test.ts index 2aa05f66c3..224bd292ea 100644 --- a/packages/cactus-cmd-api-server/src/test/typescript/integration/plugin-import-without-install.test.ts +++ b/packages/cactus-cmd-api-server/src/test/typescript/integration/plugin-import-without-install.test.ts @@ -1,47 +1,48 @@ -import path from "path"; -import test, { Test } from "tape-promise/tape"; -import { v4 as uuidv4 } from "uuid"; +import { randomUUID } from "node:crypto"; +import { readFile } from "node:fs/promises"; +import path from "node:path"; + +import "jest-extended"; +import lmify from "lmify"; +import fs from "fs-extra"; + import { LogLevelDesc } from "@hyperledger/cactus-common"; import { PluginImportAction, PluginImportType, } from "@hyperledger/cactus-core-api"; -import { - ApiServer, - AuthorizationProtocol, - ConfigService, -} from "../../../main/typescript/public-api"; -import lmify from "lmify"; -import fs from "fs-extra"; -import { readFile } from "fs/promises"; -const logLevel: LogLevelDesc = "TRACE"; +import { ConfigService } from "../../../main/typescript/config/config-service"; +import { AuthorizationProtocol } from "../../../main/typescript/config/authorization-protocol"; +import { ApiServer } from "../../../main/typescript/api-server"; + +describe("ApiServer", () => { + const logLevel: LogLevelDesc = "INFO"; + const instanceId = randomUUID(); + const keychainId = randomUUID(); -test("can instantiate plugins at runtime without install them", async (t: Test) => { - test("if plugin is not already installed and we set action to instantiate, server starting will fail", async (t2: Test) => { + it("checks for invalid case of PluginImportAction.Instantiate and PluginImportType.Local", async () => { const pluginsPath = path.join( __dirname, "../../../../../../", // walk back up to the project root ".tmp/test/cmd-api-server/plugin-import-without-install/", // the dir path from the root - uuidv4(), // then a random directory to ensure proper isolation + randomUUID(), // then a random directory to ensure proper isolation ); const pluginManagerOptionsJson = JSON.stringify({ pluginsPath }); const configService = new ConfigService(); - const apiServerOptions = await configService.newExampleConfig(); - apiServerOptions.pluginManagerOptionsJson = pluginManagerOptionsJson; - apiServerOptions.authorizationProtocol = AuthorizationProtocol.NONE; - apiServerOptions.configFile = ""; - apiServerOptions.apiCorsDomainCsv = "*"; - apiServerOptions.apiPort = 0; - apiServerOptions.cockpitPort = 0; - apiServerOptions.grpcPort = 0; - apiServerOptions.crpcPort = 0; - apiServerOptions.apiTlsEnabled = false; - - const instanceId = uuidv4(); - const keychainId = uuidv4(); + const apiSrvOpts = await configService.newExampleConfig(); + apiSrvOpts.pluginManagerOptionsJson = pluginManagerOptionsJson; + apiSrvOpts.authorizationProtocol = AuthorizationProtocol.NONE; + apiSrvOpts.configFile = ""; + apiSrvOpts.apiCorsDomainCsv = "*"; + apiSrvOpts.apiPort = 0; + apiSrvOpts.cockpitPort = 0; + apiSrvOpts.grpcPort = 0; + apiSrvOpts.crpcPort = 0; + apiSrvOpts.apiTlsEnabled = false; + const plugin = { packageName: "@hyperledger/cactus-plugin-keychain-memory", type: PluginImportType.Local, @@ -54,45 +55,55 @@ test("can instantiate plugins at runtime without install them", async (t: Test) }, }; - apiServerOptions.plugins = [plugin]; + apiSrvOpts.plugins = [plugin]; - const config = - await configService.newExampleConfigConvict(apiServerOptions); + const config = await configService.newExampleConfigConvict(apiSrvOpts); const apiServer = new ApiServer({ config: config.getProperties(), }); - await t2.rejects(apiServer.start()); - - t2.end(); + await expect(apiServer.start()).rejects.toThrowError( + expect.toSatisfy((x) => { + expect(x).toBeObject(); + expect(x).toMatchObject({ + toJSON: expect.toBeFunction(), + }); + const xAsJsonString = JSON.stringify(x.toJSON()); + return ( + xAsJsonString.includes("MODULE_NOT_FOUND") && + xAsJsonString.includes("Failed to init PluginRegistry") && + xAsJsonString.includes("Failed to start ApiServer") + ); + }), + ); }); - test("if plugin is already installed and we send a different version, it keeps using plugin installed before call apiServer", async (t2: Test) => { + test("if plugin is already installed and we send a different version, it keeps using plugin installed before call apiServer", async () => { const pluginsPath = path.join( __dirname, "../../../../../../", // walk back up to the project root ".tmp/test/cmd-api-server/plugin-import-without-install/", // the dir path from the root - uuidv4(), // then a random directory to ensure proper isolation + randomUUID(), // then a random directory to ensure proper isolation ); const pluginManagerOptionsJson = JSON.stringify({ pluginsPath }); const configService = new ConfigService(); - const apiServerOptions = await configService.newExampleConfig(); - apiServerOptions.pluginManagerOptionsJson = pluginManagerOptionsJson; - apiServerOptions.authorizationProtocol = AuthorizationProtocol.NONE; - apiServerOptions.configFile = ""; - apiServerOptions.apiCorsDomainCsv = "*"; - apiServerOptions.apiPort = 0; - apiServerOptions.cockpitPort = 0; - apiServerOptions.grpcPort = 0; - apiServerOptions.crpcPort = 0; - apiServerOptions.apiTlsEnabled = false; + const apiSrvOpts = await configService.newExampleConfig(); + apiSrvOpts.pluginManagerOptionsJson = pluginManagerOptionsJson; + apiSrvOpts.authorizationProtocol = AuthorizationProtocol.NONE; + apiSrvOpts.configFile = ""; + apiSrvOpts.apiCorsDomainCsv = "*"; + apiSrvOpts.apiPort = 0; + apiSrvOpts.cockpitPort = 0; + apiSrvOpts.grpcPort = 0; + apiSrvOpts.crpcPort = 0; + apiSrvOpts.apiTlsEnabled = false; const versionToSendServer = "0.7.0"; - const instanceId = uuidv4(); - const keychainId = uuidv4(); + const instanceId = randomUUID(); + const keychainId = randomUUID(); const plugin = { packageName: "@hyperledger/cactus-plugin-keychain-memory", type: PluginImportType.Local, @@ -104,7 +115,7 @@ test("can instantiate plugins at runtime without install them", async (t: Test) version: versionToSendServer, }, }; - apiServerOptions.plugins = [plugin]; + apiSrvOpts.plugins = [plugin]; const pluginPackageDir = path.join(pluginsPath, instanceId); const versionToInstall = "0.10.0"; @@ -123,20 +134,17 @@ test("can instantiate plugins at runtime without install them", async (t: Test) `--prefix=${pluginPackageDir}`, // "--ignore-workspace-root-check", ]); - t2.equal(out.exitCode, 0, "Plugin installed correctly"); + expect(out.exitCode).toEqual(0); const config = await configService.newExampleConfigConvict( - apiServerOptions, + apiSrvOpts, true, ); const apiServer = new ApiServer({ config: config.getProperties(), }); - await t2.doesNotReject( - apiServer.start(), - "apiServer was starting instantiating a plugin previously installed", - ); + await expect(apiServer.start()).toResolve(); const packageFilePath = path.join( pluginsPath, @@ -149,53 +157,44 @@ test("can instantiate plugins at runtime without install them", async (t: Test) const pkgJsonStr = await readFile(packageFilePath, "utf-8"); const { version } = JSON.parse(pkgJsonStr); - t2.strictEquals( - version, - versionToInstall, - "apiServer did not overwrite package", - ); + expect(version).toEqual(versionToInstall); const pluginsCount = apiServer.getPluginImportsCount(); - t2.equal(pluginsCount, 1, "apiServer instantiated 1 plugin"); - - await t2.doesNotReject( - apiServer.shutdown(), - "apiServer was stopped instantiating a plugin previously installed", - ); + expect(pluginsCount).toEqual(1); - t2.end(); + await expect(apiServer.shutdown()).toResolve(); }); - test("if we send action as Installation, apiServer will install the plugin", async (t2: Test) => { + test("if we send action as Installation, apiServer will install the plugin", async () => { const pluginsPath = path.join( __dirname, "../../../../../../", // walk back up to the project root ".tmp/test/cmd-api-server/plugin-import-without-install/", // the dir path from the root - uuidv4(), // then a random directory to ensure proper isolation + randomUUID(), // then a random directory to ensure proper isolation ); const pluginManagerOptionsJson = JSON.stringify({ pluginsPath }); const configService = new ConfigService(); - const apiServerOptions = await configService.newExampleConfig(); - apiServerOptions.pluginManagerOptionsJson = pluginManagerOptionsJson; - apiServerOptions.authorizationProtocol = AuthorizationProtocol.NONE; - apiServerOptions.configFile = ""; - apiServerOptions.apiCorsDomainCsv = "*"; - apiServerOptions.apiPort = 0; - apiServerOptions.cockpitPort = 0; - apiServerOptions.grpcPort = 0; - apiServerOptions.crpcPort = 0; - apiServerOptions.apiTlsEnabled = false; + const apiSrvOpts = await configService.newExampleConfig(); + apiSrvOpts.pluginManagerOptionsJson = pluginManagerOptionsJson; + apiSrvOpts.authorizationProtocol = AuthorizationProtocol.NONE; + apiSrvOpts.configFile = ""; + apiSrvOpts.apiCorsDomainCsv = "*"; + apiSrvOpts.apiPort = 0; + apiSrvOpts.cockpitPort = 0; + apiSrvOpts.grpcPort = 0; + apiSrvOpts.crpcPort = 0; + apiSrvOpts.apiTlsEnabled = false; const versionToInstall = "0.8.0"; - apiServerOptions.plugins = [ + apiSrvOpts.plugins = [ { packageName: "@hyperledger/cactus-plugin-keychain-memory", type: PluginImportType.Local, action: PluginImportAction.Install, options: { - instanceId: uuidv4(), - keychainId: uuidv4(), + instanceId: randomUUID(), + keychainId: randomUUID(), logLevel, version: versionToInstall, }, @@ -203,7 +202,7 @@ test("can instantiate plugins at runtime without install them", async (t: Test) ]; const config = await configService.newExampleConfigConvict( - apiServerOptions, + apiSrvOpts, true, ); @@ -211,35 +210,24 @@ test("can instantiate plugins at runtime without install them", async (t: Test) config: config.getProperties(), }); - await t2.doesNotReject( - apiServer.start(), - "apiServer was starting instantiating a plugin previously installed", - ); + await expect(apiServer.start()).toResolve(); const packageFilePath = path.join( pluginsPath, - apiServerOptions.plugins[0].options.instanceId, + apiSrvOpts.plugins[0].options.instanceId, "node_modules", - `${apiServerOptions.plugins[0].packageName}`, + `${apiSrvOpts.plugins[0].packageName}`, "package.json", ); const pkgJsonStr = await readFile(packageFilePath, "utf-8"); const { version } = JSON.parse(pkgJsonStr); - t2.strictEquals( - version, - versionToInstall, - "apiServer installed the package", - ); + expect(version).toEqual(versionToInstall); const pluginsCount = apiServer.getPluginImportsCount(); - t2.equal(pluginsCount, 1, "apiServer instantiated 1 plugin"); + expect(pluginsCount).toEqual(1); - await t2.doesNotReject(apiServer.shutdown(), "apiServer was stopped"); - - t2.end(); + await expect(apiServer.shutdown()).toResolve(); }); - - t.end(); }); diff --git a/packages/cactus-cmd-api-server/src/test/typescript/integration/remote-plugin-imports.test.ts b/packages/cactus-cmd-api-server/src/test/typescript/integration/remote-plugin-imports.test.ts index 5792139b0b..f2fc9bc54b 100644 --- a/packages/cactus-cmd-api-server/src/test/typescript/integration/remote-plugin-imports.test.ts +++ b/packages/cactus-cmd-api-server/src/test/typescript/integration/remote-plugin-imports.test.ts @@ -1,11 +1,4 @@ -import test, { Test } from "tape-promise/tape"; -import { v4 as uuidv4 } from "uuid"; - -import { - ApiServer, - AuthorizationProtocol, - ConfigService, -} from "../../../main/typescript/public-api"; +import "jest-extended"; import { CactusKeychainVaultServer, @@ -22,95 +15,118 @@ import { PluginImportType, } from "@hyperledger/cactus-core-api"; import path from "path"; +import { randomUUID } from "crypto"; +import { ConfigService } from "../../../main/typescript/config/config-service"; +import { AuthorizationProtocol } from "../../../main/typescript/config/authorization-protocol"; +import { ApiServer } from "../../../main/typescript/api-server"; +import { LoggerProvider, LogLevelDesc } from "@hyperledger/cactus-common"; -test("NodeJS API server + Rust plugin work together", async (t: Test) => { - const vaultTestContainer = new VaultTestServer({}); - await vaultTestContainer.start(); - - const ci = await Containers.getById(vaultTestContainer.containerId); - const vaultIpAddr = await Containers.getContainerInternalIp(ci); - t.comment(`Container VaultTestServer has IPv4: ${vaultIpAddr}`); - - test.onFinish(async () => { - await vaultTestContainer.stop(); - await vaultTestContainer.destroy(); - }); - - const hostPortVault = await vaultTestContainer.getHostPortHttp(); - t.comment(`Container VaultTestServer (Port=${hostPortVault}) started OK`); - const vaultHost = `http://${vaultIpAddr}:${K_DEFAULT_VAULT_HTTP_PORT}`; +describe("ApiServer", () => { + const key = randomUUID(); + const expected = randomUUID(); - const pluginContainer = new CactusKeychainVaultServer({ - envVars: [ - `VAULT_HOST=${vaultHost}`, - `VAULT_TOKEN=${K_DEFAULT_VAULT_DEV_ROOT_TOKEN}`, - "HOST=0.0.0.0:8080", - ], - }); - await pluginContainer.start(); + const logLevel: LogLevelDesc = "INFO"; - test.onFinish(async () => { - await pluginContainer.stop(); - await pluginContainer.destroy(); + const log = LoggerProvider.getOrCreate({ + label: "remote-plugin-imports.test.ts", + level: logLevel, }); - const hostPort = await pluginContainer.getHostPortHttp(); - t.comment(`CactusKeychainVaultServer (Port=${hostPort}) started OK`); - - const configuration = new Configuration({ - basePath: `http://127.0.0.1:${hostPort}`, - }); - const apiClient = new DefaultApi(configuration); + const configService = new ConfigService(); const pluginsPath = path.join( __dirname, // start at the current file's path "../../../../../../", // walk back up to the project root ".tmp/test/cmd-api-server/remote-plugin-imports_test", // the dir path from the root - uuidv4(), // then a random directory to ensure proper isolation + randomUUID(), // then a random directory to ensure proper isolation ); + const pluginManagerOptionsJson = JSON.stringify({ pluginsPath }); + const vaultTestContainer = new VaultTestServer({}); - const configService = new ConfigService(); - const apiServerOptions = await configService.newExampleConfig(); - apiServerOptions.authorizationProtocol = AuthorizationProtocol.NONE; - apiServerOptions.pluginManagerOptionsJson = pluginManagerOptionsJson; - apiServerOptions.configFile = ""; - apiServerOptions.apiCorsDomainCsv = "*"; - apiServerOptions.apiPort = 0; - apiServerOptions.cockpitPort = 0; - apiServerOptions.grpcPort = 0; - apiServerOptions.crpcPort = 0; - apiServerOptions.apiTlsEnabled = false; - apiServerOptions.plugins = [ - { - packageName: "@hyperledger/cactus-plugin-keychain-vault", - type: PluginImportType.Remote, - action: PluginImportAction.Install, - options: { - keychainId: "_keychainId_", - instanceId: "_instanceId_", - remoteConfig: configuration, - }, - }, - ]; - const config = await configService.newExampleConfigConvict(apiServerOptions); + let apiServer: ApiServer; + let pluginContainer: CactusKeychainVaultServer; + + afterAll(async () => { + await apiServer.shutdown(); + }); + + afterAll(async () => { + await vaultTestContainer.stop(); + await vaultTestContainer.destroy(); + }); + + afterAll(async () => { + await pluginContainer.stop(); + await pluginContainer.destroy(); + }); - const apiServer = new ApiServer({ - config: config.getProperties(), + beforeAll(async () => { + await vaultTestContainer.start(); }); - await t.doesNotReject(apiServer.start(), "Started API server OK"); - test.onFinish(() => apiServer.shutdown()); + it("can install plugin-keychain-vault from npm", async () => { + const cId = await Containers.getById(vaultTestContainer.containerId); + const vaultIpAddr = await Containers.getContainerInternalIp(cId); + log.debug(`Container VaultTestServer has IPv4: ${vaultIpAddr}`); + + const hostPortVault = await vaultTestContainer.getHostPortHttp(); + log.debug(`Container VaultTestServer (Port=${hostPortVault}) started OK`); + const vaultHost = `http://${vaultIpAddr}:${K_DEFAULT_VAULT_HTTP_PORT}`; + + pluginContainer = new CactusKeychainVaultServer({ + envVars: [ + `VAULT_HOST=${vaultHost}`, + `VAULT_TOKEN=${K_DEFAULT_VAULT_DEV_ROOT_TOKEN}`, + "HOST=0.0.0.0:8080", + ], + }); + await pluginContainer.start(); + + const hostPort = await pluginContainer.getHostPortHttp(); + log.debug(`CactusKeychainVaultServer (Port=${hostPort}) started OK`); + + const configuration = new Configuration({ + basePath: `http://127.0.0.1:${hostPort}`, + }); + const apiClient = new DefaultApi(configuration); + + const apiSrvOpts = await configService.newExampleConfig(); + apiSrvOpts.authorizationProtocol = AuthorizationProtocol.NONE; + apiSrvOpts.pluginManagerOptionsJson = pluginManagerOptionsJson; + apiSrvOpts.configFile = ""; + apiSrvOpts.apiCorsDomainCsv = "*"; + apiSrvOpts.apiPort = 0; + apiSrvOpts.cockpitPort = 0; + apiSrvOpts.grpcPort = 0; + apiSrvOpts.crpcPort = 0; + apiSrvOpts.apiTlsEnabled = false; + apiSrvOpts.plugins = [ + { + packageName: "@hyperledger/cactus-plugin-keychain-vault", + type: PluginImportType.Remote, + action: PluginImportAction.Install, + options: { + keychainId: "_keychainId_", + instanceId: "_instanceId_", + remoteConfig: configuration, + }, + }, + ]; + const config = await configService.newExampleConfigConvict(apiSrvOpts); + + apiServer = new ApiServer({ + config: config.getProperties(), + }); - const key = uuidv4(); - const expected = uuidv4(); + await expect(apiServer.start()).toResolve(); - await apiClient.setKeychainEntryV1({ key, value: expected }); - const { - data: { value: actual }, - } = await apiClient.getKeychainEntryV1({ key }); + await apiClient.setKeychainEntryV1({ key, value: expected }); - t.equal(actual, expected, "Keychain stored value matches input OK"); + const { + data: { value: actual }, + } = await apiClient.getKeychainEntryV1({ key }); - t.end(); + expect(actual).toEqual(expected); + }); }); diff --git a/packages/cactus-test-tooling/src/main/typescript/cactus-keychain-vault-server/cactus-keychain-vault-server.ts b/packages/cactus-test-tooling/src/main/typescript/cactus-keychain-vault-server/cactus-keychain-vault-server.ts index 5d09644059..80af323f99 100644 --- a/packages/cactus-test-tooling/src/main/typescript/cactus-keychain-vault-server/cactus-keychain-vault-server.ts +++ b/packages/cactus-test-tooling/src/main/typescript/cactus-keychain-vault-server/cactus-keychain-vault-server.ts @@ -79,14 +79,9 @@ export class CactusKeychainVaultServer { [], { Env: this.envVars, - PublishAllPorts: true, - // HostConfig: { - // // This is a workaround needed for macOS which has issues with routing - // // to docker container's IP addresses directly... - // // https://stackoverflow.com/a/39217691 - // PublishAllPorts: true, - // // NetworkMode: "host", - // }, + HostConfig: { + PublishAllPorts: true, + }, }, {}, (err: unknown) => {