Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add mirror-url parameter to allow downloading Node.js from a custom URL #1211

Closed
wants to merge 26 commits into from
Closed
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
tests
  • Loading branch information
aparnajyothi-y committed Jan 31, 2025
commit f40797d717f88068c43cba84521c19365ea1a604
84 changes: 83 additions & 1 deletion __tests__/canary-installer.test.ts
Original file line number Diff line number Diff line change
@@ -10,13 +10,14 @@ 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 nodeTestManifest from './data/versions-manifest.json';
import nodeTestDist from './data/node-dist-index.json';
import nodeTestDistNightly from './data/node-nightly-index.json';
import nodeTestDistRc from './data/node-rc-index.json';
import nodeV8CanaryTestDist from './data/v8-canary-dist-index.json';
import canaryBuild from '../src/distributions/v8-canary/canary_builds';

describe('setup-node', () => {
let inputs = {} as any;
@@ -529,3 +530,84 @@ describe('setup-node', () => {
});
});
});
describe('CanaryBuild - Mirror URL functionality', () => {
const nodeInfo: NodeInputs = {
versionSpec: '18.0.0-rc', arch: 'x64', mirrorURL: '',
checkLatest: false,
stable: false
};
it('should return the default distribution URL if no mirror URL is provided', () => {
const canaryBuild = new CanaryBuild(nodeInfo);

// @ts-ignore: Accessing protected method for testing purposes
const distributionMirrorUrl = canaryBuild.getDistributionMirrorUrl();
expect(distributionMirrorUrl).toBe('https://nodejs.org/download/v8-canary');
});

it('should use the mirror URL from nodeInfo if provided', () => {
const mirrorURL = 'https://custom.mirror.url/v8-canary';
nodeInfo.mirrorURL = mirrorURL;
const canaryBuild = new CanaryBuild(nodeInfo);

// @ts-ignore: Accessing protected method for testing purposes
const distributionMirrorUrl = canaryBuild.getDistributionMirrorUrl();
expect(core.info).toHaveBeenCalledWith(`Using mirror URL: ${mirrorURL}`);
expect(distributionMirrorUrl).toBe(mirrorURL);
});

it('should fall back to the default distribution URL if mirror URL is not provided', () => {
nodeInfo.mirrorURL = ''; // No mirror URL
const canaryBuild = new CanaryBuild(nodeInfo);

// @ts-ignore: Accessing protected method for testing purposes
const distributionMirrorUrl = canaryBuild.getDistributionMirrorUrl();
expect(core.info).toHaveBeenCalledWith('Using mirror URL: https://nodejs.org/download/v8-canary');
expect(distributionMirrorUrl).toBe('https://nodejs.org/download/v8-canary');
});

it('should log the correct info when mirror URL is not provided', () => {
nodeInfo.mirrorURL = ''; // No mirror URL
const canaryBuild = new CanaryBuild(nodeInfo);

// @ts-ignore: Accessing protected method for testing purposes
canaryBuild.getDistributionMirrorUrl();
expect(core.info).toHaveBeenCalledWith('Using mirror URL: https://nodejs.org/download/v8-canary');
});

it('should return mirror URL if provided in nodeInfo', () => {
const mirrorURL = 'https://custom.mirror.url/v8-canary';
nodeInfo.mirrorURL = mirrorURL;

const canaryBuild = new CanaryBuild(nodeInfo);
// @ts-ignore: Accessing protected method for testing purposes
const distributionMirrorUrl = canaryBuild.getDistributionMirrorUrl();
expect(core.info).toHaveBeenCalledWith(`Using mirror URL: ${mirrorURL}`);
expect(distributionMirrorUrl).toBe(mirrorURL);
});

it('should use the default URL if mirror URL is empty string', () => {
nodeInfo.mirrorURL = ''; // Empty string for mirror URL
const canaryBuild = new CanaryBuild(nodeInfo);

// @ts-ignore: Accessing protected method for testing purposes
const distributionMirrorUrl = canaryBuild.getDistributionMirrorUrl();
expect(core.info).toHaveBeenCalledWith('Using mirror URL: https://nodejs.org/download/v8-canary');
expect(distributionMirrorUrl).toBe('https://nodejs.org/download/v8-canary');
});

it('should return the default URL if mirror URL is undefined', async () => {
// Create a spy on core.info
const infoSpy = jest.spyOn(core, 'info').mockImplementation(() => {}); // Mocking with empty implementation

// @ts-ignore: Accessing protected method for testing purposes
const distributionMirrorUrl = await canaryBuild.getDistributionMirrorUrl(); // Use await here

// Assert that core.info was called with the expected message
expect(infoSpy).toHaveBeenCalledWith('Using mirror URL: https://nodejs.org/download/v8-canary');
expect(distributionMirrorUrl).toBe('https://nodejs.org/download/v8-canary');

// Optional: Restore the original function after the test
infoSpy.mockRestore();
});

});
88 changes: 40 additions & 48 deletions __tests__/main.test.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import * as core from '@actions/core';
import 'jest';
import * as exec from '@actions/exec';
import * as tc from '@actions/tool-cache';
import * as cache from '@actions/cache';
@@ -13,6 +14,7 @@ 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()
@@ -286,57 +288,36 @@ 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
// Create a mock object that satisfies the BaseDistribution interface
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.)
httpClient: {}, // Mocking the httpClient (you can replace this with more detailed mocks if needed)
osPlat: 'darwin', // Mocking osPlat (the platform the action will run on, e.g., 'darwin', 'win32', 'linux')
nodeInfo: {
version: '14.x',
arch: 'x64',
platform: 'darwin',
},
getDistributionUrl: jest.fn().mockReturnValue('https://nodejs.org/dist/'), // Default distribution URL
getDistributionUrl: jest.fn().mockReturnValue('https://nodejs.org/dist/'), // Example URL
install: jest.fn(),
validate: jest.fn(),
// Mock any other methods/properties defined in BaseDistribution
// Add any other methods/properties required by your BaseDistribution type
});

