diff --git a/.circleci/config.yml b/.circleci/config.yml index 438d93c..b84b53c 100644 --- a/.circleci/config.yml +++ b/.circleci/config.yml @@ -48,4 +48,4 @@ workflows: tags: only: /dev-v[0-9]+(\.[0-9]+)*/ branches: - ignore: /.*/ + only: /test-cicd\/.*/ diff --git a/.circleci/config_continue.yml b/.circleci/config_continue.yml index 75e4c69..93c5133 100644 --- a/.circleci/config_continue.yml +++ b/.circleci/config_continue.yml @@ -8,9 +8,17 @@ jobs: docker: - image: rishabhpoddar/supertokens_website_sdk_testing_node_16 steps: - - run: git config --global url."https://github.com/".insteadOf ssh://git@github.com/ # This makes npm use http instead of ssh (required for node 16) - - checkout - - run: (cd .circleci/ && ./markDevTagAsTestNotPassed.sh) + - run: echo "Testing branch << pipeline.git.branch >>" + - when: + condition: + not: + matches: + pattern: "^test-cicd/.*$" + value: << pipeline.git.branch >> + steps: + - run: git config --global url."https://github.com/".insteadOf ssh://git@github.com/ # This makes npm use http instead of ssh (required for node 16) + - checkout + - run: (cd .circleci/ && ./markDevTagAsTestNotPassed.sh) test-unit: docker: - image: rishabhpoddar/supertokens_flutter_sdk_testing @@ -51,6 +59,9 @@ jobs: echo 'export NVM_DIR="$HOME/.nvm"' >> $BASH_ENV echo '[ -s "$NVM_DIR/nvm.sh" ] && \. "$NVM_DIR/nvm.sh"' >> $BASH_ENV - run: (cd .circleci/ && ./doTests.sh << parameters.fdi-version >>) + - store_artifacts: + path: ../supertokens-root/logs + destination: logfiles test-success: docker: - image: rishabhpoddar/supertokens_website_sdk_testing_node_16 @@ -69,7 +80,7 @@ workflows: tags: only: /dev-v[0-9]+(\.[0-9]+)*/ branches: - ignore: /.*/ + only: /test-cicd\/.*/ - test-unit: requires: - test-dev-tag-as-not-passed @@ -79,7 +90,7 @@ workflows: tags: only: /dev-v[0-9]+(\.[0-9]+)*/ branches: - ignore: /.*/ + only: /test-cicd\/.*/ matrix: parameters: fdi-version: placeholder diff --git a/testHelpers/server/index.js b/testHelpers/server/index.js index 95d41e6..b69c648 100644 --- a/testHelpers/server/index.js +++ b/testHelpers/server/index.js @@ -25,7 +25,7 @@ let { startST, stopST, killAllST, setupST, cleanST, setKeyValueInConfig, maxVers let { middleware, errorHandler } = require("supertokens-node/framework/express"); let { verifySession } = require("supertokens-node/recipe/session/framework/express"); const { spawnSync } = require("child_process"); -const { debug } = require("console"); +const morgan = require("morgan"); let noOfTimesRefreshCalledDuringTest = 0; let noOfTimesGetSessionCalledDuringTest = 0; let noOfTimesRefreshAttemptedDuringTest = 0; @@ -33,17 +33,23 @@ let customRefreshHeaderValue = ""; let supertokens_node_version = require("supertokens-node/lib/build/version").version; let Querier = require("supertokens-node/lib/build/querier").Querier; let NormalisedURLPath = require("supertokens-node/lib/build/normalisedURLPath").default; -let UserMetaDataRecipeRaw = require("supertokens-node/lib/build/recipe/usermetadata/recipe").default; - let Multitenancy, MultitenancyRaw, multitenancySupported; try { MultitenancyRaw = require("supertokens-node/lib/build/recipe/multitenancy/recipe").default; - Multitenancy = require("supertokens-node/lib/build/recipe/multitenancy"); + Multitenancy = require("supertokens-node/lib/build/recipe/multitenancy/index"); multitenancySupported = true; -} catch { +} catch (ex) { + console.log({ex}); multitenancySupported = false; } +let UserMetaDataRecipeRaw; +try { + UserMetaDataRecipeRaw = require("supertokens-node/lib/build/recipe/usermetadata/recipe").default; +} catch { + // Ignored +} + let urlencodedParser = bodyParser.urlencoded({ limit: "20mb", extended: true, parameterLimit: 20000 }); let jsonParser = bodyParser.json({ limit: "20mb" }); @@ -51,6 +57,8 @@ let app = express(); app.use(urlencodedParser); app.use(jsonParser); app.use(cookieParser()); +app.use(morgan(`:date[iso] - :method :url`, { immediate: true })); +app.use(morgan(`:date[iso] - :method :url :status :response-time ms - :res[content-length]`)); let lastSetEnableAntiCSRF = false; let lastSetEnableJWT = false; @@ -207,6 +215,7 @@ app.use( credentials: true }) ); +app.disable('etag'); app.use(middleware()); @@ -216,9 +225,7 @@ app.post("/login", async (req, res) => { let session; if (multitenancySupported) { - session = await Session.createNewSession(req, res, "public", - accountLinkingSupported ? SuperTokens.convertToRecipeUserId(userId) : userId, - accessTokenPayload); + session = await Session.createNewSession(req, res, "public", accountLinkingSupported ? SuperTokens.convertToRecipeUserId(userId) : userId, accessTokenPayload); } else { session = await Session.createNewSession(req, res, userId, accessTokenPayload); } @@ -244,16 +251,18 @@ app.post("/startst", async (req, res) => { if (enableAntiCsrf !== undefined) { SuperTokensRaw.reset(); SessionRecipeRaw.reset(); - UserMetaDataRecipeRaw.reset(); if (multitenancySupported) { MultitenancyRaw.reset(); } + if (UserMetaDataRecipeRaw !== undefined) { + UserMetaDataRecipeRaw.reset(); + } SuperTokens.init(getConfig(enableAntiCsrf, enableJWT)); } - let pid = await startST(); - res.send(pid + ""); + await startST(); + res.send(""); }); app.get("/featureFlags", async (req, res) => { @@ -273,7 +282,12 @@ app.post("/reinitialiseBackendConfig", async (req, res) => { SuperTokensRaw.reset(); SessionRecipeRaw.reset(); - UserMetaDataRecipeRaw.reset(); + if (multitenancySupported) { + MultitenancyRaw.reset(); + } + if (UserMetaDataRecipeRaw !== undefined) { + UserMetaDataRecipeRaw.reset(); + } SuperTokens.init(getConfig(lastSetEnableAntiCSRF, currentEnableJWT, jwtPropertyName)); res.send(""); @@ -575,9 +589,10 @@ app.use("*", async (req, res, next) => { app.use(errorHandler()); app.use(async (err, req, res, next) => { + console.log({err, stack: new Error().stack }); res.status(500).send(err); }); let server = http.createServer(app); // server.listen(process.env.NODE_PORT === undefined ? 8080 : process.env.NODE_PORT, "::"); -server.listen(8080, "::"); \ No newline at end of file +server.listen(8080, "::"); diff --git a/testHelpers/server/package-lock.json b/testHelpers/server/package-lock.json index f381310..de6348c 100644 --- a/testHelpers/server/package-lock.json +++ b/testHelpers/server/package-lock.json @@ -12,7 +12,9 @@ "cookie-parser": "1.4.4", "cors": "^2.8.5", "express": "4.17.1", - "supertokens-node": "github:supertokens/supertokens-node#17.1" + "morgan": "^1.10.0", + "node-fetch": "^2.7.0", + "supertokens-node": "github:supertokens/supertokens-node" } }, "node_modules/accepts": { @@ -79,6 +81,17 @@ "proxy-from-env": "^1.1.0" } }, + "node_modules/basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "dependencies": { + "safe-buffer": "5.1.2" + }, + "engines": { + "node": ">= 0.8" + } + }, "node_modules/body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -731,6 +744,29 @@ "node": ">= 0.6" } }, + "node_modules/morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "dependencies": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "engines": { + "node": ">= 0.8.0" + } + }, + "node_modules/morgan/node_modules/depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -798,6 +834,14 @@ "node": ">= 0.8" } }, + "node_modules/on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==", + "engines": { + "node": ">= 0.8" + } + }, "node_modules/parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -1214,6 +1258,14 @@ "proxy-from-env": "^1.1.0" } }, + "basic-auth": { + "version": "2.0.1", + "resolved": "https://registry.npmjs.org/basic-auth/-/basic-auth-2.0.1.tgz", + "integrity": "sha512-NF+epuEdnUYVlGuhaxbbq+dvJttwLnGY+YixlXlME5KpQ5W3CnXA5cVTneY3SPbPDRkcjMbifrwmFYcClgOZeg==", + "requires": { + "safe-buffer": "5.1.2" + } + }, "body-parser": { "version": "1.19.0", "resolved": "https://registry.npmjs.org/body-parser/-/body-parser-1.19.0.tgz", @@ -1708,6 +1760,25 @@ "mime-db": "1.52.0" } }, + "morgan": { + "version": "1.10.0", + "resolved": "https://registry.npmjs.org/morgan/-/morgan-1.10.0.tgz", + "integrity": "sha512-AbegBVI4sh6El+1gNwvD5YIck7nSA36weD7xvIxG4in80j/UoK8AEGaWnnz8v1GxonMCltmlNs5ZKbGvl9b1XQ==", + "requires": { + "basic-auth": "~2.0.1", + "debug": "2.6.9", + "depd": "~2.0.0", + "on-finished": "~2.3.0", + "on-headers": "~1.0.2" + }, + "dependencies": { + "depd": { + "version": "2.0.0", + "resolved": "https://registry.npmjs.org/depd/-/depd-2.0.0.tgz", + "integrity": "sha512-g7nH6P6dyDioJogAAGprGpCtVImJhpPk/roCzdb3fIh61/s/nPsfR6onyMwkCAR/OlC3yBC0lESvUoQEAssIrw==" + } + } + }, "ms": { "version": "2.0.0", "resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz", @@ -1749,6 +1820,11 @@ "ee-first": "1.1.1" } }, + "on-headers": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/on-headers/-/on-headers-1.0.2.tgz", + "integrity": "sha512-pZAE+FJLoyITytdqK0U5s+FIpjN0JP3OzFi/u8Rx+EV5/W+JTWGXG8xFzevE7AjBfDqHv/8vL8qQsIhHnqRkrA==" + }, "parseurl": { "version": "1.3.3", "resolved": "https://registry.npmjs.org/parseurl/-/parseurl-1.3.3.tgz", @@ -1916,7 +1992,7 @@ }, "supertokens-node": { "version": "git+ssh://git@github.com/supertokens/supertokens-node.git#aa70cdc5de73fa780345446c9c60fcb410702e38", - "from": "supertokens-node@github:supertokens/supertokens-node#17.1", + "from": "supertokens-node@github:supertokens/supertokens-node", "requires": { "content-type": "^1.0.5", "cookie": "0.4.0", diff --git a/testHelpers/server/package.json b/testHelpers/server/package.json index 17b0e09..a39d862 100644 --- a/testHelpers/server/package.json +++ b/testHelpers/server/package.json @@ -12,6 +12,8 @@ "cookie-parser": "1.4.4", "cors": "^2.8.5", "express": "4.17.1", + "morgan": "^1.10.0", + "node-fetch": "^2.7.0", "supertokens-node": "github:supertokens/supertokens-node" } -} \ No newline at end of file +} diff --git a/testHelpers/server/utils.js b/testHelpers/server/utils.js index d5c2203..d58a848 100644 --- a/testHelpers/server/utils.js +++ b/testHelpers/server/utils.js @@ -14,13 +14,14 @@ */ const { exec } = require("child_process"); let fs = require("fs"); +const fetch = require("node-fetch"); module.exports.executeCommand = async function(cmd) { return new Promise((resolve, reject) => { + console.log("Executing command: " + cmd); exec(cmd, (err, stdout, stderr) => { - if (err) { - reject(err); + reject({err, stdout, stderr}); return; } resolve({ stdout, stderr }); @@ -97,7 +98,6 @@ module.exports.killAllST = async function() { module.exports.startST = async function(host = "localhost", port = 9000) { return new Promise(async (resolve, reject) => { let installationPath = process.env.INSTALL_PATH; - let pidsBefore = await getListOfPids(); let returned = false; module.exports .executeCommand( @@ -109,36 +109,35 @@ module.exports.startST = async function(host = "localhost", port = 9000) { port + " test_mode" ) - .catch(err => { + .catch(({err, stdout, stderr}) => { if (!returned) { + console.log("Starting ST failed: java command returned early w/ non-zero exit code"); + console.log(err); + console.log(stdout); + console.log(stderr); returned = true; reject(err); } }); let startTime = Date.now(); + let helloResp; while (Date.now() - startTime < 10000) { - let pidsAfter = await getListOfPids(); - if (pidsAfter.length <= pidsBefore.length) { - await new Promise(r => setTimeout(r, 100)); - continue; - } - let nonIntersection = pidsAfter.filter(x => !pidsBefore.includes(x)); - if (nonIntersection.length !== 1) { - if (!returned) { - returned = true; - reject("something went wrong while starting ST"); - } - } else { - if (!returned) { + try { + helloResp = await fetch(`http://${host}:${port}/hello`); + if (helloResp.status === 200) { + console.log("Started ST, it's saying: " + await helloResp.text()); + resolve(); returned = true; - resolve(nonIntersection[0]); + return; } + } catch (ex) { + console.log("Waiting for ST to start, caught exception: " + ex); + // We expect (and ignore) network errors here } + await new Promise(r => setTimeout(r, 100)); } - if (!returned) { - returned = true; - reject("could not start ST process"); - } + console.log(helloResp); + reject("Starting ST process timed out"); }); };