| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  | import * as core from '@actions/core'; | 
					
						
							|  |  |  | import * as cache from '@actions/cache'; | 
					
						
							|  |  |  | import * as exec from '@actions/exec'; | 
					
						
							| 
									
										
										
										
											2022-07-25 15:02:06 +02:00
										 |  |  | import * as io from '@actions/io'; | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  | import {getCacheDistributor} from '../src/cache-distributions/cache-factory'; | 
					
						
							| 
									
										
										
										
											2022-07-19 14:20:19 +02:00
										 |  |  | import * as utils from './../src/utils'; | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  | describe('restore-cache', () => { | 
					
						
							|  |  |  |   const pipFileLockHash = | 
					
						
							| 
									
										
										
										
											2022-06-29 19:09:14 +02:00
										 |  |  |     'a3bdcc71289e4979ca9e051810d81999cc99823109faf6912e17ff14c8e621a6'; | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  |   const requirementsHash = | 
					
						
							|  |  |  |     'd8110e0006d7fb5ee76365d565eef9d37df1d11598b912d3eb66d398d57a1121'; | 
					
						
							|  |  |  |   const requirementsLinuxHash = | 
					
						
							|  |  |  |     '2d0ff7f46b0e120e3d3294db65768b474934242637b9899b873e6283dfd16d7c'; | 
					
						
							| 
									
										
										
										
											2022-03-06 20:30:49 -06:00
										 |  |  |   const poetryLockHash = | 
					
						
							|  |  |  |     '571bf984f8d210e6a97f854e479fdd4a2b5af67b5fdac109ec337a0ea16e7836'; | 
					
						
							| 
									
										
										
										
											2021-11-24 18:40:05 +00:00
										 |  |  |   const poetryConfigOutput = `
 | 
					
						
							|  |  |  | cache-dir = "/Users/patrick/Library/Caches/pypoetry" | 
					
						
							|  |  |  | experimental.new-installer = false | 
					
						
							|  |  |  | installer.parallel = true | 
					
						
							|  |  |  | virtualenvs.create = true | 
					
						
							|  |  |  | virtualenvs.in-project = true | 
					
						
							|  |  |  | virtualenvs.path = "{cache-dir}/virtualenvs"  # /Users/patrick/Library/Caches/pypoetry/virtualenvs | 
					
						
							|  |  |  |   `;
 | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // core spy
 | 
					
						
							|  |  |  |   let infoSpy: jest.SpyInstance; | 
					
						
							|  |  |  |   let warningSpy: jest.SpyInstance; | 
					
						
							|  |  |  |   let debugSpy: jest.SpyInstance; | 
					
						
							|  |  |  |   let saveSatetSpy: jest.SpyInstance; | 
					
						
							|  |  |  |   let getStateSpy: jest.SpyInstance; | 
					
						
							| 
									
										
										
										
											2022-04-05 06:57:13 -07:00
										 |  |  |   let setOutputSpy: jest.SpyInstance; | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |   // cache spy
 | 
					
						
							|  |  |  |   let restoreCacheSpy: jest.SpyInstance; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   // exec spy
 | 
					
						
							|  |  |  |   let getExecOutputSpy: jest.SpyInstance; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-25 15:02:06 +02:00
										 |  |  |   // io spy
 | 
					
						
							|  |  |  |   let whichSpy: jest.SpyInstance; | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  |   beforeEach(() => { | 
					
						
							|  |  |  |     process.env['RUNNER_OS'] = process.env['RUNNER_OS'] ?? 'linux'; | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     infoSpy = jest.spyOn(core, 'info'); | 
					
						
							|  |  |  |     infoSpy.mockImplementation(input => undefined); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     warningSpy = jest.spyOn(core, 'warning'); | 
					
						
							|  |  |  |     warningSpy.mockImplementation(input => undefined); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     debugSpy = jest.spyOn(core, 'debug'); | 
					
						
							|  |  |  |     debugSpy.mockImplementation(input => undefined); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     saveSatetSpy = jest.spyOn(core, 'saveState'); | 
					
						
							|  |  |  |     saveSatetSpy.mockImplementation(input => undefined); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getStateSpy = jest.spyOn(core, 'getState'); | 
					
						
							|  |  |  |     getStateSpy.mockImplementation(input => undefined); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     getExecOutputSpy = jest.spyOn(exec, 'getExecOutput'); | 
					
						
							|  |  |  |     getExecOutputSpy.mockImplementation((input: string) => { | 
					
						
							|  |  |  |       if (input.includes('pip')) { | 
					
						
							|  |  |  |         return {stdout: 'pip', stderr: '', exitCode: 0}; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-11-24 18:40:05 +00:00
										 |  |  |       if (input.includes('poetry')) { | 
					
						
							|  |  |  |         return {stdout: poetryConfigOutput, stderr: '', exitCode: 0}; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2022-12-07 18:12:42 +01:00
										 |  |  |       if (input.includes('lsb_release')) { | 
					
						
							|  |  |  |         return {stdout: 'Ubuntu\n20.04', stderr: '', exitCode: 0}; | 
					
						
							|  |  |  |       } | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  | 
 | 
					
						
							|  |  |  |       return {stdout: '', stderr: 'Error occured', exitCode: 2}; | 
					
						
							|  |  |  |     }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 06:57:13 -07:00
										 |  |  |     setOutputSpy = jest.spyOn(core, 'setOutput'); | 
					
						
							|  |  |  |     setOutputSpy.mockImplementation(input => undefined); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  |     restoreCacheSpy = jest.spyOn(cache, 'restoreCache'); | 
					
						
							|  |  |  |     restoreCacheSpy.mockImplementation( | 
					
						
							|  |  |  |       (cachePaths: string[], primaryKey: string, restoreKey?: string) => { | 
					
						
							|  |  |  |         return primaryKey; | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     ); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:20:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-25 15:02:06 +02:00
										 |  |  |     whichSpy = jest.spyOn(io, 'which'); | 
					
						
							|  |  |  |     whichSpy.mockImplementation(() => '/path/to/python'); | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('Validate provided package manager', () => { | 
					
						
							|  |  |  |     it.each(['npm', 'pip2', 'pip21', 'pip21.3', 'pipenv32'])( | 
					
						
							|  |  |  |       'Throw an error because %s is not supported', | 
					
						
							|  |  |  |       async packageManager => { | 
					
						
							|  |  |  |         expect(() => | 
					
						
							|  |  |  |           getCacheDistributor(packageManager, '3.8.12', undefined) | 
					
						
							|  |  |  |         ).toThrowError(`Caching for '${packageManager}' is not supported`); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('Restore dependencies', () => { | 
					
						
							|  |  |  |     it.each([ | 
					
						
							|  |  |  |       ['pip', '3.8.12', undefined, requirementsHash], | 
					
						
							|  |  |  |       ['pip', '3.8.12', '**/requirements-linux.txt', requirementsLinuxHash], | 
					
						
							|  |  |  |       [ | 
					
						
							|  |  |  |         'pip', | 
					
						
							|  |  |  |         '3.8.12', | 
					
						
							|  |  |  |         '__tests__/data/requirements-linux.txt', | 
					
						
							|  |  |  |         requirementsLinuxHash | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |       ['pip', '3.8.12', '__tests__/data/requirements.txt', requirementsHash], | 
					
						
							|  |  |  |       ['pipenv', '3.9.1', undefined, pipFileLockHash], | 
					
						
							| 
									
										
										
										
											2021-11-24 18:40:05 +00:00
										 |  |  |       ['pipenv', '3.9.12', '__tests__/data/requirements.txt', requirementsHash], | 
					
						
							|  |  |  |       ['poetry', '3.9.1', undefined, poetryLockHash] | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  |     ])( | 
					
						
							|  |  |  |       'restored dependencies for %s by primaryKey', | 
					
						
							|  |  |  |       async (packageManager, pythonVersion, dependencyFile, fileHash) => { | 
					
						
							| 
									
										
										
										
											2022-04-05 06:57:13 -07:00
										 |  |  |         const cacheDistributor = getCacheDistributor( | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  |           packageManager, | 
					
						
							|  |  |  |           pythonVersion, | 
					
						
							|  |  |  |           dependencyFile | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2022-07-19 14:20:19 +02:00
										 |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  |         await cacheDistributor.restoreCache(); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-07-19 14:20:19 +02:00
										 |  |  |         if (process.platform === 'linux' && packageManager === 'pip') { | 
					
						
							|  |  |  |           expect(infoSpy).toHaveBeenCalledWith( | 
					
						
							| 
									
										
										
										
											2022-12-07 18:12:42 +01:00
										 |  |  |             `Cache restored from key: setup-python-${process.env['RUNNER_OS']}-20.04-Ubuntu-python-${pythonVersion}-${packageManager}-${fileHash}` | 
					
						
							| 
									
										
										
										
											2022-07-19 14:20:19 +02:00
										 |  |  |           ); | 
					
						
							|  |  |  |         } else { | 
					
						
							|  |  |  |           expect(infoSpy).toHaveBeenCalledWith( | 
					
						
							|  |  |  |             `Cache restored from key: setup-python-${process.env['RUNNER_OS']}-python-${pythonVersion}-${packageManager}-${fileHash}` | 
					
						
							|  |  |  |           ); | 
					
						
							|  |  |  |         } | 
					
						
							| 
									
										
										
										
											2022-02-04 14:00:41 +03:00
										 |  |  |       }, | 
					
						
							|  |  |  |       30000 | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  |     ); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |     it.each([ | 
					
						
							|  |  |  |       ['pip', '3.8.12', 'requirements-linux.txt', 'requirements-linux.txt'], | 
					
						
							|  |  |  |       ['pip', '3.8.12', 'requirements.txt', 'requirements.txt'], | 
					
						
							|  |  |  |       ['pipenv', '3.9.12', 'requirements.txt', 'requirements.txt'] | 
					
						
							|  |  |  |     ])( | 
					
						
							|  |  |  |       'Should throw an error because dependency file is not found', | 
					
						
							|  |  |  |       async ( | 
					
						
							|  |  |  |         packageManager, | 
					
						
							|  |  |  |         pythonVersion, | 
					
						
							|  |  |  |         dependencyFile, | 
					
						
							|  |  |  |         cacheDependencyPath | 
					
						
							|  |  |  |       ) => { | 
					
						
							| 
									
										
										
										
											2022-04-05 06:57:13 -07:00
										 |  |  |         const cacheDistributor = getCacheDistributor( | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  |           packageManager, | 
					
						
							|  |  |  |           pythonVersion, | 
					
						
							|  |  |  |           dependencyFile | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |         await expect(cacheDistributor.restoreCache()).rejects.toThrowError( | 
					
						
							|  |  |  |           `No file in ${process.cwd()} matched to [${cacheDependencyPath | 
					
						
							|  |  |  |             .split('\n') | 
					
						
							|  |  |  |             .join(',')}], make sure you have checked out the target repository`
 | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |   describe('Dependencies changed', () => { | 
					
						
							|  |  |  |     it.each([ | 
					
						
							|  |  |  |       ['pip', '3.8.12', undefined, pipFileLockHash], | 
					
						
							|  |  |  |       ['pip', '3.8.12', '**/requirements-linux.txt', pipFileLockHash], | 
					
						
							|  |  |  |       [ | 
					
						
							|  |  |  |         'pip', | 
					
						
							|  |  |  |         '3.8.12', | 
					
						
							|  |  |  |         '__tests__/data/requirements-linux.txt', | 
					
						
							|  |  |  |         pipFileLockHash | 
					
						
							|  |  |  |       ], | 
					
						
							|  |  |  |       ['pip', '3.8.12', '__tests__/data/requirements.txt', pipFileLockHash], | 
					
						
							|  |  |  |       ['pipenv', '3.9.1', undefined, requirementsHash], | 
					
						
							| 
									
										
										
										
											2021-11-24 18:40:05 +00:00
										 |  |  |       ['pipenv', '3.9.12', '__tests__/data/requirements.txt', requirementsHash], | 
					
						
							|  |  |  |       ['poetry', '3.9.1', undefined, requirementsHash] | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  |     ])( | 
					
						
							|  |  |  |       'restored dependencies for %s by primaryKey', | 
					
						
							|  |  |  |       async (packageManager, pythonVersion, dependencyFile, fileHash) => { | 
					
						
							|  |  |  |         restoreCacheSpy.mockImplementation( | 
					
						
							|  |  |  |           (cachePaths: string[], primaryKey: string, restoreKey?: string) => { | 
					
						
							|  |  |  |             return primaryKey !== fileHash && restoreKey ? pipFileLockHash : ''; | 
					
						
							|  |  |  |           } | 
					
						
							|  |  |  |         ); | 
					
						
							| 
									
										
										
										
											2022-04-05 06:57:13 -07:00
										 |  |  |         const cacheDistributor = getCacheDistributor( | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  |           packageManager, | 
					
						
							|  |  |  |           pythonVersion, | 
					
						
							|  |  |  |           dependencyFile | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |         await cacheDistributor.restoreCache(); | 
					
						
							|  |  |  |         let result = ''; | 
					
						
							| 
									
										
										
										
											2021-11-24 18:40:05 +00:00
										 |  |  | 
 | 
					
						
							|  |  |  |         switch (packageManager) { | 
					
						
							|  |  |  |           case 'pip': | 
					
						
							|  |  |  |             result = `Cache restored from key: ${fileHash}`; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           case 'pipenv': | 
					
						
							|  |  |  |             result = 'pipenv cache is not found'; | 
					
						
							|  |  |  |             break; | 
					
						
							|  |  |  |           case 'poetry': | 
					
						
							|  |  |  |             result = 'poetry cache is not found'; | 
					
						
							|  |  |  |             break; | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  |         } | 
					
						
							|  |  |  | 
 | 
					
						
							|  |  |  |         expect(infoSpy).toHaveBeenCalledWith(result); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2022-04-05 06:57:13 -07:00
										 |  |  |   describe('Check if handleMatchResult', () => { | 
					
						
							|  |  |  |     it.each([ | 
					
						
							|  |  |  |       ['pip', '3.8.12', 'requirements.txt', 'someKey', 'someKey', true], | 
					
						
							|  |  |  |       ['pipenv', '3.9.1', 'requirements.txt', 'someKey', 'someKey', true], | 
					
						
							|  |  |  |       ['poetry', '3.8.12', 'requirements.txt', 'someKey', 'someKey', true], | 
					
						
							|  |  |  |       ['pip', '3.9.2', 'requirements.txt', undefined, 'someKey', false], | 
					
						
							|  |  |  |       ['pipenv', '3.8.12', 'requirements.txt', undefined, 'someKey', false], | 
					
						
							|  |  |  |       ['poetry', '3.9.12', 'requirements.txt', undefined, 'someKey', false] | 
					
						
							|  |  |  |     ])( | 
					
						
							|  |  |  |       'sets correct outputs', | 
					
						
							|  |  |  |       async ( | 
					
						
							|  |  |  |         packageManager, | 
					
						
							|  |  |  |         pythonVersion, | 
					
						
							|  |  |  |         dependencyFile, | 
					
						
							|  |  |  |         matchedKey, | 
					
						
							|  |  |  |         restoredKey, | 
					
						
							|  |  |  |         expectedOutputValue | 
					
						
							|  |  |  |       ) => { | 
					
						
							|  |  |  |         const cacheDistributor = getCacheDistributor( | 
					
						
							|  |  |  |           packageManager, | 
					
						
							|  |  |  |           pythonVersion, | 
					
						
							|  |  |  |           dependencyFile | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |         cacheDistributor.handleMatchResult(matchedKey, restoredKey); | 
					
						
							|  |  |  |         expect(setOutputSpy).toHaveBeenCalledWith( | 
					
						
							|  |  |  |           'cache-hit', | 
					
						
							|  |  |  |           expectedOutputValue | 
					
						
							|  |  |  |         ); | 
					
						
							|  |  |  |       } | 
					
						
							|  |  |  |     ); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | 
 | 
					
						
							| 
									
										
										
										
											2021-11-17 13:31:22 +03:00
										 |  |  |   afterEach(() => { | 
					
						
							|  |  |  |     jest.resetAllMocks(); | 
					
						
							|  |  |  |     jest.clearAllMocks(); | 
					
						
							|  |  |  |   }); | 
					
						
							|  |  |  | }); |