@hashgraph/solo
Version:
An opinionated CLI tool to deploy and manage private Hedera Networks.
99 lines • 4.95 kB
JavaScript
// SPDX-License-Identifier: Apache-2.0
import { expect } from 'chai';
import { afterEach, describe, it } from 'mocha';
import sinon from 'sinon';
import { Address } from '../../../../src/business/address/address.js';
function buildK8StubWithService(service) {
const servicesStub = {
list: sinon.stub().resolves([service]),
};
return { services: () => servicesStub };
}
describe('Address', () => {
afterEach(() => {
sinon.restore();
});
describe('getExternalAddress', () => {
const mockConsensusNode = {
name: 'node1',
nodeId: 0,
namespace: 'solo',
cluster: 'cluster1',
context: 'context1',
dnsBaseDomain: 'cluster.local',
dnsConsensusNodePattern: 'network-node{nodeId}-svc',
fullyQualifiedDomainName: 'network-node0-svc.solo.svc.cluster.local',
blockNodeMap: [],
externalBlockNodeMap: [],
};
it('should return LoadBalancer IP when available', async () => {
const k8Stub = buildK8StubWithService({
metadata: { name: 'network-node0-svc' },
spec: { type: 'LoadBalancer', clusterIP: '10.0.0.1' },
status: { loadBalancer: { ingress: [{ ip: '1.2.3.4' }] } },
});
const address = await Address.getExternalAddress(mockConsensusNode, k8Stub, 50_111);
expect(address.ipAddressV4).to.equal('1.2.3.4');
expect(address.domainName).to.be.undefined;
});
it('should return LoadBalancer hostname when available', async () => {
const k8Stub = buildK8StubWithService({
metadata: { name: 'network-node0-svc' },
spec: { type: 'LoadBalancer', clusterIP: '10.0.0.1' },
status: { loadBalancer: { ingress: [{ hostname: 'my.lb.example.com' }] } },
});
const address = await Address.getExternalAddress(mockConsensusNode, k8Stub, 50_111);
expect(address.domainName).to.equal('my.lb.example.com');
expect(address.ipAddressV4).to.be.undefined;
});
it('should return cluster IP for NodePort service (no LoadBalancer IP)', async () => {
const k8Stub = buildK8StubWithService({
metadata: { name: 'network-node0-svc' },
spec: { type: 'NodePort', clusterIP: '10.96.0.5' },
status: { loadBalancer: {} },
});
const address = await Address.getExternalAddress(mockConsensusNode, k8Stub, 50_111);
expect(address.ipAddressV4).to.equal('10.96.0.5');
expect(address.domainName).to.be.undefined;
});
it('should return FQDN for NodePort when gossipFqdnRestricted is false', async () => {
const k8Stub = buildK8StubWithService({
metadata: { name: 'network-node0-svc' },
spec: { type: 'NodePort', clusterIP: '10.96.0.5' },
status: { loadBalancer: {} },
});
const address = await Address.getExternalAddress(mockConsensusNode, k8Stub, 50_111, false);
expect(address.domainName).to.equal('network-node0-svc.solo.svc.cluster.local');
expect(address.ipAddressV4).to.be.undefined;
});
it('should return cluster IP when LoadBalancer has no ingress', async () => {
const k8Stub = buildK8StubWithService({
metadata: { name: 'network-node0-svc' },
spec: { type: 'LoadBalancer', clusterIP: '10.96.0.6' },
status: { loadBalancer: { ingress: [] } },
});
const address = await Address.getExternalAddress(mockConsensusNode, k8Stub, 50_111);
expect(address.ipAddressV4).to.equal('10.96.0.6');
expect(address.domainName).to.be.undefined;
});
it('should fall back to FQDN when service list is empty', async () => {
const servicesStub = {
list: sinon.stub().resolves([]),
};
const k8Stub = { services: () => servicesStub };
const address = await Address.getExternalAddress(mockConsensusNode, k8Stub, 50_111);
expect(address.domainName).to.equal('network-node0-svc.solo.svc.cluster.local');
expect(address.ipAddressV4).to.be.undefined;
});
it('should fall back to FQDN when k8 service lookup throws', async () => {
const servicesStub = {
list: sinon.stub().rejects(new Error('k8s API error')),
};
const k8Stub = { services: () => servicesStub };
const address = await Address.getExternalAddress(mockConsensusNode, k8Stub, 50_111);
expect(address.domainName).to.equal('network-node0-svc.solo.svc.cluster.local');
expect(address.ipAddressV4).to.be.undefined;
});
});
});
//# sourceMappingURL=address.test.js.map