adding wrapper to save-only and testcases

This commit is contained in:
Tanuj Kumar Mishra 2022-12-01 15:50:23 +00:00
parent a92fb881ae
commit 0685539942
7 changed files with 61622 additions and 77 deletions

165
__tests__/save-only.test.ts Normal file
View file

@ -0,0 +1,165 @@
import * as cache from "@actions/cache";
import * as core from "@actions/core";
import { Events, Inputs, RefKey } from "../src/constants";
import run from "../src/save-only";
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, "getCacheState").mockImplementation(() => {
return jest.requireActual("../src/utils/actionUtils").getCacheState();
});
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 cache when save-only is required", async () => {
const failedMock = jest.spyOn(core, "setFailed");
const primaryKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
const savedCacheKey = "Linux-node-";
jest.spyOn(core, "getInput")
// Cache Entry State
.mockImplementationOnce(() => {
return savedCacheKey;
})
// Cache Key
.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 when save on any failure is true", async () => {
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
const failedMock = jest.spyOn(core, "setFailed");
const savedCacheKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
const primaryKey = "Linux-node-";
const inputPath = "node_modules";
jest.spyOn(core, "getInput")
// Cache Entry State
.mockImplementationOnce(() => {
return savedCacheKey;
})
// Cache Key
.mockImplementationOnce(() => {
return primaryKey;
});
testUtils.setInput(Inputs.Path, inputPath);
testUtils.setInput(Inputs.UploadChunkSize, "4000000");
testUtils.setInput(Inputs.SaveOnAnyFailure, "true");
const cacheId = 4;
const saveCacheMock = jest
.spyOn(cache, "saveCache")
.mockImplementationOnce(() => {
return Promise.resolve(cacheId);
});
await run();
expect(saveCacheMock).toHaveBeenCalledTimes(1);
expect(logWarningMock).toHaveBeenCalledTimes(0);
expect(failedMock).toHaveBeenCalledTimes(0);
});
test("save with no primary key in input 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 savedCacheKey;
})
// Cache Key
.mockImplementationOnce(() => {
return "";
});
const saveCacheMock = jest.spyOn(cache, "saveCache");
await run();
expect(saveCacheMock).toHaveBeenCalledTimes(0);
expect(logWarningMock).toHaveBeenCalledWith(
`Error retrieving key from inputs.`
);
expect(logWarningMock).toHaveBeenCalledTimes(1);
expect(failedMock).toHaveBeenCalledTimes(0);
});

View file

@ -389,73 +389,3 @@ test("save with valid inputs uploads a cache", async () => {
expect(failedMock).toHaveBeenCalledTimes(0); expect(failedMock).toHaveBeenCalledTimes(0);
}); });
test("save with no primary key in state reads key from input", async () => {
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
const failedMock = jest.spyOn(core, "setFailed");
const savedCacheKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
const primaryKey = "Linux-node-";
jest.spyOn(core, "getInput")
// Cache Entry Input
.mockImplementationOnce(() => {
return savedCacheKey;
})
// Cache Key Input
.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(logWarningMock).toHaveBeenCalledTimes(0);
expect(failedMock).toHaveBeenCalledTimes(0);
});
test("save when save on any failure is true", async () => {
const logWarningMock = jest.spyOn(actionUtils, "logWarning");
const failedMock = jest.spyOn(core, "setFailed");
const savedCacheKey = "Linux-node-bb828da54c148048dd17899ba9fda624811cfb43";
const primaryKey = "Linux-node-";
const inputPath = "node_modules";
jest.spyOn(core, "getState")
// Cache Entry State
.mockImplementationOnce(() => {
return savedCacheKey;
})
// Cache Key State
.mockImplementationOnce(() => {
return primaryKey;
});
testUtils.setInput(Inputs.Path, inputPath);
testUtils.setInput(Inputs.UploadChunkSize, "4000000");
testUtils.setInput(Inputs.SaveOnAnyFailure, "true");
const cacheId = 4;
const saveCacheMock = jest
.spyOn(cache, "saveCache")
.mockImplementationOnce(() => {
return Promise.resolve(cacheId);
});
await run();
expect(saveCacheMock).toHaveBeenCalledTimes(1);
expect(logWarningMock).toHaveBeenCalledTimes(0);
expect(failedMock).toHaveBeenCalledTimes(0);
});

61367
dist/save-only/index.js vendored Normal file

File diff suppressed because one or more lines are too long

68
dist/save/index.js vendored
View file

