mirror of
				https://github.com/actions/cache.git
				synced 2025-11-01 02:44:18 +08:00 
			
		
		
		
	Renamed variables and added tests
This commit is contained in:
		
							parent
							
								
									d91f5bd2fd
								
							
						
					
					
						commit
						3d4af52c52
					
				| @ -1,7 +1,7 @@ | |||||||
| import * as cache from "@actions/cache"; | import * as cache from "@actions/cache"; | ||||||
| import * as core from "@actions/core"; | import * as core from "@actions/core"; | ||||||
| 
 | 
 | ||||||
| import { Events, Inputs, RefKey } from "../src/constants"; | import { Events, RefKey } from "../src/constants"; | ||||||
| import run from "../src/restore"; | import run from "../src/restore"; | ||||||
| import * as actionUtils from "../src/utils/actionUtils"; | import * as actionUtils from "../src/utils/actionUtils"; | ||||||
| import * as testUtils from "../src/utils/testUtils"; | import * as testUtils from "../src/utils/testUtils"; | ||||||
| @ -45,158 +45,6 @@ afterEach(() => { | |||||||
|     delete process.env[RefKey]; |     delete process.env[RefKey]; | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| test("restore with invalid event outputs warning", async () => { |  | ||||||
|     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
|     const invalidEvent = "commit_comment"; |  | ||||||
|     process.env[Events.Key] = invalidEvent; |  | ||||||
|     delete process.env[RefKey]; |  | ||||||
|     await run(); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledWith( |  | ||||||
|         `Event Validation Error: The event type ${invalidEvent} is not supported because it's not tied to a branch or tag ref.` |  | ||||||
|     ); |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore without AC available should no-op", async () => { |  | ||||||
|     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => false); |  | ||||||
|     jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation( |  | ||||||
|         () => false |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); |  | ||||||
|     const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput"); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
|     expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(setCacheHitOutputMock).toHaveBeenCalledWith(false); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore on GHES without AC available should no-op", async () => { |  | ||||||
|     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true); |  | ||||||
|     jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation( |  | ||||||
|         () => false |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); |  | ||||||
|     const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput"); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
|     expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(setCacheHitOutputMock).toHaveBeenCalledWith(false); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore on GHES with AC available ", async () => { |  | ||||||
|     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true); |  | ||||||
|     const path = "node_modules"; |  | ||||||
|     const key = "node-test"; |  | ||||||
|     testUtils.setInputs({ |  | ||||||
|         path: path, |  | ||||||
|         key |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     const infoMock = jest.spyOn(core, "info"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
|     const stateMock = jest.spyOn(core, "saveState"); |  | ||||||
|     const setCacheHitOutputMock = jest.spyOn(core, "setOutput"); |  | ||||||
|     const restoreCacheMock = jest |  | ||||||
|         .spyOn(cache, "restoreCache") |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return Promise.resolve(key); |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []); |  | ||||||
| 
 |  | ||||||
|     expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); |  | ||||||
|     expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "true"); |  | ||||||
| 
 |  | ||||||
|     expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`); |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore with no path should fail", async () => { |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
|     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); |  | ||||||
|     await run(); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
|     // this input isn't necessary for restore b/c tarball contains entries relative to workspace
 |  | ||||||
|     expect(failedMock).not.toHaveBeenCalledWith( |  | ||||||
|         "Input required and not supplied: path" |  | ||||||
|     ); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore with no key", async () => { |  | ||||||
|     testUtils.setInput(Inputs.Path, "node_modules"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
|     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); |  | ||||||
|     await run(); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
|     expect(failedMock).toHaveBeenCalledWith( |  | ||||||
|         "Input required and not supplied: key" |  | ||||||
|     ); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore with too many keys should fail", async () => { |  | ||||||
|     const path = "node_modules"; |  | ||||||
|     const key = "node-test"; |  | ||||||
|     const restoreKeys = [...Array(20).keys()].map(x => x.toString()); |  | ||||||
|     testUtils.setInputs({ |  | ||||||
|         path: path, |  | ||||||
|         key, |  | ||||||
|         restoreKeys |  | ||||||
|     }); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
|     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); |  | ||||||
|     await run(); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, restoreKeys); |  | ||||||
|     expect(failedMock).toHaveBeenCalledWith( |  | ||||||
|         `Key Validation Error: Keys are limited to a maximum of 10.` |  | ||||||
|     ); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore with large key should fail", async () => { |  | ||||||
|     const path = "node_modules"; |  | ||||||
|     const key = "foo".repeat(512); // Over the 512 character limit
 |  | ||||||
|     testUtils.setInputs({ |  | ||||||
|         path: path, |  | ||||||
|         key |  | ||||||
|     }); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
|     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); |  | ||||||
|     await run(); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []); |  | ||||||
|     expect(failedMock).toHaveBeenCalledWith( |  | ||||||
|         `Key Validation Error: ${key} cannot be larger than 512 characters.` |  | ||||||
|     ); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore with invalid key should fail", async () => { |  | ||||||
|     const path = "node_modules"; |  | ||||||
|     const key = "comma,comma"; |  | ||||||
|     testUtils.setInputs({ |  | ||||||
|         path: path, |  | ||||||
|         key |  | ||||||
|     }); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
|     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); |  | ||||||
|     await run(); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []); |  | ||||||
|     expect(failedMock).toHaveBeenCalledWith( |  | ||||||
|         `Key Validation Error: ${key} cannot contain commas.` |  | ||||||
|     ); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore with no cache found", async () => { | test("restore with no cache found", async () => { | ||||||
|     const path = "node_modules"; |     const path = "node_modules"; | ||||||
|     const key = "node-test"; |     const key = "node-test"; | ||||||
|  | |||||||
							
								
								
									
										326
									
								
								__tests__/restoreImpl.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										326
									
								
								__tests__/restoreImpl.test.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,326 @@ | |||||||
|  | import * as cache from "@actions/cache"; | ||||||
|  | import * as core from "@actions/core"; | ||||||
|  | 
 | ||||||
|  | import { Events, Inputs, RefKey } from "../src/constants"; | ||||||
|  | import run from "../src/restoreImpl"; | ||||||
|  | import { StateProvider } from "../src/stateProvider"; | ||||||
|  | import * as actionUtils from "../src/utils/actionUtils"; | ||||||
|  | import * as testUtils from "../src/utils/testUtils"; | ||||||
|  | 
 | ||||||
|  | jest.mock("../src/utils/actionUtils"); | ||||||
|  | 
 | ||||||
|  | beforeAll(() => { | ||||||
|  |     jest.spyOn(actionUtils, "isExactKeyMatch").mockImplementation( | ||||||
|  |         (key, cacheResult) => { | ||||||
|  |             const actualUtils = jest.requireActual("../src/utils/actionUtils"); | ||||||
|  |             return actualUtils.isExactKeyMatch(key, cacheResult); | ||||||
|  |         } | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     jest.spyOn(actionUtils, "isValidEvent").mockImplementation(() => { | ||||||
|  |         const actualUtils = jest.requireActual("../src/utils/actionUtils"); | ||||||
|  |         return actualUtils.isValidEvent(); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     jest.spyOn(actionUtils, "getInputAsArray").mockImplementation( | ||||||
|  |         (name, options) => { | ||||||
|  |             const actualUtils = jest.requireActual("../src/utils/actionUtils"); | ||||||
|  |             return actualUtils.getInputAsArray(name, options); | ||||||
|  |         } | ||||||
|  |     ); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | beforeEach(() => { | ||||||
|  |     process.env[Events.Key] = Events.Push; | ||||||
|  |     process.env[RefKey] = "refs/heads/feature-branch"; | ||||||
|  | 
 | ||||||
|  |     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => false); | ||||||
|  |     jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation( | ||||||
|  |         () => true | ||||||
|  |     ); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | afterEach(() => { | ||||||
|  |     testUtils.clearInputs(); | ||||||
|  |     delete process.env[Events.Key]; | ||||||
|  |     delete process.env[RefKey]; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("restore with invalid event outputs warning", async () => { | ||||||
|  |     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  |     const invalidEvent = "commit_comment"; | ||||||
|  |     process.env[Events.Key] = invalidEvent; | ||||||
|  |     delete process.env[RefKey]; | ||||||
|  |     await run(new StateProvider()); | ||||||
|  |     expect(logWarningMock).toHaveBeenCalledWith( | ||||||
|  |         `Event Validation Error: The event type ${invalidEvent} is not supported because it's not tied to a branch or tag ref.` | ||||||
|  |     ); | ||||||
|  |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("restore without AC available should no-op", async () => { | ||||||
|  |     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => false); | ||||||
|  |     jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation( | ||||||
|  |         () => false | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); | ||||||
|  |     const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput"); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledTimes(0); | ||||||
|  |     expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(setCacheHitOutputMock).toHaveBeenCalledWith(false); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("restore on GHES without AC available should no-op", async () => { | ||||||
|  |     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true); | ||||||
|  |     jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation( | ||||||
|  |         () => false | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); | ||||||
|  |     const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput"); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledTimes(0); | ||||||
|  |     expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(setCacheHitOutputMock).toHaveBeenCalledWith(false); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("restore on GHES with AC available ", async () => { | ||||||
|  |     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true); | ||||||
|  |     const path = "node_modules"; | ||||||
|  |     const key = "node-test"; | ||||||
|  |     testUtils.setInputs({ | ||||||
|  |         path: path, | ||||||
|  |         key | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     const infoMock = jest.spyOn(core, "info"); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  |     const stateMock = jest.spyOn(core, "saveState"); | ||||||
|  |     const setCacheHitOutputMock = jest.spyOn(core, "setOutput"); | ||||||
|  |     const restoreCacheMock = jest | ||||||
|  |         .spyOn(cache, "restoreCache") | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return Promise.resolve(key); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []); | ||||||
|  | 
 | ||||||
|  |     expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); | ||||||
|  |     expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "true"); | ||||||
|  | 
 | ||||||
|  |     expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`); | ||||||
|  |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("restore with no path should fail", async () => { | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  |     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); | ||||||
|  |     await run(new StateProvider()); | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledTimes(0); | ||||||
|  |     // this input isn't necessary for restore b/c tarball contains entries relative to workspace
 | ||||||
|  |     expect(failedMock).not.toHaveBeenCalledWith( | ||||||
|  |         "Input required and not supplied: path" | ||||||
|  |     ); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("restore with no key", async () => { | ||||||
|  |     testUtils.setInput(Inputs.Path, "node_modules"); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  |     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); | ||||||
|  |     await run(new StateProvider()); | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledTimes(0); | ||||||
|  |     expect(failedMock).toHaveBeenCalledWith( | ||||||
|  |         "Input required and not supplied: key" | ||||||
|  |     ); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("restore with too many keys should fail", async () => { | ||||||
|  |     const path = "node_modules"; | ||||||
|  |     const key = "node-test"; | ||||||
|  |     const restoreKeys = [...Array(20).keys()].map(x => x.toString()); | ||||||
|  |     testUtils.setInputs({ | ||||||
|  |         path: path, | ||||||
|  |         key, | ||||||
|  |         restoreKeys | ||||||
|  |     }); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  |     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); | ||||||
|  |     await run(new StateProvider()); | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, restoreKeys); | ||||||
|  |     expect(failedMock).toHaveBeenCalledWith( | ||||||
|  |         `Key Validation Error: Keys are limited to a maximum of 10.` | ||||||
|  |     ); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("restore with large key should fail", async () => { | ||||||
|  |     const path = "node_modules"; | ||||||
|  |     const key = "foo".repeat(512); // Over the 512 character limit
 | ||||||
|  |     testUtils.setInputs({ | ||||||
|  |         path: path, | ||||||
|  |         key | ||||||
|  |     }); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  |     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); | ||||||
|  |     await run(new StateProvider()); | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []); | ||||||
|  |     expect(failedMock).toHaveBeenCalledWith( | ||||||
|  |         `Key Validation Error: ${key} cannot be larger than 512 characters.` | ||||||
|  |     ); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("restore with invalid key should fail", async () => { | ||||||
|  |     const path = "node_modules"; | ||||||
|  |     const key = "comma,comma"; | ||||||
|  |     testUtils.setInputs({ | ||||||
|  |         path: path, | ||||||
|  |         key | ||||||
|  |     }); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  |     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); | ||||||
|  |     await run(new StateProvider()); | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []); | ||||||
|  |     expect(failedMock).toHaveBeenCalledWith( | ||||||
|  |         `Key Validation Error: ${key} cannot contain commas.` | ||||||
|  |     ); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("restore with no cache found", async () => { | ||||||
|  |     const path = "node_modules"; | ||||||
|  |     const key = "node-test"; | ||||||
|  |     testUtils.setInputs({ | ||||||
|  |         path: path, | ||||||
|  |         key | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     const infoMock = jest.spyOn(core, "info"); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  |     const stateMock = jest.spyOn(core, "saveState"); | ||||||
|  |     const restoreCacheMock = jest | ||||||
|  |         .spyOn(cache, "restoreCache") | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return Promise.resolve(undefined); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []); | ||||||
|  | 
 | ||||||
|  |     expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); | ||||||
|  |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
|  | 
 | ||||||
|  |     expect(infoMock).toHaveBeenCalledWith( | ||||||
|  |         `Cache not found for input keys: ${key}` | ||||||
|  |     ); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("restore with restore keys and no cache found", async () => { | ||||||
|  |     const path = "node_modules"; | ||||||
|  |     const key = "node-test"; | ||||||
|  |     const restoreKey = "node-"; | ||||||
|  |     testUtils.setInputs({ | ||||||
|  |         path: path, | ||||||
|  |         key, | ||||||
|  |         restoreKeys: [restoreKey] | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     const infoMock = jest.spyOn(core, "info"); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  |     const stateMock = jest.spyOn(core, "saveState"); | ||||||
|  |     const restoreCacheMock = jest | ||||||
|  |         .spyOn(cache, "restoreCache") | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return Promise.resolve(undefined); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]); | ||||||
|  | 
 | ||||||
|  |     expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); | ||||||
|  |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
|  | 
 | ||||||
|  |     expect(infoMock).toHaveBeenCalledWith( | ||||||
|  |         `Cache not found for input keys: ${key}, ${restoreKey}` | ||||||
|  |     ); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("restore with cache found for key", async () => { | ||||||
|  |     const path = "node_modules"; | ||||||
|  |     const key = "node-test"; | ||||||
|  |     testUtils.setInputs({ | ||||||
|  |         path: path, | ||||||
|  |         key | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     const infoMock = jest.spyOn(core, "info"); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  |     const stateMock = jest.spyOn(core, "saveState"); | ||||||
|  |     const setCacheHitOutputMock = jest.spyOn(core, "setOutput"); | ||||||
|  |     const restoreCacheMock = jest | ||||||
|  |         .spyOn(cache, "restoreCache") | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return Promise.resolve(key); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []); | ||||||
|  | 
 | ||||||
|  |     expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); | ||||||
|  |     expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "true"); | ||||||
|  | 
 | ||||||
|  |     expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`); | ||||||
|  |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("restore with cache found for restore key", async () => { | ||||||
|  |     const path = "node_modules"; | ||||||
|  |     const key = "node-test"; | ||||||
|  |     const restoreKey = "node-"; | ||||||
|  |     testUtils.setInputs({ | ||||||
|  |         path: path, | ||||||
|  |         key, | ||||||
|  |         restoreKeys: [restoreKey] | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     const infoMock = jest.spyOn(core, "info"); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  |     const stateMock = jest.spyOn(core, "saveState"); | ||||||
|  |     const setCacheHitOutputMock = jest.spyOn(core, "setOutput"); | ||||||
|  |     const restoreCacheMock = jest | ||||||
|  |         .spyOn(cache, "restoreCache") | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return Promise.resolve(restoreKey); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]); | ||||||
|  | 
 | ||||||
|  |     expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); | ||||||
|  |     expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "false"); | ||||||
|  |     expect(infoMock).toHaveBeenCalledWith( | ||||||
|  |         `Cache restored from key: ${restoreKey}` | ||||||
|  |     ); | ||||||
|  |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
|  | }); | ||||||
| @ -1,8 +1,9 @@ | |||||||
| import * as cache from "@actions/cache"; | import * as cache from "@actions/cache"; | ||||||
| import * as core from "@actions/core"; | import * as core from "@actions/core"; | ||||||
| 
 | 
 | ||||||
