From 3974f72ca37bed5fe929eb46b775e600bd02fdbb Mon Sep 17 00:00:00 2001 From: Hans Ott Date: Fri, 16 Feb 2024 17:04:52 +0100 Subject: [PATCH 1/4] Rewrite e2e logic --- end2end/tests/express-mongodb.test.js | 112 +++++++++++++------------- 1 file changed, 55 insertions(+), 57 deletions(-) diff --git a/end2end/tests/express-mongodb.test.js b/end2end/tests/express-mongodb.test.js index eca2cdc20..474017918 100644 --- a/end2end/tests/express-mongodb.test.js +++ b/end2end/tests/express-mongodb.test.js @@ -12,22 +12,12 @@ async function timeout(ms) { return new Promise((resolve) => setTimeout(resolve, ms)); } -async function kill(server) { - return new Promise((resolve) => { - if (!server.connected || server.killed || !server.pid) { - resolve(); - } +t.test("it blocks in blocking mode", (t) => { + const server = spawn(`node`, [pathToApp, "4000"], { shell: true }); - server.on("close", resolve); - server.on("exit", resolve); - server.on("error", resolve); - server.on("disconnect", resolve); - server.kill(); + server.on("close", () => { + t.end(); }); -} - -t.test("it blocks in blocking mode", async () => { - const server = spawn(`node`, [pathToApp, "4000"], { shell: true }); let stdout = ""; server.stdout.on("data", (data) => { @@ -42,35 +32,41 @@ t.test("it blocks in blocking mode", async () => { }); // Wait for the server to start - await timeout(1000); - - try { - const [noSQLInjection, normalSearch] = await Promise.all([ - fetch("http://localhost:4000/?search[$ne]=null", { - signal: AbortSignal.timeout(5000), - }), - fetch("http://localhost:4000/?search=title", { - signal: AbortSignal.timeout(5000), - }), - ]); - - t.equal(noSQLInjection.status, 500); - t.equal(normalSearch.status, 200); - t.match(stdout, /Starting agent/); - t.match(stderr, /Aikido guard has blocked a NoSQL injection/); - } catch (error) { - t.fail(error.message); - } finally { - await kill(server); - } + timeout(2000) + .then(() => + Promise.all([ + fetch("http://localhost:4000/?search[$ne]=null", { + signal: AbortSignal.timeout(5000), + }), + fetch("http://localhost:4000/?search=title", { + signal: AbortSignal.timeout(5000), + }), + ]) + ) + .then(([noSQLInjection, normalSearch]) => { + t.equal(noSQLInjection.status, 500); + t.equal(normalSearch.status, 200); + t.match(stdout, /Starting agent/); + t.match(stderr, /Aikido guard has blocked a NoSQL injection/); + }) + .catch((error) => { + t.fail(error.message); + }) + .finally(() => { + server.kill(); + }); }); -t.test("it does not block in dry mode", async () => { +t.test("it does not block in dry mode", (t) => { const server = spawn(`node`, [pathToApp, "4001"], { env: { ...process.env, AIKIDO_NO_BLOCKING: "true" }, shell: true, }); + server.on("close", () => { + t.end(); + }); + let stdout = ""; server.stdout.on("data", (data) => { stdout += data.toString(); @@ -84,25 +80,27 @@ t.test("it does not block in dry mode", async () => { }); // Wait for the server to start - await timeout(1000); - - try { - const [noSQLInjection, normalSearch] = await Promise.all([ - fetch("http://localhost:4001/?search[$ne]=null", { - signal: AbortSignal.timeout(5000), - }), - fetch("http://localhost:4001/?search=title", { - signal: AbortSignal.timeout(5000), - }), - ]); - - t.equal(noSQLInjection.status, 200); - t.equal(normalSearch.status, 200); - t.match(stdout, /Starting agent/); - t.notMatch(stderr, /Aikido guard has blocked a NoSQL injection/); - } catch (error) { - t.fail(error.message); - } finally { - await kill(server); - } + timeout(2000) + .then(() => + Promise.all([ + fetch("http://localhost:4001/?search[$ne]=null", { + signal: AbortSignal.timeout(5000), + }), + fetch("http://localhost:4001/?search=title", { + signal: AbortSignal.timeout(5000), + }), + ]) + ) + .then(([noSQLInjection, normalSearch]) => { + t.equal(noSQLInjection.status, 200); + t.equal(normalSearch.status, 200); + t.match(stdout, /Starting agent/); + t.notMatch(stderr, /Aikido guard has blocked a NoSQL injection/); + }) + .catch((error) => { + t.fail(error.message); + }) + .finally(() => { + server.kill(); + }); }); From 8035480b288e44a07cdffbedd325832cfea4d78f Mon Sep 17 00:00:00 2001 From: Hans Ott Date: Fri, 16 Feb 2024 17:21:27 +0100 Subject: [PATCH 2/4] Add logging --- end2end/tests/express-mongodb.test.js | 23 +++++++++++++++++------ 1 file changed, 17 insertions(+), 6 deletions(-) diff --git a/end2end/tests/express-mongodb.test.js b/end2end/tests/express-mongodb.test.js index 474017918..ff6d5607b 100644 --- a/end2end/tests/express-mongodb.test.js +++ b/end2end/tests/express-mongodb.test.js @@ -16,9 +16,15 @@ t.test("it blocks in blocking mode", (t) => { const server = spawn(`node`, [pathToApp, "4000"], { shell: true }); server.on("close", () => { + console.log("received close"); t.end(); }); + server.on("error", (err) => { + console.log("received error"); + t.fail(err.message); + }); + let stdout = ""; server.stdout.on("data", (data) => { stdout += data.toString(); @@ -33,31 +39,36 @@ t.test("it blocks in blocking mode", (t) => { // Wait for the server to start timeout(2000) - .then(() => - Promise.all([ + .then(() => { + console.log("sending requests"); + return Promise.all([ fetch("http://localhost:4000/?search[$ne]=null", { signal: AbortSignal.timeout(5000), }), fetch("http://localhost:4000/?search=title", { signal: AbortSignal.timeout(5000), }), - ]) - ) + ]); + }) .then(([noSQLInjection, normalSearch]) => { + console.log("noSQLInjection", noSQLInjection.status); + console.log("normalSearch", normalSearch.status); t.equal(noSQLInjection.status, 500); t.equal(normalSearch.status, 200); t.match(stdout, /Starting agent/); t.match(stderr, /Aikido guard has blocked a NoSQL injection/); }) .catch((error) => { + console.log("error", error.message); t.fail(error.message); }) .finally(() => { + console.log("killing server"); server.kill(); }); }); -t.test("it does not block in dry mode", (t) => { +/*t.test("it does not block in dry mode", (t) => { const server = spawn(`node`, [pathToApp, "4001"], { env: { ...process.env, AIKIDO_NO_BLOCKING: "true" }, shell: true, @@ -103,4 +114,4 @@ t.test("it does not block in dry mode", (t) => { .finally(() => { server.kill(); }); -}); +});*/ From 7eb75e376430ba8dda3fe1bf66170caa8bebe189 Mon Sep 17 00:00:00 2001 From: Hans Ott Date: Fri, 16 Feb 2024 17:28:01 +0100 Subject: [PATCH 3/4] Remove shell option --- end2end/tests/express-mongodb.test.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/end2end/tests/express-mongodb.test.js b/end2end/tests/express-mongodb.test.js index ff6d5607b..055647bbc 100644 --- a/end2end/tests/express-mongodb.test.js +++ b/end2end/tests/express-mongodb.test.js @@ -13,7 +13,7 @@ async function timeout(ms) { } t.test("it blocks in blocking mode", (t) => { - const server = spawn(`node`, [pathToApp, "4000"], { shell: true }); + const server = spawn(`node`, [pathToApp, "4000"]); server.on("close", () => { console.log("received close"); From ec347eb2547b49cbf590dfebde245d8defcd21a0 Mon Sep 17 00:00:00 2001 From: Hans Ott Date: Fri, 16 Feb 2024 17:48:05 +0100 Subject: [PATCH 4/4] This should do the trick --- end2end/package.json | 2 +- end2end/tests/express-mongodb.test.js | 21 +++------------------ end2end/timeout.js | 3 +++ 3 files changed, 7 insertions(+), 19 deletions(-) create mode 100644 end2end/timeout.js diff --git a/end2end/package.json b/end2end/package.json index ad275e4fc..015efb29a 100644 --- a/end2end/package.json +++ b/end2end/package.json @@ -5,6 +5,6 @@ "tap": "^18.7.0" }, "scripts": { - "test": "tap tests/*.js" + "test": "tap tests/*.js --allow-empty-coverage" } } diff --git a/end2end/tests/express-mongodb.test.js b/end2end/tests/express-mongodb.test.js index 055647bbc..ef072c3ee 100644 --- a/end2end/tests/express-mongodb.test.js +++ b/end2end/tests/express-mongodb.test.js @@ -1,6 +1,7 @@ const t = require("tap"); const { spawn } = require("node:child_process"); const { resolve } = require("node:path"); +const timeout = require("../timeout"); const pathToApp = resolve( __dirname, @@ -8,39 +9,30 @@ const pathToApp = resolve( "app.js" ); -async function timeout(ms) { - return new Promise((resolve) => setTimeout(resolve, ms)); -} - t.test("it blocks in blocking mode", (t) => { const server = spawn(`node`, [pathToApp, "4000"]); server.on("close", () => { - console.log("received close"); t.end(); }); server.on("error", (err) => { - console.log("received error"); t.fail(err.message); }); let stdout = ""; server.stdout.on("data", (data) => { stdout += data.toString(); - console.log("stdout", data.toString()); }); let stderr = ""; server.stderr.on("data", (data) => { stderr += data.toString(); - console.log("stderr", data.toString()); }); // Wait for the server to start timeout(2000) .then(() => { - console.log("sending requests"); return Promise.all([ fetch("http://localhost:4000/?search[$ne]=null", { signal: AbortSignal.timeout(5000), @@ -51,27 +43,22 @@ t.test("it blocks in blocking mode", (t) => { ]); }) .then(([noSQLInjection, normalSearch]) => { - console.log("noSQLInjection", noSQLInjection.status); - console.log("normalSearch", normalSearch.status); t.equal(noSQLInjection.status, 500); t.equal(normalSearch.status, 200); t.match(stdout, /Starting agent/); t.match(stderr, /Aikido guard has blocked a NoSQL injection/); }) .catch((error) => { - console.log("error", error.message); t.fail(error.message); }) .finally(() => { - console.log("killing server"); server.kill(); }); }); -/*t.test("it does not block in dry mode", (t) => { +t.test("it does not block in dry mode", (t) => { const server = spawn(`node`, [pathToApp, "4001"], { env: { ...process.env, AIKIDO_NO_BLOCKING: "true" }, - shell: true, }); server.on("close", () => { @@ -81,13 +68,11 @@ t.test("it blocks in blocking mode", (t) => { let stdout = ""; server.stdout.on("data", (data) => { stdout += data.toString(); - console.log("stdout", data.toString()); }); let stderr = ""; server.stderr.on("data", (data) => { stderr += data.toString(); - console.log("stderr", data.toString()); }); // Wait for the server to start @@ -114,4 +99,4 @@ t.test("it blocks in blocking mode", (t) => { .finally(() => { server.kill(); }); -});*/ +}); diff --git a/end2end/timeout.js b/end2end/timeout.js new file mode 100644 index 000000000..14719f34a --- /dev/null +++ b/end2end/timeout.js @@ -0,0 +1,3 @@ +module.exports = async function timeout(ms) { + return new Promise((resolve) => setTimeout(resolve, ms)); +};