From 7321c077577c6e0c738dbba1e411230530d41b2c Mon Sep 17 00:00:00 2001 From: Adrien Chinour Date: Fri, 8 Nov 2024 00:27:22 +0100 Subject: [PATCH] test: add k6 API testing (smoke+stress) --- .github/workflows/load_test.yaml | 31 +++++++++++++++++++++++ k6/.gitignore | 1 + k6/api-smoke.js | 29 ++++++++++++++++++++++ k6/api-stress.js | 42 ++++++++++++++++++++++++++++++++ k6/package-lock.json | 25 +++++++++++++++++++ k6/package.json | 6 +++++ 6 files changed, 134 insertions(+) create mode 100644 .github/workflows/load_test.yaml create mode 100644 k6/.gitignore create mode 100644 k6/api-smoke.js create mode 100644 k6/api-stress.js create mode 100644 k6/package-lock.json create mode 100644 k6/package.json diff --git a/.github/workflows/load_test.yaml b/.github/workflows/load_test.yaml new file mode 100644 index 0000000..9ec7f15 --- /dev/null +++ b/.github/workflows/load_test.yaml @@ -0,0 +1,31 @@ +name: Run k6 API testsuite +on: + workflow_dispatch: + +jobs: + run-test: + runs-on: ubuntu-latest + steps: + - name: Checkout + uses: actions/checkout@v4 + + - name: Setup K6 + uses: grafana/setup-k6-action@v1 + + - name: Run local k6 / API Smoke testing + uses: grafana/run-k6-action@v1 + env: + K6_CLOUD_TOKEN: ${{ secrets.K6_CLOUD_TOKEN }} + K6_CLOUD_PROJECT_ID: ${{ secrets.K6_CLOUD_PROJECT_ID }} + AUTH_TOKEN: ${{ secrets.ADMIN_AUTH_TOKEN }} + with: + path: k6/api-smoke.js + + - name: Run local k6 / API Stress testing + uses: grafana/run-k6-action@v1 + env: + K6_CLOUD_TOKEN: ${{ secrets.K6_CLOUD_TOKEN }} + K6_CLOUD_PROJECT_ID: ${{ secrets.K6_CLOUD_PROJECT_ID }} + AUTH_TOKEN: ${{ secrets.ADMIN_AUTH_TOKEN }} + with: + path: k6/api-stress.js diff --git a/k6/.gitignore b/k6/.gitignore new file mode 100644 index 0000000..3c3629e --- /dev/null +++ b/k6/.gitignore @@ -0,0 +1 @@ +node_modules diff --git a/k6/api-smoke.js b/k6/api-smoke.js new file mode 100644 index 0000000..af1f3c4 --- /dev/null +++ b/k6/api-smoke.js @@ -0,0 +1,29 @@ +import http from 'k6/http'; +import { check, sleep } from 'k6'; + +const paths = [ + '/articles', + '/features', + '/projects', + '/articles/@id', + '/articles/@id/comments', + '/articles/@id/recommendations', +]; + +export default function () { + for (let path of paths) { + const res = http.get( + `https://api.udfn.fr${path.replace('@id', 'NMVntUf1yiwhMkrOftLNB')}`, + { + headers: { + Authorization: `Bearer ${__ENV.AUTH_TOKEN}` + } + } + ); + check(res, { + 'is status 200': (r) => r.status === 200, + }); + + sleep(0.1); + } +} diff --git a/k6/api-stress.js b/k6/api-stress.js new file mode 100644 index 0000000..4c882ef --- /dev/null +++ b/k6/api-stress.js @@ -0,0 +1,42 @@ +import http from 'k6/http'; +import { check } from 'k6'; +import { randomItem } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js'; + +const paths = [ + '/articles', + '/features', + '/projects', + '/articles/@id', + '/articles/@id/comments', + '/articles/@id/recommendations', +]; + +const articles = [ + 'NMVntUf1yiwhMkrOftLNB', + '4aAkSjsn311n0jwAgNnIvH', + '7rLwY85ICqoRIXKyHeeSGY', + '1UXgm0ZL7D1rysOnysYlrM', + '1yN0AOunIiaLn8nXZc7k6z', + '4EXN4ffKnY92zPpVS1xrVn', + '6J0hWoFCuiuWQtjp3K1mXn', +]; + +export const options = { + vus: 50, + duration: '1m', +}; + +export default function () { + const path = randomItem(paths).replace('@id', randomItem(articles)); + const res = http.get( + `https://api.udfn.fr${path}`, + { + headers: { + Authorization: `Bearer ${__ENV.AUTH_TOKEN}` + } + } + ); + check(res, { + 'is status 200': (r) => r.status === 200, + }); +} diff --git a/k6/package-lock.json b/k6/package-lock.json new file mode 100644 index 0000000..f4b5509 --- /dev/null +++ b/k6/package-lock.json @@ -0,0 +1,25 @@ +{ + "name": "k6", + "lockfileVersion": 3, + "requires": true, + "packages": { + "": { + "dependencies": { + "@types/k6": "^0.54.1", + "k6": "^0.0.0" + } + }, + "node_modules/@types/k6": { + "version": "0.54.1", + "resolved": "https://registry.npmjs.org/@types/k6/-/k6-0.54.1.tgz", + "integrity": "sha512-ezTMhuWr3TZIMOqAv51/4rD5T4FE1pSryrh5BCgxsniuqxbi5jQ3YEiOlO9C1+LvJcliC2byyd2Cw6cnUY7CLg==", + "license": "MIT" + }, + "node_modules/k6": { + "version": "0.0.0", + "resolved": "https://registry.npmjs.org/k6/-/k6-0.0.0.tgz", + "integrity": "sha512-GAQSWayS2+LjbH5bkRi+pMPYyP1JSp7o+4j58ANZ762N/RH/SdlAT3CHHztnn8s/xgg8kYNM24Gd2IPo9b5W+g==", + "license": "AGPL-3.0" + } + } +} diff --git a/k6/package.json b/k6/package.json new file mode 100644 index 0000000..2cd5c2d --- /dev/null +++ b/k6/package.json @@ -0,0 +1,6 @@ +{ + "dependencies": { + "@types/k6": "^0.54.1", + "k6": "^0.0.0" + } +}