From da288c96ed30821008fb0527cfd5c49e44c9d120 Mon Sep 17 00:00:00 2001 From: damwu1 Date: Mon, 13 May 2024 10:56:42 +1000 Subject: [PATCH] feat: [KTD-3526] add pitfile not create directory location path checking logic --- k8s-deployer/src/deployer.ts | 25 ++++++++++++++----- k8s-deployer/src/k8s.ts | 6 +++-- k8s-deployer/src/pitfile/pitfile-loader.ts | 2 +- k8s-deployer/src/test-suite-handler.ts | 14 +++++------ .../test/pitfile/pitfile-loader.spec.ts | 4 +-- k8s-deployer/test/test-suite-handler.spec.ts | 25 ++++++++++--------- 6 files changed, 46 insertions(+), 30 deletions(-) diff --git a/k8s-deployer/src/deployer.ts b/k8s-deployer/src/deployer.ts index 4c5e558..e1d22d9 100644 --- a/k8s-deployer/src/deployer.ts +++ b/k8s-deployer/src/deployer.ts @@ -1,11 +1,10 @@ import * as fs from "fs" +import { Config } from "./config.js" import { logger } from "./logger.js" -import { CommitSha, Namespace, Schema, DeployedComponent } from "./model.js" -import * as Shell from "./shell-facade.js" +import { CommitSha, DeployedComponent, Namespace, Schema } from "./model.js" import { LocationType } from "./pitfile/schema-v1.js" -import { config } from "process" -import { Config } from "./config.js" +import * as Shell from "./shell-facade.js" export class DeployOptions { namespace?: Namespace @@ -37,6 +36,16 @@ const isExecutable = async (filePath: string) => { } } +const isAccessible = async (filePath: string): Promise => { + try { + await fs.promises.access(filePath, fs.constants.F_OK) + return true + } catch (e) { + logger.error(`There is no ${filePath} or it is not accessible.`, { cause: e }) + return false + } +} + export const cloneFromGit = async (appId: string, location: Schema.Location, targetDirectory: string): Promise => { logger.info("The '%s' will be copied from '%s' into %s' using '%s'", appId, location.gitRepository, targetDirectory, location.gitRef) const fullCommand = `k8s-deployer/scripts/git-co.sh ${ location.gitRepository } ${ location.gitRef } ${ targetDirectory }` @@ -214,7 +223,9 @@ export const deployComponent = async ( appDir = spec.location.path logger.info("The application directory will be taken from 'location.path' attribute: '%s' of '%s'", appDir, spec.name) } else { - appDir = spec.id + const isFilePathExists = await isAccessible(appDir) + appDir = isFilePathExists ? spec.id : '.' + logger.info("The application directory will be taken from 'id' attribute: '%s' of '%s'", appDir, spec.name) } commitSha = await Shell.exec(`cd ${ appDir } && git log --pretty=format:"%h" -1`) @@ -233,7 +244,9 @@ export const undeployComponent = async (workspace: string, namespace: Namespace, appDir = spec.location.path logger.info("The application directory will be taken from 'location.path' attribute: '%s' of '%s'", appDir, spec.name) } else { - appDir = spec.id + const isFilePathExists = await isAccessible(appDir) + appDir = isFilePathExists ? spec.id : '.' + logger.info("The application directory will be taken from 'id' attribute: '%s' of '%s'", appDir, spec.name) } } diff --git a/k8s-deployer/src/k8s.ts b/k8s-deployer/src/k8s.ts index 168a454..a481752 100644 --- a/k8s-deployer/src/k8s.ts +++ b/k8s-deployer/src/k8s.ts @@ -1,7 +1,7 @@ -import * as Shell from "./shell-facade.js" +import * as cfg from "./config.js" import { logger } from "./logger.js" import { Namespace } from "./model.js" -import * as cfg from "./config.js" +import * as Shell from "./shell-facade.js" const pad = (v: string | number, len: number = 2): string => { let result = `${ v }` @@ -29,8 +29,10 @@ export const createNamespace = async (workspace: string, rootNamespace: Namespac const logFile = `${ workspace }/logs/create-ns-${ namespace }.log` logger.info("Creating namespace: '%s'", namespace) + const command = `k8s-deployer/scripts/k8s-manage-namespace.sh ${ rootNamespace } create "${ namespace }" ${ timeoutSeconds }` const timeoutMs = timeoutSeconds * 1_000 + await Shell.exec(command, { logFileName: logFile, tailTarget: logger.info, timeoutMs }) logger.info("Namespace created: '%s'", namespace) diff --git a/k8s-deployer/src/pitfile/pitfile-loader.ts b/k8s-deployer/src/pitfile/pitfile-loader.ts index 022ade4..b3ae71d 100644 --- a/k8s-deployer/src/pitfile/pitfile-loader.ts +++ b/k8s-deployer/src/pitfile/pitfile-loader.ts @@ -61,7 +61,7 @@ const applyDefaultsToLocation = (name: string, input: SchemaV1.Location): Schema location.type = SchemaV1.LocationType.Local } else if (location.type === SchemaV1.LocationType.Remote) { if (!location.gitRepository) { - throw new Error(`Invalid configiuration for '${name}'. The 'location.gitRepository' is required when location.type is ${SchemaV1.LocationType.Remote}`) + throw new Error(`Invalid configuration for '${name}'. The 'location.gitRepository' is required when location.type is ${SchemaV1.LocationType.Remote}`) } if (!location.gitRef) { location.gitRef = DEFAULT_GIT_REFERENCE diff --git a/k8s-deployer/src/test-suite-handler.ts b/k8s-deployer/src/test-suite-handler.ts index 57618bd..b3e27bb 100644 --- a/k8s-deployer/src/test-suite-handler.ts +++ b/k8s-deployer/src/test-suite-handler.ts @@ -1,14 +1,14 @@ import * as fs from "fs" +import { Config } from "./config.js" +import * as Deployer from "./deployer.js" +import * as K8s from "./k8s.js" import { LOG_SEPARATOR_LINE, logger } from "./logger.js" import { DeployedComponent, DeployedTestSuite, GraphDeploymentResult, Namespace, Prefix, Schema } from "./model.js" -import * as Deployer from "./deployer.js" -import { Config } from "./config.js" import * as PifFileLoader from "./pitfile/pitfile-loader.js" -import * as K8s from "./k8s.js" -import * as TestRunner from "./test-app-client/test-runner.js" -import * as Shell from "./shell-facade.js" import { PodLogTail } from "./pod-log-tail.js" +import * as Shell from "./shell-facade.js" +import * as TestRunner from "./test-app-client/test-runner.js" export const generatePrefix = (env: string): Prefix => { return generatePrefixByDate(new Date(), env) @@ -137,7 +137,7 @@ const deployLocal = async ( logger.info("process.env.MOCK_NS=%s", process.env.MOCK_NS) } - logger.info("NAMEPSACE IN USE=%s, process.env.MOCK_NS=%s", ns, process.env.MOCK_NS) + logger.info("NAMESPACE IN USE=%s, process.env.MOCK_NS=%s", ns, process.env.MOCK_NS) await deployLockManager(config, workspace, ns, pitfile.lockManager.enabled, testSuite.id) logger.info("") @@ -234,7 +234,7 @@ export const processTestSuite = async ( // By default assume processing strategy to be "deploy all then run tests one by one" logger.info("") - logger.info("--------------- Processig %s ---------------", testSuite.id) + logger.info("--------------- Processing %s ---------------", testSuite.id) logger.info("") const list = await deployAll(prefix, config, pitfile, seqNumber, testSuite) diff --git a/k8s-deployer/test/pitfile/pitfile-loader.spec.ts b/k8s-deployer/test/pitfile/pitfile-loader.spec.ts index ff15b88..2cf7272 100644 --- a/k8s-deployer/test/pitfile/pitfile-loader.spec.ts +++ b/k8s-deployer/test/pitfile/pitfile-loader.spec.ts @@ -1,6 +1,6 @@ -import * as sinon from "sinon" import * as chai from "chai" import chaiAsPromised from 'chai-as-promised' +import * as sinon from "sinon" chai.use(chaiAsPromised) import * as PifFileLoader from "../../src/pitfile/pitfile-loader.js" @@ -47,7 +47,7 @@ describe("Loads pitfile from disk", () => { }) it("should throw if location has no gitRemote", async () => { - const errorMessage = `Invalid configiuration for 'suite-1'. The 'location.gitRepository' is required when location.type is REMOTE` + const errorMessage = `Invalid configuration for 'suite-1'. The 'location.gitRepository' is required when location.type is REMOTE` await chai.expect(PifFileLoader.loadFromFile("dist/test/pitfile/test-pitfile-valid-3-invalid.yml")).eventually.rejectedWith(errorMessage) }) diff --git a/k8s-deployer/test/test-suite-handler.spec.ts b/k8s-deployer/test/test-suite-handler.spec.ts index fec6ff3..78d0a3c 100644 --- a/k8s-deployer/test/test-suite-handler.spec.ts +++ b/k8s-deployer/test/test-suite-handler.spec.ts @@ -1,17 +1,17 @@ -import esmock from "esmock" -import * as sinon from "sinon" import * as chai from "chai" import { SpawnOptions } from "child_process" +import esmock from "esmock" import { RequestInit } from "node-fetch" +import * as sinon from "sinon" import { logger } from "../src/logger.js" -import * as webapi from "../src/test-app-client/web-api/schema-v1.js" -import { ShellOptions } from "../src/shell-facade.js" +import { Config, DEFAULT_SUB_NAMESPACE_PREFIX, SUB_NAMESPACE_GENERATOR_TYPE_DATE } from "../src/config.js" import { LocationType } from "../src/pitfile/schema-v1.js" import { SchemaVersion } from "../src/pitfile/version.js" -import { Config, DEFAULT_SUB_NAMESPACE_PREFIX, SUB_NAMESPACE_GENERATOR_TYPE_DATE } from "../src/config.js" +import { ShellOptions } from "../src/shell-facade.js" import { ScalarMetric, TestOutcomeType, TestStream } from "../src/test-app-client/report/schema-v1.js" +import * as webapi from "../src/test-app-client/web-api/schema-v1.js" import { generatePrefixByDate } from "../src/test-suite-handler.js" describe("Helper functions", () => { @@ -209,16 +209,17 @@ describe("Deployment happy path", async () => { // check verification for expected directories and shell executables - chai.expect(fsAccessStubs.callCount).eq(7) - - // check for presense of workspace direectory on the disk + chai.expect(fsAccessStubs.callCount).eq(9) + // check for presense of workspace directory on the disk chai.expect(fsAccessStubs.getCall(0).calledWith(workspace)).be.true chai.expect(fsAccessStubs.getCall(1).calledWith("lock-manager/deployment/pit/deploy.sh")).be.true chai.expect(fsAccessStubs.getCall(2).calledWith("lock-manager/deployment/pit/is-deployment-ready.sh")).be.true - chai.expect(fsAccessStubs.getCall(3).calledWith("comp-1/deployment/pit/deploy.sh")).be.true - chai.expect(fsAccessStubs.getCall(4).calledWith("comp-1/deployment/pit/is-deployment-ready.sh")).be.true - chai.expect(fsAccessStubs.getCall(5).calledWith("comp-1-test-app/deployment/pit/deploy.sh")).be.true - chai.expect(fsAccessStubs.getCall(6).calledWith("comp-1-test-app/deployment/pit/is-deployment-ready.sh")).be.true + chai.expect(fsAccessStubs.getCall(3).calledWith("12345_t1/comp-1")).equal(true) + chai.expect(fsAccessStubs.getCall(4).calledWith("comp-1/deployment/pit/deploy.sh")).equal(true) + chai.expect(fsAccessStubs.getCall(5).calledWith("comp-1/deployment/pit/is-deployment-ready.sh")).equal(true) + chai.expect(fsAccessStubs.getCall(6).calledWith("12345_t1/comp-1-test-app")).equal(true) + chai.expect(fsAccessStubs.getCall(7).calledWith("comp-1-test-app/deployment/pit/deploy.sh")).equal(true) + chai.expect(fsAccessStubs.getCall(8).calledWith("comp-1-test-app/deployment/pit/is-deployment-ready.sh")).equal(true) // check shell calls