UNPKG

@hashgraph/solo

Version:

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

158 lines 8.8 kB
// SPDX-License-Identifier: Apache-2.0 import { expect } from 'chai'; import { after, before, describe, it } from 'mocha'; import each from 'mocha-each'; import fs from 'node:fs'; import path from 'node:path'; import sinon from 'sinon'; import { HelmDependencyManager } from '../../../../../src/core/dependency-managers/index.js'; import { getTestCacheDirectory, getTemporaryDirectory } from '../../../../test-utility.js'; import * as version from '../../../../../version.js'; import { PathEx } from '../../../../../src/business/utils/path-ex.js'; import { OperatingSystem } from '../../../../../src/business/utils/operating-system.js'; import { InjectTokens } from '../../../../../src/core/dependency-injection/inject-tokens.js'; import { container } from 'tsyringe-neo'; import { platform } from 'node:process'; import * as constants from '../../../../../src/core/constants.js'; describe('HelmDependencyManager', () => { const originalPlatform = platform; const temporaryDirectory = PathEx.join(getTemporaryDirectory(), 'bin'); const installationDirectory = getTemporaryDirectory(); const originalInstallationDirectory = container.resolve(InjectTokens.HelmInstallationDirectory); let sandbox; before(() => { fs.mkdirSync(temporaryDirectory); sandbox = sinon.createSandbox(); container.register(InjectTokens.HelmInstallationDirectory, { useValue: installationDirectory }); }); after(() => { if (fs.existsSync(temporaryDirectory)) { fs.rmSync(temporaryDirectory, { recursive: true }); } if (fs.existsSync(installationDirectory)) { fs.rmSync(installationDirectory, { recursive: true }); } container.register(InjectTokens.HelmInstallationDirectory, { useValue: originalInstallationDirectory }); }); afterEach(() => { container.register(InjectTokens.OsPlatform, { useValue: originalPlatform }); sandbox.restore(); }); it('should return helm version', () => { const helmDependencyManager = new HelmDependencyManager(undefined, undefined, temporaryDirectory, undefined, undefined); expect(helmDependencyManager.getRequiredVersion()).to.equal(version.HELM_VERSION); }); it('should be able to check when helm not installed', () => { const helmDependencyManager = new HelmDependencyManager(undefined, undefined, temporaryDirectory, undefined, undefined); expect(helmDependencyManager.isInstalledLocally()).not.to.be.ok; }); it('should be able to check when helm is installed', async () => { const helmDependencyManager = new HelmDependencyManager(undefined, undefined, temporaryDirectory, undefined, undefined); // Create the local executable file for testing const localPath = PathEx.join(temporaryDirectory, 'helm'); fs.writeFileSync(localPath, ''); expect(helmDependencyManager.isInstalledLocally()).to.be.ok; }); describe('Helm Installation Tests', () => { afterEach(() => { container.register(InjectTokens.OsPlatform, { useValue: originalPlatform }); container.register(InjectTokens.HelmInstallationDirectory, { useValue: originalInstallationDirectory }); sandbox.restore(); if (fs.existsSync(temporaryDirectory)) { fs.rmSync(temporaryDirectory, { recursive: true }); } if (fs.existsSync(installationDirectory)) { fs.rmSync(installationDirectory, { recursive: true }); } }); each([ [OperatingSystem.OS_LINUX, 'x64'], [OperatingSystem.OS_LINUX, 'amd64'], [OperatingSystem.OS_WIN32, 'amd64'], ]).it('should be able to install helm base on %s and %s', async (osPlatform, osArch) => { container.register(InjectTokens.OsPlatform, { useValue: osPlatform }); container.register(InjectTokens.HelmInstallationDirectory, { useValue: installationDirectory }); const helmDependencyManager = new HelmDependencyManager(undefined, undefined, installationDirectory, osArch, undefined); if (fs.existsSync(temporaryDirectory)) { fs.rmSync(temporaryDirectory, { recursive: true }); } if (fs.existsSync(getTestCacheDirectory())) { fs.rmSync(getTestCacheDirectory(), { recursive: true }); } helmDependencyManager.uninstallLocal(); expect(helmDependencyManager.isInstalledLocally()).not.to.be.ok; // Stub accessSync so the native PATH scan finds no global helm installation. sandbox.stub(fs, 'accessSync').throws(Object.assign(new Error('ENOENT'), { code: 'ENOENT' })); expect(await helmDependencyManager.install(getTestCacheDirectory())).to.be.true; expect(helmDependencyManager.isInstalledLocally()).to.be.ok; if (fs.existsSync(temporaryDirectory)) { fs.rmSync(temporaryDirectory, { recursive: true }); } }); }); describe('when helm is installed globally', () => { let helmDependencyManager; let runStub; beforeEach(() => { helmDependencyManager = new HelmDependencyManager(undefined, undefined, temporaryDirectory, process.arch, undefined); helmDependencyManager.uninstallLocal(); runStub = sandbox.stub(helmDependencyManager, 'run'); }); afterEach(() => { sandbox.restore(); }); it('should prefer the global installation if it meets the requirements', async () => { // Point PATH at a fake directory and stub accessSync to make the native PATH // scan discover a fake global helm binary without creating a real file. const fakeGlobalBinDirectory = '/test-solo-global-bin'; const fakeGlobalHelmPath = `${fakeGlobalBinDirectory}/helm`; const originalPath = process.env.PATH ?? ''; process.env.PATH = `${fakeGlobalBinDirectory}${path.delimiter}${originalPath}`; sandbox.stub(fs, 'accessSync').callsFake((filePath) => { if (String(filePath) === fakeGlobalHelmPath) { return; } throw Object.assign(new Error('ENOENT'), { code: 'ENOENT' }); }); runStub.withArgs(`"${fakeGlobalHelmPath}" version --short`).resolves(['v4.1.3+gc94d381']); try { // @ts-expect-error TS2341: Property isInstalledGloballyAndMeetsRequirements is private const result = await helmDependencyManager.isInstalledGloballyAndMeetsRequirements(); expect(result).to.be.true; expect(await helmDependencyManager.install(getTestCacheDirectory())).to.be.true; // Should not install locally since global installation meets requirements expect(fs.existsSync(PathEx.join(temporaryDirectory, 'helm'))).to.be.not.ok; // Should return global path since it meets requirements expect(await helmDependencyManager.getExecutable()).to.equal(constants.HELM); } finally { process.env.PATH = originalPath; } }); it('should install helm locally if the global installation does not meet the requirements', async () => { const fakeGlobalBinDirectory = '/test-solo-global-bin'; const fakeGlobalHelmPath = `${fakeGlobalBinDirectory}/helm`; const originalPath = process.env.PATH ?? ''; process.env.PATH = `${fakeGlobalBinDirectory}${path.delimiter}${originalPath}`; sandbox.stub(fs, 'accessSync').callsFake((filePath) => { if (String(filePath) === fakeGlobalHelmPath) { return; } throw Object.assign(new Error('ENOENT'), { code: 'ENOENT' }); }); runStub.withArgs(`"${fakeGlobalHelmPath}" version --short`).resolves(['v0.1.0+gabcdef']); try { // @ts-expect-error TS2341: Property isInstalledGloballyAndMeetsRequirements is private const result = await helmDependencyManager.isInstalledGloballyAndMeetsRequirements(); expect(result).to.be.false; expect(await helmDependencyManager.install(getTestCacheDirectory())).to.be.true; expect(fs.existsSync(PathEx.join(temporaryDirectory, 'helm'))).to.be.ok; expect(await helmDependencyManager.getExecutable()).to.equal(constants.HELM); } finally { process.env.PATH = originalPath; } }); }); }); //# sourceMappingURL=helm-dependency-manager.test.js.map