@hashgraph/solo
Version:
An opinionated CLI tool to deploy and manage private Hedera Networks.
120 lines • 6.64 kB
JavaScript
// SPDX-License-Identifier: Apache-2.0
import sinon from 'sinon';
import { after, afterEach, before, beforeEach, describe, it } from 'mocha';
import { expect } from 'chai';
import { getTestCacheDirectory } from '../../test-utility.js';
import * as constants from '../../../src/core/constants.js';
import { sleep } from '../../../src/core/helpers.js';
import { Duration } from '../../../src/core/time/duration.js';
import * as fs from 'node:fs';
import * as yaml from 'yaml';
import { PathEx } from '../../../src/business/utils/path-ex.js';
import { SoloPinoLogger } from '../../../src/core/logging/solo-pino-logger.js';
import { container } from 'tsyringe-neo';
import { ClusterCommandTasks } from '../../../src/commands/cluster/tasks.js';
import { InjectTokens } from '../../../src/core/dependency-injection/inject-tokens.js';
import { EndToEndTestSuiteBuilder } from '../end-to-end-test-suite-builder.js';
import { ClusterReferenceTest } from './tests/cluster-reference-test.js';
import { main } from '../../../src/index.js';
const testName = 'cluster-test';
const endToEndTestSuite = new EndToEndTestSuiteBuilder()
.withTestName(testName)
.withTestSuiteName('Dual Cluster Full E2E Test Suite')
.withNamespace(testName)
.withDeployment(`${testName}-deployment`)
.withClusterCount(1)
.withConsensusNodesCount(1)
.withLoadBalancerEnabled(true)
.withPinger(true)
.withRealm(2)
.withShard(3)
.withServiceMonitor(true)
.withPodLog(true)
.withTestSuiteCallback((options, preDestroy) => {
describe('Cluster E2E Test', () => {
const { clusterReferenceNameArray, contexts, namespace } = options;
const clusterReferenceName = clusterReferenceNameArray[0];
const contextName = contexts[0];
const clusterCmdTasks = container.resolve(ClusterCommandTasks);
const chartManager = container.resolve(InjectTokens.ChartManager);
const configManager = container.resolve(InjectTokens.ConfigManager);
const k8Factory = container.resolve(InjectTokens.K8Factory);
beforeEach(() => configManager.reset());
// mock showUser and showJSON to silent logging during tests
before(async () => {
sinon.stub(SoloPinoLogger.prototype, 'showUser');
sinon.stub(SoloPinoLogger.prototype, 'showJSON');
await container.resolve(InjectTokens.LocalConfigRuntimeState).load();
});
after(async function () {
// @ts-expect-error: TS2339 - to restore
SoloPinoLogger.prototype.showUser.restore();
// @ts-expect-error: TS2339 - to restore
SoloPinoLogger.prototype.showJSON.restore();
this.timeout(Duration.ofMinutes(3).toMillis());
await preDestroy(endToEndTestSuite);
await k8Factory.default().namespaces().delete(namespace);
ClusterReferenceTest.setup(options);
do {
await sleep(Duration.ofSeconds(5));
} while (!(await chartManager.isChartInstalled(constants.SOLO_SETUP_NAMESPACE, constants.MINIO_OPERATOR_RELEASE_NAME)));
});
// give a few ticks so that connections can close
afterEach(async () => await sleep(Duration.ofMillis(20)));
it('should cleanup existing deployment', async () => {
if (await chartManager.isChartInstalled(constants.SOLO_SETUP_NAMESPACE, constants.MINIO_OPERATOR_RELEASE_NAME)) {
ClusterReferenceTest.reset(options);
}
}).timeout(Duration.ofMinutes(1).toMillis());
it('solo cluster setup should fail with invalid cluster name', async () => {
await expect(main(ClusterReferenceTest.soloClusterReferenceSetup(testName, clusterReferenceName, 'INVALID'))).to.be.rejectedWith("Namespace name 'INVALID' is invalid");
}).timeout(Duration.ofMinutes(1).toMillis());
it('solo cluster setup should work with valid args', async () => {
await main(ClusterReferenceTest.soloClusterReferenceSetup(testName, clusterReferenceName));
}).timeout(Duration.ofMinutes(1).toMillis());
it('cluster-ref config connect should pass with correct data', async () => {
const localConfigPath = PathEx.join(getTestCacheDirectory(), constants.DEFAULT_LOCAL_CONFIG_FILE);
await main(ClusterReferenceTest.soloClusterReferenceConnectArgv(testName, clusterReferenceName, contextName));
const localConfigYaml = fs.readFileSync(localConfigPath).toString();
const localConfigData = yaml.parse(localConfigYaml);
expect(localConfigData.clusterRefs).to.have.own.property(clusterReferenceName);
expect(localConfigData.clusterRefs[clusterReferenceName]).to.equal(contextName);
});
it('solo cluster info should work', () => {
ClusterReferenceTest.info(options);
}).timeout(Duration.ofMinutes(1).toMillis());
it('solo cluster list', async () => {
ClusterReferenceTest.list(options);
}).timeout(Duration.ofMinutes(1).toMillis());
it('function showInstalledChartList should return right true', async () => {
// @ts-expect-error to access private property
await expect(clusterCmdTasks.showInstalledChartList()).to.eventually.be.undefined;
}).timeout(Duration.ofMinutes(1).toMillis());
// helm list would return an empty list if given invalid namespace
it('solo cluster reset should fail with invalid cluster name', async () => {
try {
await main(ClusterReferenceTest.soloClusterReferenceReset(testName, 'INVALID'));
expect.fail();
}
catch (error) {
expect(error.message).to.include('Error on cluster reset');
}
}).timeout(Duration.ofMinutes(1).toMillis());
it('solo cluster reset should work with valid args', async () => {
ClusterReferenceTest.reset(options);
}).timeout(Duration.ofMinutes(1).toMillis());
it('cluster-ref config connect should fail with invalid context name', async () => {
const invalidContextName = 'INVALID_CONTEXT';
try {
await main(ClusterReferenceTest.soloClusterReferenceConnectArgv(testName, clusterReferenceName, invalidContextName));
expect.fail();
}
catch (error) {
expect(error.message).to.include(`Context ${invalidContextName} is not valid for cluster`);
}
});
});
})
.build();
endToEndTestSuite.runTestSuite();
//# sourceMappingURL=cluster.test.js.map