UNPKG

@hashgraph/solo

Version:

An opinionated CLI tool to deploy and manage private Hedera Networks.

95 lines 6.59 kB
// SPDX-License-Identifier: Apache-2.0 import { BaseCommandTest } from './base-command-test.js'; import { main } from '../../../../src/index.js'; import { InjectTokens } from '../../../../src/core/dependency-injection/inject-tokens.js'; import { Duration } from '../../../../src/core/time/duration.js'; import { container } from 'tsyringe-neo'; import { expect } from 'chai'; import { Flags as flags, Flags } from '../../../../src/commands/flags.js'; import { ConsensusCommandDefinition } from '../../../../src/commands/command-definitions/consensus-command-definition.js'; import { it } from 'mocha'; import { sleep } from '../../../../src/core/helpers.js'; import * as constants from '../../../../src/core/constants.js'; export class NetworkTest extends BaseCommandTest { static soloNetworkDeployArgv(testName, deployment, enableLocalBuildPathTesting, localBuildReleaseTag, loadBalancerEnabled, releaseTagOverride) { const { newArgv, argvPushGlobalFlags, optionFromFlag } = NetworkTest; const argv = newArgv(); argv.push(ConsensusCommandDefinition.COMMAND_NAME, ConsensusCommandDefinition.NETWORK_SUBCOMMAND_NAME, ConsensusCommandDefinition.NETWORK_DEPLOY, optionFromFlag(Flags.deployment), deployment, optionFromFlag(flags.persistentVolumeClaims), optionFromFlag(Flags.serviceMonitor), optionFromFlag(Flags.podLog)); // have to enable load balancer to resolve cross cluster in multi-cluster if (loadBalancerEnabled) { argv.push(optionFromFlag(Flags.loadBalancerEnabled)); } if (releaseTagOverride) { argv.push(optionFromFlag(Flags.releaseTag), releaseTagOverride); } else if (enableLocalBuildPathTesting) { argv.push(optionFromFlag(Flags.releaseTag), localBuildReleaseTag); } argvPushGlobalFlags(argv, testName, true, true); return argv; } static deploy(options, releaseTagOverride) { const { testName, deployment, namespace, contexts, enableLocalBuildPathTesting, localBuildReleaseTag, loadBalancerEnabled, clusterReferenceNameArray, consensusNodesCount, } = options; const { soloNetworkDeployArgv } = NetworkTest; it(`${testName}: consensus network deploy`, async () => { await main(soloNetworkDeployArgv(testName, deployment, enableLocalBuildPathTesting, localBuildReleaseTag, loadBalancerEnabled, releaseTagOverride)); const k8Factory = container.resolve(InjectTokens.K8Factory); const clusterCount = clusterReferenceNameArray.length; const base = Math.floor(consensusNodesCount / clusterCount); const remainder = consensusNodesCount % clusterCount; const nodeCountsPerCluster = clusterReferenceNameArray.map((_, index) => index < remainder ? base + 1 : base); for (const [index, context_] of contexts.entries()) { const nodeCount = nodeCountsPerCluster[index]; const namespaceExists = await k8Factory.getK8(context_).namespaces().has(namespace); expect(namespaceExists, `namespace ${namespace} should exist in ${context_}`).to.be.true; const pods = await k8Factory .getK8(context_) .pods() .list(namespace, ['solo.hedera.com/type=network-node']); expect(pods.length, `expected exactly ${nodeCount} network-node pod in namespace ${namespace} for context ${context_}`).to.equal(nodeCount); } }).timeout(Duration.ofMinutes(5).toMillis()); } static soloConsensusNetworkDestroyArgv(testName, deployment) { const { newArgv, argvPushGlobalFlags, optionFromFlag } = NetworkTest; const argv = newArgv(); argv.push(ConsensusCommandDefinition.COMMAND_NAME, ConsensusCommandDefinition.NETWORK_SUBCOMMAND_NAME, ConsensusCommandDefinition.NETWORK_DESTROY, optionFromFlag(Flags.deployment), deployment, optionFromFlag(Flags.deletePvcs), optionFromFlag(Flags.deleteSecrets), optionFromFlag(Flags.force), optionFromFlag(Flags.quiet)); argvPushGlobalFlags(argv, testName, false, true); return argv; } static destroy(options) { const { testName, deployment } = options; const { soloConsensusNetworkDestroyArgv } = NetworkTest; it(`${testName}: consensus network destroy`, async () => { await main(soloConsensusNetworkDestroyArgv(testName, deployment)); }).timeout(Duration.ofMinutes(10).toMillis()); it(`${testName}: consensus network destroy should success`, async () => { const { namespace, contexts: contextRecord, testLogger: logger } = options; const k8Factory = container.resolve(InjectTokens.K8Factory); const chartManager = container.resolve(InjectTokens.ChartManager); const contexts = [...contextRecord.values()]; // get all contexts async function getPodsCountInMultipleNamespaces(label) { return await Promise.all(contexts.map((context) => k8Factory.getK8(context).pods().list(namespace, label))).then((results) => results.flat().length); } async function waitUntilPodsGone(label) { logger.showUser(`Waiting for pod ${label} to be gone`); while (true) { const podsCount = await getPodsCountInMultipleNamespaces(label); if (podsCount === 0) { break; } await sleep(Duration.ofSeconds(3)); } } await waitUntilPodsGone(['solo.hedera.com/type=network-node']); await waitUntilPodsGone(['app=minio']); const isChartInstalled = await chartManager.isChartInstalled(namespace, constants.SOLO_DEPLOYMENT_CHART); expect(isChartInstalled).to.be.false; await expect(k8Factory.getK8(contexts[0]).pvcs().list(namespace, []), 'PVCs should be deleted in cluster[0]').eventually.to.have.lengthOf(0); await expect(k8Factory.getK8(contexts[1]).pvcs().list(namespace, []), 'PVCs should be deleted in cluster[1]').eventually.to.have.lengthOf(0); await expect(k8Factory.getK8(contexts[0]).secrets().list(namespace), 'Secrets should be deleted in cluster[0]').eventually.to.have.lengthOf(0); await expect(k8Factory.getK8(contexts[1]).secrets().list(namespace), 'Secrets should be deleted in cluster[1]').eventually.to.have.lengthOf(0); }).timeout(Duration.ofMinutes(4).toMillis()); } } //# sourceMappingURL=network-test.js.map