diff --git a/src/performanceTest/README.md b/src/performanceTest/README.md index 13cb77c6..345d12b5 100644 --- a/src/performanceTest/README.md +++ b/src/performanceTest/README.md @@ -31,6 +31,10 @@ BASTION_USERNAME= HOST= +# No sign up Test +JWT_RAW_SECRET= +JWT_ISSUER= + # Monitoring Configuration (Optional) GRAFANA_HOST= K6_OUT= #experimental-prometheus-rw diff --git a/src/performanceTest/docker-compose.yml b/src/performanceTest/docker-compose.yml index ec04ea04..61298c91 100644 --- a/src/performanceTest/docker-compose.yml +++ b/src/performanceTest/docker-compose.yml @@ -32,6 +32,9 @@ services: GRAFANA_HOST: ${GRAFANA_HOST} OUTPUT_HTML_DIR: "/results" + JWT_RAW_SECRET: ${JWT_RAW_SECRET} + JWT_ISSUER: ${JWT_ISSUER} + # https://k6.io/docs/using-k6/k6-options/reference/#results-output K6_OUT: ${K6_OUT} K6_PROMETHEUS_RW_SERVER_URL: ${K6_PROMETHEUS_RW_SERVER_URL} diff --git a/src/performanceTest/initdb/sqls/cleanup.sql b/src/performanceTest/initdb/sqls/cleanup.sql index 0feaaa52..d9f9897b 100644 --- a/src/performanceTest/initdb/sqls/cleanup.sql +++ b/src/performanceTest/initdb/sqls/cleanup.sql @@ -2,7 +2,6 @@ USE ticketingdb; SET foreign_key_checks = 0; -TRUNCATE user; TRUNCATE event; TRUNCATE bookmark; TRUNCATE reservation; diff --git a/src/performanceTest/scripts/healthCheck.js b/src/performanceTest/scripts/check/healthCheck.js similarity index 80% rename from src/performanceTest/scripts/healthCheck.js rename to src/performanceTest/scripts/check/healthCheck.js index 007fee3f..c23b6432 100644 --- a/src/performanceTest/scripts/healthCheck.js +++ b/src/performanceTest/scripts/check/healthCheck.js @@ -1,6 +1,6 @@ import { check } from "k6"; -import Request from "./lib/request.js"; -import hooks from "./lib/hooks.js"; +import Request from "../lib/request.js"; +import hooks from "../lib/hooks.js"; export const setup = hooks.setup export const handleSummary = hooks.handleSummary diff --git a/src/performanceTest/scripts/check/jwtCheck.js b/src/performanceTest/scripts/check/jwtCheck.js new file mode 100644 index 00000000..15f4c6e8 --- /dev/null +++ b/src/performanceTest/scripts/check/jwtCheck.js @@ -0,0 +1,19 @@ +import { check } from "k6"; +import exec from 'k6/execution'; +import Request from "../lib/request.js"; +import hooks from "../lib/hooks.js"; +import { encode } from "../lib/jwt.js"; + +export const setup = hooks.setup +export const handleSummary = hooks.handleSummary + +export default function () { + const req = new Request() + + const token = encode(1) + req.setToken(token) + + const res = req.access_token_info() + check(res, { "status == 200": (r) => r.status == 200 }); + check(res, { "res has userId key": (r) => r.json().userId > 0 }); +} diff --git a/src/performanceTest/scripts/reservationCheck.js b/src/performanceTest/scripts/check/reservationCheck.js similarity index 74% rename from src/performanceTest/scripts/reservationCheck.js rename to src/performanceTest/scripts/check/reservationCheck.js index 5e8dfa4c..97027d97 100644 --- a/src/performanceTest/scripts/reservationCheck.js +++ b/src/performanceTest/scripts/check/reservationCheck.js @@ -1,8 +1,8 @@ import { check } from "k6"; -import Request from "./lib/request.js"; -import generator from "./lib/generator.js"; -import hooks from "./lib/hooks.js"; -import { getOneFromList } from "./lib/helpers.js"; +import Request from "../lib/request.js"; +import generator from "../lib/generator.js"; +import hooks from "../lib/hooks.js"; +import { getOneFromList } from "../lib/helpers.js"; export const setup = hooks.setup export const handleSummary = hooks.handleSummary diff --git a/src/performanceTest/scripts/signinCheck.js b/src/performanceTest/scripts/check/signinCheck.js similarity index 69% rename from src/performanceTest/scripts/signinCheck.js rename to src/performanceTest/scripts/check/signinCheck.js index 3432c5ba..4ba21239 100644 --- a/src/performanceTest/scripts/signinCheck.js +++ b/src/performanceTest/scripts/check/signinCheck.js @@ -1,7 +1,7 @@ import { check } from "k6"; -import Request from "./lib/request.js"; -import generator from "./lib/generator.js"; -import hooks from "./lib/hooks.js"; +import Request from "../lib/request.js"; +import generator from "../lib/generator.js"; +import hooks from "../lib/hooks.js"; export const setup = hooks.setup export const handleSummary = hooks.handleSummary @@ -14,7 +14,7 @@ export default function () { req.signup(user) req.signin(user) - const res = req.access_token_info().json() + const res = req.access_token_info() check(res, { "status == 200": (r) => r.status == 200 }); check(res, { "res has userId key": (r) => r.json().userId > 0 }); diff --git a/src/performanceTest/scripts/lib/config.js b/src/performanceTest/scripts/lib/config.js index 736c1263..757e6bb4 100644 --- a/src/performanceTest/scripts/lib/config.js +++ b/src/performanceTest/scripts/lib/config.js @@ -9,5 +9,8 @@ const config = { HOST: removeLastSlash(__ENV.HOST), GRAFANA_HOST: removeLastSlash(__ENV.GRAFANA_HOST), OUTPUT_HTML_DIR: __ENV.OUTPUT_HTML_DIR || './results', + + JWT_RAW_SECRET: __ENV.JWT_RAW_SECRET, + JWT_ISSUER: __ENV.JWT_ISSUER, } export default config \ No newline at end of file diff --git a/src/performanceTest/scripts/lib/jwt.js b/src/performanceTest/scripts/lib/jwt.js new file mode 100644 index 00000000..21388313 --- /dev/null +++ b/src/performanceTest/scripts/lib/jwt.js @@ -0,0 +1,33 @@ +import crypto from "k6/crypto"; +import encoding from "k6/encoding"; +import config from "./config.js"; + +// from https://github.com/grafana/k6/blob/master/examples/jwt.js + +const algToHash = { + HS256: "sha256", + HS384: "sha384", + HS512: "sha512" +}; + +function sign(data, hashAlg, secret) { + let hasher = crypto.createHMAC(hashAlg, secret); + hasher.update(data); + + return hasher.digest("base64").replace(/\//g, "_").replace(/\+/g, "-").replace(/=/g, ""); +} + +export function encode(userid) { + const NOW = Math.floor(Date.now() / 1000) + const algorithm = "HS256"; + let header = encoding.b64encode(JSON.stringify({ alg: algorithm }), "rawurl"); + let payload = { + sub: `${userid}`, + iss: config.JWT_ISSUER, + iat: NOW, + exp: NOW + (60 * 60), + } + payload = encoding.b64encode(JSON.stringify(payload), "rawurl", "s"); + let sig = sign(header + "." + payload, algToHash[algorithm], config.JWT_RAW_SECRET); + return [header, payload, sig].join("."); +} \ No newline at end of file diff --git a/src/performanceTest/scripts/makeUsers.js b/src/performanceTest/scripts/makeUsers.js index ebfba411..d62989a0 100644 --- a/src/performanceTest/scripts/makeUsers.js +++ b/src/performanceTest/scripts/makeUsers.js @@ -1,8 +1,7 @@ import { check } from "k6"; import Request from "./lib/request.js"; -import generator from "./lib/generator.js"; import hooks from "./lib/hooks.js"; -import { isSuccess, getOneFromList, randomInt } from "./lib/helpers.js"; +import { isSuccess } from "./lib/helpers.js"; import exec from 'k6/execution'; export const setup = hooks.setup diff --git a/src/performanceTest/scripts/spikeTest_nosignup.js b/src/performanceTest/scripts/spikeTest_nosignup.js new file mode 100644 index 00000000..4755edd2 --- /dev/null +++ b/src/performanceTest/scripts/spikeTest_nosignup.js @@ -0,0 +1,61 @@ +import { check } from "k6"; +import Request from "./lib/request.js"; +import { encode } from "./lib/jwt.js"; +import hooks from "./lib/hooks.js"; +import { isSuccess, getOneFromList, randomInt } from "./lib/helpers.js"; +import exec from 'k6/execution'; + +export const setup = hooks.setup +export const handleSummary = hooks.handleSummary + +export const options = { + tags: { + testid: `${__ENV.ENTRYPOINT}` + }, + ext: { + loadimpact: { + apm: [ + { + includeTestRunId: true, + } + ] + } + }, + scenarios: { + contacts: { + executor: 'per-vu-iterations', + vus: 200, + iterations: 1, + maxDuration: '1m', + }, + }, + + thresholds: { + http_req_failed: ['rate<0.01'], // http errors should be less than 1% + http_req_duration: ['p(95)<200'], // 95% of requests should be below 100ms + }, +}; + +export default function () { + const req = new Request() + + const getAvaliableReservation = () => { + let count = 0 + while (count < 10) { + req.getEvents() + count++ + } + const events = req.getEvents() + return getOneFromList(events.json()) + } + + req.setToken(encode(exec.vu.idInTest)) + + const event = getAvaliableReservation() + if (event) { + const res = req.createReservation({ + eventId: event.id + }) + check(res, {"Success Reservation": isSuccess}); + } +} \ No newline at end of file