| import { Events, Inputs, RefKey } from "../src/constants"; | import { Events, RefKey } from "../src/constants"; | ||||||
| import run from "../src/restoreOnly"; | import run from "../src/restoreImpl"; | ||||||
|  | import { StateProvider } from "../src/stateProvider"; | ||||||
| import * as actionUtils from "../src/utils/actionUtils"; | import * as actionUtils from "../src/utils/actionUtils"; | ||||||
| import * as testUtils from "../src/utils/testUtils"; | import * as testUtils from "../src/utils/testUtils"; | ||||||
| 
 | 
 | ||||||
| @ -45,157 +46,6 @@ afterEach(() => { | |||||||
|     delete process.env[RefKey]; |     delete process.env[RefKey]; | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| test("restore with invalid event outputs warning", async () => { |  | ||||||
|     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
|     const invalidEvent = "commit_comment"; |  | ||||||
|     process.env[Events.Key] = invalidEvent; |  | ||||||
|     delete process.env[RefKey]; |  | ||||||
|     await run(); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledWith( |  | ||||||
|         `Event Validation Error: The event type ${invalidEvent} is not supported because it's not tied to a branch or tag ref.` |  | ||||||
|     ); |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore without AC available should no-op", async () => { |  | ||||||
|     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => false); |  | ||||||
|     jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation( |  | ||||||
|         () => false |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); |  | ||||||
|     const outputMock = jest.spyOn(actionUtils, "setCacheHitOutput"); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
|     expect(outputMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(outputMock).toHaveBeenCalledWith(false); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore on GHES without AC available should no-op", async () => { |  | ||||||
|     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true); |  | ||||||
|     jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation( |  | ||||||
|         () => false |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); |  | ||||||
|     const outputMock = jest.spyOn(actionUtils, "setCacheHitOutput"); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
|     expect(outputMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(outputMock).toHaveBeenCalledWith(false); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore on GHES with AC available ", async () => { |  | ||||||
|     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true); |  | ||||||
|     const path = "node_modules"; |  | ||||||
|     const key = "node-test"; |  | ||||||
|     testUtils.setInputs({ |  | ||||||
|         path: path, |  | ||||||
|         key |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     const infoMock = jest.spyOn(core, "info"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
|     const outputMock = jest.spyOn(core, "setOutput"); |  | ||||||
|     const restoreCacheMock = jest |  | ||||||
|         .spyOn(cache, "restoreCache") |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return Promise.resolve(key); |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []); |  | ||||||
| 
 |  | ||||||
|     expect(outputMock).toHaveBeenCalledWith("CACHE_KEY", key); |  | ||||||
|     expect(outputMock).toHaveBeenCalledTimes(3); |  | ||||||
|     expect(outputMock).toHaveBeenCalledWith("cache-hit", "true"); |  | ||||||
| 
 |  | ||||||
|     expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`); |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore with no path should fail", async () => { |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
|     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); |  | ||||||
|     await run(); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
|     // this input isn't necessary for restore b/c tarball contains entries relative to workspace
 |  | ||||||
|     expect(failedMock).not.toHaveBeenCalledWith( |  | ||||||
|         "Input required and not supplied: path" |  | ||||||
|     ); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore with no key", async () => { |  | ||||||
|     testUtils.setInput(Inputs.Path, "node_modules"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
|     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); |  | ||||||
|     await run(); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
|     expect(failedMock).toHaveBeenCalledWith( |  | ||||||
|         "Input required and not supplied: key" |  | ||||||
|     ); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore with too many keys should fail", async () => { |  | ||||||
|     const path = "node_modules"; |  | ||||||
|     const key = "node-test"; |  | ||||||
|     const restoreKeys = [...Array(20).keys()].map(x => x.toString()); |  | ||||||
|     testUtils.setInputs({ |  | ||||||
|         path: path, |  | ||||||
|         key, |  | ||||||
|         restoreKeys |  | ||||||
|     }); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
|     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); |  | ||||||
|     await run(); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, restoreKeys); |  | ||||||
|     expect(failedMock).toHaveBeenCalledWith( |  | ||||||
|         `Key Validation Error: Keys are limited to a maximum of 10.` |  | ||||||
|     ); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore with large key should fail", async () => { |  | ||||||
|     const path = "node_modules"; |  | ||||||
|     const key = "foo".repeat(512); // Over the 512 character limit
 |  | ||||||
|     testUtils.setInputs({ |  | ||||||
|         path: path, |  | ||||||
|         key |  | ||||||
|     }); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
|     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); |  | ||||||
|     await run(); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []); |  | ||||||
|     expect(failedMock).toHaveBeenCalledWith( |  | ||||||
|         `Key Validation Error: ${key} cannot be larger than 512 characters.` |  | ||||||
|     ); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore with invalid key should fail", async () => { |  | ||||||
|     const path = "node_modules"; |  | ||||||
|     const key = "comma,comma"; |  | ||||||
|     testUtils.setInputs({ |  | ||||||
|         path: path, |  | ||||||
|         key |  | ||||||
|     }); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
|     const restoreCacheMock = jest.spyOn(cache, "restoreCache"); |  | ||||||
|     await run(); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []); |  | ||||||
|     expect(failedMock).toHaveBeenCalledWith( |  | ||||||
|         `Key Validation Error: ${key} cannot contain commas.` |  | ||||||
|     ); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("restore with no cache found", async () => { | test("restore with no cache found", async () => { | ||||||
|     const path = "node_modules"; |     const path = "node_modules"; | ||||||
|     const key = "node-test"; |     const key = "node-test"; | ||||||
| @ -206,19 +56,19 @@ test("restore with no cache found", async () => { | |||||||
| 
 | 
 | ||||||
|     const infoMock = jest.spyOn(core, "info"); |     const infoMock = jest.spyOn(core, "info"); | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|     const outputMock = jest.spyOn(core, "setOutput"); |     const stateMock = jest.spyOn(core, "saveState"); | ||||||
|     const restoreCacheMock = jest |     const restoreCacheMock = jest | ||||||
|         .spyOn(cache, "restoreCache") |         .spyOn(cache, "restoreCache") | ||||||
|         .mockImplementationOnce(() => { |         .mockImplementationOnce(() => { | ||||||
|             return Promise.resolve(undefined); |             return Promise.resolve(undefined); | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|     await run(); |     await run(new StateProvider()); | ||||||
| 
 | 
 | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(1); |     expect(restoreCacheMock).toHaveBeenCalledTimes(1); | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []); |     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []); | ||||||
| 
 | 
 | ||||||
|     expect(outputMock).toHaveBeenCalledWith("CACHE_KEY", key); |     expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
| 
 | 
 | ||||||
|     expect(infoMock).toHaveBeenCalledWith( |     expect(infoMock).toHaveBeenCalledWith( | ||||||
| @ -238,19 +88,19 @@ test("restore with restore keys and no cache found", async () => { | |||||||
| 
 | 
 | ||||||
|     const infoMock = jest.spyOn(core, "info"); |     const infoMock = jest.spyOn(core, "info"); | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|     const outputMock = jest.spyOn(core, "setOutput"); |     const stateMock = jest.spyOn(core, "saveState"); | ||||||
|     const restoreCacheMock = jest |     const restoreCacheMock = jest | ||||||
|         .spyOn(cache, "restoreCache") |         .spyOn(cache, "restoreCache") | ||||||
|         .mockImplementationOnce(() => { |         .mockImplementationOnce(() => { | ||||||
|             return Promise.resolve(undefined); |             return Promise.resolve(undefined); | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|     await run(); |     await run(new StateProvider()); | ||||||
| 
 | 
 | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(1); |     expect(restoreCacheMock).toHaveBeenCalledTimes(1); | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]); |     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]); | ||||||
| 
 | 
 | ||||||
|     expect(outputMock).toHaveBeenCalledWith("CACHE_KEY", key); |     expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
| 
 | 
 | ||||||
|     expect(infoMock).toHaveBeenCalledWith( |     expect(infoMock).toHaveBeenCalledWith( | ||||||
| @ -268,21 +118,22 @@ test("restore with cache found for key", async () => { | |||||||
| 
 | 
 | ||||||
|     const infoMock = jest.spyOn(core, "info"); |     const infoMock = jest.spyOn(core, "info"); | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|     const outputMock = jest.spyOn(core, "setOutput"); |     const stateMock = jest.spyOn(core, "saveState"); | ||||||
|  |     const setCacheHitOutputMock = jest.spyOn(core, "setOutput"); | ||||||
|     const restoreCacheMock = jest |     const restoreCacheMock = jest | ||||||
|         .spyOn(cache, "restoreCache") |         .spyOn(cache, "restoreCache") | ||||||
|         .mockImplementationOnce(() => { |         .mockImplementationOnce(() => { | ||||||
|             return Promise.resolve(key); |             return Promise.resolve(key); | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|     await run(); |     await run(new StateProvider()); | ||||||
| 
 | 
 | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(1); |     expect(restoreCacheMock).toHaveBeenCalledTimes(1); | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []); |     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, []); | ||||||
| 
 | 
 | ||||||
|     expect(outputMock).toHaveBeenCalledWith("CACHE_KEY", key); |     expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); | ||||||
|     expect(outputMock).toHaveBeenCalledTimes(3); |     expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); | ||||||
|     expect(outputMock).toHaveBeenCalledWith("cache-hit", "true"); |     expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "true"); | ||||||
| 
 | 
 | ||||||
|     expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`); |     expect(infoMock).toHaveBeenCalledWith(`Cache restored from key: ${key}`); | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
| @ -300,21 +151,22 @@ test("restore with cache found for restore key", async () => { | |||||||
| 
 | 
 | ||||||
|     const infoMock = jest.spyOn(core, "info"); |     const infoMock = jest.spyOn(core, "info"); | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|     const outputMock = jest.spyOn(core, "setOutput"); |     const stateMock = jest.spyOn(core, "saveState"); | ||||||
|  |     const setCacheHitOutputMock = jest.spyOn(core, "setOutput"); | ||||||
|     const restoreCacheMock = jest |     const restoreCacheMock = jest | ||||||
|         .spyOn(cache, "restoreCache") |         .spyOn(cache, "restoreCache") | ||||||
|         .mockImplementationOnce(() => { |         .mockImplementationOnce(() => { | ||||||
|             return Promise.resolve(restoreKey); |             return Promise.resolve(restoreKey); | ||||||
|         }); |         }); | ||||||
| 
 | 
 | ||||||
|     await run(); |     await run(new StateProvider()); | ||||||
| 
 | 
 | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledTimes(1); |     expect(restoreCacheMock).toHaveBeenCalledTimes(1); | ||||||
|     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]); |     expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]); | ||||||
| 
 | 
 | ||||||
|     expect(outputMock).toHaveBeenCalledWith("CACHE_KEY", key); |     expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key); | ||||||
|     expect(outputMock).toHaveBeenCalledTimes(3); |     expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1); | ||||||
|     expect(outputMock).toHaveBeenCalledWith("cache-hit", "false"); |     expect(setCacheHitOutputMock).toHaveBeenCalledWith("cache-hit", "false"); | ||||||
|     expect(infoMock).toHaveBeenCalledWith( |     expect(infoMock).toHaveBeenCalledWith( | ||||||
|         `Cache restored from key: ${restoreKey}` |         `Cache restored from key: ${restoreKey}` | ||||||
|     ); |     ); | ||||||
|  | |||||||
| @ -61,294 +61,6 @@ afterEach(() => { | |||||||
|     delete process.env[RefKey]; |     delete process.env[RefKey]; | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| test("save with invalid event outputs warning", async () => { |  | ||||||
|     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
|     const invalidEvent = "commit_comment"; |  | ||||||
|     process.env[Events.Key] = invalidEvent; |  | ||||||
|     delete process.env[RefKey]; |  | ||||||
|     await run(); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledWith( |  | ||||||
|         `Event Validation Error: The event type ${invalidEvent} is not supported because it's not tied to a branch or tag ref.` |  | ||||||
|     ); |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save with no primary key in state outputs warning", async () => { |  | ||||||
|     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
| 
 |  | ||||||
|     const savedCacheKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; |  | ||||||
|     jest.spyOn(core, "getState") |  | ||||||
|         // Cache Entry State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return ""; |  | ||||||
|         }) |  | ||||||
|         // Cache Key State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return savedCacheKey; |  | ||||||
|         }); |  | ||||||
|     const saveCacheMock = jest.spyOn(cache, "saveCache"); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledWith( |  | ||||||
|         `Error retrieving key from state.` |  | ||||||
|     ); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save without AC available should no-op", async () => { |  | ||||||
|     jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation( |  | ||||||
|         () => false |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     const saveCacheMock = jest.spyOn(cache, "saveCache"); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save on ghes without AC available should no-op", async () => { |  | ||||||
|     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true); |  | ||||||
|     jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation( |  | ||||||
|         () => false |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     const saveCacheMock = jest.spyOn(cache, "saveCache"); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save on GHES with AC available", async () => { |  | ||||||
|     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
| 
 |  | ||||||
|     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; |  | ||||||
|     const savedCacheKey = "Linux-node-"; |  | ||||||
| 
 |  | ||||||
|     jest.spyOn(core, "getState") |  | ||||||
|         // Cache Entry State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return savedCacheKey; |  | ||||||
|         }) |  | ||||||
|         // Cache Key State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return primaryKey; |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     const inputPath = "node_modules"; |  | ||||||
|     testUtils.setInput(Inputs.Path, inputPath); |  | ||||||
|     testUtils.setInput(Inputs.UploadChunkSize, "4000000"); |  | ||||||
| 
 |  | ||||||
