From 5c3f8656041461c5489a9f32efdbeba61f7ebbd8 Mon Sep 17 00:00:00 2001 From: Dunemask Date: Tue, 12 Jul 2022 02:44:44 +0000 Subject: [PATCH] Updated things for compound testing --- dev/suite/runner.js | 4 +- lib/core/Qualiteer.js | 5 ++- lib/core/job-builder.js | 4 +- lib/core/server.js | 2 +- lib/rabbit/rabbit-workers.js | 7 ++- lib/rabbit/workers/TestResultsWorker.js | 24 +++++++++- lib/rabbit/workers/index.js | 3 +- lib/routes/dev-route.js | 5 +-- lib/sockets/clients/Initiator.js | 59 +++++++++++++++++++++++++ lib/sockets/events.js | 4 ++ lib/sockets/handler.js | 1 + src/Views.jsx | 6 +-- src/views/Jobs.jsx | 21 ++++++--- src/views/components/JobLogView.jsx | 25 +++++++---- src/views/components/JobView.jsx | 39 ++++++++-------- tests/index.js | 7 +-- 16 files changed, 160 insertions(+), 56 deletions(-) diff --git a/dev/suite/runner.js b/dev/suite/runner.js index 17168ab..458547d 100644 --- a/dev/suite/runner.js +++ b/dev/suite/runner.js @@ -11,7 +11,7 @@ const reportingUrl = `${process.env.QUALITEER_URL}/api/dev/rabbit/TestResults`; const args = process.argv.slice(2); const test = (args.find((v)=>v.includes("test=")) ?? "").replace("test=",""); const pipelineData = (args.find((v)=>v.includes("pipelineData=")) ?? "").replace("pipelineData=",""); -const pipelineLife = parseInt((args.find((v)=>v.includes("pipelineLife=")) ?? "0").replace("pipelineLife=","")); +const pipelineTriggers = (args.find((v)=>v.includes("pipelineTriggers=")) ?? "").replace("pipelineTriggers=",""); const pipelineDashboardSocket = (args.find((v)=>v.includes("pipelineDashboardSocket=")) ?? "").replace("pipelineDashboardSocket=","") || undefined; const logNow = () => console.log(Date.now()); @@ -38,7 +38,7 @@ const runTests = () => { liveIndicator(); setTimeout(()=>{ const status = runTests(); -const testResult = {...status, name:test, pipelineLife, pipelineDashboardSocket} +const testResult = {...status, name:test, pipelineTriggers: pipelineTriggers ? pipelineTriggers : undefined, pipelineDashboardSocket} axios.post(reportingUrl, {testResult}).catch((e)=>{console.log(e.response.status)}); },endLiveCount * 1000); diff --git a/lib/core/Qualiteer.js b/lib/core/Qualiteer.js index 92f8ea2..efaef7f 100644 --- a/lib/core/Qualiteer.js +++ b/lib/core/Qualiteer.js @@ -7,7 +7,7 @@ import { INFO, OK, logInfo } from "../util/logging.js"; import expressApp from "./server.js"; import applySockets from "../sockets/handler.js"; import jobManager from "./JobManager.js"; -import rabbiteer from "../rabbit/rabbit-workers.js"; +import getRabbiteer from "../rabbit/rabbit-workers.js"; // Constants const title = "QLTR"; @@ -27,7 +27,8 @@ export default class Qualiteer { this.app = expressApp; this.server = http.createServer(this.app); this.sockets = applySockets(this.server, this.jobs); - this.rabbiteer = rabbiteer; + this.app.set("socketio", this.sockets); + this.rabbiteer = getRabbiteer(this.sockets); } start() { diff --git a/lib/core/job-builder.js b/lib/core/job-builder.js index 7ac1233..e0dd9c0 100644 --- a/lib/core/job-builder.js +++ b/lib/core/job-builder.js @@ -34,8 +34,8 @@ const pipelineMaxLife = (testName) => { const buildCompound = (jobReq, socketId) => { const { testName, command } = jobReq; - const pipelineLife = jobReq.pipelineLife ?? pipelineMaxLife(testName); - command.push(`pipelineLife=${pipelineLife}`); + const pipelineTriggers = jobReq.pipelineTriggers; + if (pipelineTriggers) command.push(`pipelineTriggers=${pipelineTriggers}`); command.push(`pipelineDashboardSocket=${socketId}`); return { ...jobReq, command }; }; diff --git a/lib/core/server.js b/lib/core/server.js index 32b01bb..ff9afbc 100644 --- a/lib/core/server.js +++ b/lib/core/server.js @@ -14,7 +14,7 @@ const app = express(); // Special Routes app.all("/", (req, res) => res.redirect("/qualiteer")); if (process.env.MOCK_ROUTES === "true") app.use(mock); -if(process.env.USE_DEV_ROUTER === "true") app.use("/api/dev",dev); +if (process.env.USE_DEV_ROUTER === "true") app.use("/api/dev", dev); // Middlewares diff --git a/lib/rabbit/rabbit-workers.js b/lib/rabbit/rabbit-workers.js index 0d7a8bd..13b1da9 100644 --- a/lib/rabbit/rabbit-workers.js +++ b/lib/rabbit/rabbit-workers.js @@ -1,5 +1,5 @@ import Rabbiteer from "rabbiteer"; -import workers from "./workers/index.js"; +import getWorkers from "./workers/index.js"; // Pull Environment Variables const { RABBIT_HOST: host, RABBIT_USER: user, RABBIT_PASS: pass } = process.env; @@ -11,4 +11,7 @@ const rabbitConfig = { pass: pass ?? "rabbit", }; -export default new Rabbiteer(null, workers, { autoRabbit: rabbitConfig }); +const getRabbiteer = (skio) => + new Rabbiteer(null, getWorkers(skio), { autoRabbit: rabbitConfig }); + +export default getRabbiteer; diff --git a/lib/rabbit/workers/TestResultsWorker.js b/lib/rabbit/workers/TestResultsWorker.js index 741870f..5009d88 100644 --- a/lib/rabbit/workers/TestResultsWorker.js +++ b/lib/rabbit/workers/TestResultsWorker.js @@ -1,9 +1,11 @@ // Imports import { Worker } from "rabbiteer"; +import evt from "../../sockets/events.js"; // Class export default class TestResultsWorker extends Worker { - constructor() { + constructor(skio) { super("TestResults"); + this.skio = skio; } /* Example Test Result @@ -22,6 +24,24 @@ export default class TestResultsWorker extends Worker { } */ onMessage(testResult) { - console.log(testResult); + const { pipelineData, pipelineTriggers, pipelineDelay } = testResult; + const pipelineTrigger = { pipelineData, pipelineTriggers, pipelineDelay }; + // Alter to start next test + // TODO the delay should be autopopulated either by the suite, or filled in by the server + if (pipelineTriggers) + return this.pipelineTrigger( + pipelineTrigger, + testResult.pipelineDashboardSocket + ); + this.pipelineClose(testResult.pipelineDashboardSocket); + } + + pipelineTrigger(pipelineTrigger, socketId) { + pipelineTrigger.pipelineDelay = 1000 * 5; + this.skio.to(socketId).emit(evt.PPL_TRG, pipelineTrigger); + } + + pipelineClose(socketId) { + this.skio.to(socketId).emit(evt.PPL_CLS); } } diff --git a/lib/rabbit/workers/index.js b/lib/rabbit/workers/index.js index 36149dc..6b9c976 100644 --- a/lib/rabbit/workers/index.js +++ b/lib/rabbit/workers/index.js @@ -1,3 +1,4 @@ import TestResultsWorker from "./TestResultsWorker.js"; -export default [new TestResultsWorker()]; +const getWorkers = (skio) => [new TestResultsWorker(skio)]; +export default getWorkers; diff --git a/lib/routes/dev-route.js b/lib/routes/dev-route.js index 68d1358..74aa541 100644 --- a/lib/routes/dev-route.js +++ b/lib/routes/dev-route.js @@ -1,13 +1,12 @@ import { Router, json as jsonMiddleware } from "express"; import TestResultsWorker from "../rabbit/workers/TestResultsWorker.js"; -const testResultsHandler = new TestResultsWorker(); - const router = Router(); router.use(jsonMiddleware()); router.post("/rabbit/TestResults", (req, res) => { const { testResult } = req.body; - testResultsHandler.onMessage(testResult); + var io = req.app.get("socketio"); + new TestResultsWorker(io).onMessage(testResult); res.sendStatus(200); }); diff --git a/lib/sockets/clients/Initiator.js b/lib/sockets/clients/Initiator.js index 74c79a1..2600444 100644 --- a/lib/sockets/clients/Initiator.js +++ b/lib/sockets/clients/Initiator.js @@ -12,6 +12,11 @@ export default class Initiator { this.onLog = options.onLog ?? ((d) => console.log(`job: ${d}`)); this.onClose = options.onClose ?? (() => {}); this.onCreate = options.onCreate ?? ((id) => console.log(`job id: ${id}`)); + this.onPipelineClose = + options.onPipelineClose ?? + (() => { + console.log("job pipeline closed"); + }); } async newJob(jobRequest, onLog, onClose, onCreate) { @@ -31,4 +36,58 @@ export default class Initiator { }) ); } + + async newPipelineJob( + jobRequest, + onLog, + onClose, + onCreate, + onPipelineTrigger, + onPipelineClose + ) { + const mgr = new Manager(this.url, { + query: { mode: this.mode, job: JSON.stringify(jobRequest) }, + }); + onLog = onLog ?? this.onLog.bind(this); + onClose = onClose ?? this.onClose.bind(this); + onCreate = onCreate ?? this.onCreate.bind(this); + onPipelineTrigger = + onPipelineTrigger ?? + ((trigger) => { + console.log("job trg:", trigger); + const testName = trigger.pipelineTriggers; + const pipelineData = trigger.pipelineData; + const pipelineTriggers = trigger.newPipelineTriggers; + const jobReq = { + ...jobRequest, + testName, + pipelineData, + pipelineTriggers, + }; + setTimeout( + () => + this.newPipelineJob( + jobReq, + onLog, + onClose, + onCreate, + onPipelineTrigger, + onPipelineClose + ), + trigger.pipelineDelay + ); + }); + onPipelineClose = onPipelineClose ?? this.onPipelineClose.bind(this); + const sk = mgr.socket("/"); + sk.on(events.JOB_LOG, onLog); + sk.on(events.JOB_CLS, onClose); + sk.on(events.PPL_TRG, onPipelineTrigger); + sk.on(events.PPL_CLS, onPipelineClose); + return new Promise((res) => + sk.on(events.JOB_CRT, function onJobCreate(id) { + onCreate(id); + res({ ...jobRequest, id }); + }) + ); + } } diff --git a/lib/sockets/events.js b/lib/sockets/events.js index 20b9136..68885e8 100644 --- a/lib/sockets/events.js +++ b/lib/sockets/events.js @@ -2,6 +2,8 @@ const JOB_REP = "jr"; // Job Report Event const JOB_LOG = "jl"; // Job Log Event const JOB_CLS = "jc"; // Job Close Event const JOB_CRT = "jcr"; // Job Create Event +const PPL_TRG = "plr"; // Pipeline Trigger Event +const PPL_CLS = "plc"; // Pipeline Close Event const ERR = "e"; // Socket Error export default { @@ -9,5 +11,7 @@ export default { JOB_LOG, JOB_CLS, JOB_CRT, + PPL_TRG, + PPL_CLS, ERR, }; diff --git a/lib/sockets/handler.js b/lib/sockets/handler.js index 9631eb1..aad913f 100644 --- a/lib/sockets/handler.js +++ b/lib/sockets/handler.js @@ -43,6 +43,7 @@ const applySockets = (server, jobs, options) => { io.on("connection", (socket) => socketConnect(io, socket, jobs)); io.of("/").adapter.on("leave-room", (room, id) => socketDrop(io, room, id)); return io; + cle; }; export default applySockets; diff --git a/src/Views.jsx b/src/Views.jsx index 8f4fd8a..d2e077e 100644 --- a/src/Views.jsx +++ b/src/Views.jsx @@ -3,11 +3,7 @@ import StoreContext from "./ctx/StoreContext.jsx"; import JobContext from "./ctx/JobContext.jsx"; import Navbar from "./Navbar.jsx"; -import { - Routes, - Route, - Navigate, -} from "react-router-dom"; +import { Routes, Route, Navigate } from "react-router-dom"; import Box from "@mui/material/Box"; import Toolbar from "@mui/material/Toolbar"; import IconButton from "@mui/material/IconButton"; diff --git a/src/views/Jobs.jsx b/src/views/Jobs.jsx index 36f3d88..0b78c12 100644 --- a/src/views/Jobs.jsx +++ b/src/views/Jobs.jsx @@ -51,7 +51,7 @@ export default function Jobs() { const handleClickOpen = () => setJobDialogOpen(true); const [queued, setQueued] = useState([]); - useEffect(() => { }, [jobState.jobs, location]); + useEffect(() => {}, [jobState.jobs, location]); const handleClose = (confirmed) => () => { setJobDialogOpen(false); @@ -61,11 +61,20 @@ export default function Jobs() { return (
- {location.hash === "" && jobState.jobs.map((v, i) => ( - - ))} - {jobState.jobs.find((job)=>job.name===location.hash.slice(1)) && ( - job.name===location.hash.slice(1))}/> + {location.hash === "" && + jobState.jobs.map((v, i) => ( + + + + ))} + {jobState.jobs.find((job) => job.name === location.hash.slice(1)) && ( + job.name === location.hash.slice(1))} + /> )} diff --git a/src/views/components/JobLogView.jsx b/src/views/components/JobLogView.jsx index 637813f..65b4d5c 100644 --- a/src/views/components/JobLogView.jsx +++ b/src/views/components/JobLogView.jsx @@ -9,8 +9,15 @@ import Stack from "@mui/material/Stack"; export default function JobLogView(props) { const { log } = props; - const LoadingDot = () => () - + const LoadingDot = () => ( + + ); + return ( {log.map((l, i) => ( - + {i + 1} @@ -50,10 +57,10 @@ export default function JobLogView(props) { ))} - - - - + + + + ); diff --git a/src/views/components/JobView.jsx b/src/views/components/JobView.jsx index e08594e..f5b8f2f 100644 --- a/src/views/components/JobView.jsx +++ b/src/views/components/JobView.jsx @@ -15,18 +15,14 @@ export default function JobView(props) { const { job: initJob } = props; const [job, setJob] = useState({ log: [initJob.name] }); - function retryJob(){ - - } - - function downloadLog(){ - - } + function retryJob() {} - function navigateToJobs(){ + function downloadLog() {} + + function navigateToJobs() { navigate("/jobs"); } - + function onLog(d) { const j = { ...job }; j.log.push(d); @@ -37,14 +33,21 @@ export default function JobView(props) { - - - - {initJob.name} - - + sx={{ + backgroundColor: "rgba(0,0,0,0)", + boxShadow: "none", + color: "black", + }} + > + + + + + + {initJob.name} + + + @@ -59,7 +62,7 @@ export default function JobView(props) { > Hello{" "} - + ); diff --git a/tests/index.js b/tests/index.js index d554929..6b40b3f 100644 --- a/tests/index.js +++ b/tests/index.js @@ -14,9 +14,10 @@ const primary = new Initiator(url); const job = { type: "compound", testName: "primary", - pipelineLife: 1, + pipelineTriggers: "secondary", name: "testing", image: "node", }; -await primary.newJob(job, null, () => console.log("Primary Job Concluded")); - +await primary.newPipelineJob(job, null, () => + console.log("Primary Job Concluded") +);