mirror of
				https://github.com/actions/cache.git
				synced 2025-11-04 13:29:10 +08:00 
			
		
		
		
	Added test cases
This commit is contained in:
		@@ -324,3 +324,113 @@ test("restore with cache found for restore key", async () => {
 | 
				
			|||||||
    );
 | 
					    );
 | 
				
			||||||
    expect(failedMock).toHaveBeenCalledTimes(0);
 | 
					    expect(failedMock).toHaveBeenCalledTimes(0);
 | 
				
			||||||
});
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("restore with enabling save on any failure feature", async () => {
 | 
				
			||||||
 | 
					    const path = "node_modules";
 | 
				
			||||||
 | 
					    const key = "node-test";
 | 
				
			||||||
 | 
					    const restoreKey = "node-";
 | 
				
			||||||
 | 
					    testUtils.setInputs({
 | 
				
			||||||
 | 
					        path: path,
 | 
				
			||||||
 | 
					        key,
 | 
				
			||||||
 | 
					        restoreKeys: [restoreKey],
 | 
				
			||||||
 | 
					        saveOnAnyFailure: "true"
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const debugMock = jest.spyOn(core, "debug");
 | 
				
			||||||
 | 
					    const infoMock = jest.spyOn(core, "info");
 | 
				
			||||||
 | 
					    const failedMock = jest.spyOn(core, "setFailed");
 | 
				
			||||||
 | 
					    const stateMock = jest.spyOn(core, "saveState");
 | 
				
			||||||
 | 
					    const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
 | 
				
			||||||
 | 
					    const restoreCacheMock = jest
 | 
				
			||||||
 | 
					        .spyOn(cache, "restoreCache")
 | 
				
			||||||
 | 
					        .mockImplementationOnce(() => {
 | 
				
			||||||
 | 
					            return Promise.resolve(restoreKey);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(restoreCacheMock).toHaveBeenCalledTimes(1);
 | 
				
			||||||
 | 
					    expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
 | 
				
			||||||
 | 
					    expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
 | 
				
			||||||
 | 
					    expect(setCacheHitOutputMock).toHaveBeenCalledWith(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(debugMock).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					        `Exporting environment variable SAVE_CACHE_ON_ANY_FAILURE`
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(infoMock).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					        `Input Variable SAVE_CACHE_ON_ANY_FAILURE is set to true, the cache will be saved despite of any failure in the build.`
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    expect(failedMock).toHaveBeenCalledTimes(0);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("Fail restore with strict restore enabled when primary key not found", async () => {
 | 
				
			||||||
 | 
					    const path = "node_modules";
 | 
				
			||||||
 | 
					    const key = "node-test";
 | 
				
			||||||
 | 
					    const restoreKey = "node-";
 | 
				
			||||||
 | 
					    testUtils.setInputs({
 | 
				
			||||||
 | 
					        path: path,
 | 
				
			||||||
 | 
					        key,
 | 
				
			||||||
 | 
					        restoreKeys: [restoreKey],
 | 
				
			||||||
 | 
					        strictRestore: "true"
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const failedMock = jest.spyOn(core, "setFailed");
 | 
				
			||||||
 | 
					    const stateMock = jest.spyOn(core, "saveState");
 | 
				
			||||||
 | 
					    const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
 | 
				
			||||||
 | 
					    const restoreCacheMock = jest
 | 
				
			||||||
 | 
					        .spyOn(cache, "restoreCache")
 | 
				
			||||||
 | 
					        .mockImplementationOnce(() => {
 | 
				
			||||||
 | 
					            return Promise.resolve(undefined);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(restoreCacheMock).toHaveBeenCalledTimes(1);
 | 
				
			||||||
 | 
					    expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
 | 
				
			||||||
 | 
					    expect(setCacheHitOutputMock).toHaveBeenCalledTimes(0);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(failedMock).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					        `Cache with the given input key ${key} is not found, hence exiting the workflow as the strict-restore requirement is not met.`
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    expect(failedMock).toHaveBeenCalledTimes(1);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					test("Fail restore with strict restore enabled when primary key doesn't match restored key", async () => {
 | 
				
			||||||
 | 
					    const path = "node_modules";
 | 
				
			||||||
 | 
					    const key = "node-test";
 | 
				
			||||||
 | 
					    const restoreKey = "node-";
 | 
				
			||||||
 | 
					    testUtils.setInputs({
 | 
				
			||||||
 | 
					        path: path,
 | 
				
			||||||
 | 
					        key,
 | 
				
			||||||
 | 
					        restoreKeys: [restoreKey],
 | 
				
			||||||
 | 
					        strictRestore: "true"
 | 
				
			||||||
 | 
					    });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    const failedMock = jest.spyOn(core, "setFailed");
 | 
				
			||||||
 | 
					    const stateMock = jest.spyOn(core, "saveState");
 | 
				
			||||||
 | 
					    const setCacheHitOutputMock = jest.spyOn(actionUtils, "setCacheHitOutput");
 | 
				
			||||||
 | 
					    const restoreCacheMock = jest
 | 
				
			||||||
 | 
					        .spyOn(cache, "restoreCache")
 | 
				
			||||||
 | 
					        .mockImplementationOnce(() => {
 | 
				
			||||||
 | 
					            return Promise.resolve(restoreKey);
 | 
				
			||||||
 | 
					        });
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    await run();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(restoreCacheMock).toHaveBeenCalledTimes(1);
 | 
				
			||||||
 | 
					    expect(restoreCacheMock).toHaveBeenCalledWith([path], key, [restoreKey]);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(stateMock).toHaveBeenCalledWith("CACHE_KEY", key);
 | 
				
			||||||
 | 
					    expect(setCacheHitOutputMock).toHaveBeenCalledTimes(1);
 | 
				
			||||||
 | 
					    expect(setCacheHitOutputMock).toHaveBeenCalledWith(false);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    expect(failedMock).toHaveBeenCalledWith(
 | 
				
			||||||
 | 
					        `Restored cache key doesn't match the given input key ${key}, hence exiting the workflow as the strict-restore requirement is not met.`
 | 
				
			||||||
 | 
					    );
 | 
				
			||||||
 | 
					    expect(failedMock).toHaveBeenCalledTimes(1);
 | 
				
			||||||
 | 
					});
 | 
				
			||||||
 
 | 
				
			|||||||
							
								
								
									
										13
									
								
								dist/restore/index.js
									
									
									
									
										vendored
									
									
								
							
							
						
						
									
										13
									
								
								dist/restore/index.js
									
									
									
									
										vendored
									
									
								
							@@ -49015,14 +49015,14 @@ function run() {
 | 
				
			|||||||
            });
 | 
					            });
 | 
				
			||||||
            const cacheKey = yield cache.restoreCache(cachePaths, primaryKey, restoreKeys);
 | 
					            const cacheKey = yield cache.restoreCache(cachePaths, primaryKey, restoreKeys);
 | 
				
			||||||
            //Check if user wants to save cache despite of failure in any previous job
 | 
					            //Check if user wants to save cache despite of failure in any previous job
 | 
				
			||||||
            const saveCache = core.getInput(constants_1.Inputs.SaveOnAnyFailure);
 | 
					            const saveCache = core.getBooleanInput(constants_1.Inputs.SaveOnAnyFailure);
 | 
				
			||||||
            if (saveCache === "yes") {
 | 
					            if (saveCache == true) {
 | 
				
			||||||
                core.debug(`save cache input variable is set to yes`);
 | 
					                core.debug(`Exporting environment variable ${constants_1.Variables.SaveCacheOnAnyFailure}`);
 | 
				
			||||||
                core.exportVariable(constants_1.Variables.SaveCacheOnAnyFailure, saveCache);
 | 
					                core.exportVariable(constants_1.Variables.SaveCacheOnAnyFailure, saveCache);
 | 
				
			||||||
                core.info(`Input Variable ${constants_1.Variables.SaveCacheOnAnyFailure} is set to yes, the cache will be saved despite of any failure in the build.`);
 | 
					                core.info(`Input Variable ${constants_1.Variables.SaveCacheOnAnyFailure} is set to true, the cache will be saved despite of any failure in the build.`);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            if (!cacheKey) {
 | 
					            if (!cacheKey) {
 | 
				
			||||||
                if (core.getInput(constants_1.Inputs.StrictRestore) == "yes") {
 | 
					                if (core.getBooleanInput(constants_1.Inputs.StrictRestore) == true) {
 | 
				
			||||||
                    throw new Error(`Cache with the given input key ${primaryKey} is not found, hence exiting the workflow as the strict-restore requirement is not met.`);
 | 
					                    throw new Error(`Cache with the given input key ${primaryKey} is not found, hence exiting the workflow as the strict-restore requirement is not met.`);
 | 
				
			||||||
                }
 | 
					                }
 | 
				
			||||||
                core.info(`Cache not found for input keys: ${[
 | 
					                core.info(`Cache not found for input keys: ${[
 | 
				
			||||||
@@ -49035,7 +49035,8 @@ function run() {
 | 
				
			|||||||
            utils.setCacheState(cacheKey);
 | 
					            utils.setCacheState(cacheKey);
 | 
				
			||||||
            const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey);
 | 
					            const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey);
 | 
				
			||||||
            utils.setCacheHitOutput(isExactKeyMatch);
 | 
					            utils.setCacheHitOutput(isExactKeyMatch);
 | 
				
			||||||
            if (!isExactKeyMatch && core.getInput(constants_1.Inputs.StrictRestore) == "yes") {
 | 
					            if (!isExactKeyMatch &&
 | 
				
			||||||
 | 
					                core.getBooleanInput(constants_1.Inputs.StrictRestore) == true) {
 | 
				
			||||||
                throw new Error(`Restored cache key doesn't match the given input key ${primaryKey}, hence exiting the workflow as the strict-restore requirement is not met.`);
 | 
					                throw new Error(`Restored cache key doesn't match the given input key ${primaryKey}, hence exiting the workflow as the strict-restore requirement is not met.`);
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
            core.info(`Cache restored from key: ${cacheKey}`);
 | 
					            core.info(`Cache restored from key: ${cacheKey}`);
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -36,17 +36,19 @@ async function run(): Promise<void> {
 | 
				
			|||||||
        );
 | 
					        );
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        //Check if user wants to save cache despite of failure in any previous job
 | 
					        //Check if user wants to save cache despite of failure in any previous job
 | 
				
			||||||
        const saveCache = core.getInput(Inputs.SaveOnAnyFailure);
 | 
					        const saveCache = core.getBooleanInput(Inputs.SaveOnAnyFailure);
 | 
				
			||||||
        if (saveCache === "yes") {
 | 
					        if (saveCache == true) {
 | 
				
			||||||
            core.debug(`save cache input variable is set to yes`);
 | 
					            core.debug(
 | 
				
			||||||
 | 
					                `Exporting environment variable ${Variables.SaveCacheOnAnyFailure}`
 | 
				
			||||||
 | 
					            );
 | 
				
			||||||
            core.exportVariable(Variables.SaveCacheOnAnyFailure, saveCache);
 | 
					            core.exportVariable(Variables.SaveCacheOnAnyFailure, saveCache);
 | 
				
			||||||
            core.info(
 | 
					            core.info(
 | 
				
			||||||
                `Input Variable ${Variables.SaveCacheOnAnyFailure} is set to yes, the cache will be saved despite of any failure in the build.`
 | 
					                `Input Variable ${Variables.SaveCacheOnAnyFailure} is set to true, the cache will be saved despite of any failure in the build.`
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!cacheKey) {
 | 
					        if (!cacheKey) {
 | 
				
			||||||
            if (core.getInput(Inputs.StrictRestore) == "yes") {
 | 
					            if (core.getBooleanInput(Inputs.StrictRestore) == true) {
 | 
				
			||||||
                throw new Error(
 | 
					                throw new Error(
 | 
				
			||||||
                    `Cache with the given input key ${primaryKey} is not found, hence exiting the workflow as the strict-restore requirement is not met.`
 | 
					                    `Cache with the given input key ${primaryKey} is not found, hence exiting the workflow as the strict-restore requirement is not met.`
 | 
				
			||||||
                );
 | 
					                );
 | 
				
			||||||
@@ -65,7 +67,10 @@ async function run(): Promise<void> {
 | 
				
			|||||||
        const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey);
 | 
					        const isExactKeyMatch = utils.isExactKeyMatch(primaryKey, cacheKey);
 | 
				
			||||||
        utils.setCacheHitOutput(isExactKeyMatch);
 | 
					        utils.setCacheHitOutput(isExactKeyMatch);
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        if (!isExactKeyMatch && core.getInput(Inputs.StrictRestore) == "yes") {
 | 
					        if (
 | 
				
			||||||
 | 
					            !isExactKeyMatch &&
 | 
				
			||||||
 | 
					            core.getBooleanInput(Inputs.StrictRestore) == true
 | 
				
			||||||
 | 
					        ) {
 | 
				
			||||||
            throw new Error(
 | 
					            throw new Error(
 | 
				
			||||||
                `Restored cache key doesn't match the given input key ${primaryKey}, hence exiting the workflow as the strict-restore requirement is not met.`
 | 
					                `Restored cache key doesn't match the given input key ${primaryKey}, hence exiting the workflow as the strict-restore requirement is not met.`
 | 
				
			||||||
            );
 | 
					            );
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -13,18 +13,27 @@ interface CacheInput {
 | 
				
			|||||||
    path: string;
 | 
					    path: string;
 | 
				
			||||||
    key: string;
 | 
					    key: string;
 | 
				
			||||||
    restoreKeys?: string[];
 | 
					    restoreKeys?: string[];
 | 
				
			||||||
 | 
					    strictRestore?: string;
 | 
				
			||||||
 | 
					    saveOnAnyFailure?: string;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function setInputs(input: CacheInput): void {
 | 
					export function setInputs(input: CacheInput): void {
 | 
				
			||||||
    setInput(Inputs.Path, input.path);
 | 
					    setInput(Inputs.Path, input.path);
 | 
				
			||||||
    setInput(Inputs.Key, input.key);
 | 
					    setInput(Inputs.Key, input.key);
 | 
				
			||||||
 | 
					    setInput(Inputs.SaveOnAnyFailure, "false");
 | 
				
			||||||
 | 
					    setInput(Inputs.StrictRestore, "false");
 | 
				
			||||||
    input.restoreKeys &&
 | 
					    input.restoreKeys &&
 | 
				
			||||||
        setInput(Inputs.RestoreKeys, input.restoreKeys.join("\n"));
 | 
					        setInput(Inputs.RestoreKeys, input.restoreKeys.join("\n"));
 | 
				
			||||||
 | 
					    input.strictRestore && setInput(Inputs.StrictRestore, input.strictRestore);
 | 
				
			||||||
 | 
					    input.saveOnAnyFailure &&
 | 
				
			||||||
 | 
					        setInput(Inputs.SaveOnAnyFailure, input.saveOnAnyFailure);
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
export function clearInputs(): void {
 | 
					export function clearInputs(): void {
 | 
				
			||||||
    delete process.env[getInputName(Inputs.Path)];
 | 
					    delete process.env[getInputName(Inputs.Path)];
 | 
				
			||||||
    delete process.env[getInputName(Inputs.Key)];
 | 
					    delete process.env[getInputName(Inputs.Key)];
 | 
				
			||||||
    delete process.env[getInputName(Inputs.RestoreKeys)];
 | 
					    delete process.env[getInputName(Inputs.RestoreKeys)];
 | 
				
			||||||
 | 
					    delete process.env[getInputName(Inputs.StrictRestore)];
 | 
				
			||||||
 | 
					    delete process.env[getInputName(Inputs.SaveOnAnyFailure)];
 | 
				
			||||||
    delete process.env[getInputName(Inputs.UploadChunkSize)];
 | 
					    delete process.env[getInputName(Inputs.UploadChunkSize)];
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user