|     const cacheId = 4; |  | ||||||
|     const saveCacheMock = jest |  | ||||||
|         .spyOn(cache, "saveCache") |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return Promise.resolve(cacheId); |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledWith([inputPath], primaryKey, { |  | ||||||
|         uploadChunkSize: 4000000 |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save with exact match returns early", async () => { |  | ||||||
|     const infoMock = jest.spyOn(core, "info"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
| 
 |  | ||||||
|     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; |  | ||||||
|     const savedCacheKey = primaryKey; |  | ||||||
| 
 |  | ||||||
|     jest.spyOn(core, "getState") |  | ||||||
|         // Cache Entry State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return savedCacheKey; |  | ||||||
|         }) |  | ||||||
|         // Cache Key State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return primaryKey; |  | ||||||
|         }); |  | ||||||
|     const saveCacheMock = jest.spyOn(cache, "saveCache"); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
|     expect(infoMock).toHaveBeenCalledWith( |  | ||||||
|         `Cache hit occurred on the primary key ${primaryKey}, not saving cache.` |  | ||||||
|     ); |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save with missing input outputs warning", async () => { |  | ||||||
|     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
| 
 |  | ||||||
|     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; |  | ||||||
|     const savedCacheKey = "Linux-node-"; |  | ||||||
| 
 |  | ||||||
|     jest.spyOn(core, "getState") |  | ||||||
|         // Cache Entry State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return savedCacheKey; |  | ||||||
|         }) |  | ||||||
|         // Cache Key State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return primaryKey; |  | ||||||
|         }); |  | ||||||
|     const saveCacheMock = jest.spyOn(cache, "saveCache"); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledWith( |  | ||||||
|         "Input required and not supplied: path" |  | ||||||
|     ); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save with large cache outputs warning", async () => { |  | ||||||
|     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
| 
 |  | ||||||
|     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; |  | ||||||
|     const savedCacheKey = "Linux-node-"; |  | ||||||
| 
 |  | ||||||
|     jest.spyOn(core, "getState") |  | ||||||
|         // Cache Entry State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return savedCacheKey; |  | ||||||
|         }) |  | ||||||
|         // Cache Key State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return primaryKey; |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     const inputPath = "node_modules"; |  | ||||||
|     testUtils.setInput(Inputs.Path, inputPath); |  | ||||||
| 
 |  | ||||||
|     const saveCacheMock = jest |  | ||||||
|         .spyOn(cache, "saveCache") |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             throw new Error( |  | ||||||
|                 "Cache size of ~6144 MB (6442450944 B) is over the 5GB limit, not saving cache." |  | ||||||
|             ); |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledWith( |  | ||||||
|         [inputPath], |  | ||||||
|         primaryKey, |  | ||||||
|         expect.anything() |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledWith( |  | ||||||
|         "Cache size of ~6144 MB (6442450944 B) is over the 5GB limit, not saving cache." |  | ||||||
|     ); |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save with reserve cache failure outputs warning", async () => { |  | ||||||
|     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
| 
 |  | ||||||
|     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; |  | ||||||
|     const savedCacheKey = "Linux-node-"; |  | ||||||
| 
 |  | ||||||
|     jest.spyOn(core, "getState") |  | ||||||
|         // Cache Entry State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return savedCacheKey; |  | ||||||
|         }) |  | ||||||
|         // Cache Key State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return primaryKey; |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     const inputPath = "node_modules"; |  | ||||||
|     testUtils.setInput(Inputs.Path, inputPath); |  | ||||||
| 
 |  | ||||||
