-
Notifications
You must be signed in to change notification settings - Fork 13
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
e9bb27d
commit 57f73f3
Showing
6 changed files
with
274 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Hauki load testing | ||
|
||
Scripts for load testing Hauki API. | ||
|
||
## Prerequisities | ||
|
||
* [k6](https://k6.io/docs/getting-started/installation) installed | ||
|
||
## How to run the tests | ||
|
||
This script works as a wrapper for the k6 command and ensures that the proper authentication token is provided in the requests. Thus you can pass all the same parameters as you would do when using k6 directly. | ||
|
||
```bash | ||
./run.sh -v 1 -i 1 <SCRIPT> | ||
``` | ||
|
||
## How to run Hauki scenarios | ||
|
||
```bash | ||
./run.sh hauki-scenarios.js | ||
``` | ||
|
||
## HTML report | ||
The script is using [k6-reporter](https://github.com/benc-uk/k6-reporter) for outputting html test report. The results `summary.html` is created under this folder. | ||
|
||
You can also open it automatically after the test like this. | ||
```bash | ||
./run.sh hauki-scenarios.js && open summary.html | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,128 @@ | ||
/* eslint-disable */ | ||
import { check, group, sleep } from 'k6'; | ||
import { Httpx } from 'https://jslib.k6.io/httpx/0.0.1/index.js'; | ||
import { createOpeningHour } from './helpers/mocks.js'; | ||
import commands from './helpers/commands.js'; | ||
import { formatDate, getRandomArbitrary } from './helpers/utils.js'; | ||
import { htmlReport } from 'https://raw.githubusercontent.com/benc-uk/k6-reporter/main/dist/bundle.js'; | ||
import { textSummary } from 'https://jslib.k6.io/k6-summary/0.0.1/index.js'; | ||
|
||
const env = global['__ENV'] || process.env; | ||
|
||
const apiUrl = env.API_URL || 'https://hauki.api.stage.hel.ninja/v1'; | ||
// const authParams = env.AUTH_PARAMS; | ||
const tprekResourceId = env.HAUKI_RESOURCE || 'tprek:41683'; | ||
|
||
const IDLE_TIME = 10; | ||
|
||
const session = new Httpx(); | ||
session.setBaseUrl(`${apiUrl}`); | ||
// session.addHeader('Authorization', `haukisigned ${authParams}`); | ||
|
||
const { addNewDatePeriod, viewResource } = commands(session); | ||
|
||
export const options = { | ||
thresholds: { | ||
http_req_duration: ['p(90) < 2000'], | ||
}, | ||
scenarios: { | ||
// add requires authorization | ||
// addOpeningHours: { | ||
// executor: 'constant-vus', | ||
// exec: 'addOpeningHours', | ||
// vus: 5, | ||
// duration: '1m', | ||
// }, | ||
requestOpeningHours: { | ||
executor: 'constant-vus', | ||
exec: 'requestOpeningHours', | ||
vus: 50, | ||
duration: '1m', | ||
}, | ||
}, | ||
teardownTimeout: '5m', | ||
}; | ||
|
||
export function setup() { | ||
const { id } = session | ||
.get(`/resource/${tprekResourceId}/?format=json`) | ||
.json(); | ||
|
||
session.post('/date_period/', JSON.stringify(createOpeningHour(id)), { | ||
headers: { 'Content-Type': 'application/json' }, | ||
}); | ||
|
||
const resources = session.get('/resource/').json(); | ||
|
||
return { resourceId: id, resources }; | ||
} | ||
|
||
export function addOpeningHours({ resourceId }) { | ||
viewResource(tprekResourceId, resourceId); | ||
sleep(getRandomArbitrary(10, IDLE_TIME)); | ||
addNewDatePeriod(resourceId); | ||
viewResource(tprekResourceId, resourceId); | ||
} | ||
|
||
export function requestOpeningHours({ resources }) { | ||
const random = Math.floor(Math.random() * resources.results.length); | ||
const resourceId = resources.results[random].id; | ||
|
||
group('Get opening hours', () => { | ||
sleep(getRandomArbitrary(1, 5)); | ||
|
||
const startDate = new Date(); | ||
const endDate = new Date(); | ||
endDate.setDate(startDate.getDate() + 365); | ||
|
||
const url = `/resource/${resourceId}/opening_hours/?start_date=${formatDate( | ||
startDate | ||
)}&end_date=${formatDate(endDate)}`; | ||
|
||
const start = new Date().toISOString(); | ||
const result = session.get(url); | ||
|
||
if (result.status !== 200) { | ||
console.log( | ||
JSON.stringify( | ||
{ | ||
url: `${apiUrl}/${url}`, | ||
status: result.status, | ||
start, | ||
end: new Date().toISOString(), | ||
body: JSON.stringify(result.body), | ||
}, | ||
null, | ||
2 | ||
) | ||
); | ||
} | ||
|
||
check(result, { | ||
'Fetching opening hours returns 200': (r) => r.status === 200, | ||
}); | ||
}); | ||
} | ||
|
||
export function teardown({ resourceId }) { | ||
const response = session | ||
.get(`/date_period/?resource=${resourceId}&end_date_gte=-1d&format=json`) | ||
.json(); | ||
|
||
const toBeDeleted = response.filter((datePeriod) => | ||
datePeriod.name.fi.includes('load-test') | ||
); | ||
|
||
toBeDeleted.forEach((datePeriod) => { | ||
session.delete(`/date_period/${datePeriod.id}/`); | ||
}); | ||
|
||
console.log(`Deleted date periods: ${toBeDeleted.length}`); | ||
} | ||
|
||
export function handleSummary(data) { | ||
return { | ||
'summary.html': htmlReport(data), | ||
stdout: textSummary(data, { indent: ' ', enableColors: true }), | ||
}; | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
import { check, sleep } from 'k6'; | ||
import { createOpeningHour } from './mocks.js'; | ||
import { getRandomArbitrary } from './utils.js'; | ||
|
||
const commands = (session) => { | ||
const viewResource = (origId, resourceId) => { | ||
session.post(`/resource/${origId}/permission_check/`); | ||
session.request('OPTIONS', '/date_period/'); | ||
|
||
const response = session.get( | ||
`/date_period/?resource=${resourceId}&end_date_gte=-1d&format=json` | ||
); | ||
|
||
check(response, { | ||
'GET date periods status is 200': (r) => r.status === 200, | ||
}); | ||
|
||
check(session.get(`/resource/${origId}/?format=json`), { | ||
'GET resource status is status 200': (r) => r.status === 200, | ||
}); | ||
|
||
return response.json(); | ||
}; | ||
|
||
const viewDatePeriod = (resourceId, datePeriodId) => { | ||
session.post(`/resource/${resourceId}/permission_check/`); | ||
|
||
check(session.get(`/resource/${resourceId}/?format=json`), { | ||
'GET resource status is status 200': (r) => r.status === 200, | ||
}); | ||
|
||
check(session.get(`/date_period/${datePeriodId}/?format=json`), { | ||
'GET date period status is 200': (r) => r.status === 200, | ||
}); | ||
|
||
session.request('OPTIONS', '/date_period/'); | ||
}; | ||
|
||
const addNewDatePeriod = (resourceId) => { | ||
session.post(`/resource/${resourceId}/permission_check/`); | ||
session.request('OPTIONS', '/date_period/'); | ||
|
||
check(session.get(`/resource/${resourceId}/?format=json`), { | ||
'GET resource status is status 200': (r) => r.status === 200, | ||
}); | ||
|
||
sleep(getRandomArbitrary(10, 20)); | ||
|
||
const response = session.post( | ||
'/date_period/', | ||
JSON.stringify(createOpeningHour(resourceId)), | ||
{ | ||
headers: { 'Content-Type': 'application/json' }, | ||
} | ||
); | ||
|
||
check(response, { | ||
'POST date period status is status 201': (r) => r.status === 201, | ||
}); | ||
}; | ||
|
||
return { | ||
addNewDatePeriod, | ||
viewDatePeriod, | ||
viewResource, | ||
}; | ||
}; | ||
|
||
export default commands; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,33 @@ | ||
/* eslint-disable import/prefer-default-export */ | ||
export const createOpeningHour = (resource) => ({ | ||
resource, | ||
name: { fi: `load-test ${new Date().toISOString()}`, sv: '', en: '' }, | ||
description: { fi: '', sv: '', en: '' }, | ||
start_date: '2022-01-01', | ||
end_date: '2022-12-31', | ||
resource_state: 'undefined', | ||
override: false, | ||
time_span_groups: [ | ||
{ | ||
rules: [], | ||
time_spans: [ | ||
{ | ||
description: { fi: null, sv: null, en: null }, | ||
end_time: '16:00:00', | ||
start_time: '08:00:00', | ||
resource_state: 'open', | ||
full_day: false, | ||
weekdays: [1, 2, 3, 4, 5], | ||
}, | ||
{ | ||
description: { fi: null, sv: null, en: null }, | ||
end_time: '18:00:00', | ||
start_time: '10:00:00', | ||
resource_state: 'open', | ||
full_day: false, | ||
weekdays: [6], | ||
}, | ||
], | ||
}, | ||
], | ||
}); |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,6 @@ | ||
/* eslint-disable import/prefer-default-export */ | ||
export const getRandomArbitrary = (min, max) => { | ||
return Math.random() * (max - min) + min; | ||
}; | ||
|
||
export const formatDate = (d) => d.toISOString().split('T')[0]; |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,9 @@ | ||
cd $(dirname "$0") | ||
|
||
export HAUKI_USER='[email protected]'; | ||
export HAUKI_RESOURCE='tprek:41683'; #40759 41835 41683 | ||
export API_URL=https://hauki.api.stage.hel.ninja/v1 | ||
|
||
# export AUTH_PARAMS=$(node ../scripts/generate-auth-params.js) | ||
|
||
k6 run "$@" |