From 7a87a49de99a34026e3ac6de31e0c8335e3441e8 Mon Sep 17 00:00:00 2001 From: Bryan Lopez Date: Wed, 13 Mar 2024 19:23:48 -0400 Subject: [PATCH 01/11] adding files to dynamically show latest pewpew version on Toaster --- controller/.latestpewpewversionfile.ts | 1 + .../components/PewPewVersions/index.tsx | 5 ++ .../components/PewPewVersions/initialProps.ts | 5 +- .../components/PewPewVersions/story.tsx | 1 + controller/components/StartTestForm/story.tsx | 2 + controller/components/Toaster/index.tsx | 49 +++++++++++++++++++ controller/components/Toaster/story.tsx | 16 ++++++ controller/pages/admin.tsx | 2 +- controller/pages/api/util/pewpew.ts | 24 ++++++++- controller/tsconfig.json | 2 +- 10 files changed, 103 insertions(+), 4 deletions(-) create mode 100644 controller/.latestpewpewversionfile.ts create mode 100644 controller/components/Toaster/index.tsx create mode 100644 controller/components/Toaster/story.tsx diff --git a/controller/.latestpewpewversionfile.ts b/controller/.latestpewpewversionfile.ts new file mode 100644 index 00000000..2ce56ec0 --- /dev/null +++ b/controller/.latestpewpewversionfile.ts @@ -0,0 +1 @@ +export const latestPewPewInFile = {"version": "0.5.13"}; // Wed Mar 13 2024 19:21:37 GMT-0400 (Eastern Daylight Time); \ No newline at end of file diff --git a/controller/components/PewPewVersions/index.tsx b/controller/components/PewPewVersions/index.tsx index 414188e7..784d776a 100644 --- a/controller/components/PewPewVersions/index.tsx +++ b/controller/components/PewPewVersions/index.tsx @@ -1,6 +1,7 @@ import { Danger } from "../Alert"; import Div from "../Div"; import React from "react"; +import Toaster from "../Toaster" import styled from "styled-components"; const VersionDiv = styled(Div)` @@ -24,6 +25,7 @@ const VersionDivSelect = styled(Div)` export interface VersionInitalProps { pewpewVersion: string; pewpewVersions: string[]; + latestInFile: string; loading: boolean; error: boolean; } @@ -38,12 +40,14 @@ export const PewPewVersions = ({ name, pewpewVersion, onChange, + latestInFile, pewpewVersions = [], loading, error }: VersionProps) => { // console.log("PewPewVersions state", { pewpewVersions, loading, error }); let optionItems: JSX.Element[] | undefined; + const toasterMessage: string = "IMPORTANT: Please configure your YAML properly!!! The latest version of Pewpew is set to: " + latestInFile; if (pewpewVersions && pewpewVersions.length > 0) { optionItems = pewpewVersions.map((version: string) => ()); } @@ -53,6 +57,7 @@ export const PewPewVersions = ({ {loading && Loading...} {!loading && !error && } {error && Could not load the current PewPew Versions} + ); }; diff --git a/controller/components/PewPewVersions/initialProps.ts b/controller/components/PewPewVersions/initialProps.ts index d2f81f8d..731a2fdc 100644 --- a/controller/components/PewPewVersions/initialProps.ts +++ b/controller/components/PewPewVersions/initialProps.ts @@ -1,12 +1,13 @@ import { LogLevel, log } from "@fs/ppaas-common"; import { API_PEWPEW } from "../../types"; import { VersionInitalProps } from "."; -import { getPewPewVersionsInS3 } from "../../pages/api/util/pewpew"; +import { getPewPewVersionInFile, getPewPewVersionsInS3 } from "../../pages/api/util/pewpew"; import { latestPewPewVersion } from "../../pages/api/util/clientutil"; export const getServerSideProps = async (): Promise => { try { const pewpewVersions: string[] = await getPewPewVersionsInS3(); + const latestPewpewInFile: string = getPewPewVersionInFile(); log("getPewPewVersionsInS3", LogLevel.DEBUG, pewpewVersions); // Grab the response // console.log("PewPewVersions pewpewVersions: " + JSON.stringify(pewpewVersions), pewpewVersions); @@ -16,6 +17,7 @@ export const getServerSideProps = async (): Promise => { return { pewpewVersion: latestPewPewVersion, // We always want to default to latest pewpewVersions, + latestInFile: latestPewpewInFile, loading: false, error: false }; @@ -25,6 +27,7 @@ export const getServerSideProps = async (): Promise => { return { pewpewVersion: "", pewpewVersions: [], + latestInFile: "", loading: false, error: true }; diff --git a/controller/components/PewPewVersions/story.tsx b/controller/components/PewPewVersions/story.tsx index 68d7be34..9a3f2f4f 100644 --- a/controller/components/PewPewVersions/story.tsx +++ b/controller/components/PewPewVersions/story.tsx @@ -15,6 +15,7 @@ const props: VersionProps = { console.log("newVal: ", newVal); }, pewpewVersions: ["0.1.1", "0.1.2", "0.1.3", "0.1.4", "0.1.5", latestPewPewVersion, "0.1.6"], + latestInFile : "latestVersion", loading: false, error: false }; diff --git a/controller/components/StartTestForm/story.tsx b/controller/components/StartTestForm/story.tsx index b557e282..52907e91 100644 --- a/controller/components/StartTestForm/story.tsx +++ b/controller/components/StartTestForm/story.tsx @@ -38,6 +38,7 @@ const versionInitalPropsEmpty: VersionInitalProps = { pewpewVersion: "", loading: false, pewpewVersions: [], + latestInFile: "", error: true }; const queueInitialProps: QueueInitialProps = { @@ -50,6 +51,7 @@ const versionInitalProps: VersionInitalProps = { pewpewVersion: "", loading: false, pewpewVersions: [latestPewPewVersion, "0.5.10", "0.5.11", "0.5.12"], + latestInFile: "latest", error: false }; let ppaasTestId: PpaasTestId; diff --git a/controller/components/Toaster/index.tsx b/controller/components/Toaster/index.tsx new file mode 100644 index 00000000..77b14fce --- /dev/null +++ b/controller/components/Toaster/index.tsx @@ -0,0 +1,49 @@ +import React, { useEffect } from "react"; +import styled, { keyframes } from "styled-components"; +import { Info } from "../Alert"; + +interface ToasterProps { + message: string; // Ensure message prop is of type string + duration?: number; + id: string; // Unique ID for the toaster +} + +// Fade-in animation +const fadeIn = keyframes` + from { opacity: 0; } + to { opacity: 1; } +`; + +// Fade-out animation +const fadeOut = keyframes` + from { opacity: 1; } + to { opacity: 0; } +`; + +const Container = styled(Info)` + position: fixed; + bottom: 20px; + right: 20px; + width: 30%; + font-size: 17px; + + animation: ${fadeIn} 0.3s ease-in-out forwards; + &.fade-out { animation: ${fadeOut} 0.3s ease-in-out forwards; } +`; + +const Toaster: React.FC = ({ id, message, duration = 7000 }) => { + useEffect(() => { + setTimeout(() => { + const toasterElement = document.getElementById(id); + if (toasterElement) { + toasterElement.classList.add("fade-out"); + setTimeout(() => { + toasterElement.remove(); + }, 300); // Wait for fade-out animation to complete before removing element + } + }, duration); + }, [id, duration]); + return {message}; +}; + +export default Toaster; diff --git a/controller/components/Toaster/story.tsx b/controller/components/Toaster/story.tsx new file mode 100644 index 00000000..d94ca9f2 --- /dev/null +++ b/controller/components/Toaster/story.tsx @@ -0,0 +1,16 @@ +import type { Meta, StoryFn } from "@storybook/react"; +import { GlobalStyle } from "../Layout"; +import React from "react"; +import Toaster from "./index"; + +export default { + title: "Toaster", + component: Toaster +} as Meta; + +export const Default: StoryFn = () => ( + + + + +); diff --git a/controller/pages/admin.tsx b/controller/pages/admin.tsx index 4b73e9d0..dcfc26d8 100644 --- a/controller/pages/admin.tsx +++ b/controller/pages/admin.tsx @@ -329,7 +329,7 @@ const Admin = ({ authPermission, versionInitalProps, error: propsError }: AdminP export const getServerSideProps: GetServerSideProps = async (ctx: GetServerSidePropsContext): Promise> => { - let versionInitalProps: VersionInitalProps = { pewpewVersion: "", loading: false, pewpewVersions: [], error: true }; + let versionInitalProps: VersionInitalProps = { pewpewVersion: "", loading: false, pewpewVersions: [], latestInFile: "", error: true }; try { // Authenticate const authPermissions: AuthPermissions | string = await authPage(ctx, AuthPermission.Admin); diff --git a/controller/pages/api/util/pewpew.ts b/controller/pages/api/util/pewpew.ts index 35e8e5be..47b308af 100644 --- a/controller/pages/api/util/pewpew.ts +++ b/controller/pages/api/util/pewpew.ts @@ -22,6 +22,8 @@ import { latestPewPewVersion, versionSort } from "./clientutil"; import { TestScheduler } from "./testscheduler"; import { execFile as _execFile } from "child_process"; import { chmod } from "fs/promises"; +import fs from "fs" +import { latestPewPewInFile } from "../../../.latestpewpewversionfile" import os from "os"; import { promisify } from "util"; import semver from "semver"; @@ -134,7 +136,17 @@ export async function postPewPew (parsedForm: ParsedForm, authPermissions: AuthP if (version === null) { return { json: { message: `${match[1]} is not a valid semver version: ${version}` }, status: 400 }; } - + // If latest version is being updated, write it to file: + if(latest){ + const filename = "./.latestpewpewversionfile.ts"; + const data = "export const latestPewPewInFile = {\"version\": \"" + version + "\"}; // " + new Date() + ";"; + try { + fs.writeFileSync(filename, data); + log("Sucessfully saved PewPew's latest version to file. ", LogLevel.INFO); + } catch (error) { + log("Writing latest PewPew's latest version to file failed: ", LogLevel.ERROR, error); + } + } const uploadPromises: Promise[] = []; const versionLogDisplay = latest ? `${version} as latest` : version; const versionFolder = latest ? latestPewPewVersion : version; @@ -215,3 +227,13 @@ export async function deletePewPew (query: Partial Date: Wed, 13 Mar 2024 19:39:04 -0400 Subject: [PATCH 02/11] cleaning up code for lintter to pass --- controller/components/PewPewVersions/index.tsx | 4 ++-- controller/components/PewPewVersions/initialProps.ts | 2 +- controller/pages/api/util/pewpew.ts | 4 ++-- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/controller/components/PewPewVersions/index.tsx b/controller/components/PewPewVersions/index.tsx index 784d776a..641628cf 100644 --- a/controller/components/PewPewVersions/index.tsx +++ b/controller/components/PewPewVersions/index.tsx @@ -1,7 +1,7 @@ import { Danger } from "../Alert"; import Div from "../Div"; import React from "react"; -import Toaster from "../Toaster" +import Toaster from "../Toaster"; import styled from "styled-components"; const VersionDiv = styled(Div)` @@ -25,7 +25,7 @@ const VersionDivSelect = styled(Div)` export interface VersionInitalProps { pewpewVersion: string; pewpewVersions: string[]; - latestInFile: string; + latestInFile: string; loading: boolean; error: boolean; } diff --git a/controller/components/PewPewVersions/initialProps.ts b/controller/components/PewPewVersions/initialProps.ts index 731a2fdc..ae62aaef 100644 --- a/controller/components/PewPewVersions/initialProps.ts +++ b/controller/components/PewPewVersions/initialProps.ts @@ -1,7 +1,7 @@ import { LogLevel, log } from "@fs/ppaas-common"; +import { getPewPewVersionInFile, getPewPewVersionsInS3 } from "../../pages/api/util/pewpew"; import { API_PEWPEW } from "../../types"; import { VersionInitalProps } from "."; -import { getPewPewVersionInFile, getPewPewVersionsInS3 } from "../../pages/api/util/pewpew"; import { latestPewPewVersion } from "../../pages/api/util/clientutil"; export const getServerSideProps = async (): Promise => { diff --git a/controller/pages/api/util/pewpew.ts b/controller/pages/api/util/pewpew.ts index 47b308af..335f5e47 100644 --- a/controller/pages/api/util/pewpew.ts +++ b/controller/pages/api/util/pewpew.ts @@ -22,8 +22,8 @@ import { latestPewPewVersion, versionSort } from "./clientutil"; import { TestScheduler } from "./testscheduler"; import { execFile as _execFile } from "child_process"; import { chmod } from "fs/promises"; -import fs from "fs" -import { latestPewPewInFile } from "../../../.latestpewpewversionfile" +import fs from "fs"; +import { latestPewPewInFile } from "../../../.latestpewpewversionfile"; import os from "os"; import { promisify } from "util"; import semver from "semver"; From dfface4090262e8fc1e4dda3069b8f4201430181 Mon Sep 17 00:00:00 2001 From: Bryan Lopez Date: Fri, 15 Mar 2024 12:20:33 -0400 Subject: [PATCH 03/11] refactoring code to use tags in S3 --- controller/.latestpewpewversionfile.ts | 1 - .../components/PewPewVersions/index.tsx | 6 +-- .../components/PewPewVersions/initialProps.ts | 8 ++-- .../components/PewPewVersions/story.tsx | 2 +- controller/components/StartTestForm/story.tsx | 4 +- controller/pages/admin.tsx | 2 +- controller/pages/api/util/pewpew.ts | 48 ++++++++++++------- 7 files changed, 42 insertions(+), 29 deletions(-) delete mode 100644 controller/.latestpewpewversionfile.ts diff --git a/controller/.latestpewpewversionfile.ts b/controller/.latestpewpewversionfile.ts deleted file mode 100644 index 2ce56ec0..00000000 --- a/controller/.latestpewpewversionfile.ts +++ /dev/null @@ -1 +0,0 @@ -export const latestPewPewInFile = {"version": "0.5.13"}; // Wed Mar 13 2024 19:21:37 GMT-0400 (Eastern Daylight Time); \ No newline at end of file diff --git a/controller/components/PewPewVersions/index.tsx b/controller/components/PewPewVersions/index.tsx index 641628cf..23d1c035 100644 --- a/controller/components/PewPewVersions/index.tsx +++ b/controller/components/PewPewVersions/index.tsx @@ -25,7 +25,7 @@ const VersionDivSelect = styled(Div)` export interface VersionInitalProps { pewpewVersion: string; pewpewVersions: string[]; - latestInFile: string; + latestPewPewVersion: string; loading: boolean; error: boolean; } @@ -40,14 +40,14 @@ export const PewPewVersions = ({ name, pewpewVersion, onChange, - latestInFile, + latestPewPewVersion: latestPewPewTag, pewpewVersions = [], loading, error }: VersionProps) => { // console.log("PewPewVersions state", { pewpewVersions, loading, error }); let optionItems: JSX.Element[] | undefined; - const toasterMessage: string = "IMPORTANT: Please configure your YAML properly!!! The latest version of Pewpew is set to: " + latestInFile; + const toasterMessage: string = "IMPORTANT: Please configure your YAML properly!!! The latest version of Pewpew is set to: " + latestPewPewTag; if (pewpewVersions && pewpewVersions.length > 0) { optionItems = pewpewVersions.map((version: string) => ()); } diff --git a/controller/components/PewPewVersions/initialProps.ts b/controller/components/PewPewVersions/initialProps.ts index ae62aaef..38f301ff 100644 --- a/controller/components/PewPewVersions/initialProps.ts +++ b/controller/components/PewPewVersions/initialProps.ts @@ -1,5 +1,5 @@ import { LogLevel, log } from "@fs/ppaas-common"; -import { getPewPewVersionInFile, getPewPewVersionsInS3 } from "../../pages/api/util/pewpew"; +import { getCurrentPewPewLatestVersion, getPewPewVersionsInS3 } from "../../pages/api/util/pewpew"; import { API_PEWPEW } from "../../types"; import { VersionInitalProps } from "."; import { latestPewPewVersion } from "../../pages/api/util/clientutil"; @@ -7,7 +7,7 @@ import { latestPewPewVersion } from "../../pages/api/util/clientutil"; export const getServerSideProps = async (): Promise => { try { const pewpewVersions: string[] = await getPewPewVersionsInS3(); - const latestPewpewInFile: string = getPewPewVersionInFile(); + const currentPewPewLatestVersion: string | undefined = await getCurrentPewPewLatestVersion(); log("getPewPewVersionsInS3", LogLevel.DEBUG, pewpewVersions); // Grab the response // console.log("PewPewVersions pewpewVersions: " + JSON.stringify(pewpewVersions), pewpewVersions); @@ -17,7 +17,7 @@ export const getServerSideProps = async (): Promise => { return { pewpewVersion: latestPewPewVersion, // We always want to default to latest pewpewVersions, - latestInFile: latestPewpewInFile, + latestPewPewVersion: currentPewPewLatestVersion || "unknown", loading: false, error: false }; @@ -27,7 +27,7 @@ export const getServerSideProps = async (): Promise => { return { pewpewVersion: "", pewpewVersions: [], - latestInFile: "", + latestPewPewVersion: "unknown", loading: false, error: true }; diff --git a/controller/components/PewPewVersions/story.tsx b/controller/components/PewPewVersions/story.tsx index 9a3f2f4f..2c23991c 100644 --- a/controller/components/PewPewVersions/story.tsx +++ b/controller/components/PewPewVersions/story.tsx @@ -15,7 +15,7 @@ const props: VersionProps = { console.log("newVal: ", newVal); }, pewpewVersions: ["0.1.1", "0.1.2", "0.1.3", "0.1.4", "0.1.5", latestPewPewVersion, "0.1.6"], - latestInFile : "latestVersion", + latestPewPewVersion : "latestVersion", loading: false, error: false }; diff --git a/controller/components/StartTestForm/story.tsx b/controller/components/StartTestForm/story.tsx index 52907e91..ef000689 100644 --- a/controller/components/StartTestForm/story.tsx +++ b/controller/components/StartTestForm/story.tsx @@ -38,7 +38,7 @@ const versionInitalPropsEmpty: VersionInitalProps = { pewpewVersion: "", loading: false, pewpewVersions: [], - latestInFile: "", + latestPewPewVersion: "", error: true }; const queueInitialProps: QueueInitialProps = { @@ -51,7 +51,7 @@ const versionInitalProps: VersionInitalProps = { pewpewVersion: "", loading: false, pewpewVersions: [latestPewPewVersion, "0.5.10", "0.5.11", "0.5.12"], - latestInFile: "latest", + latestPewPewVersion: "latest", error: false }; let ppaasTestId: PpaasTestId; diff --git a/controller/pages/admin.tsx b/controller/pages/admin.tsx index dcfc26d8..5e6c86b5 100644 --- a/controller/pages/admin.tsx +++ b/controller/pages/admin.tsx @@ -329,7 +329,7 @@ const Admin = ({ authPermission, versionInitalProps, error: propsError }: AdminP export const getServerSideProps: GetServerSideProps = async (ctx: GetServerSidePropsContext): Promise> => { - let versionInitalProps: VersionInitalProps = { pewpewVersion: "", loading: false, pewpewVersions: [], latestInFile: "", error: true }; + let versionInitalProps: VersionInitalProps = { pewpewVersion: "", loading: false, pewpewVersions: [], latestPewPewVersion: "", error: true }; try { // Authenticate const authPermissions: AuthPermissions | string = await authPage(ctx, AuthPermission.Admin); diff --git a/controller/pages/api/util/pewpew.ts b/controller/pages/api/util/pewpew.ts index 335f5e47..5fd46ff1 100644 --- a/controller/pages/api/util/pewpew.ts +++ b/controller/pages/api/util/pewpew.ts @@ -22,8 +22,6 @@ import { latestPewPewVersion, versionSort } from "./clientutil"; import { TestScheduler } from "./testscheduler"; import { execFile as _execFile } from "child_process"; import { chmod } from "fs/promises"; -import fs from "fs"; -import { latestPewPewInFile } from "../../../.latestpewpewversionfile"; import os from "os"; import { promisify } from "util"; import semver from "semver"; @@ -35,6 +33,7 @@ logger.config.LogFileName = "ppaas-controller"; const deleteS3 = s3.deleteObject; export const PEWPEW_EXECUTABLE_NAME: string = "pewpew"; const PEWPEW_EXECUTABLE_NAME_WINDOWS: string = "pewpew.exe"; +const VERSION_TAG_NAME: string = "version"; /** * Queries S3 for all objects in the pewpew/ folder that end with pewpew (not pewpew.exe). @@ -48,6 +47,8 @@ export async function getPewPewVersionsInS3 (): Promise { localDirectory: LOCAL_FILE_LOCATION, extension: PEWPEW_EXECUTABLE_NAME }); + console.log("PEWPEW FILES FROM S3") + console.log(pewpewFiles) if (pewpewFiles.length === 0) { throw new Error("No pewpew binaries found in s3"); } @@ -76,6 +77,16 @@ export async function getPewpew (): Promise[] = []; const versionLogDisplay = latest ? `${version} as latest` : version; const versionFolder = latest ? latestPewPewVersion : version; log(PEWPEW_EXECUTABLE_NAME + " only upload, version: " + versionLogDisplay, LogLevel.DEBUG, files); // Pass in an override Map to override the default tags and not set a "test" tag - const tags = new Map([["pewpew", "true"]]); + const tags = new Map([[PEWPEW_BINARY_FOLDER, "true"], [VERSION_TAG_NAME, version]]); if (Array.isArray(files.additionalFiles)) { for (const file of files.additionalFiles) { uploadPromises.push(uploadFile(file, `${PEWPEW_BINARY_FOLDER}/${versionFolder}`, tags)); @@ -161,6 +161,16 @@ export async function postPewPew (parsedForm: ParsedForm, authPermissions: AuthP uploadPromises.push(uploadFile(files.additionalFiles, `${PEWPEW_BINARY_FOLDER}/${versionFolder}`, tags)); } await Promise.all(uploadPromises); + // If latest version is being updated: + if(latest){ + global.currentLatestVersion = version; + try { + + log("Sucessfully saved PewPew's latest version to file. ", LogLevel.INFO); + } catch (error) { + log("Writing latest PewPew's latest version to file failed: ", LogLevel.ERROR, error); + } + } log(PEWPEW_EXECUTABLE_NAME + " only uploaded, version: " + versionLogDisplay, LogLevel.INFO, { files, authPermissions: getLogAuthPermissions(authPermissions) }); return { json: { message: "PewPew uploaded, version: " + versionLogDisplay }, status: 200 }; } else { @@ -228,10 +238,14 @@ export async function deletePewPew (query: Partial{ + if(global.currentLatestVersion){ + return global.currentLatestVersion; + } try { - const latestVersion: string = latestPewPewInFile.version; - return latestVersion; + const pewpewTags = await s3.getTags({s3Folder: `${PEWPEW_BINARY_FOLDER}/${latestPewPewVersion}`, filename: PEWPEW_EXECUTABLE_NAME}); + global.currentLatestVersion = pewpewTags && pewpewTags.get(VERSION_TAG_NAME); // <- change to get the tag here + return global.currentLatestVersion; } catch (error) { log("Could not load latest pewpew in file", LogLevel.ERROR, error); throw error; From 22b431a800c93d08c07633f1fbcd67adceb3012d Mon Sep 17 00:00:00 2001 From: Bryan Lopez Date: Fri, 15 Mar 2024 12:22:31 -0400 Subject: [PATCH 04/11] removing files from tsconfig --- controller/tsconfig.json | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/controller/tsconfig.json b/controller/tsconfig.json index 21088f2a..d9fbba37 100644 --- a/controller/tsconfig.json +++ b/controller/tsconfig.json @@ -31,6 +31,5 @@ "include": [ "next-env.d.ts", "**/*.ts", - "**/*.tsx" -, ".latestpewpewversionfile.ts", "pages/api/util/.latestpewpewversionfile.ts" ] + "**/*.tsx"] } From 448db64ef9c0d5548a8d50309a97df2422199c8e Mon Sep 17 00:00:00 2001 From: Bryan Lopez Date: Fri, 15 Mar 2024 12:42:57 -0400 Subject: [PATCH 05/11] fixing lint rules --- controller/pages/api/util/pewpew.ts | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/controller/pages/api/util/pewpew.ts b/controller/pages/api/util/pewpew.ts index 5fd46ff1..51239800 100644 --- a/controller/pages/api/util/pewpew.ts +++ b/controller/pages/api/util/pewpew.ts @@ -47,8 +47,6 @@ export async function getPewPewVersionsInS3 (): Promise { localDirectory: LOCAL_FILE_LOCATION, extension: PEWPEW_EXECUTABLE_NAME }); - console.log("PEWPEW FILES FROM S3") - console.log(pewpewFiles) if (pewpewFiles.length === 0) { throw new Error("No pewpew binaries found in s3"); } @@ -82,8 +80,8 @@ export async function getPewpew (): Promise Date: Fri, 15 Mar 2024 12:57:55 -0400 Subject: [PATCH 06/11] fixing spacing as local linter didnt catch those but the build did --- controller/pages/api/util/pewpew.ts | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/controller/pages/api/util/pewpew.ts b/controller/pages/api/util/pewpew.ts index 51239800..af03379c 100644 --- a/controller/pages/api/util/pewpew.ts +++ b/controller/pages/api/util/pewpew.ts @@ -160,7 +160,7 @@ export async function postPewPew (parsedForm: ParsedForm, authPermissions: AuthP } await Promise.all(uploadPromises); // If latest version is being updated: - if(latest){ + if (latest) { global.currentLatestVersion = version; try { @@ -237,7 +237,7 @@ export async function deletePewPew (query: Partial{ - if(global.currentLatestVersion){ + if (global.currentLatestVersion) { return global.currentLatestVersion; } try { From c2d739743facc6287fa49118336b2aac29047209 Mon Sep 17 00:00:00 2001 From: Bryan Lopez Date: Fri, 15 Mar 2024 13:02:42 -0400 Subject: [PATCH 07/11] missed one space --- controller/pages/api/util/pewpew.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/controller/pages/api/util/pewpew.ts b/controller/pages/api/util/pewpew.ts index af03379c..d36d3cfb 100644 --- a/controller/pages/api/util/pewpew.ts +++ b/controller/pages/api/util/pewpew.ts @@ -236,7 +236,7 @@ export async function deletePewPew (query: Partial{ +export async function getCurrentPewPewLatestVersion (): Promise { if (global.currentLatestVersion) { return global.currentLatestVersion; } From 56a0d4d134a84ddb7bcba28c0f547c5b422e845c Mon Sep 17 00:00:00 2001 From: Bryan Lopez Date: Fri, 15 Mar 2024 17:29:21 -0400 Subject: [PATCH 08/11] adding tests, cleaning up files --- controller/integration/pewpew.spec.ts | 74 +++++++++++++++++++++++---- controller/pages/api/util/pewpew.ts | 2 +- controller/test/pewpew.spec.ts | 14 +++++ controller/tsconfig.json | 3 +- 4 files changed, 82 insertions(+), 11 deletions(-) diff --git a/controller/integration/pewpew.spec.ts b/controller/integration/pewpew.spec.ts index 75b85d64..01629553 100644 --- a/controller/integration/pewpew.spec.ts +++ b/controller/integration/pewpew.spec.ts @@ -1,8 +1,8 @@ import { AuthPermission, AuthPermissions, ErrorResponse, PewPewVersionsResponse, TestManagerError } from "../types"; import type { File, Files } from "formidable"; -import { LogLevel, log, logger } from "@fs/ppaas-common"; -import { ParsedForm, createFormidableFile, unzipFile } from "../pages/api/util/util"; -import { deletePewPew, getPewPewVersionsInS3, getPewpew, postPewPew } from "../pages/api/util/pewpew"; +import { LogLevel, PpaasS3File, log, logger } from "@fs/ppaas-common"; +import { PEWPEW_BINARY_FOLDER, ParsedForm, createFormidableFile, unzipFile } from "../pages/api/util/util"; +import { VERSION_TAG_NAME, deletePewPew, getCurrentPewPewLatestVersion, getPewPewVersionsInS3, getPewpew, postPewPew } from "../pages/api/util/pewpew"; import { expect } from "chai"; import { latestPewPewVersion } from "../pages/api/util/clientutil"; import path from "path"; @@ -28,6 +28,7 @@ const pewpewZipFile: File = createFormidableFile( ); let sharedPewPewVersions: string[] | undefined; let uploadedPewPewVersion: string | undefined; // Used for delete +let currentPewPewLatestVersion: string | undefined; describe("PewPew Util Integration", () => { let files: Files = {}; @@ -75,7 +76,7 @@ describe("PewPew Util Integration", () => { files }; log("postPewPew parsedForm", LogLevel.DEBUG, parsedForm); - postPewPew(parsedForm, authAdmin).then((res: ErrorResponse) => { + postPewPew(parsedForm, authAdmin).then(async (res: ErrorResponse) => { log("postPewPew res", LogLevel.DEBUG, res); expect(res.status, JSON.stringify(res.json)).to.equal(200); const body: TestManagerError = res.json; @@ -97,6 +98,21 @@ describe("PewPew Util Integration", () => { sharedPewPewVersions.push(version); } log("sharedPewPewVersions: " + sharedPewPewVersions, LogLevel.DEBUG); + try { + const pewpewFiles = await PpaasS3File.getAllFilesInS3({ + s3Folder: `${PEWPEW_BINARY_FOLDER}/${version}`, + localDirectory: process.env.TEMP || "/tmp" + }); + expect(pewpewFiles).to.not.equal(undefined); + expect(pewpewFiles.length).to.be.greaterThan(0); + const pewpewFile = pewpewFiles.find( (file) => file.filename === "pewpew"); + expect(pewpewFile).to.not.equal(undefined); + expect(pewpewFile?.tags).to.not.equal(undefined); + expect(pewpewFile?.tags?.get(VERSION_TAG_NAME)).to.equal(version); + } catch (error) { + log("postPewPew error while checking latest tag: ", LogLevel.ERROR, error); + throw error; + } done(); }).catch((error) => { log("postPewPew error", LogLevel.ERROR, error); @@ -112,7 +128,7 @@ describe("PewPew Util Integration", () => { files }; log("postPewPew parsedForm", LogLevel.DEBUG, parsedForm); - postPewPew(parsedForm, authAdmin).then((res: ErrorResponse) => { + postPewPew(parsedForm, authAdmin).then(async (res: ErrorResponse) => { log("postPewPew res", LogLevel.DEBUG, res); expect(res.status, JSON.stringify(res.json)).to.equal(200); const body: TestManagerError = res.json; @@ -121,14 +137,34 @@ describe("PewPew Util Integration", () => { expect(body.message).to.not.equal(undefined); expect(body.message).to.include("PewPew uploaded, version"); expect(body.message).to.include("as latest"); - const version = latestPewPewVersion; + const match: RegExpMatchArray | null = body.message.match(/PewPew uploaded, version: (\d+\.\d+\.\d+)/); + log(`pewpew match: ${match}`, LogLevel.DEBUG, match); + expect(match, "pewpew match").to.not.equal(null); + expect(match!.length, "pewpew match.length").to.be.greaterThan(1); + const version: string = match![1]; // If this runs before the other acceptance tests populate the shared pewpew versions if (!sharedPewPewVersions) { - sharedPewPewVersions = [version]; - } else if (!sharedPewPewVersions.includes(version)) { - sharedPewPewVersions.push(version); + sharedPewPewVersions = [latestPewPewVersion]; + } else if (!sharedPewPewVersions.includes(latestPewPewVersion)) { + sharedPewPewVersions.push(latestPewPewVersion); } log("sharedPewPewVersions: " + sharedPewPewVersions, LogLevel.DEBUG); + try { + const pewpewFiles = await PpaasS3File.getAllFilesInS3({ + s3Folder: `${PEWPEW_BINARY_FOLDER}/${latestPewPewVersion}`, + localDirectory: process.env.TEMP || "/tmp" + }); + expect(pewpewFiles).to.not.equal(undefined); + expect(pewpewFiles.length).to.be.greaterThan(0); + const pewpewFile = pewpewFiles.find( (file) => file.filename === "pewpew"); + expect(pewpewFile).to.not.equal(undefined); + expect(pewpewFile?.tags).to.not.equal(undefined); + expect(pewpewFile?.tags?.get(VERSION_TAG_NAME)).to.equal(version); + } catch (error) { + log("postPewPew error while checking latest tag: ", LogLevel.ERROR, error); + throw error; + } + currentPewPewLatestVersion = version; done(); }).catch((error) => { log("postPewPew error", LogLevel.ERROR, error); @@ -138,6 +174,20 @@ describe("PewPew Util Integration", () => { }); describe("getPewpew", () => { + before(async () => { + try { + const pewpewFiles = await PpaasS3File.getAllFilesInS3({ + s3Folder: `${PEWPEW_BINARY_FOLDER}/${latestPewPewVersion}`, + localDirectory: process.env.TEMP || "/tmp" + }); + expect(pewpewFiles).to.not.equal(undefined); + const pewpewFile = pewpewFiles.find( (file) => file.filename === "pewpew"); + expect(pewpewFile).to.not.equal(undefined); + } catch (error) { + log("getCurrentPewPewLatest Version failed: ", LogLevel.ERROR, error); + throw error; + } + }); it("getPewpew should respond 200 OK", (done: Mocha.Done) => { expect(sharedPewPewVersions, "sharedPewPewVersions").to.not.equal(undefined); getPewpew().then((res: ErrorResponse | PewPewVersionsResponse) => { @@ -153,6 +203,12 @@ describe("PewPew Util Integration", () => { done(); }).catch((error) => done(error)); }); + + it("getCurrentPewPewLatestVersion", async () => { + expect(currentPewPewLatestVersion, "currentPewPewLatestVersion").to.not.equal(undefined); + const result = await getCurrentPewPewLatestVersion(); + expect(result, "result").to.equal(currentPewPewLatestVersion); + }); }); describe("deletePewPew", () => { diff --git a/controller/pages/api/util/pewpew.ts b/controller/pages/api/util/pewpew.ts index d36d3cfb..52b73db4 100644 --- a/controller/pages/api/util/pewpew.ts +++ b/controller/pages/api/util/pewpew.ts @@ -33,7 +33,7 @@ logger.config.LogFileName = "ppaas-controller"; const deleteS3 = s3.deleteObject; export const PEWPEW_EXECUTABLE_NAME: string = "pewpew"; const PEWPEW_EXECUTABLE_NAME_WINDOWS: string = "pewpew.exe"; -const VERSION_TAG_NAME: string = "version"; +export const VERSION_TAG_NAME: string = "version"; /** * Queries S3 for all objects in the pewpew/ folder that end with pewpew (not pewpew.exe). diff --git a/controller/test/pewpew.spec.ts b/controller/test/pewpew.spec.ts index 38a1d8a2..6b33b52f 100644 --- a/controller/test/pewpew.spec.ts +++ b/controller/test/pewpew.spec.ts @@ -15,7 +15,9 @@ import { } from "../pages/api/util/util"; import { PEWPEW_EXECUTABLE_NAME, + VERSION_TAG_NAME, deletePewPew, + getCurrentPewPewLatestVersion, getPewPewVersionsInS3, getPewpew, postPewPew @@ -106,6 +108,18 @@ describe("PewPew Util", () => { resetMockS3(); }); + describe("getCurrentPewPewLatestVersion", () => { + it("getCurrentPewPewLatestVersion should return version with latest tag from S3", (done: Mocha.Done) => { + const expected = "0.5.13"; + mockGetObjectTagging(new Map([[VERSION_TAG_NAME, expected]])); + getCurrentPewPewLatestVersion().then((result: string | undefined) => { + log("getPewPewVersionsInS3()", LogLevel.DEBUG, result); + expect(result).to.equal(expected); + done(); + }).catch((error) => done(error)); + }); + }); + describe("getPewPewVersionsInS3", () => { it("getPewPewVersionsInS3() should return array with elements", (done: Mocha.Done) => { mockListObjects(versions.map((version): S3Object => ({ ...s3Object, Key: `${pewpewS3Folder}/${version}/${pewpewFilename}` }))); diff --git a/controller/tsconfig.json b/controller/tsconfig.json index d9fbba37..9ceb92ae 100644 --- a/controller/tsconfig.json +++ b/controller/tsconfig.json @@ -31,5 +31,6 @@ "include": [ "next-env.d.ts", "**/*.ts", - "**/*.tsx"] + "**/*.tsx" + ] } From de0396ab9d5b538f0838f20202bdc48aa73b1ced Mon Sep 17 00:00:00 2001 From: Bryan Lopez Date: Fri, 15 Mar 2024 17:34:35 -0400 Subject: [PATCH 09/11] removing trailing spaces failing on build --- controller/components/PewPewVersions/story.tsx | 2 +- controller/integration/pewpew.spec.ts | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/controller/components/PewPewVersions/story.tsx b/controller/components/PewPewVersions/story.tsx index 2c23991c..8ffdd9d8 100644 --- a/controller/components/PewPewVersions/story.tsx +++ b/controller/components/PewPewVersions/story.tsx @@ -15,7 +15,7 @@ const props: VersionProps = { console.log("newVal: ", newVal); }, pewpewVersions: ["0.1.1", "0.1.2", "0.1.3", "0.1.4", "0.1.5", latestPewPewVersion, "0.1.6"], - latestPewPewVersion : "latestVersion", + latestPewPewVersion: "latestVersion", loading: false, error: false }; diff --git a/controller/integration/pewpew.spec.ts b/controller/integration/pewpew.spec.ts index 01629553..9fb2e6ba 100644 --- a/controller/integration/pewpew.spec.ts +++ b/controller/integration/pewpew.spec.ts @@ -112,7 +112,7 @@ describe("PewPew Util Integration", () => { } catch (error) { log("postPewPew error while checking latest tag: ", LogLevel.ERROR, error); throw error; - } + } done(); }).catch((error) => { log("postPewPew error", LogLevel.ERROR, error); From f07dd19bd57c8283148e0fffdb4518bcfdb82fe6 Mon Sep 17 00:00:00 2001 From: Bryan Lopez Date: Mon, 18 Mar 2024 10:46:09 -0400 Subject: [PATCH 10/11] adding DS_Store - make specific file to gitignore --- .gitignore | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index c4aba493..882a8fdd 100644 --- a/.gitignore +++ b/.gitignore @@ -18,4 +18,4 @@ testmerge.json .env.development.local* .env.test.local* .env.production.local* - +.DS_Store From 7d03c608afefdbbffcafa2136eea93b7c5c0129e Mon Sep 17 00:00:00 2001 From: Bryan Lopez Date: Mon, 18 Mar 2024 11:20:17 -0400 Subject: [PATCH 11/11] updating storybook to show pewpew latest version output --- controller/components/PewPewVersions/story.tsx | 6 +++--- controller/components/StartTestForm/story.tsx | 4 ++-- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/controller/components/PewPewVersions/story.tsx b/controller/components/PewPewVersions/story.tsx index 8ffdd9d8..42c4b011 100644 --- a/controller/components/PewPewVersions/story.tsx +++ b/controller/components/PewPewVersions/story.tsx @@ -15,12 +15,12 @@ const props: VersionProps = { console.log("newVal: ", newVal); }, pewpewVersions: ["0.1.1", "0.1.2", "0.1.3", "0.1.4", "0.1.5", latestPewPewVersion, "0.1.6"], - latestPewPewVersion: "latestVersion", + latestPewPewVersion: "0.1.6", loading: false, error: false }; -const propsLoading: VersionProps = { ...props, pewpewVersions: [], loading: true }; -const propsError: VersionProps = { ...props, error: true }; +const propsLoading: VersionProps = { ...props, pewpewVersions: [], latestPewPewVersion: "unknown", loading: true }; +const propsError: VersionProps = { ...props, error: true, latestPewPewVersion: "unknown" }; export default { title: "PewPewVersions" diff --git a/controller/components/StartTestForm/story.tsx b/controller/components/StartTestForm/story.tsx index ef000689..18560c4e 100644 --- a/controller/components/StartTestForm/story.tsx +++ b/controller/components/StartTestForm/story.tsx @@ -38,7 +38,7 @@ const versionInitalPropsEmpty: VersionInitalProps = { pewpewVersion: "", loading: false, pewpewVersions: [], - latestPewPewVersion: "", + latestPewPewVersion: "unknown", error: true }; const queueInitialProps: QueueInitialProps = { @@ -51,7 +51,7 @@ const versionInitalProps: VersionInitalProps = { pewpewVersion: "", loading: false, pewpewVersions: [latestPewPewVersion, "0.5.10", "0.5.11", "0.5.12"], - latestPewPewVersion: "latest", + latestPewPewVersion: "0.5.12", error: false }; let ppaasTestId: PpaasTestId;