|     const saveCacheMock = jest |  | ||||||
|         .spyOn(cache, "saveCache") |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             const actualCache = jest.requireActual("@actions/cache"); |  | ||||||
|             const error = new actualCache.ReserveCacheError( |  | ||||||
|                 `Unable to reserve cache with key ${primaryKey}, another job may be creating this cache.` |  | ||||||
|             ); |  | ||||||
|             throw error; |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledWith( |  | ||||||
|         [inputPath], |  | ||||||
|         primaryKey, |  | ||||||
|         expect.anything() |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledWith( |  | ||||||
|         `Unable to reserve cache with key ${primaryKey}, another job may be creating this cache.` |  | ||||||
|     ); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save with server error outputs warning", async () => { |  | ||||||
|     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
| 
 |  | ||||||
|     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; |  | ||||||
|     const savedCacheKey = "Linux-node-"; |  | ||||||
| 
 |  | ||||||
|     jest.spyOn(core, "getState") |  | ||||||
|         // Cache Entry State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return savedCacheKey; |  | ||||||
|         }) |  | ||||||
|         // Cache Key State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return primaryKey; |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     const inputPath = "node_modules"; |  | ||||||
|     testUtils.setInput(Inputs.Path, inputPath); |  | ||||||
| 
 |  | ||||||