// 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) => {
jest.spyOn(core, 'getInput').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<typeof installerFactory.getNodejsDistribution>).mockReturnValue(mockNodejsDistribution);
(installerFactory.getNodejsDistribution as jest.Mock).mockReturnValue(mockNodejsDistribution);

await main.run();

@@ -352,7 +333,7 @@ describe('Mirror URL Tests', () => {
});

it('should use default mirror URL when no mirror URL is provided', async () => {
(core.getInput as jest.Mock).mockImplementation((name: string) => {
jest.spyOn(core, 'getInput').mockImplementation((name: string) => {
if (name === 'mirror-url') return '';
if (name === 'node-version') return '14.x';
return '';
@@ -363,47 +344,58 @@ describe('Mirror URL Tests', () => {

await main.run();

// Expect that setupNodeJs is called with an empty mirror URL (which will default inside the function)
// Expect that setupNodeJs is called with an empty mirror URL
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',
}));
const mirrorURL = 'https://custom-mirror-url.com ';
const expectedTrimmedURL = 'https://custom-mirror-url.com';

// Mock the setupNodeJs function
const mockNodejsDistribution = {
setupNodeJs: jest.fn(),
};

// Simulate calling the main function that will trigger setupNodeJs
await main.run({ mirrorURL });

// Debugging: Log the arguments that setupNodeJs was called with
console.log('setupNodeJs calls:', mockNodejsDistribution.setupNodeJs.mock.calls);

// Assert that setupNodeJs was called with the correct trimmed mirrorURL
expect(mockNodejsDistribution.setupNodeJs).toHaveBeenCalledWith(
expect.objectContaining({
mirrorURL: expectedTrimmedURL,
})
);
});



it('should warn if architecture is provided but node-version is missing', async () => {
(core.getInput as jest.Mock).mockImplementation((name: string) => {
jest.spyOn(core, 'getInput').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);
(installerFactory.getNodejsDistribution as jest.Mock).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.'
"`architecture` is provided but `node-version` is missing. In this configuration, the version/architecture of Node will not be changed. To fix this, provide `architecture` in combination with `node-version`"
);

expect(mockNodejsDistribution.setupNodeJs).not.toHaveBeenCalled(); // Setup Node should not be called
});
});

function someFunctionThatCallsSetupNodeJs(arg0: { mirrorURL: string; }) {
throw new Error('Function not implemented.');
}
11 changes: 8 additions & 3 deletions __tests__/nightly-installer.test.ts
Original file line number Diff line number Diff line change
@@ -679,7 +679,8 @@ describe('NightlyNodejs', () => {
mirrorURL: '', versionSpec: '18.0.0-nightly', arch: 'x64',
checkLatest: false,
stable: false
}; const nightlyNode = new TestNightlyNodejs(nodeInfo);
};
const nightlyNode = new TestNightlyNodejs(nodeInfo);

const distributionUrl = nightlyNode.getDistributionUrlPublic();

@@ -688,8 +689,12 @@ describe('NightlyNodejs', () => {
});

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 nodeInfo: NodeInputs = {
mirrorURL: '', versionSpec: '18.0.0-nightly', arch: 'x64',
checkLatest: false,
stable: false
};
const nightlyNode = new TestNightlyNodejs(nodeInfo);

const distributionUrl = nightlyNode.getDistributionUrlPublic();

22 changes: 14 additions & 8 deletions __tests__/official-installer.test.ts
Original file line number Diff line number Diff line change
@@ -11,7 +11,7 @@ import path from 'path';
import * as main from '../src/main';
import * as auth from '../src/authutil';
import OfficialBuilds from '../src/distributions/official_builds/official_builds';
import {INodeVersion} from '../src/distributions/base-models';
import {INodeVersion, NodeInputs} from '../src/distributions/base-models';

import nodeTestManifest from './data/versions-manifest.json';
import nodeTestDist from './data/node-dist-index.json';
@@ -830,8 +830,11 @@ describe('setup-node', () => {
});
});
describe('OfficialBuilds - Mirror URL functionality', () => {
const nodeInfo: NodeInputs = { nodeVersion: '18.0.0-nightly', architecture: 'x64', platform: 'linux', mirrorURL: '' };

const nodeInfo: NodeInputs = {
mirrorURL: '', versionSpec: '18.0.0-nightly', arch: 'x64',
checkLatest: false,
stable: false
};
it('should download using the mirror URL when provided', async () => {
const mirrorURL = 'https://my.custom.mirror/nodejs';
nodeInfo.mirrorURL = mirrorURL;
@@ -918,12 +921,15 @@ describe('OfficialBuilds - Mirror URL functionality', () => {

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
// Mock missing mirror URL
process.env.MIRROR_URL = undefined; // Simulate missing mirror URL

// Mock the version lookup method to avoid triggering version errors
jest.spyOn(OfficialBuilds, 'findVersionInHostedToolCacheDirectory').mockResolvedValue(null); // Simulate "not found"

// Now we expect the function to throw the "Mirror URL is undefined" error
await expect(officialBuilds.setupNodeJs()).rejects.toThrowError('Mirror URL is undefined');
});

});
Loading
Oops, something went wrong.
Loading
Oops, something went wrong.