@hashgraph/solo
Version:
An opinionated CLI tool to deploy and manage private Hedera Networks.
144 lines • 7.36 kB
JavaScript
// SPDX-License-Identifier: Apache-2.0
import { expect } from 'chai';
import sinon from 'sinon';
import { DefaultKindClient } from '../../../../../src/integration/kind/impl/default-kind-client.js';
import { KindExecutionBuilder } from '../../../../../src/integration/kind/execution/kind-execution-builder.js';
import { ClusterCreateResponse } from '../../../../../src/integration/kind/model/create-cluster/cluster-create-response.js';
import { KindExecution } from '../../../../../src/integration/kind/execution/kind-execution.js';
describe('DefaultKindClient - createCluster', () => {
let client;
let executionBuilderStub;
let executionStub;
beforeEach(() => {
client = new DefaultKindClient('/usr/local/bin/kind');
executionBuilderStub = sinon.createStubInstance(KindExecutionBuilder);
executionStub = sinon.createStubInstance(KindExecution);
// Set up the builder stub
executionBuilderStub.build.returns(executionStub);
sinon.stub(KindExecutionBuilder.prototype, 'build').returns(executionStub);
});
afterEach(() => {
sinon.restore();
});
it('should create a cluster and parse the response correctly', async () => {
// Use a different name pattern to test regex extraction
const clusterName = 'dev-cluster';
const contextName = 'kind-dev-cluster';
// Create output that contains the necessary patterns but with different text
executionStub.responseAs.callsFake((responseClass) => {
const output = `Creating cluster "${clusterName}" ... ✓ Various steps completed ✓ Set kubectl context to "${contextName}"`;
return Promise.resolve(new responseClass(output));
});
const result = await client.createCluster(clusterName);
expect(result).to.be.instanceOf(ClusterCreateResponse);
expect(result.name).to.equal(clusterName);
expect(result.context).to.equal(contextName);
});
it('should throw if responseAs throws', async () => {
executionStub.responseAs.rejects(new Error('fail'));
try {
await client.createCluster('test-cluster');
expect.fail('Expected error');
}
catch (error) {
expect(error.message).to.equal('fail');
}
});
it('should extract cluster name with special characters', async () => {
const clusterName = 'my.cluster-with_special-chars_123';
const contextName = `kind-${clusterName}`;
executionStub.responseAs.callsFake((responseClass) => {
const output = `Creating cluster "${clusterName}" ... [some logs] Set kubectl context to "${contextName}"`;
return Promise.resolve(new responseClass(output));
});
const result = await client.createCluster(clusterName);
expect(result.name).to.equal(clusterName);
expect(result.context).to.equal(contextName);
});
it('should handle missing context information gracefully', async () => {
const clusterName = 'partial-output-cluster';
executionStub.responseAs.callsFake((responseClass) => {
// Output missing the context part
const output = `Creating cluster "${clusterName}" ... ✓ Various steps completed`;
return Promise.resolve(new responseClass(output));
});
const result = await client.createCluster(clusterName);
expect(result.name).to.equal(clusterName);
expect(result.context).to.be.undefined;
});
it('should pass cluster name and options to execution builder', async () => {
const clusterName = 'options-test-cluster';
const options = {
config: './custom-config.yaml',
image: 'custom/node:v1.27.0',
name: clusterName,
retain: true,
wait: '120s',
};
// Create a spy to track subcommands and arguments
const subcommandsSpy = sinon.spy(KindExecutionBuilder.prototype, 'subcommands');
const argumentSpy = sinon.spy(KindExecutionBuilder.prototype, 'argument');
const flagSpy = sinon.spy(KindExecutionBuilder.prototype, 'flag');
await client.createCluster(clusterName, options);
// Verify subcommands were called correctly
expect(subcommandsSpy.calledWith('create', 'cluster')).to.be.true;
// Verify arguments were set correctly
expect(argumentSpy.calledWith('name', clusterName)).to.be.true;
expect(argumentSpy.calledWith('image', options.image)).to.be.true;
expect(argumentSpy.calledWith('config', options.config)).to.be.true;
expect(argumentSpy.calledWith('wait', options.wait)).to.be.true;
// Verify flags were set correctly
expect(flagSpy.calledWith('retain')).to.be.true;
});
it('should handle boolean options correctly', async () => {
const clusterName = 'boolean-options-cluster';
// Test with boolean options turned on and off
const options = {
name: clusterName,
retain: true,
};
// Create a spy to track flag calls
const flagSpy = sinon.spy(KindExecutionBuilder.prototype, 'flag');
const argumentSpy = sinon.spy(KindExecutionBuilder.prototype, 'argument');
await client.createCluster(clusterName, options);
// Should include options that are true
expect(flagSpy.calledWith('retain')).to.be.true;
// Should set name as argument
expect(argumentSpy.calledWith('name', clusterName)).to.be.true;
});
it('should handle string options correctly', async () => {
const clusterName = 'mixed-options-cluster';
const options = {
wait: '60s',
image: 'kindest/node:v1.29.0',
name: clusterName,
};
// Create a spy to track argument calls
const argumentSpy = sinon.spy(KindExecutionBuilder.prototype, 'argument');
await client.createCluster(clusterName, options);
// Options should be passed as arguments
expect(argumentSpy.calledWith('wait', '60s')).to.be.true;
expect(argumentSpy.calledWith('image', 'kindest/node:v1.29.0')).to.be.true;
});
it('should handle no options provided', async () => {
const clusterName = 'default-options-cluster';
const contextName = 'kind-default-options-cluster';
executionStub.responseAs.callsFake((responseClass) => {
const output = `Creating cluster "${clusterName}" ... completed ... Set kubectl context to "${contextName}"`;
return Promise.resolve(new responseClass(output));
});
// Create a spy to track argument calls
const argumentSpy = sinon.spy(KindExecutionBuilder.prototype, 'argument');
// Call without options object
const result = await client.createCluster(clusterName);
// Verify only name parameter was set
expect(argumentSpy.calledWith('name', clusterName)).to.be.true;
// Check number of calls to argument to verify no other arguments were set
// Adding 1 for the name argument
expect(argumentSpy.callCount).to.equal(1);
// Response should be correct
expect(result.name).to.equal(clusterName);
expect(result.context).to.equal(contextName);
});
});
//# sourceMappingURL=create-cluster.test.js.map