|     const saveCacheMock = jest |  | ||||||
|         .spyOn(cache, "saveCache") |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             throw new Error("HTTP Error Occurred"); |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledWith( |  | ||||||
|         [inputPath], |  | ||||||
|         primaryKey, |  | ||||||
|         expect.anything() |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledWith("HTTP Error Occurred"); |  | ||||||
| 
 |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save with valid inputs uploads a cache", async () => { | test("save with valid inputs uploads a cache", async () => { | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										388
									
								
								__tests__/saveImpl.test.ts
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										388
									
								
								__tests__/saveImpl.test.ts
									
									
									
									
									
										Normal file
									
								
							| @ -0,0 +1,388 @@ | |||||||
|  | import * as cache from "@actions/cache"; | ||||||
|  | import * as core from "@actions/core"; | ||||||
|  | 
 | ||||||
|  | import { Events, Inputs, RefKey } from "../src/constants"; | ||||||
|  | import run from "../src/saveImpl"; | ||||||
|  | import { StateProvider } from "../src/stateProvider"; | ||||||
|  | import * as actionUtils from "../src/utils/actionUtils"; | ||||||
|  | import * as testUtils from "../src/utils/testUtils"; | ||||||
|  | 
 | ||||||
|  | jest.mock("@actions/core"); | ||||||
|  | jest.mock("@actions/cache"); | ||||||
|  | jest.mock("../src/utils/actionUtils"); | ||||||
|  | 
 | ||||||
|  | beforeAll(() => { | ||||||
|  |     jest.spyOn(core, "getInput").mockImplementation((name, options) => { | ||||||
|  |         return jest.requireActual("@actions/core").getInput(name, options); | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     jest.spyOn(actionUtils, "getInputAsArray").mockImplementation( | ||||||
|  |         (name, options) => { | ||||||
|  |             return jest | ||||||
|  |                 .requireActual("../src/utils/actionUtils") | ||||||
|  |                 .getInputAsArray(name, options); | ||||||
|  |         } | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     jest.spyOn(actionUtils, "getInputAsInt").mockImplementation( | ||||||
|  |         (name, options) => { | ||||||
|  |             return jest | ||||||
|  |                 .requireActual("../src/utils/actionUtils") | ||||||
|  |                 .getInputAsInt(name, options); | ||||||
|  |         } | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     jest.spyOn(actionUtils, "isExactKeyMatch").mockImplementation( | ||||||
|  |         (key, cacheResult) => { | ||||||
|  |             return jest | ||||||
|  |                 .requireActual("../src/utils/actionUtils") | ||||||
|  |                 .isExactKeyMatch(key, cacheResult); | ||||||
|  |         } | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     jest.spyOn(actionUtils, "isValidEvent").mockImplementation(() => { | ||||||
|  |         const actualUtils = jest.requireActual("../src/utils/actionUtils"); | ||||||
|  |         return actualUtils.isValidEvent(); | ||||||
|  |     }); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | beforeEach(() => { | ||||||
|  |     process.env[Events.Key] = Events.Push; | ||||||
|  |     process.env[RefKey] = "refs/heads/feature-branch"; | ||||||
|  | 
 | ||||||
|  |     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => false); | ||||||
|  |     jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation( | ||||||
|  |         () => true | ||||||
|  |     ); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | afterEach(() => { | ||||||
|  |     testUtils.clearInputs(); | ||||||
|  |     delete process.env[Events.Key]; | ||||||
|  |     delete process.env[RefKey]; | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("save with invalid event outputs warning", async () => { | ||||||
|  |     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  |     const invalidEvent = "commit_comment"; | ||||||
|  |     process.env[Events.Key] = invalidEvent; | ||||||
|  |     delete process.env[RefKey]; | ||||||
|  |     await run(new StateProvider()); | ||||||
|  |     expect(logWarningMock).toHaveBeenCalledWith( | ||||||
|  |         `Event Validation Error: The event type ${invalidEvent} is not supported because it's not tied to a branch or tag ref.` | ||||||
|  |     ); | ||||||
|  |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("save with no primary key in state outputs warning", async () => { | ||||||
|  |     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  | 
 | ||||||
|  |     const savedCacheKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; | ||||||
|  |     jest.spyOn(core, "getState") | ||||||
|  |         // Cache Entry State
 | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return ""; | ||||||
|  |         }) | ||||||
|  |         // Cache Key State
 | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return savedCacheKey; | ||||||
|  |         }); | ||||||
|  |     const saveCacheMock = jest.spyOn(cache, "saveCache"); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(saveCacheMock).toHaveBeenCalledTimes(0); | ||||||
|  |     expect(logWarningMock).toHaveBeenCalledWith( | ||||||
|  |         `Error retrieving key from state.` | ||||||
|  |     ); | ||||||
|  |     expect(logWarningMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("save without AC available should no-op", async () => { | ||||||
|  |     jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation( | ||||||
|  |         () => false | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const saveCacheMock = jest.spyOn(cache, "saveCache"); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(saveCacheMock).toHaveBeenCalledTimes(0); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("save on ghes without AC available should no-op", async () => { | ||||||
|  |     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true); | ||||||
|  |     jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation( | ||||||
|  |         () => false | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     const saveCacheMock = jest.spyOn(cache, "saveCache"); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(saveCacheMock).toHaveBeenCalledTimes(0); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("save on GHES with AC available", async () => { | ||||||
|  |     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  | 
 | ||||||
|  |     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; | ||||||
|  |     const savedCacheKey = "Linux-node-"; | ||||||
|  | 
 | ||||||
|  |     jest.spyOn(core, "getState") | ||||||
|  |         // Cache Entry State
 | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return savedCacheKey; | ||||||
|  |         }) | ||||||
|  |         // Cache Key State
 | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return primaryKey; | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |     const inputPath = "node_modules"; | ||||||
|  |     testUtils.setInput(Inputs.Path, inputPath); | ||||||
|  |     testUtils.setInput(Inputs.UploadChunkSize, "4000000"); | ||||||
|  | 
 | ||||||
|  |     const cacheId = 4; | ||||||
|  |     const saveCacheMock = jest | ||||||
|  |         .spyOn(cache, "saveCache") | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return Promise.resolve(cacheId); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(saveCacheMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(saveCacheMock).toHaveBeenCalledWith([inputPath], primaryKey, { | ||||||
|  |         uploadChunkSize: 4000000 | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("save with exact match returns early", async () => { | ||||||
|  |     const infoMock = jest.spyOn(core, "info"); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  | 
 | ||||||
|  |     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; | ||||||
|  |     const savedCacheKey = primaryKey; | ||||||
|  | 
 | ||||||
|  |     jest.spyOn(core, "getState") | ||||||
|  |         // Cache Entry State
 | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return savedCacheKey; | ||||||
|  |         }) | ||||||
|  |         // Cache Key State
 | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return primaryKey; | ||||||
|  |         }); | ||||||
|  |     const saveCacheMock = jest.spyOn(cache, "saveCache"); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(saveCacheMock).toHaveBeenCalledTimes(0); | ||||||
|  |     expect(infoMock).toHaveBeenCalledWith( | ||||||
|  |         `Cache hit occurred on the primary key ${primaryKey}, not saving cache.` | ||||||
|  |     ); | ||||||
|  |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("save with missing input outputs warning", async () => { | ||||||
|  |     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  | 
 | ||||||
|  |     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; | ||||||
|  |     const savedCacheKey = "Linux-node-"; | ||||||
|  | 
 | ||||||
|  |     jest.spyOn(core, "getState") | ||||||
|  |         // Cache Entry State
 | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return savedCacheKey; | ||||||
|  |         }) | ||||||
|  |         // Cache Key State
 | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return primaryKey; | ||||||
|  |         }); | ||||||
|  |     const saveCacheMock = jest.spyOn(cache, "saveCache"); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(saveCacheMock).toHaveBeenCalledTimes(0); | ||||||
|  |     expect(logWarningMock).toHaveBeenCalledWith( | ||||||
|  |         "Input required and not supplied: path" | ||||||
|  |     ); | ||||||
|  |     expect(logWarningMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("save with large cache outputs warning", async () => { | ||||||
|  |     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  | 
 | ||||||
|  |     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; | ||||||
|  |     const savedCacheKey = "Linux-node-"; | ||||||
|  | 
 | ||||||
|  |     jest.spyOn(core, "getState") | ||||||
|  |         // Cache Entry State
 | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return savedCacheKey; | ||||||
|  |         }) | ||||||
|  |         // Cache Key State
 | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return primaryKey; | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |     const inputPath = "node_modules"; | ||||||
|  |     testUtils.setInput(Inputs.Path, inputPath); | ||||||
|  | 
 | ||||||
|  |     const saveCacheMock = jest | ||||||
|  |         .spyOn(cache, "saveCache") | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             throw new Error( | ||||||
|  |                 "Cache size of ~6144 MB (6442450944 B) is over the 5GB limit, not saving cache." | ||||||
|  |             ); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(saveCacheMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(saveCacheMock).toHaveBeenCalledWith( | ||||||
|  |         [inputPath], | ||||||
|  |         primaryKey, | ||||||
|  |         expect.anything() | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     expect(logWarningMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(logWarningMock).toHaveBeenCalledWith( | ||||||
|  |         "Cache size of ~6144 MB (6442450944 B) is over the 5GB limit, not saving cache." | ||||||
|  |     ); | ||||||
|  |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("save with reserve cache failure outputs warning", async () => { | ||||||
|  |     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  | 
 | ||||||
|  |     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; | ||||||
|  |     const savedCacheKey = "Linux-node-"; | ||||||
|  | 
 | ||||||
|  |     jest.spyOn(core, "getState") | ||||||
|  |         // Cache Entry State
 | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return savedCacheKey; | ||||||
|  |         }) | ||||||
|  |         // Cache Key State
 | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return primaryKey; | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |     const inputPath = "node_modules"; | ||||||
|  |     testUtils.setInput(Inputs.Path, inputPath); | ||||||
|  | 
 | ||||||
|  |     const saveCacheMock = jest | ||||||
|  |         .spyOn(cache, "saveCache") | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             const actualCache = jest.requireActual("@actions/cache"); | ||||||
|  |             const error = new actualCache.ReserveCacheError( | ||||||
|  |                 `Unable to reserve cache with key ${primaryKey}, another job may be creating this cache.` | ||||||
|  |             ); | ||||||
|  |             throw error; | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(saveCacheMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(saveCacheMock).toHaveBeenCalledWith( | ||||||
|  |         [inputPath], | ||||||
|  |         primaryKey, | ||||||
|  |         expect.anything() | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     expect(logWarningMock).toHaveBeenCalledWith( | ||||||
|  |         `Unable to reserve cache with key ${primaryKey}, another job may be creating this cache.` | ||||||
|  |     ); | ||||||
|  |     expect(logWarningMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("save with server error outputs warning", async () => { | ||||||
|  |     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  | 
 | ||||||
|  |     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; | ||||||
|  |     const savedCacheKey = "Linux-node-"; | ||||||
|  | 
 | ||||||
|  |     jest.spyOn(core, "getState") | ||||||
|  |         // Cache Entry State
 | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return savedCacheKey; | ||||||
|  |         }) | ||||||
|  |         // Cache Key State
 | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return primaryKey; | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |     const inputPath = "node_modules"; | ||||||
|  |     testUtils.setInput(Inputs.Path, inputPath); | ||||||
|  | 
 | ||||||
|  |     const saveCacheMock = jest | ||||||
|  |         .spyOn(cache, "saveCache") | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             throw new Error("HTTP Error Occurred"); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(saveCacheMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(saveCacheMock).toHaveBeenCalledWith( | ||||||
|  |         [inputPath], | ||||||
|  |         primaryKey, | ||||||
|  |         expect.anything() | ||||||
|  |     ); | ||||||
|  | 
 | ||||||
|  |     expect(logWarningMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(logWarningMock).toHaveBeenCalledWith("HTTP Error Occurred"); | ||||||
|  | 
 | ||||||
|  |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
|  | }); | ||||||
|  | 
 | ||||||
|  | test("save with valid inputs uploads a cache", async () => { | ||||||
|  |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
|  | 
 | ||||||
|  |     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; | ||||||
|  |     const savedCacheKey = "Linux-node-"; | ||||||
|  | 
 | ||||||
|  |     jest.spyOn(core, "getState") | ||||||
|  |         // Cache Entry State
 | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return savedCacheKey; | ||||||
|  |         }) | ||||||
|  |         // Cache Key State
 | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return primaryKey; | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |     const inputPath = "node_modules"; | ||||||
|  |     testUtils.setInput(Inputs.Path, inputPath); | ||||||
|  |     testUtils.setInput(Inputs.UploadChunkSize, "4000000"); | ||||||
|  | 
 | ||||||
|  |     const cacheId = 4; | ||||||
|  |     const saveCacheMock = jest | ||||||
|  |         .spyOn(cache, "saveCache") | ||||||
|  |         .mockImplementationOnce(() => { | ||||||
|  |             return Promise.resolve(cacheId); | ||||||
|  |         }); | ||||||
|  | 
 | ||||||
|  |     await run(new StateProvider()); | ||||||
|  | 
 | ||||||
|  |     expect(saveCacheMock).toHaveBeenCalledTimes(1); | ||||||
|  |     expect(saveCacheMock).toHaveBeenCalledWith([inputPath], primaryKey, { | ||||||
|  |         uploadChunkSize: 4000000 | ||||||
|  |     }); | ||||||
|  | 
 | ||||||
|  |     expect(failedMock).toHaveBeenCalledTimes(0); | ||||||
|  | }); | ||||||
| @ -2,7 +2,7 @@ import * as cache from "@actions/cache"; | |||||||
| import * as core from "@actions/core"; | import * as core from "@actions/core"; | ||||||
| 
 | 
 | ||||||
| import { Events, Inputs, RefKey } from "../src/constants"; | import { Events, Inputs, RefKey } from "../src/constants"; | ||||||
| import run from "../src/save"; | import run from "../src/saveOnly"; | ||||||
| import * as actionUtils from "../src/utils/actionUtils"; | import * as actionUtils from "../src/utils/actionUtils"; | ||||||
| import * as testUtils from "../src/utils/testUtils"; | import * as testUtils from "../src/utils/testUtils"; | ||||||
| 
 | 
 | ||||||
| @ -61,311 +61,13 @@ afterEach(() => { | |||||||
|     delete process.env[RefKey]; |     delete process.env[RefKey]; | ||||||
| }); | }); | ||||||
| 
 | 
 | ||||||
| test("save with invalid event outputs warning", async () => { |  | ||||||
|     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
|     const invalidEvent = "commit_comment"; |  | ||||||
|     process.env[Events.Key] = invalidEvent; |  | ||||||
|     delete process.env[RefKey]; |  | ||||||
|     await run(); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledWith( |  | ||||||
|         `Event Validation Error: The event type ${invalidEvent} is not supported because it's not tied to a branch or tag ref.` |  | ||||||
|     ); |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save with no primary key in state outputs warning", async () => { |  | ||||||
|     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
| 
 |  | ||||||
|     const savedCacheKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; |  | ||||||
|     jest.spyOn(core, "getState") |  | ||||||
|         // Cache Entry State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return ""; |  | ||||||
|         }) |  | ||||||
|         // Cache Key State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return savedCacheKey; |  | ||||||
|         }); |  | ||||||
|     const saveCacheMock = jest.spyOn(cache, "saveCache"); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledWith( |  | ||||||
|         `Error retrieving key from state.` |  | ||||||
|     ); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save without AC available should no-op", async () => { |  | ||||||
|     jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation( |  | ||||||
|         () => false |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     const saveCacheMock = jest.spyOn(cache, "saveCache"); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save on ghes without AC available should no-op", async () => { |  | ||||||
|     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true); |  | ||||||
|     jest.spyOn(actionUtils, "isCacheFeatureAvailable").mockImplementation( |  | ||||||
|         () => false |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     const saveCacheMock = jest.spyOn(cache, "saveCache"); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save on GHES with AC available", async () => { |  | ||||||
|     jest.spyOn(actionUtils, "isGhes").mockImplementation(() => true); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
| 
 |  | ||||||
|     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; |  | ||||||
|     const savedCacheKey = "Linux-node-"; |  | ||||||
| 
 |  | ||||||
|     jest.spyOn(core, "getState") |  | ||||||
|         // Cache Entry State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return savedCacheKey; |  | ||||||
|         }) |  | ||||||
|         // Cache Key State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return primaryKey; |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     const inputPath = "node_modules"; |  | ||||||
|     testUtils.setInput(Inputs.Path, inputPath); |  | ||||||
|     testUtils.setInput(Inputs.UploadChunkSize, "4000000"); |  | ||||||
| 
 |  | ||||||
|     const cacheId = 4; |  | ||||||
|     const saveCacheMock = jest |  | ||||||
|         .spyOn(cache, "saveCache") |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return Promise.resolve(cacheId); |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledWith([inputPath], primaryKey, { |  | ||||||
|         uploadChunkSize: 4000000 |  | ||||||
|     }); |  | ||||||
| 
 |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save with exact match returns early", async () => { |  | ||||||
|     const infoMock = jest.spyOn(core, "info"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
| 
 |  | ||||||
|     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; |  | ||||||
|     const savedCacheKey = primaryKey; |  | ||||||
| 
 |  | ||||||
|     jest.spyOn(core, "getState") |  | ||||||
|         // Cache Entry State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return savedCacheKey; |  | ||||||
|         }) |  | ||||||
|         // Cache Key State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return primaryKey; |  | ||||||
|         }); |  | ||||||
|     const saveCacheMock = jest.spyOn(cache, "saveCache"); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
|     expect(infoMock).toHaveBeenCalledWith( |  | ||||||
|         `Cache hit occurred on the primary key ${primaryKey}, not saving cache.` |  | ||||||
|     ); |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save with missing input outputs warning", async () => { |  | ||||||
|     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
| 
 |  | ||||||
|     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; |  | ||||||
|     const savedCacheKey = "Linux-node-"; |  | ||||||
| 
 |  | ||||||
|     jest.spyOn(core, "getState") |  | ||||||
|         // Cache Entry State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return savedCacheKey; |  | ||||||
|         }) |  | ||||||
|         // Cache Key State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return primaryKey; |  | ||||||
|         }); |  | ||||||
|     const saveCacheMock = jest.spyOn(cache, "saveCache"); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(0); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledWith( |  | ||||||
|         "Input required and not supplied: path" |  | ||||||
|     ); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save with large cache outputs warning", async () => { |  | ||||||
|     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
| 
 |  | ||||||
|     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; |  | ||||||
|     const savedCacheKey = "Linux-node-"; |  | ||||||
| 
 |  | ||||||
|     jest.spyOn(core, "getState") |  | ||||||
|         // Cache Entry State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return savedCacheKey; |  | ||||||
|         }) |  | ||||||
|         // Cache Key State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return primaryKey; |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     const inputPath = "node_modules"; |  | ||||||
|     testUtils.setInput(Inputs.Path, inputPath); |  | ||||||
| 
 |  | ||||||
|     const saveCacheMock = jest |  | ||||||
|         .spyOn(cache, "saveCache") |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             throw new Error( |  | ||||||
|                 "Cache size of ~6144 MB (6442450944 B) is over the 5GB limit, not saving cache." |  | ||||||
|             ); |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledWith( |  | ||||||
|         [inputPath], |  | ||||||
|         primaryKey, |  | ||||||
|         expect.anything() |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledWith( |  | ||||||
|         "Cache size of ~6144 MB (6442450944 B) is over the 5GB limit, not saving cache." |  | ||||||
|     ); |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save with reserve cache failure outputs warning", async () => { |  | ||||||
|     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
| 
 |  | ||||||
|     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; |  | ||||||
|     const savedCacheKey = "Linux-node-"; |  | ||||||
| 
 |  | ||||||
|     jest.spyOn(core, "getState") |  | ||||||
|         // Cache Entry State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return savedCacheKey; |  | ||||||
|         }) |  | ||||||
|         // Cache Key State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return primaryKey; |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     const inputPath = "node_modules"; |  | ||||||
|     testUtils.setInput(Inputs.Path, inputPath); |  | ||||||
| 
 |  | ||||||
|     const saveCacheMock = jest |  | ||||||
|         .spyOn(cache, "saveCache") |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             const actualCache = jest.requireActual("@actions/cache"); |  | ||||||
|             const error = new actualCache.ReserveCacheError( |  | ||||||
|                 `Unable to reserve cache with key ${primaryKey}, another job may be creating this cache.` |  | ||||||
|             ); |  | ||||||
|             throw error; |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledWith( |  | ||||||
|         [inputPath], |  | ||||||
|         primaryKey, |  | ||||||
|         expect.anything() |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledWith( |  | ||||||
|         `Unable to reserve cache with key ${primaryKey}, another job may be creating this cache.` |  | ||||||
|     ); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save with server error outputs warning", async () => { |  | ||||||
|     const logWarningMock = jest.spyOn(actionUtils, "logWarning"); |  | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |  | ||||||
| 
 |  | ||||||
|     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; |  | ||||||
|     const savedCacheKey = "Linux-node-"; |  | ||||||
| 
 |  | ||||||
|     jest.spyOn(core, "getState") |  | ||||||
|         // Cache Entry State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return savedCacheKey; |  | ||||||
|         }) |  | ||||||
|         // Cache Key State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return primaryKey; |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     const inputPath = "node_modules"; |  | ||||||
|     testUtils.setInput(Inputs.Path, inputPath); |  | ||||||
| 
 |  | ||||||
|     const saveCacheMock = jest |  | ||||||
|         .spyOn(cache, "saveCache") |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             throw new Error("HTTP Error Occurred"); |  | ||||||
|         }); |  | ||||||
| 
 |  | ||||||
|     await run(); |  | ||||||
| 
 |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(saveCacheMock).toHaveBeenCalledWith( |  | ||||||
|         [inputPath], |  | ||||||
|         primaryKey, |  | ||||||
|         expect.anything() |  | ||||||
|     ); |  | ||||||
| 
 |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledTimes(1); |  | ||||||
|     expect(logWarningMock).toHaveBeenCalledWith("HTTP Error Occurred"); |  | ||||||
| 
 |  | ||||||
|     expect(failedMock).toHaveBeenCalledTimes(0); |  | ||||||
| }); |  | ||||||
| 
 |  | ||||||
| test("save with valid inputs uploads a cache", async () => { | test("save with valid inputs uploads a cache", async () => { | ||||||
|     const failedMock = jest.spyOn(core, "setFailed"); |     const failedMock = jest.spyOn(core, "setFailed"); | ||||||
| 
 | 
 | ||||||
|     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; |     const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43"; | ||||||
|     const savedCacheKey = "Linux-node-"; |  | ||||||
| 
 |  | ||||||
|     jest.spyOn(core, "getState") |  | ||||||
|         // Cache Entry State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return savedCacheKey; |  | ||||||
|         }) |  | ||||||
|         // Cache Key State
 |  | ||||||
|         .mockImplementationOnce(() => { |  | ||||||
|             return primaryKey; |  | ||||||
|         }); |  | ||||||
| 
 | 
 | ||||||
|     const inputPath = "node_modules"; |     const inputPath = "node_modules"; | ||||||
|  |     testUtils.setInput(Inputs.Key, primaryKey); | ||||||
|     testUtils.setInput(Inputs.Path, inputPath); |     testUtils.setInput(Inputs.Path, inputPath); | ||||||
|     testUtils.setInput(Inputs.UploadChunkSize, "4000000"); |     testUtils.setInput(Inputs.UploadChunkSize, "4000000"); | ||||||
| 
 | 
 | ||||||
|  | |||||||
							
								
								
									
										25
									
								
								dist/restore-only/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								dist/restore-only/index.js
									
									
									
									
										vendored
									
									
								
							| @ -4943,20 +4943,19 @@ exports.checkBypass = checkBypass; | |||||||
| "use strict"; | "use strict"; | ||||||
| 
 | 
 | ||||||
| Object.defineProperty(exports, "__esModule", { value: true }); | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
| exports.RefKey = exports.Events = exports.State = exports.Outputs = exports.Inputs = void 0; | exports.stateToOutputMap = exports.RefKey = exports.Events = exports.State = exports.Outputs = exports.Inputs = void 0; | ||||||
| var Inputs; | var Inputs; | ||||||
| (function (Inputs) { | (function (Inputs) { | ||||||
|     Inputs["Key"] = "key"; |     Inputs["Key"] = "key"; | ||||||
|     Inputs["Path"] = "path"; |     Inputs["Path"] = "path"; | ||||||
|     Inputs["RestoreKeys"] = "restore-keys"; |     Inputs["RestoreKeys"] = "restore-keys"; | ||||||
|     Inputs["UploadChunkSize"] = "upload-chunk-size"; |     Inputs["UploadChunkSize"] = "upload-chunk-size"; // Input for cache, save action
 | ||||||
|     Inputs["RestoredKey"] = "restored-key"; // Input from save action
 |  | ||||||
| })(Inputs = exports.Inputs || (exports.Inputs = {})); | })(Inputs = exports.Inputs || (exports.Inputs = {})); | ||||||
| var Outputs; | var Outputs; | ||||||
| (function (Outputs) { | (function (Outputs) { | ||||||
|     Outputs["CacheHit"] = "cache-hit"; |     Outputs["CacheHit"] = "cache-hit"; | ||||||
|     Outputs["InputtedKey"] = "inputted-key"; |     Outputs["CachePrimaryKey"] = "cache-primary-key"; | ||||||
|     Outputs["MatchedKey"] = "matched-key"; // Output from restore action
 |     Outputs["CacheRestoreKey"] = "cache-restore-key"; // Output from restore action
 | ||||||
| })(Outputs = exports.Outputs || (exports.Outputs = {})); | })(Outputs = exports.Outputs || (exports.Outputs = {})); | ||||||
| var State; | var State; | ||||||
| (function (State) { | (function (State) { | ||||||
| @ -4970,6 +4969,10 @@ var Events; | |||||||
|     Events["PullRequest"] = "pull_request"; |     Events["PullRequest"] = "pull_request"; | ||||||
| })(Events = exports.Events || (exports.Events = {})); | })(Events = exports.Events || (exports.Events = {})); | ||||||
| exports.RefKey = "GITHUB_REF"; | exports.RefKey = "GITHUB_REF"; | ||||||
|  | exports.stateToOutputMap = new Map([ | ||||||
|  |     [State.CacheMatchedKey, Outputs.CacheRestoreKey], | ||||||
|  |     [State.CachePrimaryKey, Outputs.CachePrimaryKey] | ||||||
|  | ]); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /***/ }), | /***/ }), | ||||||
| @ -9361,7 +9364,7 @@ const constants_1 = __webpack_require__(196); | |||||||
| class StateProviderBase { | class StateProviderBase { | ||||||
|     constructor() { |     constructor() { | ||||||
|         // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
 |         // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
 | ||||||
|         this.setState = (key, value, outputKey) => { }; |         this.setState = (key, value) => { }; | ||||||
|         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 |         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||||
|         this.getState = (key) => ""; |         this.getState = (key) => ""; | ||||||
|     } |     } | ||||||
| @ -9385,10 +9388,8 @@ exports.StateProvider = StateProvider; | |||||||
| class NullStateProvider extends StateProviderBase { | class NullStateProvider extends StateProviderBase { | ||||||
|     constructor() { |     constructor() { | ||||||
|         super(...arguments); |         super(...arguments); | ||||||
|         this.setState = (key, value, outputKey) => { |         this.setState = (key, value) => { | ||||||
|             if (outputKey) { |             core.setOutput(constants_1.stateToOutputMap.get(key), value); | ||||||
|                 core.setOutput(outputKey, value); |  | ||||||
|             } |  | ||||||
|         }; |         }; | ||||||
|         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 |         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||||
|         this.getState = (key) => ""; |         this.getState = (key) => ""; | ||||||
| @ -50467,7 +50468,7 @@ function restoreImpl(stateProvider) { | |||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             const primaryKey = core.getInput(constants_1.Inputs.Key, { required: true }); |             const primaryKey = core.getInput(constants_1.Inputs.Key, { required: true }); | ||||||
|             stateProvider.setState(constants_1.State.CachePrimaryKey, primaryKey, constants_1.Outputs.InputtedKey); |             stateProvider.setState(constants_1.State.CachePrimaryKey, primaryKey); | ||||||
|             const restoreKeys = utils.getInputAsArray(constants_1.Inputs.RestoreKeys); |             const restoreKeys = utils.getInputAsArray(constants_1.Inputs.RestoreKeys); | ||||||
|             const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, { |             const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, { | ||||||
|                 required: true |                 required: true | ||||||
| @ -50481,7 +50482,7 @@ function restoreImpl(stateProvider) { | |||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             // Store the matched cache key in states
 |             // Store the matched cache key in states
 | ||||||
|             stateProvider.setState(constants_1.State.CacheMatchedKey, cacheKey, constants_1.Outputs.MatchedKey); |             stateProvider.setState(constants_1.State.CacheMatchedKey, cacheKey); | ||||||
|             const isExactKeyMatch = utils.isExactKeyMatch(core.getInput(constants_1.Inputs.Key, { required: true }), cacheKey); |             const isExactKeyMatch = utils.isExactKeyMatch(core.getInput(constants_1.Inputs.Key, { required: true }), cacheKey); | ||||||
|             core.setOutput(constants_1.Outputs.CacheHit, isExactKeyMatch.toString()); |             core.setOutput(constants_1.Outputs.CacheHit, isExactKeyMatch.toString()); | ||||||
|             core.info(`Cache restored from key: ${cacheKey}`); |             core.info(`Cache restored from key: ${cacheKey}`); | ||||||
|  | |||||||
							
								
								
									
										25
									
								
								dist/restore/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										25
									
								
								dist/restore/index.js
									
									
									
									
										vendored
									
									
								
							| @ -4943,20 +4943,19 @@ exports.checkBypass = checkBypass; | |||||||
| "use strict"; | "use strict"; | ||||||
| 
 | 
 | ||||||
| Object.defineProperty(exports, "__esModule", { value: true }); | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
| exports.RefKey = exports.Events = exports.State = exports.Outputs = exports.Inputs = void 0; | exports.stateToOutputMap = exports.RefKey = exports.Events = exports.State = exports.Outputs = exports.Inputs = void 0; | ||||||
| var Inputs; | var Inputs; | ||||||
| (function (Inputs) { | (function (Inputs) { | ||||||
|     Inputs["Key"] = "key"; |     Inputs["Key"] = "key"; | ||||||
|     Inputs["Path"] = "path"; |     Inputs["Path"] = "path"; | ||||||
|     Inputs["RestoreKeys"] = "restore-keys"; |     Inputs["RestoreKeys"] = "restore-keys"; | ||||||
|     Inputs["UploadChunkSize"] = "upload-chunk-size"; |     Inputs["UploadChunkSize"] = "upload-chunk-size"; // Input for cache, save action
 | ||||||
|     Inputs["RestoredKey"] = "restored-key"; // Input from save action
 |  | ||||||
| })(Inputs = exports.Inputs || (exports.Inputs = {})); | })(Inputs = exports.Inputs || (exports.Inputs = {})); | ||||||
| var Outputs; | var Outputs; | ||||||
| (function (Outputs) { | (function (Outputs) { | ||||||
|     Outputs["CacheHit"] = "cache-hit"; |     Outputs["CacheHit"] = "cache-hit"; | ||||||
|     Outputs["InputtedKey"] = "inputted-key"; |     Outputs["CachePrimaryKey"] = "cache-primary-key"; | ||||||
|     Outputs["MatchedKey"] = "matched-key"; // Output from restore action
 |     Outputs["CacheRestoreKey"] = "cache-restore-key"; // Output from restore action
 | ||||||
| })(Outputs = exports.Outputs || (exports.Outputs = {})); | })(Outputs = exports.Outputs || (exports.Outputs = {})); | ||||||
| var State; | var State; | ||||||
| (function (State) { | (function (State) { | ||||||
| @ -4970,6 +4969,10 @@ var Events; | |||||||
|     Events["PullRequest"] = "pull_request"; |     Events["PullRequest"] = "pull_request"; | ||||||
| })(Events = exports.Events || (exports.Events = {})); | })(Events = exports.Events || (exports.Events = {})); | ||||||
| exports.RefKey = "GITHUB_REF"; | exports.RefKey = "GITHUB_REF"; | ||||||
|  | exports.stateToOutputMap = new Map([ | ||||||
|  |     [State.CacheMatchedKey, Outputs.CacheRestoreKey], | ||||||
|  |     [State.CachePrimaryKey, Outputs.CachePrimaryKey] | ||||||
|  | ]); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /***/ }), | /***/ }), | ||||||
| @ -9361,7 +9364,7 @@ const constants_1 = __webpack_require__(196); | |||||||
| class StateProviderBase { | class StateProviderBase { | ||||||
|     constructor() { |     constructor() { | ||||||
|         // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
 |         // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
 | ||||||
|         this.setState = (key, value, outputKey) => { }; |         this.setState = (key, value) => { }; | ||||||
|         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 |         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||||
|         this.getState = (key) => ""; |         this.getState = (key) => ""; | ||||||
|     } |     } | ||||||
| @ -9385,10 +9388,8 @@ exports.StateProvider = StateProvider; | |||||||
| class NullStateProvider extends StateProviderBase { | class NullStateProvider extends StateProviderBase { | ||||||
|     constructor() { |     constructor() { | ||||||
|         super(...arguments); |         super(...arguments); | ||||||
|         this.setState = (key, value, outputKey) => { |         this.setState = (key, value) => { | ||||||
|             if (outputKey) { |             core.setOutput(constants_1.stateToOutputMap.get(key), value); | ||||||
|                 core.setOutput(outputKey, value); |  | ||||||
|             } |  | ||||||
|         }; |         }; | ||||||
|         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 |         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||||
|         this.getState = (key) => ""; |         this.getState = (key) => ""; | ||||||
| @ -50467,7 +50468,7 @@ function restoreImpl(stateProvider) { | |||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             const primaryKey = core.getInput(constants_1.Inputs.Key, { required: true }); |             const primaryKey = core.getInput(constants_1.Inputs.Key, { required: true }); | ||||||
|             stateProvider.setState(constants_1.State.CachePrimaryKey, primaryKey, constants_1.Outputs.InputtedKey); |             stateProvider.setState(constants_1.State.CachePrimaryKey, primaryKey); | ||||||
|             const restoreKeys = utils.getInputAsArray(constants_1.Inputs.RestoreKeys); |             const restoreKeys = utils.getInputAsArray(constants_1.Inputs.RestoreKeys); | ||||||
|             const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, { |             const cachePaths = utils.getInputAsArray(constants_1.Inputs.Path, { | ||||||
|                 required: true |                 required: true | ||||||
| @ -50481,7 +50482,7 @@ function restoreImpl(stateProvider) { | |||||||
|                 return; |                 return; | ||||||
|             } |             } | ||||||
|             // Store the matched cache key in states
 |             // Store the matched cache key in states
 | ||||||
|             stateProvider.setState(constants_1.State.CacheMatchedKey, cacheKey, constants_1.Outputs.MatchedKey); |             stateProvider.setState(constants_1.State.CacheMatchedKey, cacheKey); | ||||||
|             const isExactKeyMatch = utils.isExactKeyMatch(core.getInput(constants_1.Inputs.Key, { required: true }), cacheKey); |             const isExactKeyMatch = utils.isExactKeyMatch(core.getInput(constants_1.Inputs.Key, { required: true }), cacheKey); | ||||||
|             core.setOutput(constants_1.Outputs.CacheHit, isExactKeyMatch.toString()); |             core.setOutput(constants_1.Outputs.CacheHit, isExactKeyMatch.toString()); | ||||||
|             core.info(`Cache restored from key: ${cacheKey}`); |             core.info(`Cache restored from key: ${cacheKey}`); | ||||||
|  | |||||||
							
								
								
									
										23
									
								
								dist/save-only/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								dist/save-only/index.js
									
									
									
									
										vendored
									
									
								
							| @ -4972,20 +4972,19 @@ exports.checkBypass = checkBypass; | |||||||
| "use strict"; | "use strict"; | ||||||
| 
 | 
 | ||||||
| Object.defineProperty(exports, "__esModule", { value: true }); | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
| exports.RefKey = exports.Events = exports.State = exports.Outputs = exports.Inputs = void 0; | exports.stateToOutputMap = exports.RefKey = exports.Events = exports.State = exports.Outputs = exports.Inputs = void 0; | ||||||
| var Inputs; | var Inputs; | ||||||
| (function (Inputs) { | (function (Inputs) { | ||||||
|     Inputs["Key"] = "key"; |     Inputs["Key"] = "key"; | ||||||
|     Inputs["Path"] = "path"; |     Inputs["Path"] = "path"; | ||||||
|     Inputs["RestoreKeys"] = "restore-keys"; |     Inputs["RestoreKeys"] = "restore-keys"; | ||||||
|     Inputs["UploadChunkSize"] = "upload-chunk-size"; |     Inputs["UploadChunkSize"] = "upload-chunk-size"; // Input for cache, save action
 | ||||||
|     Inputs["RestoredKey"] = "restored-key"; // Input from save action
 |  | ||||||
| })(Inputs = exports.Inputs || (exports.Inputs = {})); | })(Inputs = exports.Inputs || (exports.Inputs = {})); | ||||||
| var Outputs; | var Outputs; | ||||||
| (function (Outputs) { | (function (Outputs) { | ||||||
|     Outputs["CacheHit"] = "cache-hit"; |     Outputs["CacheHit"] = "cache-hit"; | ||||||
|     Outputs["InputtedKey"] = "inputted-key"; |     Outputs["CachePrimaryKey"] = "cache-primary-key"; | ||||||
|     Outputs["MatchedKey"] = "matched-key"; // Output from restore action
 |     Outputs["CacheRestoreKey"] = "cache-restore-key"; // Output from restore action
 | ||||||
| })(Outputs = exports.Outputs || (exports.Outputs = {})); | })(Outputs = exports.Outputs || (exports.Outputs = {})); | ||||||
| var State; | var State; | ||||||
| (function (State) { | (function (State) { | ||||||
| @ -4999,6 +4998,10 @@ var Events; | |||||||
|     Events["PullRequest"] = "pull_request"; |     Events["PullRequest"] = "pull_request"; | ||||||
| })(Events = exports.Events || (exports.Events = {})); | })(Events = exports.Events || (exports.Events = {})); | ||||||
| exports.RefKey = "GITHUB_REF"; | exports.RefKey = "GITHUB_REF"; | ||||||
|  | exports.stateToOutputMap = new Map([ | ||||||
|  |     [State.CacheMatchedKey, Outputs.CacheRestoreKey], | ||||||
|  |     [State.CachePrimaryKey, Outputs.CachePrimaryKey] | ||||||
|  | ]); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /***/ }), | /***/ }), | ||||||
| @ -9390,7 +9393,7 @@ const constants_1 = __webpack_require__(196); | |||||||
| class StateProviderBase { | class StateProviderBase { | ||||||
|     constructor() { |     constructor() { | ||||||
|         // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
 |         // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
 | ||||||
|         this.setState = (key, value, outputKey) => { }; |         this.setState = (key, value) => { }; | ||||||
|         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 |         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||||
|         this.getState = (key) => ""; |         this.getState = (key) => ""; | ||||||
|     } |     } | ||||||
| @ -9414,10 +9417,8 @@ exports.StateProvider = StateProvider; | |||||||
| class NullStateProvider extends StateProviderBase { | class NullStateProvider extends StateProviderBase { | ||||||
|     constructor() { |     constructor() { | ||||||
|         super(...arguments); |         super(...arguments); | ||||||
|         this.setState = (key, value, outputKey) => { |         this.setState = (key, value) => { | ||||||
|             if (outputKey) { |             core.setOutput(constants_1.stateToOutputMap.get(key), value); | ||||||
|                 core.setOutput(outputKey, value); |  | ||||||
|             } |  | ||||||
|         }; |         }; | ||||||
|         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 |         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||||
|         this.getState = (key) => ""; |         this.getState = (key) => ""; | ||||||
| @ -41111,7 +41112,7 @@ function saveImpl(stateProvider) { | |||||||
|             } |             } | ||||||
|             // If matched restore key is same as primary key, then do not save cache
 |             // If matched restore key is same as primary key, then do not save cache
 | ||||||
|             // NO-OP in case of SaveOnly action
 |             // NO-OP in case of SaveOnly action
 | ||||||
|             const restoredKey = stateProvider.getCacheState() || core.getInput(constants_1.Inputs.RestoredKey); |             const restoredKey = stateProvider.getCacheState(); | ||||||
|             if (utils.isExactKeyMatch(primaryKey, restoredKey)) { |             if (utils.isExactKeyMatch(primaryKey, restoredKey)) { | ||||||
|                 core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`); |                 core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`); | ||||||
|                 return; |                 return; | ||||||
|  | |||||||
							
								
								
									
										23
									
								
								dist/save/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										23
									
								
								dist/save/index.js
									
									
									
									
										vendored
									
									
								
							| @ -4943,20 +4943,19 @@ exports.checkBypass = checkBypass; | |||||||
| "use strict"; | "use strict"; | ||||||
| 
 | 
 | ||||||
| Object.defineProperty(exports, "__esModule", { value: true }); | Object.defineProperty(exports, "__esModule", { value: true }); | ||||||
| exports.RefKey = exports.Events = exports.State = exports.Outputs = exports.Inputs = void 0; | exports.stateToOutputMap = exports.RefKey = exports.Events = exports.State = exports.Outputs = exports.Inputs = void 0; | ||||||
| var Inputs; | var Inputs; | ||||||
| (function (Inputs) { | (function (Inputs) { | ||||||
|     Inputs["Key"] = "key"; |     Inputs["Key"] = "key"; | ||||||
|     Inputs["Path"] = "path"; |     Inputs["Path"] = "path"; | ||||||
|     Inputs["RestoreKeys"] = "restore-keys"; |     Inputs["RestoreKeys"] = "restore-keys"; | ||||||
|     Inputs["UploadChunkSize"] = "upload-chunk-size"; |     Inputs["UploadChunkSize"] = "upload-chunk-size"; // Input for cache, save action
 | ||||||
|     Inputs["RestoredKey"] = "restored-key"; // Input from save action
 |  | ||||||
| })(Inputs = exports.Inputs || (exports.Inputs = {})); | })(Inputs = exports.Inputs || (exports.Inputs = {})); | ||||||
| var Outputs; | var Outputs; | ||||||
| (function (Outputs) { | (function (Outputs) { | ||||||
|     Outputs["CacheHit"] = "cache-hit"; |     Outputs["CacheHit"] = "cache-hit"; | ||||||
|     Outputs["InputtedKey"] = "inputted-key"; |     Outputs["CachePrimaryKey"] = "cache-primary-key"; | ||||||
|     Outputs["MatchedKey"] = "matched-key"; // Output from restore action
 |     Outputs["CacheRestoreKey"] = "cache-restore-key"; // Output from restore action
 | ||||||
| })(Outputs = exports.Outputs || (exports.Outputs = {})); | })(Outputs = exports.Outputs || (exports.Outputs = {})); | ||||||
| var State; | var State; | ||||||
| (function (State) { | (function (State) { | ||||||
| @ -4970,6 +4969,10 @@ var Events; | |||||||
|     Events["PullRequest"] = "pull_request"; |     Events["PullRequest"] = "pull_request"; | ||||||
| })(Events = exports.Events || (exports.Events = {})); | })(Events = exports.Events || (exports.Events = {})); | ||||||
| exports.RefKey = "GITHUB_REF"; | exports.RefKey = "GITHUB_REF"; | ||||||
|  | exports.stateToOutputMap = new Map([ | ||||||
|  |     [State.CacheMatchedKey, Outputs.CacheRestoreKey], | ||||||
|  |     [State.CachePrimaryKey, Outputs.CachePrimaryKey] | ||||||
|  | ]); | ||||||
| 
 | 
 | ||||||
| 
 | 
 | ||||||
| /***/ }), | /***/ }), | ||||||
| @ -9361,7 +9364,7 @@ const constants_1 = __webpack_require__(196); | |||||||
| class StateProviderBase { | class StateProviderBase { | ||||||
|     constructor() { |     constructor() { | ||||||
|         // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
 |         // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
 | ||||||
|         this.setState = (key, value, outputKey) => { }; |         this.setState = (key, value) => { }; | ||||||
|         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 |         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||||
|         this.getState = (key) => ""; |         this.getState = (key) => ""; | ||||||
|     } |     } | ||||||
| @ -9385,10 +9388,8 @@ exports.StateProvider = StateProvider; | |||||||
| class NullStateProvider extends StateProviderBase { | class NullStateProvider extends StateProviderBase { | ||||||
|     constructor() { |     constructor() { | ||||||
|         super(...arguments); |         super(...arguments); | ||||||
|         this.setState = (key, value, outputKey) => { |         this.setState = (key, value) => { | ||||||
|             if (outputKey) { |             core.setOutput(constants_1.stateToOutputMap.get(key), value); | ||||||
|                 core.setOutput(outputKey, value); |  | ||||||
|             } |  | ||||||
|         }; |         }; | ||||||
|         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 |         // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||||
|         this.getState = (key) => ""; |         this.getState = (key) => ""; | ||||||
| @ -41082,7 +41083,7 @@ function saveImpl(stateProvider) { | |||||||
|             } |             } | ||||||
|             // If matched restore key is same as primary key, then do not save cache
 |             // If matched restore key is same as primary key, then do not save cache
 | ||||||
|             // NO-OP in case of SaveOnly action
 |             // NO-OP in case of SaveOnly action
 | ||||||
|             const restoredKey = stateProvider.getCacheState() || core.getInput(constants_1.Inputs.RestoredKey); |             const restoredKey = stateProvider.getCacheState(); | ||||||
|             if (utils.isExactKeyMatch(primaryKey, restoredKey)) { |             if (utils.isExactKeyMatch(primaryKey, restoredKey)) { | ||||||
|                 core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`); |                 core.info(`Cache hit occurred on the primary key ${primaryKey}, not saving cache.`); | ||||||
|                 return; |                 return; | ||||||
|  | |||||||
| @ -14,9 +14,9 @@ inputs: | |||||||
| outputs: | outputs: | ||||||
|   cache-hit: |   cache-hit: | ||||||
|     description: 'A boolean value to indicate an exact match was found for the primary key' |     description: 'A boolean value to indicate an exact match was found for the primary key' | ||||||
|   inputted-key: |   cache-primary-key: | ||||||
|     description: 'Key passed in the input to use in subsequent steps of the workflow' |     description: 'Cache primary key passed in the input to use in subsequent steps of the workflow' | ||||||
|   matched-key: |   cache-restore-key: | ||||||
|     description: 'Cache key restored' |     description: 'Cache key restored' | ||||||
| runs: | runs: | ||||||
|   using: 'node16' |   using: 'node16' | ||||||
|  | |||||||
| @ -11,9 +11,6 @@ inputs: | |||||||
|   upload-chunk-size: |   upload-chunk-size: | ||||||
|     description: 'The chunk size used to split up large files during upload, in bytes' |     description: 'The chunk size used to split up large files during upload, in bytes' | ||||||
|     required: false |     required: false | ||||||
|   restored-key: |  | ||||||
|     description: 'Cache key restored from the restore action' |  | ||||||
|     required: false |  | ||||||
| runs: | runs: | ||||||
|   using: 'node16' |   using: 'node16' | ||||||
|   main: '../dist/save-only/index.js' |   main: '../dist/save-only/index.js' | ||||||
|  | |||||||
| @ -1,15 +1,14 @@ | |||||||
| export enum Inputs { | export enum Inputs { | ||||||
|     Key = "key", // Input from cache, restore, save action
 |     Key = "key", // Input for cache, restore, save action
 | ||||||
|     Path = "path", // Input from cache, restore, save action
 |     Path = "path", // Input for cache, restore, save action
 | ||||||
|     RestoreKeys = "restore-keys", // Input from cache, restore action
 |     RestoreKeys = "restore-keys", // Input for cache, restore action
 | ||||||
|     UploadChunkSize = "upload-chunk-size", // Input from cache, save action
 |     UploadChunkSize = "upload-chunk-size" // Input for cache, save action
 | ||||||
|     RestoredKey = "restored-key" // Input from save action
 |  | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export enum Outputs { | export enum Outputs { | ||||||
|     CacheHit = "cache-hit", // Output from cache, restore action
 |     CacheHit = "cache-hit", // Output from cache, restore action
 | ||||||
|     InputtedKey = "inputted-key", // Output from restore action
 |     CachePrimaryKey = "cache-primary-key", // Output from restore action
 | ||||||
|     MatchedKey = "matched-key" // Output from restore action
 |     CacheRestoreKey = "cache-restore-key" // Output from restore action
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export enum State { | export enum State { | ||||||
| @ -24,3 +23,8 @@ export enum Events { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export const RefKey = "GITHUB_REF"; | export const RefKey = "GITHUB_REF"; | ||||||
|  | 
 | ||||||
|  | export const stateToOutputMap = new Map<string, string>([ | ||||||
|  |     [State.CacheMatchedKey, Outputs.CacheRestoreKey], | ||||||
|  |     [State.CachePrimaryKey, Outputs.CachePrimaryKey] | ||||||
|  | ]); | ||||||
|  | |||||||
| @ -25,11 +25,7 @@ async function restoreImpl( | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         const primaryKey = core.getInput(Inputs.Key, { required: true }); |         const primaryKey = core.getInput(Inputs.Key, { required: true }); | ||||||
|         stateProvider.setState( |         stateProvider.setState(State.CachePrimaryKey, primaryKey); | ||||||
|             State.CachePrimaryKey, |  | ||||||
|             primaryKey, |  | ||||||
|             Outputs.InputtedKey |  | ||||||
|         ); |  | ||||||
| 
 | 
 | ||||||
|         const restoreKeys = utils.getInputAsArray(Inputs.RestoreKeys); |         const restoreKeys = utils.getInputAsArray(Inputs.RestoreKeys); | ||||||
|         const cachePaths = utils.getInputAsArray(Inputs.Path, { |         const cachePaths = utils.getInputAsArray(Inputs.Path, { | ||||||
| @ -54,11 +50,7 @@ async function restoreImpl( | |||||||
|         } |         } | ||||||
| 
 | 
 | ||||||
|         // Store the matched cache key in states
 |         // Store the matched cache key in states
 | ||||||
|         stateProvider.setState( |         stateProvider.setState(State.CacheMatchedKey, cacheKey); | ||||||
|             State.CacheMatchedKey, |  | ||||||
|             cacheKey, |  | ||||||
|             Outputs.MatchedKey |  | ||||||
|         ); |  | ||||||
| 
 | 
 | ||||||
|         const isExactKeyMatch = utils.isExactKeyMatch( |         const isExactKeyMatch = utils.isExactKeyMatch( | ||||||
|             core.getInput(Inputs.Key, { required: true }), |             core.getInput(Inputs.Key, { required: true }), | ||||||
|  | |||||||
| @ -42,8 +42,7 @@ async function saveImpl(stateProvider: IStateProvider): Promise<void> { | |||||||
| 
 | 
 | ||||||
|         // If matched restore key is same as primary key, then do not save cache
 |         // If matched restore key is same as primary key, then do not save cache
 | ||||||
|         // NO-OP in case of SaveOnly action
 |         // NO-OP in case of SaveOnly action
 | ||||||
|         const restoredKey = |         const restoredKey = stateProvider.getCacheState(); | ||||||
|             stateProvider.getCacheState() || core.getInput(Inputs.RestoredKey); |  | ||||||
| 
 | 
 | ||||||
|         if (utils.isExactKeyMatch(primaryKey, restoredKey)) { |         if (utils.isExactKeyMatch(primaryKey, restoredKey)) { | ||||||
|             core.info( |             core.info( | ||||||
|  | |||||||
| @ -1,9 +1,9 @@ | |||||||
| import * as core from "@actions/core"; | import * as core from "@actions/core"; | ||||||
| 
 | 
 | ||||||
| import { State } from "./constants"; | import { State, stateToOutputMap } from "./constants"; | ||||||
| 
 | 
 | ||||||
| export interface IStateProvider { | export interface IStateProvider { | ||||||
|     setState(key: string, value: string, outputKey?: string): void; |     setState(key: string, value: string): void; | ||||||
|     getState(key: string): string; |     getState(key: string): string; | ||||||
| 
 | 
 | ||||||
|     getCacheState(): string | undefined; |     getCacheState(): string | undefined; | ||||||
| @ -21,7 +21,7 @@ class StateProviderBase implements IStateProvider { | |||||||
|     } |     } | ||||||
| 
 | 
 | ||||||
|     // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
 |     // eslint-disable-next-line @typescript-eslint/no-unused-vars, @typescript-eslint/no-empty-function
 | ||||||
|     setState = (key: string, value: string, outputKey?: string) => {}; |     setState = (key: string, value: string) => {}; | ||||||
| 
 | 
 | ||||||
|     // eslint-disable-next-line @typescript-eslint/no-unused-vars
 |     // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||||
|     getState = (key: string) => ""; |     getState = (key: string) => ""; | ||||||
| @ -33,10 +33,8 @@ export class StateProvider extends StateProviderBase { | |||||||
| } | } | ||||||
| 
 | 
 | ||||||
| export class NullStateProvider extends StateProviderBase { | export class NullStateProvider extends StateProviderBase { | ||||||
|     setState = (key: string, value: string, outputKey?: string) => { |     setState = (key: string, value: string) => { | ||||||
|         if (outputKey) { |         core.setOutput(stateToOutputMap.get(key) as string, value); | ||||||
|             core.setOutput(outputKey, value); |  | ||||||
|         } |  | ||||||
|     }; |     }; | ||||||
|     // eslint-disable-next-line @typescript-eslint/no-unused-vars
 |     // eslint-disable-next-line @typescript-eslint/no-unused-vars
 | ||||||
|     getState = (key: string) => ""; |     getState = (key: string) => ""; | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user
	 Sankalp Kotewar
						Sankalp Kotewar