Savepoint
This commit is contained in:
parent
7db1a3456b
commit
02c483950c
45 changed files with 5136 additions and 256 deletions
|
@ -6,11 +6,10 @@ const jobStr = process.argv.slice(2)[0];
|
|||
const job = JSON.parse(jobStr);
|
||||
const { command } = job.spec.template.spec.containers[0];
|
||||
INFO("EXEC", "Internal Executor Starting!");
|
||||
cp.exec(command, (error, stdout, stderr)=>{
|
||||
if(error) ERR("EXEC", error);
|
||||
//if(stdout) VERB("EXEC-STDOUT", stdout);
|
||||
//if(stderr) VERB("EXEC-STDERR", stderr);
|
||||
OK("EXEC", "Internal Executor Finished!");
|
||||
process.exit(error? 1 : 0 );
|
||||
cp.exec(command, (error, stdout, stderr) => {
|
||||
if (error) ERR("EXEC", error);
|
||||
//if(stdout) VERB("EXEC-STDOUT", stdout);
|
||||
//if(stderr) VERB("EXEC-STDERR", stderr);
|
||||
OK("EXEC", "Internal Executor Finished!");
|
||||
process.exit(error ? 1 : 0);
|
||||
});
|
||||
|
||||
|
|
|
@ -5,9 +5,11 @@ import path from "path";
|
|||
const internalDeploy = process.env.INTERNAL_DEPLOY === "true";
|
||||
const executorUrl = process.env.EXECUTOR_URL;
|
||||
const executorScriptOnly = process.env.EXECUTOR_SCRIPT_ONLY === "true";
|
||||
const executorBin = process.env.EXECUTOR_BIN ?? `qltr-executor${executorScriptOnly ? ".js": ""}`;
|
||||
const executorBin =
|
||||
process.env.EXECUTOR_BIN ?? `qltr-executor${executorScriptOnly ? ".js" : ""}`;
|
||||
|
||||
const qualiteerUrl = process.env.QUALITEER_URL ?? "file:///home/runner/Qualiteer/bin/executor";
|
||||
const qualiteerUrl =
|
||||
process.env.QUALITEER_URL ?? "file:///home/runner/Qualiteer/bin/executor";
|
||||
|
||||
const kubCmd = "kubectl apply -f";
|
||||
const jobsDir = "jobs/";
|
||||
|
@ -16,11 +18,15 @@ const defaults = JSON.parse(
|
|||
);
|
||||
|
||||
const wrapCommand = (jobId, command) => {
|
||||
const bin = executorScriptOnly ? `node ${executorBin}`:`chmod +x ${executorBin} && ./${executorBin}`;
|
||||
const cmd = command.map((arg)=>JSON.stringify(arg))
|
||||
const curlCmd = `curl -o qltr-executor ${executorUrl} && ${bin} ${qualiteerUrl} ${jobId} ${cmd.join(" ")}`;
|
||||
const bin = executorScriptOnly
|
||||
? `node ${executorBin}`
|
||||
: `chmod +x ${executorBin} && ./${executorBin}`;
|
||||
const cmd = command.map((arg) => JSON.stringify(arg));
|
||||
const curlCmd = `curl -o qltr-executor ${executorUrl} && ${bin} ${qualiteerUrl} ${jobId} ${cmd.join(
|
||||
" "
|
||||
)}`;
|
||||
return curlCmd;
|
||||
}
|
||||
};
|
||||
|
||||
const createFile = (job) => {
|
||||
const { name } = job.metadata;
|
||||
|
|
|
@ -5,11 +5,15 @@ import express from "express";
|
|||
import results from "../routes/results-route.js";
|
||||
import alerting from "../routes/alerting-route.js";
|
||||
import react from "../routes/react-route.js";
|
||||
import tests from "../routes/tests-route.js";
|
||||
import catalog from "../routes/catalog-route.js";
|
||||
import jobs from "../routes/jobs-route.js";
|
||||
|
||||
import mock from "../routes/mock-route.js";
|
||||
|
||||
const app = express();
|
||||
// Special Routes
|
||||
app.all("/", (req, res) => res.redirect("/qualiteer"));
|
||||
if (process.env.MOCK_ROUTES === "true") app.use(mock);
|
||||
|
||||
// Middlewares
|
||||
|
||||
|
@ -17,7 +21,7 @@ app.all("/", (req, res) => res.redirect("/qualiteer"));
|
|||
app.use(react); // Static Build Route
|
||||
app.use("/api/results", results);
|
||||
app.use("/api/alerting", alerting);
|
||||
app.use("/api/tests", tests);
|
||||
app.use("/api/catalog", catalog);
|
||||
app.use("/api/jobs", jobs);
|
||||
|
||||
export default app;
|
||||
|
|
|
@ -1,32 +1,34 @@
|
|||
CREATE SEQUENCE test_results_id_seq;
|
||||
CREATE TABLE test_results (
|
||||
id bigint NOT NULL DEFAULT nextval('test_results_seq') PRIMARY KEY,
|
||||
test_name varchar(255) DEFAULT NULL,
|
||||
test_class varchar(255) DEFAULT NULL,
|
||||
test_method varchar(255) DEFAULT NULL,
|
||||
test_path varchar(255) DEFAULT NULL,
|
||||
test_type varchar(32) DEFAULT NULL,
|
||||
test_timestamp timestamptz NOT NULL DEFAULT now(),
|
||||
test_retry BOOLEAN DEFAULT FALSE,
|
||||
origin varchar(255) DEFAULT NULL,
|
||||
failed BOOLEAN DEFAULT FALSE,
|
||||
failed_message varchar(2047) DEFAULT NULL,
|
||||
screenshot_url varchar(255) DEFAULT NULL,
|
||||
weblog_url varchar(255) DEFAULT NULL,
|
||||
id bigint NOT NULL DEFAULT nextval('test_results_seq') PRIMARY KEY,
|
||||
test_name varchar(255) DEFAULT NULL,
|
||||
test_class varchar(255) DEFAULT NULL,
|
||||
test_method varchar(255) DEFAULT NULL,
|
||||
test_path varchar(255) DEFAULT NULL,
|
||||
test_type varchar(32) DEFAULT NULL,
|
||||
test_timestamp timestamptz NOT NULL DEFAULT now(),
|
||||
test_retry BOOLEAN DEFAULT FALSE,
|
||||
origin varchar(255) DEFAULT NULL,
|
||||
failed BOOLEAN DEFAULT FALSE,
|
||||
failed_message varchar(2047) DEFAULT NULL,
|
||||
screenshot_url varchar(255) DEFAULT NULL,
|
||||
weblog_url varchar(255) DEFAULT NULL,
|
||||
);
|
||||
ALTER SEQUENCE test_results_id_seq OWNED BY test_results.id;
|
||||
|
||||
# Tables
|
||||
|
||||
PG Database Tables Mapped Out
|
||||
|
||||
## ```test_results```
|
||||
## `test_results`
|
||||
|
||||
| id | test_name | test_class | test_method | test_path | test_type | test_timestamp | test_retry | origin | failed | failed_message | screenshot_url | weblog_url |
|
||||
| int | string | string | string | string | string | timestamp | boolean | string | boolean | string | string | string |
|
||||
| 1 | My Test | My Test Class | My Failing Test Method | My Test Class Path | API | Date.now() | false | Test Suite A | true | Some Failure Messsage | screenshotUrl | weblogUrl |
|
||||
|
||||
- id Automatically Generated
|
||||
- test_name\* Name of test
|
||||
- test_class\* Name of class
|
||||
- test_class\* Name of class
|
||||
- test_method Name of failed method if failed else null
|
||||
- test_path Path to test class
|
||||
- test_type API/UI/Mobile
|
||||
|
@ -35,8 +37,5 @@ PG Database Tables Mapped Out
|
|||
- origin Test Suite test belongs to
|
||||
- failed Indicates if the test failed or not
|
||||
- failed_message Failure Message of test or null
|
||||
- screenshot_url Screenshot of failure
|
||||
- screenshot_url Screenshot of failure
|
||||
- weblog_url Log from the web console
|
||||
|
||||
|
||||
|
||||
|
|
|
@ -1,19 +1,14 @@
|
|||
CREATE SEQUENCE test_results_id_seq;
|
||||
CREATE TABLE test_results (
|
||||
id bigint NOT NULL DEFAULT nextval('test_results_seq') PRIMARY KEY,
|
||||
test_name varchar(255) DEFAULT NULL,
|
||||
test_class varchar(255) DEFAULT NULL,
|
||||
test_method varchar(255) DEFAULT NULL,
|
||||
test_path varchar(255) DEFAULT NULL,
|
||||
test_type varchar(32) DEFAULT NULL,
|
||||
test_timestamp timestamptz NOT NULL DEFAULT now(),
|
||||
test_retry BOOLEAN DEFAULT FALSE,
|
||||
origin varchar(255) DEFAULT NULL,
|
||||
id bigint NOT NULL DEFAULT nextval('test_results_id_seq') PRIMARY KEY,
|
||||
name varchar(255) DEFAULT NULL,
|
||||
"method" varchar(255) DEFAULT NULL,
|
||||
env varchar(31) DEFAULT NULL,
|
||||
"timestamp" TIMESTAMP NOT NULL DEFAULT now(),
|
||||
retry BOOLEAN DEFAULT FALSE,
|
||||
failed BOOLEAN DEFAULT FALSE,
|
||||
failed_message varchar(2047) DEFAULT NULL,
|
||||
screenshot_url varchar(255) DEFAULT NULL,
|
||||
weblog_url varchar(255) DEFAULT NULL,
|
||||
screenshot varchar(255) DEFAULT NULL,
|
||||
weblog varchar(255) DEFAULT NULL
|
||||
);
|
||||
ALTER SEQUENCE test_results_id_seq OWNED BY test_results.id;
|
||||
|
||||
|
||||
ALTER SEQUENCE test_results_id_seq OWNED BY test_results.id;
|
18
lib/database/migrations/2_create_catalog_table.sql
Normal file
18
lib/database/migrations/2_create_catalog_table.sql
Normal file
|
@ -0,0 +1,18 @@
|
|||
CREATE SEQUENCE test_catalog_id_seq;
|
||||
CREATE TABLE test_catalog (
|
||||
id bigint NOT NULL DEFAULT nextval('test_catalog_id_seq') PRIMARY KEY,
|
||||
name varchar(255) DEFAULT NULL,
|
||||
class varchar(255) DEFAULT NULL,
|
||||
compound BOOLEAN DEFAULT FALSE,
|
||||
type varchar(31) DEFAULT NULL,
|
||||
markers varchar(255)[] DEFAULT NULL,
|
||||
ignored BOOLEAN DEFAULT FALSE,
|
||||
comment varchar(1023) DEFAULT NULL,
|
||||
coverage varchar(255)[] DEFAULT NULL,
|
||||
env varchar(31)[] DEFAULT NULL,
|
||||
"path" varchar(255) DEFAULT NULL,
|
||||
regions varchar(15)[] DEFAULT NULL,
|
||||
origin varchar(255) DEFAULT NULL,
|
||||
cron varchar(127) DEFAULT NULL
|
||||
);
|
||||
ALTER SEQUENCE test_catalog_id_seq OWNED BY test_catalog.id;
|
|
@ -2,7 +2,7 @@
|
|||
import { migrate } from "postgres-migrations";
|
||||
import createPgp from "pg-promise";
|
||||
import moment from "moment";
|
||||
import { WARN } from "../util/logging.js";
|
||||
import { INFO, WARN } from "../util/logging.js";
|
||||
// Environment Variables
|
||||
const {
|
||||
POSTGRES_DATABASE: database,
|
||||
|
|
|
@ -12,4 +12,3 @@ export const getSilencedTests = () => {
|
|||
const query = `SELECT * from ${table}`;
|
||||
return pg.query(query);
|
||||
};
|
||||
|
|
@ -12,4 +12,3 @@ export const getTests = () => {
|
|||
const query = `SELECT * from ${table}`;
|
||||
return pg.query(query);
|
||||
};
|
||||
|
64
lib/database/queries/results.js
Normal file
64
lib/database/queries/results.js
Normal file
|
@ -0,0 +1,64 @@
|
|||
import pg from "../postgres.js";
|
||||
// Imports
|
||||
import {
|
||||
insertQuery,
|
||||
selectWhereAnyQuery,
|
||||
selectWhereAllQuery,
|
||||
updateWhereAnyQuery,
|
||||
} from "../pg-query.js";
|
||||
// Constants
|
||||
const table = "test_results";
|
||||
// Queries
|
||||
export const insertTestResult = (testResult) => {
|
||||
const {
|
||||
test_name,
|
||||
test_class,
|
||||
test_method,
|
||||
test_path,
|
||||
test_type,
|
||||
test_timestamp,
|
||||
test_retry,
|
||||
origin,
|
||||
failed,
|
||||
failed_message,
|
||||
screenshot_url,
|
||||
expected_screenshot_url,
|
||||
weblog_url,
|
||||
} = testResult;
|
||||
|
||||
var query = insertQuery(table, {
|
||||
test_name,
|
||||
test_class,
|
||||
test_method,
|
||||
test_path,
|
||||
test_type,
|
||||
test_timestamp,
|
||||
test_retry,
|
||||
origin,
|
||||
failed,
|
||||
failed_message,
|
||||
screenshot_url,
|
||||
expected_screenshot_url,
|
||||
weblog_url,
|
||||
});
|
||||
|
||||
query += "\n RETURNING *";
|
||||
return pg.query(query);
|
||||
};
|
||||
|
||||
export const getCurrentlyFailing = () => {
|
||||
const query = `WITH recent as (SELECT * FROM test_results WHERE (timestamp BETWEEN NOW() - INTERVAL '24 HOURS' AND NOW()) AND NOT(failed AND retry)) SELECT * FROM recent WHERE timestamp = (SELECT MAX(timestamp) FROM recent r2 WHERE recent.name = r2.name) AND failed;
|
||||
`;
|
||||
return pg.query(query);
|
||||
|
||||
/*SELECT * FROM test_results WHERE "timestamp" BETWEEN NOW() - INTERVAL '24 HOURS' AND NOW(); <-- Last 24 hours all runs*/
|
||||
|
||||
/* SELECT * FROM test_results tr1 WHERE timestamp BETWEEN NOW() - INTERVAL '24 HOURS' AND NOW() AND timestamp = (SELECT MAX(timestamp) FROM test_results tr2 WHERE tr1.name = tr2.name); <-- Last 24 hours only most recent
|
||||
*/
|
||||
};
|
||||
|
||||
export const getCurrentlyFailingFull = (env) => {
|
||||
const query = `WITH recent AS (SELECT * FROM test_results WHERE (timestamp BETWEEN NOW() - INTERVAL '24 HOURS' AND NOW()) AND NOT(failed AND retry) AND env='prod') SELECT * FROM recent INNER JOIN test_catalog USING(name) WHERE timestamp = (SELECT MAX(timestamp) FROM recent r2 WHERE recent.name = r2.name) AND failed;
|
||||
;`;
|
||||
return pg.query(query);
|
||||
};
|
|
@ -1,51 +0,0 @@
|
|||
import pg from "../postgres.js";
|
||||
// Imports
|
||||
import {
|
||||
insertQuery,
|
||||
selectWhereAnyQuery,
|
||||
updateWhereAnyQuery,
|
||||
} from "../pg-query.js";
|
||||
// Constants
|
||||
const table = "test_results";
|
||||
// Queries
|
||||
export const insertTestResult = (testResult) => {
|
||||
const {
|
||||
test_name,
|
||||
test_class,
|
||||
test_method,
|
||||
test_path,
|
||||
test_type,
|
||||
test_timestamp,
|
||||
test_retry,
|
||||
origin,
|
||||
failed,
|
||||
failed_message,
|
||||
screenshot_url,
|
||||
expected_screenshot_url,
|
||||
weblog_url,
|
||||
} = testResult;
|
||||
|
||||
var query = insertQuery(table, {
|
||||
test_name,
|
||||
test_class,
|
||||
test_method,
|
||||
test_path,
|
||||
test_type,
|
||||
test_timestamp,
|
||||
test_retry,
|
||||
origin,
|
||||
failed,
|
||||
failed_message,
|
||||
screenshot_url,
|
||||
expected_screenshot_url,
|
||||
weblog_url,
|
||||
});
|
||||
|
||||
query += "\n RETURNING *";
|
||||
return pg.query(query);
|
||||
};
|
||||
|
||||
export const getCurrentlyFailing = () => {
|
||||
const query = "SELECT *";
|
||||
return pg.query(query);
|
||||
};
|
|
@ -1,5 +1,5 @@
|
|||
import { Router, json as jsonMiddleware } from "express";
|
||||
import { getSilencedTests } from "../database/queries/silenced_tests.js";
|
||||
import { getSilencedTests } from "../database/queries/alerting.js";
|
||||
const router = Router();
|
||||
|
||||
// Apply Middlewares
|
||||
|
@ -11,8 +11,8 @@ router.get("/silenced", (req, res) => {
|
|||
});
|
||||
|
||||
// Post Routes
|
||||
router.post("/silence", (req,res)=>{
|
||||
res.sendStatus(200);
|
||||
router.post("/silence", (req, res) => {
|
||||
res.sendStatus(200);
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
|
|
@ -1,11 +1,11 @@
|
|||
import { Router, json as jsonMiddleware } from "express";
|
||||
import { getTests } from "../database/queries/tests.js";
|
||||
import { getTests } from "../database/queries/catalog.js";
|
||||
const router = Router();
|
||||
|
||||
const maxSize = 1024 * 1024 * 100; // 100MB
|
||||
|
||||
// Apply Middlewares
|
||||
router.use(jsonMiddleware({limit: maxSize}));
|
||||
router.use(jsonMiddleware({ limit: maxSize }));
|
||||
|
||||
// Get Routes
|
||||
router.get("/tests", async (req, res) => {
|
||||
|
@ -14,7 +14,7 @@ router.get("/tests", async (req, res) => {
|
|||
});
|
||||
|
||||
// Post Routes
|
||||
router.post("/update", (req,res)=>{
|
||||
router.post("/update", (req, res) => {
|
||||
// Update All Tests
|
||||
res.sendStatus(200);
|
||||
});
|
|
@ -4,9 +4,9 @@ import jobs from "../core/JobManager.js";
|
|||
const router = Router();
|
||||
|
||||
router.get("/jobs", (req, res) => {
|
||||
const { clients } = jobs;
|
||||
const { clients } = jobs;
|
||||
const allJobs = [];
|
||||
for(var c of clients) allJobs.push(...c.jobs);
|
||||
for (var c of clients) allJobs.push(...c.jobs);
|
||||
res.json(allJobs);
|
||||
});
|
||||
export default router;
|
||||
|
|
37
lib/routes/mock-route.js
Normal file
37
lib/routes/mock-route.js
Normal file
|
@ -0,0 +1,37 @@
|
|||
import { Router } from "express";
|
||||
import { readFileSync } from "fs";
|
||||
|
||||
const router = Router();
|
||||
|
||||
const catalog = "lib/routes/mocks/catalog.json";
|
||||
const alerting = "lib/routes/mocks/alerting.json";
|
||||
const results = "lib/routes/mocks/results.json";
|
||||
|
||||
const query = async (mock) => JSON.parse(readFileSync(mock));
|
||||
|
||||
// Queries
|
||||
router.get("/api/catalog/tests", (req, res) => {
|
||||
query(catalog).then((catalog) => {
|
||||
res.json(req.get("full") ? catalog["tests:full"] : catalog.tests);
|
||||
});
|
||||
});
|
||||
|
||||
router.get("/api/results/failing", async (req, res) => {
|
||||
query(results).then(async (results) => {
|
||||
if (req.get("count")) res.json({ failing: results.results.length });
|
||||
else if (!req.get("full")) res.json(results.results);
|
||||
else
|
||||
query(catalog).then((catalog) => {
|
||||
res.json(
|
||||
results.results.map((r) => ({
|
||||
...catalog["tests:full"].find((t) => t.name === r.name),
|
||||
...r,
|
||||
}))
|
||||
);
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Mutations
|
||||
|
||||
export default router;
|
32
lib/routes/mocks/alerting.json
Normal file
32
lib/routes/mocks/alerting.json
Normal file
|
@ -0,0 +1,32 @@
|
|||
{
|
||||
"silenced": [
|
||||
{
|
||||
"name": "Test1",
|
||||
"class": "TestClass1",
|
||||
"method": "TestMethod1",
|
||||
"regions": ["us"],
|
||||
"alerting": "MyUtcDate"
|
||||
},
|
||||
{
|
||||
"name": "Test2",
|
||||
"class": null,
|
||||
"method": "TestMethod1",
|
||||
"regions": [],
|
||||
"alerting": "MyUtcDate"
|
||||
},
|
||||
{
|
||||
"name": "*",
|
||||
"class": "*",
|
||||
"method": "TestMethod1",
|
||||
"regions": [],
|
||||
"alerting": "MyUtcDate"
|
||||
},
|
||||
{
|
||||
"name": "Test3",
|
||||
"class": "TestClass3",
|
||||
"method": "*",
|
||||
"regions": ["us", "au"],
|
||||
"alerting": "MyUtcDate"
|
||||
}
|
||||
]
|
||||
}
|
92
lib/routes/mocks/catalog.json
Normal file
92
lib/routes/mocks/catalog.json
Normal file
|
@ -0,0 +1,92 @@
|
|||
{
|
||||
"tests": [
|
||||
{
|
||||
"name": "Test 1",
|
||||
"class": "Test Class 1",
|
||||
"compound": false,
|
||||
"type": "api"
|
||||
},
|
||||
{
|
||||
"name": "Test 2",
|
||||
"class": "Test Class 2",
|
||||
"compound": false,
|
||||
"type": "ui"
|
||||
},
|
||||
{
|
||||
"name": "Test Primary",
|
||||
"class": "Test Class Primary",
|
||||
"compound": true,
|
||||
"type": "api"
|
||||
},
|
||||
{
|
||||
"name": "Test Secondary",
|
||||
"class": "Test Class Secondary",
|
||||
"compound": true,
|
||||
"type": "ui"
|
||||
}
|
||||
],
|
||||
"tests:full": [
|
||||
{
|
||||
"name": "Test1",
|
||||
"class": "TestClass1",
|
||||
"compound": false,
|
||||
"type": "api",
|
||||
"markers": ["Service1"],
|
||||
"ignored": false,
|
||||
"comment": "This Comment Is Part Of Test 1",
|
||||
"coverage": ["/api/test1", "/api/test2"],
|
||||
"env": ["prod", "ci"],
|
||||
"path": "tests/api/test1.js",
|
||||
"regions": ["us", "ca"],
|
||||
"origin": "Repo1",
|
||||
"cron": "1hour"
|
||||
},
|
||||
{
|
||||
"name": "Test2",
|
||||
"class": "TestClass2",
|
||||
"compound": false,
|
||||
"type": "ui",
|
||||
"markers": ["Service2"],
|
||||
"ignored": false,
|
||||
"comment": "Comment belonging to Test2",
|
||||
"coverage": ["Page1/FeatureA"],
|
||||
"env": ["prod"],
|
||||
"path": "tests/ui/test2.js",
|
||||
"regions": [],
|
||||
"origin": "Repo2",
|
||||
"cron": "30min"
|
||||
},
|
||||
{
|
||||
"name": "TestPrimary",
|
||||
"class": "TestClassPrimary",
|
||||
"compound": true,
|
||||
"type": "api",
|
||||
"markers": [
|
||||
"ServiceComplex",
|
||||
"compound_Repo2!TestClassSecondary#TestSecondary"
|
||||
],
|
||||
"ignored": false,
|
||||
"comment": "Comment belonging to Test Primary",
|
||||
"coverage": ["/api/compound"],
|
||||
"env": ["ci"],
|
||||
"path": "tests/api/primary.js",
|
||||
"regions": [],
|
||||
"origin": "Repo1",
|
||||
"cron": "2hour"
|
||||
},
|
||||
{
|
||||
"name": "TestSecondary",
|
||||
"class": "TestClassSecondary",
|
||||
"compound": true,
|
||||
"type": "ui",
|
||||
"markers": ["ServiceComplex"],
|
||||
"ignored": false,
|
||||
"coverage": ["PageComplex/FeatureA"],
|
||||
"env": ["ci"],
|
||||
"path": "tests/ui/secondary.js",
|
||||
"regions": [],
|
||||
"origin": "Repo2",
|
||||
"cron": "2hour"
|
||||
}
|
||||
]
|
||||
}
|
48
lib/routes/mocks/results.json
Normal file
48
lib/routes/mocks/results.json
Normal file
|
@ -0,0 +1,48 @@
|
|||
{
|
||||
"results": [
|
||||
{
|
||||
"name": "Test1",
|
||||
"method": "Test1Method",
|
||||
"env": "prod",
|
||||
"timestamp": "2022-05-10T16:35:27.220Z",
|
||||
"retry": false,
|
||||
"failed": true,
|
||||
"failed_message": "Some failure message",
|
||||
"screenshot": "https://example.com",
|
||||
"weblog": "https://example.com"
|
||||
},
|
||||
{
|
||||
"name": "Test2",
|
||||
"method": "Test2Method",
|
||||
"env": "prod",
|
||||
"timestamp": "2022-05-10T16:35:31.682Z",
|
||||
"retry": false,
|
||||
"failed": true,
|
||||
"failed_message": "Some failure message 2",
|
||||
"screenshot": "https://example.com",
|
||||
"weblog": "https://example.com"
|
||||
},
|
||||
{
|
||||
"name": "Test1",
|
||||
"method": null,
|
||||
"env": "prod",
|
||||
"timestamp": "2022-05-10T16:35:33.810Z",
|
||||
"retry": false,
|
||||
"failed": false,
|
||||
"failed_message": null,
|
||||
"screenshot": "https://example.com",
|
||||
"weblog": "https://example.com"
|
||||
},
|
||||
{
|
||||
"name": "Test1",
|
||||
"method": null,
|
||||
"env": "ci",
|
||||
"timestamp": "2022-05-10T16:35:33.810Z",
|
||||
"retry": false,
|
||||
"failed": false,
|
||||
"failed_message": null,
|
||||
"screenshot": "https://example.com",
|
||||
"weblog": "https://example.com"
|
||||
}
|
||||
]
|
||||
}
|
|
@ -1,5 +1,5 @@
|
|||
import { Router, json as jsonMiddleware } from "express";
|
||||
import { getCurrentlyFailing } from "../database/queries/test_results.js";
|
||||
import { getCurrentlyFailing } from "../database/queries/results.js";
|
||||
const router = Router();
|
||||
|
||||
// Apply Middlewares
|
||||
|
@ -11,8 +11,8 @@ router.get("/failing", (req, res) => {
|
|||
});
|
||||
|
||||
// Post Routes
|
||||
router.post("/history", (req,res)=>{
|
||||
res.send([]);
|
||||
router.post("/history", (req, res) => {
|
||||
res.send([]);
|
||||
});
|
||||
|
||||
export default router;
|
||||
|
|
|
@ -67,7 +67,8 @@ export default class Executor {
|
|||
report(d, dType) {
|
||||
this.buf[dType] += d;
|
||||
if (!this.buf[dType].includes("\n")) return;
|
||||
if(this.buf[dType].endsWith("\n")) this.buf[dType] = this.buf[dType].slice(0, -1);
|
||||
if (this.buf[dType].endsWith("\n"))
|
||||
this.buf[dType] = this.buf[dType].slice(0, -1);
|
||||
this.socket.emit(events.JOB_REP, this.buf[dType]);
|
||||
if (dType === ERR) console.error(`err: ${this.buf[dType]}`);
|
||||
else console.log(`out: ${this.buf[dType]}`);
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue