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) => {