Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

test(cmd-api-server): jestify install-basic-plugin-consortium-manual #3562

Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion .github/workflows/ci.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -437,7 +437,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/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-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-ledger-connector-fabric-0-7-0.test.ts}
TAPE_TEST_RUNNER_DISABLED: false
runs-on: ubuntu-22.04
steps:
Expand Down
1 change: 0 additions & 1 deletion .taprc
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@ files:
- ./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/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
- ./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/config/self-signed-certificate-generator/certificates-work-for-mutual-tls.test.ts
- ./packages/cactus-cmd-api-server/src/test/typescript/unit/grpc-proto-gen-ts-client-healthcheck.test.ts
Expand Down
1 change: 0 additions & 1 deletion jest.config.js
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,6 @@ module.exports = {
`./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/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`,
`./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/config/self-signed-certificate-generator/certificates-work-for-mutual-tls.test.ts`,
`./packages/cactus-cmd-api-server/src/test/typescript/unit/grpc-proto-gen-ts-client-healthcheck.test.ts`,
Expand Down
Original file line number Diff line number Diff line change
@@ -1,199 +1,200 @@
import path from "path";
import test, { Test } from "tape-promise/tape";
import { v4 as uuidv4 } from "uuid";
import { randomUUID as uuidv4 } from "node:crypto";
import path from "node:path";

import "jest-extended";
import { generateKeyPair, exportPKCS8 } from "jose";
import { StatusCodes } from "http-status-codes";

import { LogLevelDesc } from "@hyperledger/cactus-common";

import {
PluginImportType,
ConsortiumDatabase,
ICactusPlugin,
Configuration,
IPluginConsortium,
PluginImport,
PluginImportAction,
PluginImportType,
} from "@hyperledger/cactus-core-api";

import {
ApiServer,
AuthorizationProtocol,
ConfigService,
} from "../../../../main/typescript/public-api";

import { ApiServer } from "../../../../main/typescript/api-server";
import { K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS } from "../../../../main/typescript/prometheus-exporter/metrics";
import { DefaultApi as ApiServerApi } from "../../../../main/typescript/generated/openapi/typescript-axios/api";
import { ConfigService } from "../../../../main/typescript/config/config-service";
import { AuthorizationProtocol } from "../../../../main/typescript/config/authorization-protocol";
import { Configuration } from "../../../../main/typescript/generated/openapi/typescript-axios";

import { DefaultApi as ApiServerApi } from "../../../../main/typescript/public-api";

const logLevel: LogLevelDesc = "TRACE";

test("can install plugin-consortium-manual", async (t: Test) => {
describe("ApiServer", () => {
const logLevel: LogLevelDesc = "INFO";
const keychainId = uuidv4();
const consortiumPluginInstanceId = uuidv4();

// Adding a new plugin to update the prometheus metric K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS
const keyPair = await await generateKeyPair("ES256K");
const keyPairPem = await exportPKCS8(keyPair.privateKey);
const db: ConsortiumDatabase = {
cactusNode: [],
consortium: [],
consortiumMember: [],
ledger: [],
pluginInstance: [],
};

const pluginsPath = path.join(
__dirname, // start at the current file's path
"../../../../../../../", // walk back up to the project root
".tmp/test/cmd-api-server/plugin-import-with-npm-install_test", // the dir path from the root
".tmp/test/cmd-api-server/install-basic-plugin-consortium-manual_test", // the dir path from the root
uuidv4(), // then a random directory to ensure proper isolation
);

const pluginManagerOptionsJson = JSON.stringify({ pluginsPath });

let pluginImports: PluginImport[];

const configService = new ConfigService();

const apiServerOptions = await configService.newExampleConfig();
const pluginManagerOptions = { pluginsPath };
const pluginManagerOptionsJson = JSON.stringify(pluginManagerOptions);

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-plugin-keychain-memory",
type: PluginImportType.Local,
action: PluginImportAction.Install,
options: {
instanceId: uuidv4(),
keychainId,
logLevel,
let apiServer: ApiServer;
let apiClient: ApiServerApi;

beforeAll(async () => {
// Adding a new plugin to update the prometheus metric K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS
const keyPair = await await generateKeyPair("ES256K");
const keyPairPem = await exportPKCS8(keyPair.privateKey);
const db: ConsortiumDatabase = {
cactusNode: [],
consortium: [],
consortiumMember: [],
ledger: [],
pluginInstance: [],
};

pluginImports = [
{
packageName: "@hyperledger/cactus-plugin-keychain-memory",
type: PluginImportType.Local,
action: PluginImportAction.Install,
options: {
instanceId: uuidv4(),
keychainId,
logLevel,
},
},
},
{
packageName: "@hyperledger/cactus-plugin-consortium-manual",
type: PluginImportType.Local,
action: PluginImportAction.Install,
options: {
instanceId: consortiumPluginInstanceId,
keyPairPem: keyPairPem,
consortiumDatabase: db,
{
packageName: "@hyperledger/cactus-plugin-consortium-manual",
type: PluginImportType.Local,
action: PluginImportAction.Install,
options: {
instanceId: consortiumPluginInstanceId,
keyPairPem: keyPairPem,
consortiumDatabase: db,
},
},
},
];
const config = await configService.newExampleConfigConvict(apiServerOptions);

const apiServer = new ApiServer({
config: config.getProperties(),
];

const apiSrvOpts = await configService.newExampleConfig();
apiSrvOpts.pluginManagerOptionsJson = pluginManagerOptionsJson;
apiSrvOpts.authorizationProtocol = AuthorizationProtocol.NONE;
apiSrvOpts.logLevel = logLevel;
apiSrvOpts.configFile = "";
apiSrvOpts.apiCorsDomainCsv = "*";
apiSrvOpts.apiPort = 0;
apiSrvOpts.cockpitPort = 0;
apiSrvOpts.grpcPort = 0;
apiSrvOpts.crpcPort = 0;
apiSrvOpts.apiTlsEnabled = false;
apiSrvOpts.plugins = pluginImports;
const config = await configService.newExampleConfigConvict(apiSrvOpts);

apiServer = new ApiServer({
config: config.getProperties(),
});

const startResponse = apiServer.start();
await expect(startResponse).toResolve();

const addressInfoApi = (await startResponse).addressInfoApi;
const protocol = apiSrvOpts.apiTlsEnabled ? "https" : "http";
const { address, port } = addressInfoApi;
const apiHost = `${protocol}://${address}:${port}`;

const apiConfig = new Configuration({ basePath: apiHost });
apiClient = new ApiServerApi(apiConfig);
});

test.onFinish(() => apiServer.shutdown());

const startResponse = apiServer.start();
await t.doesNotReject(startResponse, "started API server OK");
t.ok(startResponse, "startResponse truthy OK");
afterAll(async () => {
await apiServer.shutdown();
});

const addressInfoApi = (await startResponse).addressInfoApi;
const protocol = apiServerOptions.apiTlsEnabled ? "https" : "http";
const { address, port } = addressInfoApi;
const apiHost = `${protocol}://${address}:${port}`;
t.comment(
`Metrics URL: ${apiHost}/api/v1/api-server/get-prometheus-exporter-metrics`,
);
it("can install plugin-consortium-manual", async () => {
{
const res = await apiClient.getPrometheusMetricsV1();
const promMetricsOutput =
"# HELP " +
K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS +
" Total number of plugins imported\n" +
"# TYPE " +
K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS +
" gauge\n" +
K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS +
'{type="' +
K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS +
'"} 2';

expect(res).toMatchObject({
status: StatusCodes.OK,
data: expect.stringContaining(promMetricsOutput),
});
}

const pluginRegistry = await apiServer.getOrInitPluginRegistry();

// this is not a working plugin but we are just testing the monitoring so
// it's okay for this particular test case. Do not copy this to other test
// cases or if you do remove right after you copied it ;-)
pluginRegistry.plugins.push({} as ICactusPlugin);

const apiConfig = new Configuration({ basePath: apiHost });
const apiClient = new ApiServerApi(apiConfig);

{
const res = await apiClient.getPrometheusMetricsV1();
const promMetricsOutput =
"# HELP " +
K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS +
" Total number of plugins imported\n" +
"# TYPE " +
K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS +
" gauge\n" +
K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS +
'{type="' +
K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS +
'"} 2';
t.ok(res);
t.ok(res.data);
t.equal(res.status, 200);
t.true(
res.data.includes(promMetricsOutput),
"Total 2 plugins imported as expected. RESULT OK",
);
}

const pluginRegistry = await apiServer.getOrInitPluginRegistry();

// this is not a working plugin but we are just testing the monitoring so
// it's okay for this particular test case. Do not copy this to other test
// cases or if you do remove right after you copied it ;-)
pluginRegistry.plugins.push({} as ICactusPlugin);

{
const res = await apiClient.getPrometheusMetricsV1();
const promMetricsOutput =
"# HELP " +
K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS +
" Total number of plugins imported\n" +
"# TYPE " +
K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS +
" gauge\n" +
K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS +
'{type="' +
K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS +
'"} 3';
t.ok(res);
t.ok(res.data);
t.equal(res.status, 200);
t.true(
res.data.includes(promMetricsOutput),
"Total 3 plugins imported as expected. RESULT OK",
);
}
// clean up after ourselves,
// e.g. remove the dummy plugin instance we just pushed
pluginRegistry.plugins.pop();

const keychain = pluginRegistry.findOneByKeychainId(keychainId);

const hasX1 = await keychain.has("x");
t.false(hasX1, "hasX1 === false OK");

await keychain.set("x", "y");

const hasX2 = await keychain.has("x");
t.true(hasX2, "hasX2 === true OK");

type DummyConsortiumPlugin = IPluginConsortium<
unknown,
unknown,
unknown,
unknown
>;

// TODO - use the new getOneById implementation once
// https://github.com/hyperledger/cactus/issues/1197
// has been resolved
const consortiumPlugin = pluginRegistry
.getPlugins()
.find(
(it) => it.getInstanceId() === consortiumPluginInstanceId,
) as DummyConsortiumPlugin;

t.ok(consortiumPlugin, "consortiumPlugin located via instance ID truthy OK");

// FIXME - uncomment this once https://github.com/hyperledger/cactus/issues/1199
// has been resolved (and also published to npm)
// const nodeJwsRes = await consortiumPlugin.getNodeJws({});
// t.ok(nodeJwsRes, "nodeJwsRes truthy OK");

t.end();
{
const res = await apiClient.getPrometheusMetricsV1();
const promMetricsOutput =
"# HELP " +
K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS +
" Total number of plugins imported\n" +
"# TYPE " +
K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS +
" gauge\n" +
K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS +
'{type="' +
K_CACTUS_API_SERVER_TOTAL_PLUGIN_IMPORTS +
'"} 3';

expect(res).toMatchObject({
status: StatusCodes.OK,
data: expect.stringContaining(promMetricsOutput),
});
}
// clean up after ourselves,
// e.g. remove the dummy plugin instance we just pushed
pluginRegistry.plugins.pop();

const keychain = pluginRegistry.findOneByKeychainId(keychainId);

const hasX1 = await keychain.has("x");
expect(hasX1).toBeFalse();

await keychain.set("x", "y");

const hasX2 = await keychain.has("x");
expect(hasX2).toBeTrue();

type DummyConsortiumPlugin = IPluginConsortium<
unknown,
unknown,
unknown,
unknown
>;

// TODO - use the new getOneById implementation once
// https://github.com/hyperledger/cactus/issues/1197
// has been resolved
const consortiumPlugin = pluginRegistry
.getPlugins()
.find(
(it) => it.getInstanceId() === consortiumPluginInstanceId,
) as DummyConsortiumPlugin;

expect(consortiumPlugin).toBeTruthy();
expect(consortiumPlugin).toBeObject();

// FIXME - uncomment this once https://github.com/hyperledger/cactus/issues/1199
// has been resolved (and also published to npm)
// const nodeJwsRes = await consortiumPlugin.getNodeJws({});
// t.ok(nodeJwsRes, "nodeJwsRes truthy OK");
});
});
Loading