@ -47311,6 +47311,7 @@ Object.defineProperty(exports, "__esModule", { value: true });
const cache = __importStar(__webpack_require__(692)); const cache = __importStar(__webpack_require__(692));
const core = __importStar(__webpack_require__(470)); const core = __importStar(__webpack_require__(470));
const constants_1 = __webpack_require__(196); const constants_1 = __webpack_require__(196);
const save_only_1 = __webpack_require__(973);
const utils = __importStar(__webpack_require__(443)); const utils = __importStar(__webpack_require__(443));
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in // Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
// @actions/toolkit when a failed upload closes the file descriptor causing any in-process reads to // @actions/toolkit when a failed upload closes the file descriptor causing any in-process reads to
@ -47328,7 +47329,9 @@ function run() {
} }
const state = utils.getCacheState(); const state = utils.getCacheState();
// Inputs are re-evaluted before the post action, so we want the original key used for restore // Inputs are re-evaluted before the post action, so we want the original key used for restore
const primaryKey = core.getState(constants_1.State.CachePrimaryKey) || core.getInput(constants_1.Inputs.Key); const primaryKey = save_only_1.saveOnly === true
? core.getInput(constants_1.Inputs.Key)
: core.getState(constants_1.State.CachePrimaryKey);
if (!primaryKey) { if (!primaryKey) {
utils.logWarning(`Error retrieving key from state.`); utils.logWarning(`Error retrieving key from state.`);
return; return;
@ -47352,7 +47355,6 @@ function run() {
} }
}); });
} }
run();
exports.default = run; exports.default = run;
@ -55222,7 +55224,67 @@ exports.safeTrimTrailingSeparator = safeTrimTrailingSeparator;
//# sourceMappingURL=internal-path-helper.js.map //# sourceMappingURL=internal-path-helper.js.map
/***/ }), /***/ }),
/* 973 */, /* 973 */
/***/ (function(__unusedmodule, exports, __webpack_require__) {
"use strict";
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
var desc = Object.getOwnPropertyDescriptor(m, k);
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
desc = { enumerable: true, get: function() { return m[k]; } };
}
Object.defineProperty(o, k2, desc);
}) : (function(o, m, k, k2) {
if (k2 === undefined) k2 = k;
o[k2] = m[k];
}));
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
Object.defineProperty(o, "default", { enumerable: true, value: v });
}) : function(o, v) {
o["default"] = v;
});
var __importStar = (this && this.__importStar) || function (mod) {
if (mod && mod.__esModule) return mod;
var result = {};
if (mod != null) for (var k in mod) if (k !== "default" && Object.prototype.hasOwnProperty.call(mod, k)) __createBinding(result, mod, k);
__setModuleDefault(result, mod);
return result;
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.saveOnly = void 0;
const core = __importStar(__webpack_require__(470));
const constants_1 = __webpack_require__(196);
const save_1 = __importDefault(__webpack_require__(681));
const utils = __importStar(__webpack_require__(443));
function runSaveAction() {
return __awaiter(this, void 0, void 0, function* () {
if (!core.getInput(constants_1.Inputs.Key)) {
utils.logWarning(`Error retrieving key from inputs.`);
return;
}
exports.saveOnly = true;
yield (0, save_1.default)();
});
}
runSaveAction();
exports.default = runSaveAction;
/***/ }),
/* 974 */, /* 974 */,
/* 975 */ /* 975 */
/***/ (function(__unusedmodule, exports) { /***/ (function(__unusedmodule, exports) {

View file

@ -5,7 +5,7 @@
"description": "Cache dependencies and build outputs", "description": "Cache dependencies and build outputs",
"main": "dist/restore/index.js", "main": "dist/restore/index.js",
"scripts": { "scripts": {
"build": "tsc && ncc build -o dist/restore src/restore.ts && ncc build -o dist/save src/save.ts", "build": "tsc && ncc build -o dist/restore src/restore.ts && ncc build -o dist/save src/save.ts && ncc build -o dist/save-only src/save-only.ts",
"test": "tsc --noEmit && jest --coverage", "test": "tsc --noEmit && jest --coverage",
"lint": "eslint **/*.ts --cache", "lint": "eslint **/*.ts --cache",
"format": "prettier --write **/*.ts", "format": "prettier --write **/*.ts",

20
src/save-only.ts Normal file
View file

@ -0,0 +1,20 @@
import * as core from "@actions/core";
import { Inputs } from "./constants";
import save from "./save";
import * as utils from "./utils/actionUtils";
async function runSaveAction(): Promise<void> {
if (!core.getInput(Inputs.Key)) {
utils.logWarning(`Error retrieving key from inputs.`);
return;
}
saveOnly = true;
await save();
}
runSaveAction();
export default runSaveAction;
export let saveOnly: boolean;

View file

@ -2,6 +2,7 @@ import * as cache from "@actions/cache";
import * as core from "@actions/core"; import * as core from "@actions/core";
import { Events, Inputs, State } from "./constants"; import { Events, Inputs, State } from "./constants";
import { saveOnly } from "./save-only";
import * as utils from "./utils/actionUtils"; import * as utils from "./utils/actionUtils";
// Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in // Catch and log any unhandled exceptions. These exceptions can leak out of the uploadChunk method in
@ -28,7 +29,9 @@ async function run(): Promise<void> {
// Inputs are re-evaluted before the post action, so we want the original key used for restore // Inputs are re-evaluted before the post action, so we want the original key used for restore
const primaryKey = const primaryKey =
core.getState(State.CachePrimaryKey) || core.getInput(Inputs.Key); saveOnly === true
? core.getInput(Inputs.Key)
: core.getState(State.CachePrimaryKey);
if (!primaryKey) { if (!primaryKey) {
utils.logWarning(`Error retrieving key from state.`); utils.logWarning(`Error retrieving key from state.`);
@ -58,6 +61,4 @@ async function run(): Promise<void> {
} }
} }
run();
export default run; export default run;