Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .ops/performance-test/.gitignore
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
/measurements
!/measurements/.gitkeep
/node_modules
.env
17 changes: 17 additions & 0 deletions .ops/performance-test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,23 @@ Run tests
docker compose run --rm performance-test run --quiet script.js | jq --sort-keys > output.json
```

Run tests

```shell
API_ROOT_URL="http://localhost:3000"

env_file=.env

if [ -f "$env_file" ]; then
API_ROOT_URL=$(grep '^API_ROOT_URL=' "$env_file" | cut -d '=' -f 2 | tr -d '\r')
fi

datetime=$(date -u +"%Y-%m-%dT%H:%M:%SZ")
filename=$(printf "%s" "$API_ROOT_URL" | sed 's|https?://||; s|/|_|g')_$datetime.json

docker compose run --rm performance-test run --quiet script.js | jq --sort-keys > measurements/$filename
```

Run tests once to debug


Expand Down
Empty file.
28 changes: 25 additions & 3 deletions .ops/performance-test/script.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import encoding from 'k6/encoding'
import http from 'k6/http'
import { Trend } from 'k6/metrics'

// noinspection JSUnusedGlobalSymbols
export const options = {
// A number specifying the number of VUs to run concurrently.
vus: __ENV.VUS || 10,
Expand All @@ -11,6 +13,15 @@ export const options = {

const host = __ENV.API_ROOT_URL || 'http://localhost:3000'

const basicAuthUser = __ENV.BASIC_AUTH_USER
const basicAuthPassword = __ENV.BASIC_AUTH_PASSWORD

if (!!basicAuthUser !== !!basicAuthPassword) {
throw new Error('BASIC_AUTH_USER and BASIC_AUTH_PASSWORD must be set together')
}

const basicAuthActive = !!basicAuthUser && !!basicAuthPassword

const specialEndpoints = [
'/',
'/api',
Expand Down Expand Up @@ -45,20 +56,20 @@ export default function() {
const loginResponse = http.post(
`${host}/api/authentication_token`,
payload,
{ headers: { 'Content-Type': 'application/json' } })
{ headers: addAuthorizationHeadersIfNecessary({ 'Content-Type': 'application/json' }) })
loginTrend.add(loginResponse.timings.duration);

for (const [_, value] of Object.entries(getUrlsToMeasure()._links)) {
const urlWithoutTemplate = value.href.replace(/{.*$/, '')
if (!specialEndpoints.includes(urlWithoutTemplate)) {
const url = `${host}${urlWithoutTemplate}.jsonhal`
const collection = http.get(url)
const collection = http.get(url, { headers: addAuthorizationHeadersIfNecessary() })

metricsMap.get(urlWithoutTemplate)?.add(collection.timings.duration)

try {
const itemUrl = JSON.parse(collection.body)._embedded?.items[0]._links.self.href
const itemResponse = http.get(`${host}${itemUrl}.jsonhal`)
const itemResponse = http.get(`${host}${itemUrl}.jsonhal`, { headers: addAuthorizationHeadersIfNecessary() })
metricsMap.get(`${urlWithoutTemplate}/item`)?.add(itemResponse.timings.duration)
}
// this also catches the ReferenceError on the long path to find the item url
Expand Down Expand Up @@ -228,3 +239,14 @@ function getUrlsToMeasure() {
function toMetricName(name) {
return name.replaceAll("/", "_")
}

function addAuthorizationHeadersIfNecessary(headers = {}) {
const authHeaders = {}
if (basicAuthActive) {
authHeaders['Authorization'] = `Basic ${encoding.b64encode(`${basicAuthUser}:${basicAuthPassword}`)}`
}
return {
...authHeaders,
...headers
}
}
Loading