Skip to content

Commit

Permalink
Fb/test branching and cache (#97)
Browse files Browse the repository at this point in the history
* make git track local caching file in root

* avoid R_OK constant in business code modules

* completely remove fs from business modules and consolidate fs usage into static

* fix tests after fs changes
  • Loading branch information
rlindner81 authored Dec 14, 2024
1 parent eb46f89 commit 3578924
Show file tree
Hide file tree
Showing 8 changed files with 55 additions and 62 deletions.
3 changes: 0 additions & 3 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,6 @@ node_modules/
# temp
temp/

# mtx
.mtxcache.json

# npm package
*.tgz

Expand Down
9 changes: 3 additions & 6 deletions src/context.js
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,12 @@

const urllib = require("url");
const pathlib = require("path");
const {
writeFileSync,
constants: { R_OK },
} = require("fs");
const { version } = require("../package.json");

const {
tryReadJsonSync,
tryAccessSync,
writeJsonSync,
spawnAsync,
safeUnshift,
escapeRegExp,
Expand Down Expand Up @@ -133,7 +130,7 @@ const _resolveDir = (filename) => {
while (true) {
const dir = subdirs.length === 0 ? HOME : subdirs.join(pathlib.sep);
const filepath = dir + pathlib.sep + filename;
if (tryAccessSync(filepath, R_OK)) {
if (tryAccessSync(filepath)) {
return {
dir,
filepath,
Expand Down Expand Up @@ -187,7 +184,7 @@ const _writeRawAppPersistedCache = (newRuntimeCache, filepath, orgGuid, spaceGui
const appKey = orgGuid + "##" + spaceGuid + "##" + appName;
fullCache[appKey] = newRuntimeCache;
try {
writeFileSync(filepath, JSON.stringify(fullCache, null, 2) + "\n");
writeJsonSync(filepath, fullCache);
} catch (err) {
fail("caught error while writing app cache:", err.message);
}
Expand Down
19 changes: 17 additions & 2 deletions src/shared/static.js
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,13 @@
// NOTE: static here means we only allow imports from the node standard library

const readline = require("readline");
const { accessSync, readFileSync } = require("fs");
const {
accessSync,
readFileSync,
writeFileSync,
unlinkSync,
constants: { R_OK },
} = require("fs");
const net = require("net");
const childProcess = require("child_process");
const util = require("util");
Expand Down Expand Up @@ -48,7 +54,7 @@ const tryReadJsonSync = (filepath) => {
}
};

const tryAccessSync = (filepath, mode) => {
const tryAccessSync = (filepath, mode = R_OK) => {
try {
accessSync(filepath, mode);
return true;
Expand All @@ -65,6 +71,12 @@ const tryJsonParse = (input) => {
}
};

const writeTextSync = (filepath, data) => writeFileSync(filepath, data);

const writeJsonSync = (filepath, data) => writeFileSync(filepath, JSON.stringify(data, null, 2) + "\n");

const deleteFileSync = (filepath) => unlinkSync(filepath);

const tableList = (table, { sortCol = 0, noHeader = false, withRowNumber = true } = {}) => {
if (!table || !table.length || !table[0] || !table[0].length) {
return null;
Expand Down Expand Up @@ -371,6 +383,9 @@ module.exports = {
sleep,
question,
tryReadJsonSync,
writeTextSync,
writeJsonSync,
deleteFileSync,
tryAccessSync,
tryJsonParse,
tableList,
Expand Down
7 changes: 3 additions & 4 deletions src/submodules/serverDiagnostic.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,6 @@
"use strict";

const { writeFileSync } = require("fs");
const { orderedStringify } = require("../shared/static");
const { orderedStringify, writeTextSync } = require("../shared/static");
const { assert } = require("../shared/error");
const { request } = require("../shared/request");
const { Logger } = require("../shared/logger");
Expand Down Expand Up @@ -70,7 +69,7 @@ const serverEnvironment = async (context, [appName]) => {
const { cfEnvServices, cfEnvApp, cfEnvVariables } = appName
? await context.getAppNameInfoCached(appName)
: await context.getSrvInfo();
writeFileSync(
writeTextSync(
DEFAULT_ENV_FILENAME,
orderedStringify({ VCAP_SERVICES: cfEnvServices, VCAP_APPLICATION: cfEnvApp, ...cfEnvVariables }, null, 2) + "\n"
);
Expand All @@ -80,7 +79,7 @@ const serverCertificates = async (context, [appName, appInstance = 0]) => {
const { cfSsh, cfAppName } = appName ? await context.getAppNameInfoCached(appName) : await context.getSrvInfo();
const dumpFile = async (cfFilename, localFilename) => {
const [file] = await cfSsh({ command: `cat ${cfFilename}`, appInstance });
writeFileSync(localFilename, file);
writeTextSync(localFilename, file);
};
await dumpFile("$CF_INSTANCE_CERT", `certificate-${cfAppName}-${appInstance}.crt`);
await dumpFile("$CF_INSTANCE_KEY", `certificate-${cfAppName}-${appInstance}.key`);
Expand Down
13 changes: 4 additions & 9 deletions src/submodules/setup.js
Original file line number Diff line number Diff line change
@@ -1,13 +1,8 @@
"use strict";

const pathlib = require("path");
const {
writeFileSync,
unlinkSync,
constants: { R_OK },
} = require("fs");

const { question, tryAccessSync } = require("../shared/static");
const { question, tryAccessSync, writeJsonSync, deleteFileSync } = require("../shared/static");
const { fail } = require("../shared/error");
const { SETTING } = require("../setting");
const { Logger } = require("../shared/logger");
Expand Down Expand Up @@ -36,7 +31,7 @@ const _resolveDir = (filename) => {
while (true) {
const dir = subdirs.length === 0 ? HOME : subdirs.join(pathlib.sep);
const filepath = dir + pathlib.sep + filename;
if (tryAccessSync(filepath, R_OK)) {
if (tryAccessSync(filepath)) {
return {
dir,
filepath,
Expand All @@ -52,7 +47,7 @@ const _resolveDir = (filename) => {

const _writeRuntimeConfig = async (runtimeConfig, filepath) => {
try {
writeFileSync(filepath, JSON.stringify(runtimeConfig, null, 2) + "\n");
writeJsonSync(filepath, runtimeConfig);
logger.info("wrote runtime config");
} catch (err) {
fail("caught error while writing runtime config:", err.message);
Expand Down Expand Up @@ -113,7 +108,7 @@ const setupCleanCache = () => {
break;
}
try {
unlinkSync(filepath);
deleteFileSync(filepath);
logger.info(`removed ${location.toLowerCase()} cache`, filepath);
} catch (err) {
fail(`could not remove ${filepath}`);
Expand Down
7 changes: 4 additions & 3 deletions test/__mocks/sharedNockPlayback/static.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
"use strict";

const { format } = require("util");
const sharedStatic = jest.requireActual("../../../src/shared/static");
const realStatic = jest.requireActual("../../../src/shared/static");

const mockCfConfig = {
OrganizationFields: {
Expand All @@ -24,7 +24,7 @@ const mockRuntimeConfig = {
};

module.exports = {
...sharedStatic,
...realStatic,
// mock file read and access
tryReadJsonSync: jest.fn((filepath) => {
if (filepath.endsWith("config.json")) {
Expand All @@ -40,6 +40,7 @@ module.exports = {
return true;
}
}),
writeJsonSync: jest.fn(),
// mock spawn
spawnAsync: jest.fn(async (command, args, options) => {
switch (`${command} ${args.join(" ")}`) {
Expand All @@ -50,5 +51,5 @@ module.exports = {
}
}),
// speed up sleep
sleep: jest.fn(async () => await sharedStatic.sleep(0)),
sleep: jest.fn(),
};
1 change: 1 addition & 0 deletions test/context.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,7 @@ jest.mock("../src/shared/static", () => {
makeOneTime,
tryAccessSync: jest.fn(),
tryReadJsonSync: jest.fn(),
writeJsonSync: jest.fn(),
spawnAsync: jest.fn(),
};
});
Expand Down
58 changes: 23 additions & 35 deletions test/submodules/setup.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,8 @@ jest.mock("../../src/shared/logger", () => require("../__mocks/shared/logger"));
const mockStatic = require("../../src/shared/static");
jest.mock("../../src/shared/static", () => ({
tryAccessSync: jest.fn(),
writeJsonSync: jest.fn(),
deleteFileSync: jest.fn(),
question: jest.fn(),
}));

Expand All @@ -15,13 +17,6 @@ jest.mock("../../src/context", () => ({
readRuntimeConfig: jest.fn(),
}));

const mockFs = require("fs");
jest.mock("fs", () => ({
writeFileSync: jest.fn(),
unlinkSync: jest.fn(),
constants: { R_OK: 4 },
}));

const processCwdSpy = jest.spyOn(process, "cwd");

const { outputFromLogger } = require("../test-util/static");
Expand Down Expand Up @@ -71,18 +66,17 @@ describe("set tests", () => {
expect(await set.setup()).toMatchInlineSnapshot(`undefined`);
expect(mockStatic.tryAccessSync).toHaveBeenCalledTimes(0);
expect(mockContextModule.readRuntimeConfig).toHaveBeenCalledTimes(1);
expect(mockFs.writeFileSync).toHaveBeenCalledTimes(1);
expect(mockFs.writeFileSync.mock.calls[0]).toMatchInlineSnapshot(`
expect(mockStatic.writeJsonSync).toHaveBeenCalledTimes(1);
expect(mockStatic.writeJsonSync.mock.calls[0]).toMatchInlineSnapshot(`
[
"/root/home-dir/.mtxrc.json",
"{
"uaaAppName": "answer 1",
"regAppName": "answer 2",
"cdsAppName": "answer 3",
"hdiAppName": "answer 4",
"srvAppName": "answer 5"
}
",
{
"cdsAppName": "answer 3",
"hdiAppName": "answer 4",
"regAppName": "answer 2",
"srvAppName": "answer 5",
"uaaAppName": "answer 1",
},
]
`);
expect(outputFromLogger(mockLogger.info.mock.calls)).toMatchInlineSnapshot(`
Expand Down Expand Up @@ -115,7 +109,7 @@ describe("set tests", () => {
for (let i = 0; i < Object.keys(mockRuntimeConfig).length; i++) {
mockStatic.question.mockReturnValueOnce(`answer ${i + 1}`);
}
mockFs.writeFileSync.mockImplementationOnce(() => {
mockStatic.writeJsonSync.mockImplementationOnce(() => {
throw new Error("cannot write");
});

Expand All @@ -133,18 +127,17 @@ describe("set tests", () => {
expect(await set.setupLocal()).toMatchInlineSnapshot(`undefined`);
expect(mockStatic.tryAccessSync).toHaveBeenCalledTimes(0);
expect(mockContextModule.readRuntimeConfig).toHaveBeenCalledTimes(1);
expect(mockFs.writeFileSync).toHaveBeenCalledTimes(1);
expect(mockFs.writeFileSync.mock.calls[0]).toMatchInlineSnapshot(`
expect(mockStatic.writeJsonSync).toHaveBeenCalledTimes(1);
expect(mockStatic.writeJsonSync.mock.calls[0]).toMatchInlineSnapshot(`
[
"/root/local-dir/.mtxrc.json",
"{
"uaaAppName": "answer 1",
"regAppName": "answer 2",
"cdsAppName": "answer 3",
"hdiAppName": "answer 4",
"srvAppName": "answer 5"
}
",
{
"cdsAppName": "answer 3",
"hdiAppName": "answer 4",
"regAppName": "answer 2",
"srvAppName": "answer 5",
"uaaAppName": "answer 1",
},
]
`);
expect(outputFromLogger(mockLogger.info.mock.calls)).toMatchInlineSnapshot(`
Expand All @@ -165,27 +158,22 @@ describe("set tests", () => {
[
[
"/root/local-dir/.mtxcache.json",
4,
],
[
"/root/local-dir/.mtxcache.json",
4,
],
[
"/root/.mtxcache.json",
4,
],
[
"/.mtxcache.json",
4,
],
[
"/root/home-dir/.mtxcache.json",
4,
],
]
`);
expect(mockFs.unlinkSync.mock.calls).toMatchInlineSnapshot(`
expect(mockStatic.deleteFileSync.mock.calls).toMatchInlineSnapshot(`
[
[
"/root/local-dir/.mtxcache.json",
Expand All @@ -203,7 +191,7 @@ describe("set tests", () => {
for (let i = 0; i < 4; i++) {
mockStatic.tryAccessSync.mockReturnValueOnce(false);
}
mockFs.unlinkSync.mockImplementationOnce(() => {
mockStatic.deleteFileSync.mockImplementationOnce(() => {
throw new Error("failing delete");
});

Expand Down

0 comments on commit 3578924

Please sign in to comment.