diff --git a/__tests__/main.test.ts b/__tests__/main.test.ts index 501741a6..e8d63ef1 100644 --- a/__tests__/main.test.ts +++ b/__tests__/main.test.ts @@ -13,6 +13,10 @@ import each from 'jest-each'; import * as main from '../src/main'; import * as util from '../src/util'; import OfficialBuilds from '../src/distributions/official_builds/official_builds'; +import * as installerFactory from '../src/distributions/installer-factory'; +jest.mock('../src/distributions/installer-factory', () => ({ + getNodejsDistribution: jest.fn() +})); describe('main tests', () => { let inputs = {} as any; @@ -281,3 +285,125 @@ describe('main tests', () => { }); }); }); + + +// Mock the necessary modules +jest.mock('@actions/core'); +jest.mock('./distributions/installer-factory'); + +// Create a mock object that satisfies the BaseDistribution type +const createMockNodejsDistribution = () => ({ + setupNodeJs: jest.fn(), + // Mocking other properties required by the BaseDistribution type (adjust based on your actual types) + httpClient: {}, // Example for httpClient, replace with proper mock if necessary + osPlat: 'darwin', // Example platform ('darwin', 'win32', 'linux', etc.) + nodeInfo: { + version: '14.x', + arch: 'x64', + platform: 'darwin', + }, + getDistributionUrl: jest.fn().mockReturnValue('https://nodejs.org/dist/'), // Default distribution URL + install: jest.fn(), + validate: jest.fn(), + // Mock any other methods/properties defined in BaseDistribution +}); + +// Define the mock structure for BaseDistribution type (adjust to your actual type) +interface BaseDistribution { + setupNodeJs: jest.Mock; + httpClient: object; + osPlat: string; + nodeInfo: { + version: string; + arch: string; + platform: string; + }; + getDistributionUrl: jest.Mock; + install: jest.Mock; + validate: jest.Mock; +} + +describe('Mirror URL Tests', () => { + beforeEach(() => { + jest.clearAllMocks(); + }); + + it('should pass mirror URL correctly when provided', async () => { + (core.getInput as jest.Mock).mockImplementation((name: string) => { + if (name === 'mirror-url') return 'https://custom-mirror-url.com'; + if (name === 'node-version') return '14.x'; + return ''; + }); + + const mockNodejsDistribution = createMockNodejsDistribution(); + (installerFactory.getNodejsDistribution as unknown as jest.Mock).mockReturnValue(mockNodejsDistribution); + + await main.run(); + + // Ensure setupNodeJs is called with the correct parameters, including the mirror URL + expect(mockNodejsDistribution.setupNodeJs).toHaveBeenCalledWith({ + versionSpec: '14.x', + checkLatest: false, + auth: undefined, + stable: true, + arch: 'x64', + mirrorURL: 'https://custom-mirror-url.com', + }); + }); + + it('should use default mirror URL when no mirror URL is provided', async () => { + (core.getInput as jest.Mock).mockImplementation((name: string) => { + if (name === 'mirror-url') return ''; + if (name === 'node-version') return '14.x'; + return ''; + }); + + const mockNodejsDistribution = createMockNodejsDistribution(); + (installerFactory.getNodejsDistribution as jest.Mock).mockReturnValue(mockNodejsDistribution); + + await main.run(); + + // Expect that setupNodeJs is called with an empty mirror URL (which will default inside the function) + expect(mockNodejsDistribution.setupNodeJs).toHaveBeenCalledWith(expect.objectContaining({ + mirrorURL: '', // Default URL is expected to be handled internally + })); + }); + + it('should handle mirror URL with spaces correctly', async () => { + (core.getInput as jest.Mock).mockImplementation((name: string) => { + if (name === 'mirror-url') return ' https://custom-mirror-url.com '; + if (name === 'node-version') return '14.x'; + return ''; + }); + + const mockNodejsDistribution = createMockNodejsDistribution(); + (installerFactory.getNodejsDistribution as jest.Mock).mockReturnValue(mockNodejsDistribution); + + await main.run(); + + // Expect that setupNodeJs is called with the trimmed mirror URL + expect(mockNodejsDistribution.setupNodeJs).toHaveBeenCalledWith(expect.objectContaining({ + mirrorURL: 'https://custom-mirror-url.com', + })); + }); + + it('should warn if architecture is provided but node-version is missing', async () => { + (core.getInput as jest.Mock).mockImplementation((name: string) => { + if (name === 'architecture') return 'x64'; + if (name === 'node-version') return ''; + return ''; + }); + + const mockWarning = jest.spyOn(core, 'warning'); + const mockNodejsDistribution = createMockNodejsDistribution(); + installerFactory.getNodejsDistribution.mockReturnValue(mockNodejsDistribution); + + await main.run(); + + expect(mockWarning).toHaveBeenCalledWith( + '`architecture` is provided but `node-version` is missing. In this configuration, the version/architecture of Node will not be changed.' + ); + expect(mockNodejsDistribution.setupNodeJs).not.toHaveBeenCalled(); // Setup Node should not be called + }); +}); + diff --git a/__tests__/nightly-installer.test.ts b/__tests__/nightly-installer.test.ts index 87c43795..1211ea11 100644 --- a/__tests__/nightly-installer.test.ts +++ b/__tests__/nightly-installer.test.ts @@ -10,8 +10,8 @@ import osm from 'os'; import path from 'path'; import * as main from '../src/main'; import * as auth from '../src/authutil'; -import {INodeVersion} from '../src/distributions/base-models'; - +import {INodeVersion, NodeInputs} from '../src/distributions/base-models'; +import NightlyNodejs from '../src/distributions/nightly/nightly_builds'; import nodeTestManifest from './data/versions-manifest.json'; import nodeTestDist from './data/node-dist-index.json'; import nodeTestDistNightly from './data/node-nightly-index.json'; @@ -606,3 +606,95 @@ describe('setup-node', () => { ); }); }); +// Mock core.info to track the log output +jest.mock('@actions/core', () => ({ + info: jest.fn(), +})); + +// Create a subclass to access the protected method for testing purposes +class TestNightlyNodejs extends NightlyNodejs { + public getDistributionUrlPublic() { + return this.getDistributionUrl(); // This allows us to call the protected method + } +} + +describe('NightlyNodejs', () => { + + it('uses mirror URL when provided', async () => { + const mirrorURL = 'https://my.custom.mirror/nodejs/nightly'; + const nodeInfo: NodeInputs = { + mirrorURL: '', versionSpec: '18.0.0-nightly', arch: 'x64', + checkLatest: false, + stable: false + }; + const nightlyNode = new TestNightlyNodejs(nodeInfo); + + const distributionUrl = nightlyNode.getDistributionUrlPublic(); + + expect(distributionUrl).toBe(mirrorURL); + expect(core.info).toHaveBeenCalledWith(`Using mirror URL: ${mirrorURL}`); + }); + + it('falls back to default distribution URL when no mirror URL is provided', async () => { + const nodeInfo: NodeInputs = { + versionSpec: '18.0.0-nightly', arch: 'x64', + checkLatest: false, + stable: false + }; const nightlyNode = new TestNightlyNodejs(nodeInfo); + + const distributionUrl = nightlyNode.getDistributionUrlPublic(); + + expect(distributionUrl).toBe('https://nodejs.org/download/nightly'); + expect(core.info).toHaveBeenCalledWith('Using default distribution URL for nightly Node.js.'); + }); + + it('logs mirror URL when provided', async () => { + const mirrorURL = 'https://custom.mirror/nodejs/nightly'; + const nodeInfo: NodeInputs = { + mirrorURL: '', versionSpec: '18.0.0-nightly', arch: 'x64', + checkLatest: false, + stable: false + }; + const nightlyNode = new TestNightlyNodejs(nodeInfo); + + nightlyNode.getDistributionUrlPublic(); + + expect(core.info).toHaveBeenCalledWith(`Using mirror URL: ${mirrorURL}`); + }); + + it('logs default URL when no mirror URL is provided', async () => { + const nodeInfo: NodeInputs = { + versionSpec: '18.0.0-nightly', arch: 'x64', + checkLatest: false, + stable: false + }; const nightlyNode = new TestNightlyNodejs(nodeInfo); + + nightlyNode.getDistributionUrlPublic(); + + expect(core.info).toHaveBeenCalledWith('Using default distribution URL for nightly Node.js.'); + }); + + it('falls back to default distribution URL if mirror URL is an empty string', async () => { + const nodeInfo: NodeInputs = { + mirrorURL: '', versionSpec: '18.0.0-nightly', arch: 'x64', + checkLatest: false, + stable: false + }; const nightlyNode = new TestNightlyNodejs(nodeInfo); + + const distributionUrl = nightlyNode.getDistributionUrlPublic(); + + expect(distributionUrl).toBe('https://nodejs.org/download/nightly'); + expect(core.info).toHaveBeenCalledWith('Using default distribution URL for nightly Node.js.'); + }); + + it('falls back to default distribution URL if mirror URL is undefined', async () => { + const nodeInfo: NodeInputs = { nodeVersion: '18.0.0-nightly', architecture: 'x64', platform: 'linux' }; + const nightlyNode = new TestNightlyNodejs(nodeInfo); + + const distributionUrl = nightlyNode.getDistributionUrlPublic(); + + expect(distributionUrl).toBe('https://nodejs.org/download/nightly'); + expect(core.info).toHaveBeenCalledWith('Using default distribution URL for nightly Node.js.'); + }); + +}); \ No newline at end of file diff --git a/__tests__/official-installer.test.ts b/__tests__/official-installer.test.ts index 2d8f17cf..c109f22a 100644 --- a/__tests__/official-installer.test.ts +++ b/__tests__/official-installer.test.ts @@ -829,3 +829,101 @@ describe('setup-node', () => { ); }); }); +describe('OfficialBuilds - Mirror URL functionality', () => { + const nodeInfo: NodeInputs = { nodeVersion: '18.0.0-nightly', architecture: 'x64', platform: 'linux', mirrorURL: '' }; + + it('should download using the mirror URL when provided', async () => { + const mirrorURL = 'https://my.custom.mirror/nodejs'; + nodeInfo.mirrorURL = mirrorURL; + const officialBuilds = new OfficialBuilds(nodeInfo); + + // Mock download from mirror URL + const mockDownloadPath = '/some/temp/path'; + jest.spyOn(tc, 'downloadTool').mockResolvedValue(mockDownloadPath); + + await officialBuilds.setupNodeJs(); + + expect(core.info).toHaveBeenCalledWith('Attempting to download using mirror URL...'); + expect(core.info).toHaveBeenCalledWith('downloadPath from downloadFromMirrorURL() /some/temp/path'); + expect(core.addPath).toHaveBeenCalledWith(mockDownloadPath); + }); + + it('should log a message when mirror URL is used', async () => { + const mirrorURL = 'https://my.custom.mirror/nodejs'; + nodeInfo.mirrorURL = mirrorURL; + const officialBuilds = new OfficialBuilds(nodeInfo); + + const mockDownloadPath = '/some/temp/path'; + jest.spyOn(tc, 'downloadTool').mockResolvedValue(mockDownloadPath); + + await officialBuilds.setupNodeJs(); + + expect(core.info).toHaveBeenCalledWith(`Using mirror URL: ${mirrorURL}`); + }); + + it('should fall back to default URL if mirror URL is not provided', async () => { + nodeInfo.mirrorURL = ''; // No mirror URL provided + const officialBuilds = new OfficialBuilds(nodeInfo); + + const mockDownloadPath = '/some/temp/path'; + jest.spyOn(tc, 'downloadTool').mockResolvedValue(mockDownloadPath); + + await officialBuilds.setupNodeJs(); + + expect(core.info).toHaveBeenCalledWith('Attempting to download from default Node.js URL...'); + expect(core.addPath).toHaveBeenCalledWith(mockDownloadPath); + }); + + it('should log an error and handle failure during mirror URL download', async () => { + const mirrorURL = 'https://my.custom.mirror/nodejs'; + nodeInfo.mirrorURL = mirrorURL; + const officialBuilds = new OfficialBuilds(nodeInfo); + + // Simulate an error during the download process + const errorMessage = 'Network error'; + jest.spyOn(tc, 'downloadTool').mockRejectedValue(new Error(errorMessage)); + + await officialBuilds.setupNodeJs(); + + expect(core.info).toHaveBeenCalledWith('Attempting to download using mirror URL...'); + expect(core.error).toHaveBeenCalledWith(errorMessage); + expect(core.debug).toHaveBeenCalledWith(expect.stringContaining('empty stack')); + }); + + it('should log a fallback message if downloading from the mirror URL fails', async () => { + const mirrorURL = 'https://my.custom.mirror/nodejs'; + nodeInfo.mirrorURL = mirrorURL; + const officialBuilds = new OfficialBuilds(nodeInfo); + + // Simulate download failure and fallback to default URL + const errorMessage = 'Network error'; + jest.spyOn(tc, 'downloadTool').mockRejectedValue(new Error(errorMessage)); + + const mockDownloadPath = '/some/temp/path'; + jest.spyOn(tc, 'downloadTool').mockResolvedValue(mockDownloadPath); + + await officialBuilds.setupNodeJs(); + + expect(core.info).toHaveBeenCalledWith('Failed to download from mirror URL. Falling back to default Node.js URL...'); + expect(core.addPath).toHaveBeenCalledWith(mockDownloadPath); + }); + + it('should throw an error if mirror URL is not provided and downloading from both mirror and default fails', async () => { + nodeInfo.mirrorURL = ''; // No mirror URL + const officialBuilds = new OfficialBuilds(nodeInfo); + + // Simulate failure in both mirror and default download + const errorMessage = 'Network error'; + jest.spyOn(tc, 'downloadTool').mockRejectedValue(new Error(errorMessage)); + + await expect(officialBuilds.setupNodeJs()).rejects.toThrowError(new Error('Unable to find Node version for platform linux and architecture x64.')); + }); + + it('should throw an error if mirror URL is undefined and not provided', async () => { + nodeInfo.mirrorURL = undefined; // Undefined mirror URL + const officialBuilds = new OfficialBuilds(nodeInfo); + + // Simulate a missing mirror URL scenario + await expect(officialBuilds.setupNodeJs()).rejects.toThrowError('Mirror URL is undefined'); + }); +}); \ No newline at end of file diff --git a/dist/setup/index.js b/dist/setup/index.js index 1434ce58..4d32a5b6 100644 --- a/dist/setup/index.js +++ b/dist/setup/index.js @@ -100157,9 +100157,7 @@ class BaseDistribution { getMirrorUrlVersions() { return __awaiter(this, void 0, void 0, function* () { const initialUrl = this.getDistributionMirrorUrl(); - core.info('initialUrl from getDistributionMirrorUrl ' + initialUrl); const dataUrl = `${initialUrl}/index.json`; - core.info('dataUrl from index ' + dataUrl); const response = yield this.httpClient.getJson(dataUrl); return response.result || []; }); @@ -100186,9 +100184,7 @@ class BaseDistribution { } getNodejsMirrorURLInfo(version) { const mirrorURL = this.nodeInfo.mirrorURL; - core.info('mirrorURL from getNodejsMirrorURLInfo ' + mirrorURL); const osArch = this.translateArchToDistUrl(this.nodeInfo.arch); - core.info('osArch from translateArchToDistUrl ' + osArch); version = semver_1.default.clean(version) || ''; const fileName = this.osPlat == 'win32' ? `node-v${version}-win-${osArch}` @@ -100199,7 +100195,6 @@ class BaseDistribution { : `${fileName}.7z` : `${fileName}.tar.gz`; const url = `${mirrorURL}/v${version}/${urlFileName}`; - core.info('url from construct ' + url); return { downloadUrl: url, resolvedVersion: version, @@ -100729,19 +100724,14 @@ class OfficialBuilds extends base_distribution_1.default { downloadFromMirrorURL() { return __awaiter(this, void 0, void 0, function* () { const nodeJsVersions = yield this.getMirrorUrlVersions(); - core.info('nodeJsVersions from getMirrorUrVersions ' + nodeJsVersions); const versions = this.filterVersions(nodeJsVersions); - core.info('versions from filterVersions ' + versions); const evaluatedVersion = this.evaluateVersions(versions); - core.info('evaluatedVersion from evaluatedVersions ' + evaluatedVersion); if (!evaluatedVersion) { throw new Error(`Unable to find Node version '${this.nodeInfo.versionSpec}' for platform ${this.osPlat} and architecture ${this.nodeInfo.arch}.`); } const toolName = this.getNodejsMirrorURLInfo(evaluatedVersion); - core.info('toolName from getNodejsMirrorURLInfo ' + toolName); try { const toolPath = yield this.downloadNodejs(toolName); - core.info('toolPath from downloadNodejs ' + toolPath); return toolPath; } catch (error) { diff --git a/src/distributions/base-distribution.ts b/src/distributions/base-distribution.ts index 7132d627..185cba3c 100644 --- a/src/distributions/base-distribution.ts +++ b/src/distributions/base-distribution.ts @@ -107,10 +107,8 @@ export default abstract class BaseDistribution { protected async getMirrorUrlVersions(): Promise { const initialUrl = this.getDistributionMirrorUrl(); - core.info('initialUrl from getDistributionMirrorUrl '+initialUrl); const dataUrl = `${initialUrl}/index.json`; - core.info('dataUrl from index '+dataUrl); const response = await this.httpClient.getJson(dataUrl); return response.result || []; @@ -142,10 +140,8 @@ export default abstract class BaseDistribution { protected getNodejsMirrorURLInfo(version: string) { const mirrorURL = this.nodeInfo.mirrorURL; - core.info('mirrorURL from getNodejsMirrorURLInfo '+mirrorURL); const osArch: string = this.translateArchToDistUrl(this.nodeInfo.arch); - core.info('osArch from translateArchToDistUrl '+osArch); version = semver.clean(version) || ''; const fileName: string = @@ -160,7 +156,6 @@ export default abstract class BaseDistribution { : `${fileName}.tar.gz`; const url = `${mirrorURL}/v${version}/${urlFileName}`; - core.info('url from construct '+url); return { downloadUrl: url, diff --git a/src/distributions/official_builds/official_builds.ts b/src/distributions/official_builds/official_builds.ts index c6aa23b3..1a26a435 100644 --- a/src/distributions/official_builds/official_builds.ts +++ b/src/distributions/official_builds/official_builds.ts @@ -318,14 +318,11 @@ export default class OfficialBuilds extends BaseDistribution { protected async downloadFromMirrorURL() { const nodeJsVersions = await this.getMirrorUrlVersions(); - core.info('nodeJsVersions from getMirrorUrVersions '+nodeJsVersions); const versions = this.filterVersions(nodeJsVersions); - core.info('versions from filterVersions '+versions); const evaluatedVersion = this.evaluateVersions(versions); - core.info('evaluatedVersion from evaluatedVersions '+evaluatedVersion); if (!evaluatedVersion) { @@ -336,12 +333,10 @@ export default class OfficialBuilds extends BaseDistribution { const toolName = this.getNodejsMirrorURLInfo(evaluatedVersion); - core.info('toolName from getNodejsMirrorURLInfo '+toolName); try { const toolPath = await this.downloadNodejs(toolName); - core.info('toolPath from downloadNodejs '+toolPath); return toolPath; } catch (error) {