diff --git a/.github/workflows/ci.yaml b/.github/workflows/ci.yaml index ff13c33769..508c54fdda 100644 --- a/.github/workflows/ci.yaml +++ b/.github/workflows/ci.yaml @@ -818,7 +818,7 @@ jobs: FULL_BUILD_DISABLED: true JEST_TEST_PATTERN: packages/cactus-plugin-keychain-aws-sm/src/test/typescript/(unit|integration|benchmark)/.*/*.test.ts JEST_TEST_RUNNER_DISABLED: true - TAPE_TEST_PATTERN: '--files={./packages/cactus-plugin-keychain-aws-sm/src/test/typescript/integration/openapi/openapi-validation.test.ts,./packages/cactus-plugin-keychain-aws-sm/src/test/typescript/integration/plugin-factory-keychain.test.ts,./packages/cactus-plugin-keychain-aws-sm/src/test/typescript/integration/plugin-factory-keychain.test.ts,./packages/cactus-plugin-keychain-aws-sm/src/test/typescript/integration/plugin-keychain-aws-sm.test.ts}' + TAPE_TEST_PATTERN: '--files={./packages/cactus-plugin-keychain-aws-sm/src/test/typescript/integration/plugin-factory-keychain.test.ts,./packages/cactus-plugin-keychain-aws-sm/src/test/typescript/integration/plugin-factory-keychain.test.ts,./packages/cactus-plugin-keychain-aws-sm/src/test/typescript/integration/plugin-keychain-aws-sm.test.ts}' TAPE_TEST_RUNNER_DISABLED: false needs: build-dev runs-on: ubuntu-22.04 @@ -1276,7 +1276,7 @@ jobs: restore-keys: | ${{ runner.os }}-yarn-${{ hashFiles('./yarn.lock') }} - run: npm run configure - - run: yarn ts-node ./packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/deploy-lock-asset.test.ts + - run: yarn jest ./packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/deploy-lock-asset.test.ts plc-fabric-4: continue-on-error: false @@ -1573,7 +1573,7 @@ jobs: restore-keys: | ${{ runner.os }}-yarn-${{ hashFiles('./yarn.lock') }} - run: npm run configure - - run: yarn ts-node ./packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-with-ws-ids.test.ts + - run: yarn jest ./packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-with-ws-ids.test.ts cplc-go-ethereum-socketio: continue-on-error: false diff --git a/.taprc b/.taprc index e4dd236583..024e28e54d 100644 --- a/.taprc +++ b/.taprc @@ -5,9 +5,6 @@ jobs: 1 timeout: 3600 ts: true files: - - ./packages/cactus-plugin-keychain-aws-sm/src/test/typescript/integration/openapi/openapi-validation.test.ts - - ./packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/deploy-lock-asset.test.ts - - ./packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-with-ws-ids.test.ts - ./packages/cactus-plugin-ledger-connector-corda/src/test/typescript/integration/deploy-cordapp-jars-to-nodes-v4.8-express.test.ts - ./packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/v2.3.0-invoke-contract-json-object-endpoints.test.ts - ./packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/v21.4.1-invoke-contract-json-object-endpoints.test.ts diff --git a/jest.config.js b/jest.config.js index 591f13270c..4202250a3e 100644 --- a/jest.config.js +++ b/jest.config.js @@ -16,9 +16,6 @@ module.exports = { ], // Ignore the tests that are still using tap/tape for as their test runner testPathIgnorePatterns: [ - `./packages/cactus-plugin-keychain-aws-sm/src/test/typescript/integration/openapi/openapi-validation.test.ts`, - `./packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/deploy-lock-asset.test.ts`, - `./packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-with-ws-ids.test.ts`, `./packages/cactus-plugin-ledger-connector-corda/src/test/typescript/integration/deploy-cordapp-jars-to-nodes-v4.8-express.test.ts`, `./packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/v2.3.0-invoke-contract-json-object-endpoints.test.ts`, `./packages/cactus-plugin-ledger-connector-quorum/src/test/typescript/integration/plugin-ledger-connector-quorum/deploy-contract/v21.4.1-invoke-contract-json-object-endpoints.test.ts`, diff --git a/packages/cactus-plugin-keychain-aws-sm/src/test/typescript/integration/openapi/openapi-validation.test.ts b/packages/cactus-plugin-keychain-aws-sm/src/test/typescript/integration/openapi/openapi-validation.test.ts index a7ce4c4028..ea9c76cec0 100644 --- a/packages/cactus-plugin-keychain-aws-sm/src/test/typescript/integration/openapi/openapi-validation.test.ts +++ b/packages/cactus-plugin-keychain-aws-sm/src/test/typescript/integration/openapi/openapi-validation.test.ts @@ -1,20 +1,15 @@ -import test, { Test } from "tape-promise/tape"; import { v4 as internalIpV4 } from "internal-ip"; - import { Containers, LocalStackContainer, K_DEFAULT_LOCALSTACK_HTTP_PORT, } from "@hyperledger/cactus-test-tooling"; - import { v4 as uuidv4 } from "uuid"; - import { IListenOptions, LogLevelDesc, Servers, } from "@hyperledger/cactus-common"; - import { IPluginKeychainAwsSmOptions, PluginKeychainAwsSm, @@ -26,14 +21,12 @@ import { HasKeychainEntryRequestV1, DeleteKeychainEntryRequestV1, } from "../../../../main/typescript/public-api"; - import fs from "fs"; import path from "path"; import os from "os"; import express from "express"; import bodyParser from "body-parser"; import http from "http"; - import { installOpenapiValidationMiddleware, PluginRegistry, @@ -41,73 +34,80 @@ import { import OAS from "../../../../main/json/openapi.json"; import { AddressInfo } from "net"; -const logLevel: LogLevelDesc = "TRACE"; +const logLevel: LogLevelDesc = "INFO"; const testCase = "cactus-plugin-keychain-aws-sm API"; -test(testCase, async (t: Test) => { - const localStackContainer = new LocalStackContainer({ - logLevel: logLevel, - }); - await localStackContainer.start(); +describe("PluginKeychainAwsSm", () => { + let localStackContainer: LocalStackContainer; + let tmpDirPath: string; + let plugin: PluginKeychainAwsSm; + let expressApp: express.Express; + let server: http.Server; + let apiClient: KeychainAwsSmApi; - const ci = await Containers.getById(localStackContainer.containerId); - const localstackIpAddr = await internalIpV4(); - const hostPort = await Containers.getPublicPort( - K_DEFAULT_LOCALSTACK_HTTP_PORT, - ci, - ); - const localstackHost = `http://${localstackIpAddr}:${hostPort}`; + beforeAll(async () => { + localStackContainer = new LocalStackContainer({ logLevel: logLevel }); + await localStackContainer.start(); - test.onFinish(async () => { - await localStackContainer.stop(); - await localStackContainer.destroy(); - }); + const ci = await Containers.getById(localStackContainer.containerId); + const localstackIpAddr = await internalIpV4(); + const hostPort = await Containers.getPublicPort( + K_DEFAULT_LOCALSTACK_HTTP_PORT, + ci, + ); + const localstackHost = `http://${localstackIpAddr}:${hostPort}`; + + tmpDirPath = await fs.promises.mkdtemp(path.join(os.tmpdir(), "cactus-")); + await fs.promises.writeFile( + `${tmpDirPath}/credentials`, + "[default]\naws_secret_access_key = test\naws_access_key_id = test", + "utf-8", + ); - let tmpDirPath = "tmpDirPath"; - tmpDirPath = await fs.promises.mkdtemp(path.join(os.tmpdir(), "cactus-")); - await fs.promises.writeFile( - `${tmpDirPath}/credentials`, - "[default]\naws_secret_access_key = test\naws_access_key_id = test", - "utf-8", - ); + const options: IPluginKeychainAwsSmOptions = { + instanceId: uuidv4(), + keychainId: uuidv4(), + pluginRegistry: new PluginRegistry({}), + awsEndpoint: localstackHost, + awsRegion: "us-east-1", + awsProfile: "default", + awsCredentialType: AwsCredentialType.LocalFile, + awsCredentialFilePath: `${tmpDirPath}/credentials`, + logLevel: logLevel, + }; + plugin = new PluginKeychainAwsSm(options); - const options: IPluginKeychainAwsSmOptions = { - instanceId: uuidv4(), - keychainId: uuidv4(), - pluginRegistry: new PluginRegistry({}), - awsEndpoint: localstackHost, - awsRegion: "us-east-1", - awsProfile: "default", - awsCredentialType: AwsCredentialType.LocalFile, - awsCredentialFilePath: `${tmpDirPath}/credentials`, - logLevel: logLevel, - }; - const plugin = new PluginKeychainAwsSm(options); + expressApp = express(); + expressApp.use(bodyParser.json({ limit: "250mb" })); + server = http.createServer(expressApp); + const listenOptions: IListenOptions = { + hostname: "127.0.0.1", + port: 0, + server, + }; + const addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; + const { address, port } = addressInfo; + const apiHost = `http://${address}:${port}`; - const expressApp = express(); - expressApp.use(bodyParser.json({ limit: "250mb" })); - const server = http.createServer(expressApp); - const listenOptions: IListenOptions = { - hostname: "127.0.0.1", - port: 0, - server, - }; - const addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; - test.onFinish(async () => await Servers.shutdown(server)); - const { address, port } = addressInfo; - const apiHost = `http://${address}:${port}`; + const apiConfig = new Configuration({ basePath: apiHost }); + apiClient = new KeychainAwsSmApi(apiConfig); - const apiConfig = new Configuration({ basePath: apiHost }); - const apiClient = new KeychainAwsSmApi(apiConfig); + await installOpenapiValidationMiddleware({ + logLevel, + app: expressApp, + apiSpec: OAS, + }); - await installOpenapiValidationMiddleware({ - logLevel, - app: expressApp, - apiSpec: OAS, + await plugin.getOrCreateWebServices(); + await plugin.registerWebServices(expressApp); }); - await plugin.getOrCreateWebServices(); - await plugin.registerWebServices(expressApp); + afterAll(async () => { + await Servers.shutdown(server); + await localStackContainer.stop(); + await localStackContainer.destroy(); + fs.promises.rm(tmpDirPath, { recursive: true, force: true }); + }); const key = uuidv4(); const value = uuidv4(); @@ -120,115 +120,84 @@ test(testCase, async (t: Test) => { const cWithoutParams = "not sending all required parameters"; const cInvalidParams = "sending invalid parameters"; - test(`${testCase} - ${fSet} - ${cOk}`, async (t2: Test) => { - const res = await apiClient.setKeychainEntryV1({ - key, - value, - }); - t2.equal(res.status, 200, `Endpoint ${fSet}: response.status === 200 OK`); - t2.end(); + test(`${testCase} - ${fSet} - ${cOk}`, async () => { + const res = await apiClient.setKeychainEntryV1({ key, value }); + expect(res.status).toBe(200); }); - test(`${testCase} - ${fGet} - ${cOk}`, async (t2: Test) => { + test(`${testCase} - ${fGet} - ${cOk}`, async () => { const res = await apiClient.getKeychainEntryV1({ key }); - t2.equal(res.status, 200, `Endpoint ${fGet}: response.status === 200 OK`); - t2.equal(res.data.value, value, "response.data.value === value1"); - t2.end(); + expect(res.status).toBe(200); + expect(res.data.value).toBe(value); }); - test(`${testCase} - ${fHas} - ${cOk}`, async (t2: Test) => { + test(`${testCase} - ${fHas} - ${cOk}`, async () => { const res = await apiClient.hasKeychainEntryV1({ key }); - t2.equal(res.status, 200, `Endpoint ${fHas}: response.status === 200 OK`); - t2.end(); + expect(res.status).toBe(200); }); - test(`${testCase} - ${fDelete} - ${cOk}`, async (t2: Test) => { + test(`${testCase} - ${fDelete} - ${cOk}`, async () => { const res = await apiClient.deleteKeychainEntryV1({ key }); - t2.equal( - res.status, - 200, - `Endpoint ${fDelete}: response.status === 200 OK`, - ); - t2.end(); + expect(res.status).toBe(200); }); - test(`${testCase} - ${fSet} - ${cWithoutParams}`, async (t2: Test) => { + test(`${testCase} - ${fSet} - ${cWithoutParams}`, async () => { try { await apiClient.setKeychainEntryV1({ - value: value, + value, } as any as SetKeychainEntryRequestV1); } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fSet} without required key: response.status === 400 OK`, - ); + expect(e.response.status).toBe(400); const fields = e.response.data.map((param: any) => param.path.replace("/body/", ""), ); - t2.ok(fields.includes("key"), "Rejected because key is required"); + expect(fields.includes("key")).toBeTruthy(); } - t2.end(); }); - test(`${testCase} - ${fGet} - ${cWithoutParams}`, async (t2: Test) => { + test(`${testCase} - ${fGet} - ${cWithoutParams}`, async () => { try { await apiClient.getKeychainEntryV1( {} as any as GetKeychainEntryRequestV1, ); } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fGet} without required key: response.status === 400 OK`, - ); + expect(e.response.status).toBe(400); const fields = e.response.data.map((param: any) => param.path.replace("/body/", ""), ); - t2.ok(fields.includes("key"), "Rejected because key is required"); + expect(fields.includes("key")).toBeTruthy(); } - t2.end(); }); - test(`${testCase} - ${fHas} - ${cWithoutParams}`, async (t2: Test) => { + test(`${testCase} - ${fHas} - ${cWithoutParams}`, async () => { try { await apiClient.hasKeychainEntryV1( {} as any as HasKeychainEntryRequestV1, ); } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fHas} without required key: response.status === 400 OK`, - ); + expect(e.response.status).toBe(400); const fields = e.response.data.map((param: any) => param.path.replace("/body/", ""), ); - t2.ok(fields.includes("key"), "Rejected because key is required"); + expect(fields.includes("key")).toBeTruthy(); } - t2.end(); }); - test(`${testCase} - ${fDelete} - ${cWithoutParams}`, async (t2: Test) => { + test(`${testCase} - ${fDelete} - ${cWithoutParams}`, async () => { try { await apiClient.deleteKeychainEntryV1( {} as any as DeleteKeychainEntryRequestV1, ); } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fDelete} without required key: response.status === 400 OK`, - ); + expect(e.response.status).toBe(400); const fields = e.response.data.map((param: any) => param.path.replace("/body/", ""), ); - t2.ok(fields.includes("key"), "Rejected because key is required"); + expect(fields.includes("key")).toBeTruthy(); } - t2.end(); }); - test(`${testCase} - ${fSet} - ${cInvalidParams}`, async (t2: Test) => { + test(`${testCase} - ${fSet} - ${cInvalidParams}`, async () => { try { await apiClient.setKeychainEntryV1({ key, @@ -236,90 +205,56 @@ test(testCase, async (t: Test) => { fake: 4, } as any as SetKeychainEntryRequestV1); } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fSet} with fake=4: response.status === 400 OK`, - ); + expect(e.response.status).toBe(400); const fields = e.response.data.map((param: any) => param.path.replace("/body/", ""), ); - t2.ok( - fields.includes("fake"), - "Rejected because fake is not a valid parameter", - ); + expect(fields.includes("fake")).toBeTruthy(); } - t2.end(); }); - test(`${testCase} - ${fGet} - ${cInvalidParams}`, async (t2: Test) => { + test(`${testCase} - ${fGet} - ${cInvalidParams}`, async () => { try { await apiClient.getKeychainEntryV1({ key, fake: 4, } as any as GetKeychainEntryRequestV1); } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fGet} with fake=4: response.status === 400 OK`, - ); + expect(e.response.status).toBe(400); const fields = e.response.data.map((param: any) => param.path.replace("/body/", ""), ); - t2.ok( - fields.includes("fake"), - "Rejected because fake is not a valid parameter", - ); + expect(fields.includes("fake")).toBeTruthy(); } - t2.end(); }); - test(`${testCase} - ${fHas} - ${cInvalidParams}`, async (t2: Test) => { + test(`${testCase} - ${fHas} - ${cInvalidParams}`, async () => { try { await apiClient.hasKeychainEntryV1({ key, fake: 4, } as any as HasKeychainEntryRequestV1); } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fHas} with fake=4: response.status === 400 OK`, - ); + expect(e.response.status).toBe(400); const fields = e.response.data.map((param: any) => param.path.replace("/body/", ""), ); - t2.ok( - fields.includes("fake"), - "Rejected because fake is not a valid parameter", - ); + expect(fields.includes("fake")).toBeTruthy(); } - t2.end(); }); - test(`${testCase} - ${fDelete} - ${cInvalidParams}`, async (t2: Test) => { + test(`${testCase} - ${fDelete} - ${cInvalidParams}`, async () => { try { await apiClient.deleteKeychainEntryV1({ key, fake: 4, } as any as DeleteKeychainEntryRequestV1); } catch (e) { - t2.equal( - e.response.status, - 400, - `Endpoint ${fDelete} with fake=4: response.status === 400 OK`, - ); + expect(e.response.status).toBe(400); const fields = e.response.data.map((param: any) => param.path.replace("/body/", ""), ); - t2.ok( - fields.includes("fake"), - "Rejected because fake is not a valid parameter", - ); + expect(fields.includes("fake")).toBeTruthy(); } - t2.end(); }); - - t.end(); }); diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/deploy-lock-asset.test.ts b/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/deploy-lock-asset.test.ts index 714296fda8..a927b390a7 100644 --- a/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/deploy-lock-asset.test.ts +++ b/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/deploy-lock-asset.test.ts @@ -3,14 +3,12 @@ import http from "http"; import fs from "fs-extra"; import path from "path"; -import test, { Test } from "tape-promise/tape"; import { v4 as uuidv4 } from "uuid"; import express from "express"; import bodyParser from "body-parser"; import { - Containers, DEFAULT_FABRIC_2_AIO_IMAGE_NAME, FABRIC_25_LTS_AIO_FABRIC_VERSION, FABRIC_25_LTS_AIO_IMAGE_VERSION, @@ -21,7 +19,6 @@ import { } from "@hyperledger/cactus-test-tooling"; import { - Checks, IListenOptions, Logger, LoggerProvider, @@ -52,288 +49,280 @@ const log: Logger = LoggerProvider.getOrCreate({ label: "fabric-lock-asset", level: logLevel, }); -test("BEFORE " + testCase, async (t: Test) => { + +beforeAll(async () => { const pruning = pruneDockerAllIfGithubAction({ logLevel }); - await t.doesNotReject(pruning, "Pruning didn't throw OK"); - t.end(); + await expect(pruning).resolves.not.toThrow(); }); -test(testCase, async (t: Test) => { - const channelId = "mychannel"; - const channelName = channelId; +describe(testCase, () => { + let ledger: FabricTestLedgerV1; + let apiClient: FabricApi; + let keychainId: string; + let keychainEntryKey: string; + let server: http.Server; + + beforeAll(async () => { + ledger = new FabricTestLedgerV1({ + emitContainerLogs: true, + publishAllPorts: true, + imageName: DEFAULT_FABRIC_2_AIO_IMAGE_NAME, + imageVersion: FABRIC_25_LTS_AIO_IMAGE_VERSION, + envVars: new Map([["FABRIC_VERSION", FABRIC_25_LTS_AIO_FABRIC_VERSION]]), + logLevel, + }); - test.onFailure(async () => { - await Containers.logDiagnostics({ logLevel }); - }); + await ledger.start({ omitPull: false }); + + const connectionProfile = await ledger.getConnectionProfileOrg1(); + expect(connectionProfile).toBeTruthy(); + + const enrollAdminOut = await ledger.enrollAdmin(); + const adminWallet = enrollAdminOut[1]; + const [userIdentity] = await ledger.enrollUser(adminWallet); + const sshConfig = await ledger.getSshConfig(); - const ledger = new FabricTestLedgerV1({ - emitContainerLogs: true, - publishAllPorts: true, - imageName: DEFAULT_FABRIC_2_AIO_IMAGE_NAME, - imageVersion: FABRIC_25_LTS_AIO_IMAGE_VERSION, - envVars: new Map([["FABRIC_VERSION", FABRIC_25_LTS_AIO_FABRIC_VERSION]]), - logLevel, + const keychainInstanceId = uuidv4(); + keychainId = uuidv4(); + keychainEntryKey = "user2"; + const keychainEntryValue = JSON.stringify(userIdentity); + + const keychainPlugin = new PluginKeychainMemory({ + instanceId: keychainInstanceId, + keychainId, + logLevel, + backend: new Map([ + [keychainEntryKey, keychainEntryValue], + ["some-other-entry-key", "some-other-entry-value"], + ]), + }); + + const pluginRegistry = new PluginRegistry({ plugins: [keychainPlugin] }); + + const discoveryOptions: DiscoveryOptions = { + enabled: true, + asLocalhost: true, + }; + + const pluginOptions: IPluginLedgerConnectorFabricOptions = { + instanceId: uuidv4(), + dockerBinary: "/usr/local/bin/docker", + peerBinary: "/fabric-samples/bin/peer", + goBinary: "/usr/local/go/bin/go", + pluginRegistry, + cliContainerEnv: FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_1, + sshConfig, + logLevel, + connectionProfile, + discoveryOptions, + eventHandlerOptions: { + strategy: DefaultEventHandlerStrategy.NetworkScopeAllfortx, + commitTimeout: 300, + }, + }; + + const plugin = new PluginLedgerConnectorFabric(pluginOptions); + + const expressApp = express(); + expressApp.use(bodyParser.json({ limit: "250mb" })); + server = http.createServer(expressApp); + const listenOptions: IListenOptions = { + hostname: "127.0.0.1", + port: 0, + server, + }; + const addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; + const { port } = addressInfo; + apiClient = new FabricApi( + new Configuration({ basePath: `http://127.0.0.1:${port}` }), + ); + + await plugin.getOrCreateWebServices(); + await plugin.registerWebServices(expressApp); }); - const tearDown = async () => { + + afterAll(async () => { await ledger.stop(); await ledger.destroy(); await pruneDockerAllIfGithubAction({ logLevel }); - }; - - test.onFinish(tearDown); - await ledger.start({ omitPull: false }); - - const connectionProfile = await ledger.getConnectionProfileOrg1(); - t.ok(connectionProfile, "getConnectionProfileOrg1() out truthy OK"); - - const enrollAdminOut = await ledger.enrollAdmin(); - const adminWallet = enrollAdminOut[1]; - const [userIdentity] = await ledger.enrollUser(adminWallet); - const sshConfig = await ledger.getSshConfig(); - - const keychainInstanceId = uuidv4(); - const keychainId = uuidv4(); - const keychainEntryKey = "user2"; - const keychainEntryValue = JSON.stringify(userIdentity); - - const keychainPlugin = new PluginKeychainMemory({ - instanceId: keychainInstanceId, - keychainId, - logLevel, - backend: new Map([ - [keychainEntryKey, keychainEntryValue], - ["some-other-entry-key", "some-other-entry-value"], - ]), + await Servers.shutdown(server); }); - const pluginRegistry = new PluginRegistry({ plugins: [keychainPlugin] }); - - const discoveryOptions: DiscoveryOptions = { - enabled: true, - asLocalhost: true, - }; - - const pluginOptions: IPluginLedgerConnectorFabricOptions = { - instanceId: uuidv4(), - dockerBinary: "/usr/local/bin/docker", - peerBinary: "/fabric-samples/bin/peer", - goBinary: "/usr/local/go/bin/go", - pluginRegistry, - cliContainerEnv: FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_1, - sshConfig, - logLevel, - connectionProfile, - discoveryOptions, - eventHandlerOptions: { - strategy: DefaultEventHandlerStrategy.NetworkScopeAllfortx, - commitTimeout: 300, - }, - }; - const plugin = new PluginLedgerConnectorFabric(pluginOptions); - - const expressApp = express(); - expressApp.use(bodyParser.json({ limit: "250mb" })); - const server = http.createServer(expressApp); - const listenOptions: IListenOptions = { - hostname: "127.0.0.1", - port: 0, - server, - }; - const addressInfo = (await Servers.listen(listenOptions)) as AddressInfo; - const { port } = addressInfo; - test.onFinish(async () => await Servers.shutdown(server)); - - await plugin.getOrCreateWebServices(); - await plugin.registerWebServices(expressApp); - const apiUrl = `http://127.0.0.1:${port}`; - - const config = new Configuration({ basePath: apiUrl }); - - const apiClient = new FabricApi(config); - - const contractName = "basic-asset-transfer-2"; - - const contractRelPath = "../../fixtures/go/lock-asset/chaincode-typescript"; - const contractDir = path.join(__dirname, contractRelPath); - - // ├── package.json - // ├── src - // │ ├── assetTransfer.ts - // │ ├── asset.ts - // │ └── index.ts - // ├── tsconfig.json - const sourceFiles: FileBase64[] = []; - { - const filename = "./tsconfig.json"; - const relativePath = "./"; - const filePath = path.join(contractDir, relativePath, filename); - const buffer = await fs.readFile(filePath); - sourceFiles.push({ - body: buffer.toString("base64"), - filepath: relativePath, - filename, + test("deploys contract and performs transactions", async () => { + const channelId = "mychannel"; + const channelName = channelId; + const contractName = "basic-asset-transfer-2"; + + const contractRelPath = "../../fixtures/go/lock-asset/chaincode-typescript"; + const contractDir = path.join(__dirname, contractRelPath); + + // ├── package.json + // ├── src + // │ ├── assetTransfer.ts + // │ ├── asset.ts + // │ └── index.ts + // ├── tsconfig.json + const sourceFiles: FileBase64[] = []; + { + const filename = "./tsconfig.json"; + const relativePath = "./"; + const filePath = path.join(contractDir, relativePath, filename); + const buffer = await fs.readFile(filePath); + sourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + { + const filename = "./package.json"; + const relativePath = "./"; + const filePath = path.join(contractDir, relativePath, filename); + const buffer = await fs.readFile(filePath); + sourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + { + const filename = "./index.ts"; + const relativePath = "./src/"; + const filePath = path.join(contractDir, relativePath, filename); + const buffer = await fs.readFile(filePath); + sourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + { + const filename = "./asset.ts"; + const relativePath = "./src/"; + const filePath = path.join(contractDir, relativePath, filename); + const buffer = await fs.readFile(filePath); + sourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + { + const filename = "./assetTransfer.ts"; + const relativePath = "./src/"; + const filePath = path.join(contractDir, relativePath, filename); + const buffer = await fs.readFile(filePath); + sourceFiles.push({ + body: buffer.toString("base64"), + filepath: relativePath, + filename, + }); + } + + const res = await apiClient.deployContractV1({ + channelId, + ccVersion: "1.0.0", + sourceFiles, + ccName: contractName, + targetOrganizations: [ + FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_1, + FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_2, + ], + caFile: + FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_1.ORDERER_TLS_ROOTCERT_FILE, + ccLabel: "basic-asset-transfer-2", + ccLang: ChainCodeProgrammingLanguage.Typescript, + ccSequence: 1, + orderer: "orderer.example.com:7050", + ordererTLSHostnameOverride: "orderer.example.com", + connTimeout: 60, }); - } - { - const filename = "./package.json"; - const relativePath = "./"; - const filePath = path.join(contractDir, relativePath, filename); - const buffer = await fs.readFile(filePath); - sourceFiles.push({ - body: buffer.toString("base64"), - filepath: relativePath, - filename, - }); - } - { - const filename = "./index.ts"; - const relativePath = "./src/"; - const filePath = path.join(contractDir, relativePath, filename); - const buffer = await fs.readFile(filePath); - sourceFiles.push({ - body: buffer.toString("base64"), - filepath: relativePath, - filename, + + expect(res.status).toBe(200); + expect(res.data.success).toBe(true); + + const { + packageIds, + lifecycle: { + approveForMyOrgList, + installList, + queryInstalledList, + commit, + packaging, + queryCommitted, + }, + } = res.data; + + expect(packageIds).toBeTruthy(); + expect(Array.isArray(packageIds)).toBe(true); + expect(approveForMyOrgList).toBeTruthy(); + expect(Array.isArray(approveForMyOrgList)).toBe(true); + expect(installList).toBeTruthy(); + expect(Array.isArray(installList)).toBe(true); + expect(queryInstalledList).toBeTruthy(); + expect(Array.isArray(queryInstalledList)).toBe(true); + expect(commit).toBeTruthy(); + expect(packaging).toBeTruthy(); + expect(queryCommitted).toBeTruthy(); + + const assetId = uuidv4(); + + const createRes = await apiClient.runTransactionV1({ + contractName, + channelName, + params: [assetId, "19"], + methodName: "CreateAsset", + invocationType: FabricContractInvocationType.Send, + signingCredential: { + keychainId, + keychainRef: keychainEntryKey, + }, }); - } - { - const filename = "./asset.ts"; - const relativePath = "./src/"; - const filePath = path.join(contractDir, relativePath, filename); - const buffer = await fs.readFile(filePath); - sourceFiles.push({ - body: buffer.toString("base64"), - filepath: relativePath, - filename, + expect(createRes).toBeTruthy(); + expect(createRes.status).toBeGreaterThan(199); + expect(createRes.status).toBeLessThan(300); + + const getRes = await apiClient.runTransactionV1({ + contractName, + channelName, + params: [assetId], + methodName: "ReadAsset", + invocationType: FabricContractInvocationType.Call, + signingCredential: { + keychainId, + keychainRef: keychainEntryKey, + }, }); - } - { - const filename = "./assetTransfer.ts"; - const relativePath = "./src/"; - const filePath = path.join(contractDir, relativePath, filename); - const buffer = await fs.readFile(filePath); - sourceFiles.push({ - body: buffer.toString("base64"), - filepath: relativePath, - filename, + expect(getRes).toBeTruthy(); + expect(getRes.data).toBeTruthy(); + expect(getRes.data.functionOutput).toBeTruthy(); + expect(getRes.status).toBeGreaterThan(199); + expect(getRes.status).toBeLessThan(300); + + const asset = JSON.parse(getRes.data.functionOutput); + + expect(asset).toBeTruthy(); + expect(asset.ID).toBeTruthy(); + expect(asset.ID).toBe(assetId); + + const lockRes = await apiClient.runTransactionV1({ + contractName, + channelName, + params: [assetId], + methodName: "LockAsset", + invocationType: FabricContractInvocationType.Send, + signingCredential: { + keychainId, + keychainRef: keychainEntryKey, + }, }); - } - - const res = await apiClient.deployContractV1({ - channelId, - ccVersion: "1.0.0", - // constructorArgs: { Args: ["john", "99"] }, - sourceFiles, - ccName: contractName, - targetOrganizations: [ - FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_1, - FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_2, - ], - caFile: - FABRIC_25_LTS_FABRIC_SAMPLES_ENV_INFO_ORG_1.ORDERER_TLS_ROOTCERT_FILE, - ccLabel: "basic-asset-transfer-2", - ccLang: ChainCodeProgrammingLanguage.Typescript, - ccSequence: 1, - orderer: "orderer.example.com:7050", - ordererTLSHostnameOverride: "orderer.example.com", - connTimeout: 60, - }); - - const { packageIds, lifecycle, success } = res.data; - t.equal(res.status, 200, "res.status === 200 OK"); - t.true(success, "res.data.success === true"); - - const { - approveForMyOrgList, - installList, - queryInstalledList, - commit, - packaging, - queryCommitted, - } = lifecycle; - - Checks.truthy(packageIds, `packageIds truthy OK`); - Checks.truthy( - Array.isArray(packageIds), - `Array.isArray(packageIds) truthy OK`, - ); - Checks.truthy(approveForMyOrgList, `approveForMyOrgList truthy OK`); - Checks.truthy( - Array.isArray(approveForMyOrgList), - `Array.isArray(approveForMyOrgList) truthy OK`, - ); - Checks.truthy(installList, `installList truthy OK`); - Checks.truthy( - Array.isArray(installList), - `Array.isArray(installList) truthy OK`, - ); - Checks.truthy(queryInstalledList, `queryInstalledList truthy OK`); - Checks.truthy( - Array.isArray(queryInstalledList), - `Array.isArray(queryInstalledList) truthy OK`, - ); - Checks.truthy(commit, `commit truthy OK`); - Checks.truthy(packaging, `packaging truthy OK`); - Checks.truthy(queryCommitted, `queryCommitted truthy OK`); - - const assetId = uuidv4(); - - // CreateAsset(id string, color string, size int, owner string, appraisedValue int) - const createRes = await apiClient.runTransactionV1({ - contractName, - channelName, - params: [assetId, "19"], - methodName: "CreateAsset", - invocationType: FabricContractInvocationType.Send, - signingCredential: { - keychainId, - keychainRef: keychainEntryKey, - }, - }); - t.ok(createRes, "setRes truthy OK"); - t.true(createRes.status > 199, "createRes status > 199 OK"); - t.true(createRes.status < 300, "createRes status < 300 OK"); - t.comment(`BassicAssetTransfer.Create(): ${JSON.stringify(createRes.data)}`); - - const getRes = await apiClient.runTransactionV1({ - contractName, - channelName, - params: [assetId], - methodName: "ReadAsset", - invocationType: FabricContractInvocationType.Call, - signingCredential: { - keychainId, - keychainRef: keychainEntryKey, - }, - }); - t.ok(getRes, "getRes truthy OK"); - t.ok(getRes.data, "getRes.data truthy OK"); - t.ok(getRes.data.functionOutput, "getRes.data.functionOutput truthy OK"); - t.true(getRes.status > 199 && getRes.status < 300, "getRes status 2xx OK"); - t.comment(`HelloWorld.get() ResponseBody: ${JSON.stringify(getRes.data)}`); - - const asset = JSON.parse(getRes.data.functionOutput); - - t.ok(asset, "JSON.parse(getRes.data.functionOutput) truthy OK"); - - t.ok(asset.ID, "asset.ID truthy OK"); - t.equal(asset.ID, assetId, "asset.ID === assetId truthy OK"); - const lockRes = await apiClient.runTransactionV1({ - contractName, - channelName, - params: [assetId], - methodName: "LockAsset", - invocationType: FabricContractInvocationType.Send, - signingCredential: { - keychainId, - keychainRef: keychainEntryKey, - }, + expect(lockRes).toBeTruthy(); + expect(lockRes.data).toBeTruthy(); + expect(lockRes.data.functionOutput).toBeTruthy(); + expect(lockRes.status).toBeGreaterThan(199); + expect(lockRes.status).toBeLessThan(300); + expect(lockRes.data.functionOutput).toBe("true"); + + log.warn(lockRes.data.functionOutput); }); - t.ok(lockRes, "lockRes truthy OK"); - t.ok(lockRes.data, "lockRes.data truthy OK"); - t.ok(lockRes.data.functionOutput, "lockRes.data.functionOutput truthy OK"); - t.true(lockRes.status > 199 && lockRes.status < 300, "lockRes status 2xx OK"); - t.equal(lockRes.data.functionOutput, "true", "lockRes returns true"); - log.warn(lockRes.data.functionOutput); - t.end(); }); diff --git a/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-with-ws-ids.test.ts b/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-with-ws-ids.test.ts index e2a8d1f1c8..9c633dc3e9 100644 --- a/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-with-ws-ids.test.ts +++ b/packages/cactus-plugin-ledger-connector-fabric/src/test/typescript/integration/fabric-v2-2-x/run-transaction-with-ws-ids.test.ts @@ -1,5 +1,4 @@ import { PluginKeychainMemory } from "@hyperledger/cactus-plugin-keychain-memory"; -import test, { Test } from "tape-promise/tape"; import { IPluginLedgerConnectorFabricOptions } from "../../../../main/typescript/plugin-ledger-connector-fabric"; import { v4 as uuidv4 } from "uuid"; import { LogLevelDesc } from "@hyperledger/cactus-common"; @@ -13,7 +12,6 @@ import { FabricContractInvocationType, } from "../../../../main/typescript/public-api"; import { DiscoveryOptions } from "fabric-network"; - import { Containers, FabricTestLedgerV1, @@ -38,116 +36,122 @@ const logLevel: LogLevelDesc = "INFO"; // - make invoke (InitLedger) using 1st client // - make invoke (TransferAsset) using 2nd client (p384) client // - make query ("ReadAsset") using registrar(p256) -test("run-transaction-with-ws-ids", async (t: Test) => { - test.onFailure(async () => { + +describe("PluginLedgerConnectorFabric", () => { + let ledger: FabricTestLedgerV1; + let wsTestContainer: WsTestServer; + let wsAdmin: WsWallet; + let wsUser: WsWallet; + let wsIdClient: WsIdentityClient; + let keychainId: string; + let keychainPlugin: PluginKeychainMemory; + let plugin: PluginLedgerConnectorFabric; + const registrarKey = "registrar"; + const client2Key = "client-ws"; + + beforeAll(async () => { await Containers.logDiagnostics({ logLevel }); - }); - const ledger = new FabricTestLedgerV1({ - emitContainerLogs: true, - publishAllPorts: true, - imageName: DEFAULT_FABRIC_2_AIO_IMAGE_NAME, - imageVersion: FABRIC_25_LTS_AIO_IMAGE_VERSION, - envVars: new Map([["FABRIC_VERSION", FABRIC_25_LTS_AIO_FABRIC_VERSION]]), - logLevel, - }); + ledger = new FabricTestLedgerV1({ + emitContainerLogs: true, + publishAllPorts: true, + imageName: DEFAULT_FABRIC_2_AIO_IMAGE_NAME, + imageVersion: FABRIC_25_LTS_AIO_IMAGE_VERSION, + envVars: new Map([["FABRIC_VERSION", FABRIC_25_LTS_AIO_FABRIC_VERSION]]), + logLevel, + }); - test.onFinish(async () => { - await ledger.stop(); - await ledger.destroy(); - await pruneDockerAllIfGithubAction({ logLevel }); - }); + await ledger.start({ omitPull: false }); - const wsTestContainer = new WsTestServer({}); - await wsTestContainer.start(); - await ledger.start({ omitPull: false }); + wsTestContainer = new WsTestServer({}); + await wsTestContainer.start(); - const connectionProfile = await ledger.getConnectionProfileOrg1(); - t.ok(connectionProfile, "getConnectionProfileOrg1() out truthy OK"); + const connectionProfile = await ledger.getConnectionProfileOrg1(); + expect(connectionProfile).toBeTruthy(); - const registrarKey = "registrar"; - const client2Key = "client-ws"; - const keychainInstanceId = uuidv4(); - const keychainId = uuidv4(); + const keychainInstanceId = uuidv4(); + keychainId = uuidv4(); - const ci = await Containers.getById(wsTestContainer.containerId); - const wsIpAddr = await internalIpV4(); - const hostPort = await Containers.getPublicPort(WS_IDENTITY_HTTP_PORT, ci); + const ci = await Containers.getById(wsTestContainer.containerId); + const wsIpAddr = await internalIpV4(); + const hostPort = await Containers.getPublicPort(WS_IDENTITY_HTTP_PORT, ci); - const wsUrl = `http://${wsIpAddr}:${hostPort}`; + const wsUrl = `http://${wsIpAddr}:${hostPort}`; - const wsConfig: IWebSocketConfig = { - endpoint: wsUrl, - pathPrefix: "/identity", - }; + const wsConfig: IWebSocketConfig = { + endpoint: wsUrl, + pathPrefix: "/identity", + }; - // external web-socket client - const wsAdmin = new WsWallet({ - keyName: "admin", - logLevel, - strictSSL: false, - }); + wsAdmin = new WsWallet({ + keyName: "admin", + logLevel, + strictSSL: false, + }); - // external web-socket client - const wsUser = new WsWallet({ - keyName: "user", - logLevel, - strictSSL: false, - }); + wsUser = new WsWallet({ + keyName: "user", + logLevel, + strictSSL: false, + }); - test.onFinish(async () => { - await wsTestContainer.stop(); - await wsTestContainer.destroy(); - await wsAdmin.close(); - await wsUser.close(); - }); + keychainPlugin = new PluginKeychainMemory({ + instanceId: keychainInstanceId, + keychainId: keychainId, + logLevel, + }); - /// - const keychainPlugin = new PluginKeychainMemory({ - instanceId: keychainInstanceId, - keychainId: keychainId, - logLevel, - }); + const pluginRegistry = new PluginRegistry({ plugins: [keychainPlugin] }); - const pluginRegistry = new PluginRegistry({ plugins: [keychainPlugin] }); + const discoveryOptions: DiscoveryOptions = { + enabled: true, + asLocalhost: true, + }; - const discoveryOptions: DiscoveryOptions = { - enabled: true, - asLocalhost: true, - }; - const supportedIdentity: FabricSigningCredentialType[] = [ - FabricSigningCredentialType.WsX509, - FabricSigningCredentialType.X509, - ]; + const supportedIdentity: FabricSigningCredentialType[] = [ + FabricSigningCredentialType.WsX509, + FabricSigningCredentialType.X509, + ]; - const pluginOptions: IPluginLedgerConnectorFabricOptions = { - instanceId: uuidv4(), - pluginRegistry, - sshConfig: {}, - cliContainerEnv: {}, - peerBinary: "not-required", - logLevel, - connectionProfile, - discoveryOptions, - eventHandlerOptions: { - strategy: DefaultEventHandlerStrategy.NetworkScopeAllfortx, - commitTimeout: 300, - }, - supportedIdentity, - webSocketConfig: wsConfig, - }; + const pluginOptions: IPluginLedgerConnectorFabricOptions = { + instanceId: uuidv4(), + pluginRegistry, + sshConfig: {}, + cliContainerEnv: {}, + peerBinary: "not-required", + logLevel, + connectionProfile, + discoveryOptions, + eventHandlerOptions: { + strategy: DefaultEventHandlerStrategy.NetworkScopeAllfortx, + commitTimeout: 300, + }, + supportedIdentity, + webSocketConfig: wsConfig, + }; - const plugin = new PluginLedgerConnectorFabric(pluginOptions); + plugin = new PluginLedgerConnectorFabric(pluginOptions); - const wsIdClient = new WsIdentityClient({ - apiVersion: "v1", - endpoint: wsUrl, - rpDefaults: { - strictSSL: false, - }, + wsIdClient = new WsIdentityClient({ + apiVersion: "v1", + endpoint: wsUrl, + rpDefaults: { + strictSSL: false, + }, + }); }); - t.test("with-webSocketKey", async (t: Test) => { + afterAll(async () => { + await ledger.stop(); + await ledger.destroy(); + await pruneDockerAllIfGithubAction({ logLevel }); + await wsTestContainer.stop(); + await wsTestContainer.destroy(); + await wsAdmin.close(); + await wsUser.close(); + }); + + test("run-transaction-with-webSocketKey", async () => { let webSocketKeyAdmin, webSocketKeyUser; { const { sessionId, url } = JSON.parse( @@ -180,10 +184,10 @@ test("run-transaction-with-ws-ids", async (t: Test) => { }, ); const rawCert = await keychainPlugin.get(registrarKey + "-ws"); - t.ok(rawCert); + expect(rawCert).toBeTruthy(); const certData = JSON.parse(rawCert) as IIdentityData; - t.equal(certData.type, FabricSigningCredentialType.WsX509); - t.notok(certData.credentials.privateKey); + expect(certData.type).toBe(FabricSigningCredentialType.WsX509); + expect(certData.credentials.privateKey).toBeFalsy(); } { // register a client using registrar's ws identity @@ -201,7 +205,7 @@ test("run-transaction-with-ws-ids", async (t: Test) => { }, "ca.org1.example.com", ); - t.equal(secret, "pw"); + expect(secret).toBe("pw"); } { const { sessionId, url } = JSON.parse( @@ -233,12 +237,13 @@ test("run-transaction-with-ws-ids", async (t: Test) => { }, ); const rawCert = await keychainPlugin.get(client2Key); - t.ok(rawCert, "rawCert truthy OK"); + expect(rawCert).toBeTruthy(); const { type, credentials } = JSON.parse(rawCert) as IIdentityData; const { privateKey } = credentials; - t.equal(type, FabricSigningCredentialType.WsX509, "Cert is X509 OK"); - t.notok(privateKey, "certData.credentials.privateKey falsy OK"); + expect(type).toBe(FabricSigningCredentialType.WsX509); + expect(privateKey).toBeFalsy(); } + // Temporary workaround here: Deploy a second contract because the default // one is being hammered with "InitLedger" transactions by the container's // own healthcheck (see healthcheck.sh in the fabric-all-in-one folder). @@ -264,9 +269,7 @@ test("run-transaction-with-ws-ids", async (t: Test) => { const timeout = 180000; // 3 minutes const cwd = "/fabric-samples/test-network/"; const out = await Containers.exec(container, cmd, timeout, logLevel, cwd); - t.ok(out, "deploy Basic2 command output truthy OK"); - t.comment("Output of Basic2 contract deployment below:"); - t.comment(out); + expect(out).toBeTruthy(); { // make invoke InitLedger using a client1 client @@ -315,9 +318,7 @@ test("run-transaction-with-ws-ids", async (t: Test) => { params: ["asset1"], }); const asset = JSON.parse(resp.functionOutput); - t.equal(asset.Owner, "client2"); + expect(asset.Owner).toBe("client2"); } - t.end(); }); - t.end(); });