import fs from 'fs'; import * as tc from '@actions/tool-cache'; import * as core from '@actions/core'; import path from 'path'; import * as semver from 'semver'; import * as util from '../../src/util'; import {LocalDistribution} from '../../src/distributions/local/installer'; describe('setupJava', () => { const actualJavaVersion = '11.1.10'; const javaPath = path.join('Java_jdkfile_jdk', actualJavaVersion, 'x86'); let mockJavaBase: LocalDistribution; let spyGetToolcachePath: jest.SpyInstance; let spyTcCacheDir: jest.SpyInstance; let spyTcFindAllVersions: jest.SpyInstance; let spyCoreDebug: jest.SpyInstance; let spyCoreInfo: jest.SpyInstance; let spyCoreExportVariable: jest.SpyInstance; let spyCoreAddPath: jest.SpyInstance; let spyCoreSetOutput: jest.SpyInstance; let spyFsStat: jest.SpyInstance; let spyFsReadDir: jest.SpyInstance; let spyUtilsExtractJdkFile: jest.SpyInstance; let spyPathResolve: jest.SpyInstance; const expectedJdkFile = 'JavaLocalJdkFile'; beforeEach(() => { spyGetToolcachePath = jest.spyOn(util, 'getToolcachePath'); spyGetToolcachePath.mockImplementation( (toolname: string, javaVersion: string, architecture: string) => { const semverVersion = new semver.Range(javaVersion); if ( path.basename(javaPath) !== architecture || !javaPath.includes(toolname) ) { return ''; } return semver.satisfies(actualJavaVersion, semverVersion) ? javaPath : ''; } ); spyTcCacheDir = jest.spyOn(tc, 'cacheDir'); spyTcCacheDir.mockImplementation( ( archivePath: string, toolcacheFolderName: string, version: string, architecture: string ) => path.join(toolcacheFolderName, version, architecture) ); spyTcFindAllVersions = jest.spyOn(tc, 'findAllVersions'); spyTcFindAllVersions.mockReturnValue([actualJavaVersion]); // Spy on core methods spyCoreDebug = jest.spyOn(core, 'debug'); spyCoreDebug.mockImplementation(() => undefined); spyCoreInfo = jest.spyOn(core, 'info'); spyCoreInfo.mockImplementation(() => undefined); spyCoreAddPath = jest.spyOn(core, 'addPath'); spyCoreAddPath.mockImplementation(() => undefined); spyCoreExportVariable = jest.spyOn(core, 'exportVariable'); spyCoreExportVariable.mockImplementation(() => undefined); spyCoreSetOutput = jest.spyOn(core, 'setOutput'); spyCoreSetOutput.mockImplementation(() => undefined); // Spy on fs methods spyFsReadDir = jest.spyOn(fs, 'readdirSync'); spyFsReadDir.mockImplementation(() => ['JavaTest']); spyFsStat = jest.spyOn(fs, 'statSync'); spyFsStat.mockImplementation((file: string) => { return {isFile: () => file === expectedJdkFile}; }); // Spy on util methods spyUtilsExtractJdkFile = jest.spyOn(util, 'extractJdkFile'); spyUtilsExtractJdkFile.mockImplementation(() => 'some/random/path/'); // Spy on path methods spyPathResolve = jest.spyOn(path, 'resolve'); spyPathResolve.mockImplementation((path: string) => path); }); afterEach(() => { jest.resetAllMocks(); jest.clearAllMocks(); jest.restoreAllMocks(); }); it('java is resolved from toolcache, jdkfile is untouched', async () => { const inputs = { version: actualJavaVersion, architecture: 'x86', packageType: 'jdk', checkLatest: false }; const jdkFile = 'not_existing_one'; const expected = { version: actualJavaVersion, path: path.join('Java_jdkfile_jdk', inputs.version, inputs.architecture) }; mockJavaBase = new LocalDistribution(inputs, jdkFile); await expect(mockJavaBase.setupJava()).resolves.toEqual(expected); expect(spyGetToolcachePath).toHaveBeenCalled(); expect(spyCoreInfo).toHaveBeenCalledWith( `Resolved Java ${actualJavaVersion} from tool-cache` ); expect(spyCoreInfo).not.toHaveBeenCalledWith( `Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...` ); }); it("java is resolved from toolcache, jdkfile doesn't exist", async () => { const inputs = { version: actualJavaVersion, architecture: 'x86', packageType: 'jdk', checkLatest: false }; const jdkFile = undefined; const expected = { version: actualJavaVersion, path: path.join('Java_jdkfile_jdk', inputs.version, inputs.architecture) }; mockJavaBase = new LocalDistribution(inputs, jdkFile); await expect(mockJavaBase.setupJava()).resolves.toEqual(expected); expect(spyGetToolcachePath).toHaveBeenCalled(); expect(spyCoreInfo).toHaveBeenCalledWith( `Resolved Java ${actualJavaVersion} from tool-cache` ); expect(spyCoreInfo).not.toHaveBeenCalledWith( `Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...` ); }); it('java is unpacked from jdkfile', async () => { const inputs = { version: '11.0.289', architecture: 'x86', packageType: 'jdk', checkLatest: false }; const jdkFile = expectedJdkFile; const expected = { version: '11.0.289', path: path.join('Java_jdkfile_jdk', inputs.version, inputs.architecture) }; mockJavaBase = new LocalDistribution(inputs, jdkFile); await expect(mockJavaBase.setupJava()).resolves.toEqual(expected); expect(spyTcFindAllVersions).toHaveBeenCalled(); expect(spyCoreInfo).not.toHaveBeenCalledWith( `Resolved Java ${actualJavaVersion} from tool-cache` ); expect(spyCoreInfo).toHaveBeenCalledWith( `Extracting Java from '${jdkFile}'` ); expect(spyCoreInfo).toHaveBeenCalledWith( `Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...` ); }); it('jdk file is not found', async () => { const inputs = { version: '11.0.289', architecture: 'x86', packageType: 'jdk', checkLatest: false }; const jdkFile = 'not_existing_one'; const expected = { javaVersion: '11.0.289', javaPath: path.join( 'Java_jdkfile_jdk', inputs.version, inputs.architecture ) }; mockJavaBase = new LocalDistribution(inputs, jdkFile); expected.javaPath = path.join( 'Java_jdkfile_jdk', inputs.version, inputs.architecture ); await expect(mockJavaBase.setupJava()).rejects.toThrow( "JDK file was not found in path 'not_existing_one'" ); expect(spyTcFindAllVersions).toHaveBeenCalled(); expect(spyCoreInfo).not.toHaveBeenCalledWith( `Resolved Java ${actualJavaVersion} from tool-cache` ); expect(spyCoreInfo).not.toHaveBeenCalledWith( `Extracting Java from '${jdkFile}'` ); expect(spyCoreInfo).toHaveBeenCalledWith( `Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...` ); }); it('java is resolved from toolcache including Contents/Home on macOS', async () => { const inputs = { version: actualJavaVersion, architecture: 'x86', packageType: 'jdk', checkLatest: false }; const jdkFile = 'not_existing_one'; const expected = { version: actualJavaVersion, path: path.join( 'Java_jdkfile_jdk', inputs.version, inputs.architecture, 'Contents', 'Home' ) }; const originalPlatform = process.platform; Object.defineProperty(process, 'platform', { value: 'darwin' }); spyFsStat = jest.spyOn(fs, 'existsSync'); spyFsStat.mockImplementation((file: string) => { return file.endsWith('Home'); }); mockJavaBase = new LocalDistribution(inputs, jdkFile); await expect(mockJavaBase.setupJava()).resolves.toEqual(expected); expect(spyGetToolcachePath).toHaveBeenCalled(); expect(spyCoreInfo).toHaveBeenCalledWith( `Resolved Java ${actualJavaVersion} from tool-cache` ); expect(spyCoreInfo).not.toHaveBeenCalledWith( `Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...` ); Object.defineProperty(process, 'platform', { value: originalPlatform }); }); it('java is unpacked from jdkfile including Contents/Home on macOS', async () => { const inputs = { version: '11.0.289', architecture: 'x86', packageType: 'jdk', checkLatest: false }; const jdkFile = expectedJdkFile; const expected = { version: '11.0.289', path: path.join( 'Java_jdkfile_jdk', inputs.version, inputs.architecture, 'Contents', 'Home' ) }; const originalPlatform = process.platform; Object.defineProperty(process, 'platform', { value: 'darwin' }); spyFsStat = jest.spyOn(fs, 'existsSync'); spyFsStat.mockImplementation((file: string) => { return file.endsWith('Home'); }); mockJavaBase = new LocalDistribution(inputs, jdkFile); await expect(mockJavaBase.setupJava()).resolves.toEqual(expected); expect(spyTcFindAllVersions).toHaveBeenCalled(); expect(spyCoreInfo).not.toHaveBeenCalledWith( `Resolved Java ${actualJavaVersion} from tool-cache` ); expect(spyCoreInfo).toHaveBeenCalledWith( `Extracting Java from '${jdkFile}'` ); expect(spyCoreInfo).toHaveBeenCalledWith( `Java ${inputs.version} was not found in tool-cache. Trying to unpack JDK file...` ); Object.defineProperty(process, 'platform', { value: originalPlatform }); }); it.each([ [ { version: '8.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false }, 'otherJdkFile' ], [ { version: '11.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false }, 'otherJdkFile' ], [ { version: '12.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false }, 'otherJdkFile' ], [ { version: '11.1.11', architecture: 'x64', packageType: 'jdk', checkLatest: false }, 'not_existing_one' ] ])( `Throw an error if jdkfile has wrong path, inputs %s, jdkfile %s, real name ${expectedJdkFile}`, async (inputs, jdkFile) => { mockJavaBase = new LocalDistribution(inputs, jdkFile); await expect(mockJavaBase.setupJava()).rejects.toThrow( /JDK file was not found in path */ ); expect(spyTcFindAllVersions).toHaveBeenCalled(); } ); it.each([ [ { version: '8.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false }, '' ], [ { version: '7.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false }, undefined ], [ { version: '11.0.289', architecture: 'x64', packageType: 'jdk', checkLatest: false }, undefined ] ])( 'Throw an error if jdkfile is not specified, inputs %s', async (inputs, jdkFile) => { mockJavaBase = new LocalDistribution(inputs, jdkFile); await expect(mockJavaBase.setupJava()).rejects.toThrow( "'jdkFile' is not specified" ); expect(spyTcFindAllVersions).toHaveBeenCalled(); } ); });