Skip to content

Commit

Permalink
load test prep for usage with flood (#926)
Browse files Browse the repository at this point in the history
* update readme, remove hardcoded values, give params useful names

* give test appropriate name

* rename test files

* rehouse data files alongside scenarios as flood has no concept of directories

* dynamic pupil pin gen

* add gitignore and use min admin run

* tweak outputs

* working pupil id extraction with XPATH

* teacher account per thread

* remove teacher login data set

* csrf token extraction, generates pupil pins

* change name of scenario

* increase pin generation to 30 pupils

* fix linting issues, update readme

* update tips file

* add editorconfig with default policies
  • Loading branch information
GuyHarwood authored Dec 6, 2018
1 parent e107d8c commit 0eb9586
Show file tree
Hide file tree
Showing 18 changed files with 1,271 additions and 481 deletions.
8 changes: 8 additions & 0 deletions .editorconfig
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
root = true

[*]
indent_style = space
indent_size = 2
charset = utf-8
trim_trailing_whitespace = true
insert_final_newline = true
9 changes: 9 additions & 0 deletions deploy/sql-migrations/seed-db.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
#!/usr/bin/env bash

# $1 is the SQL_ADMIN_USER
# $2 is the SQL_ADMIN_USER_PASSWORD
# $3 is the SQL_APP_USER_PASSWORD
cd $BUILD_REPOSITORY_LOCALPATH
cd admin
npm install
SQL_ADMIN_USER=$1 SQL_ADMIN_USER_PASSWORD=$2 SQL_APP_USER_PASSWORD=$3 npm run seed-sql
2 changes: 2 additions & 0 deletions load-test/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
reports
html-report
71 changes: 41 additions & 30 deletions load-test/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,28 +11,39 @@

### Mac OS
* Install JDK 7 or later
* Install latest JMeter using brew: `brew install jmeter`
* Install latest JMeter using brew: `brew install jmeter --with-plugins`
* Run JMeter: `open /usr/local/bin/jmeter`

### Windows
* Install JDK 7 or later
* Download [JMeter 5.0](http://www-us.apache.org/dist//jmeter/binaries/apache-jmeter-5.0.tgz)
* Run `/bin/jmeter.bat` to launch JMeter


## Teacher load test data preparation
* Ensure admin application is running and the migrations have been applied
* If a password is not specified the passwords will be set to 'password'
* While in `load-test/bin` directory:
* The following command will execute a node script which takes a password as an optional argument and will generate one teacher for each school in the database: `node generate-teacher-load-test-data.js`
* To set a custom password (i.e. 'newpassword') run: `node generate-teacher-load-test-data.js newpassword`

### Install Jmeter Plugins - Custom JMeter Functions
### Install Jmeter Plugins - Custom JMeter Functions (not required)
* download Jmeter plugin manager
https://www.blazemeter.com/blog/how-install-jmeter-plugins-manager
* download the Custom JMeter Functions plugin
https://jmeter-plugins.org/wiki/Functions/

## Best practices
* **Use a HTTP defaults item for each scenario** You can specify defaults for protocol, port & hostname for the target and parameterise each property. This ensures you do not have to set them for each request.
* **Do not hardcode data** It does not work at scale. Instead use tools such as the XPath extractor to find elements in web pages and obtain record IDs from the value property (see the `admin-generate-pins.jmx` scenario as an example).
* **Use the Debug Sampler for local scenario development** Use it to output variables and other useful information after a local test run. This can help you see what data / parameters / values are being produced at runtime.
* **Run a small load test locally after making changes** The JMeter UI can handle running 1-5 user load on a local instance of the app. The UI can sometimes be flaky, but its useful for viewing results and debug sampler information as you build out your scenarios. If you encounter issues with the UI, run from the command line.


## Teacher pin generation load test preparation (local test)
### Initialise storage services
Execute `./start.sh` to clear storage account contents, start SQL Server Docker instance, execute migrations and seed default data set.
* **NOTE**: in order to successfully clear storage account contents, you must have the `AZURE_STORAGE_CONNECTION_STRING` variable set for the admin app. Either in a `.env` file or as environment variable.
### Start the admin application
start the admin app with `yarn start`

## Seed load test data (non-local test only)
The scenarios have low defaults (2 users) so they can be executed quickly in a local environment. However, when performing load test at scale you will want to seed the database with a high volume of users (teachers) and pupils
* While in `load-test/bin` directory:
* The following command will execute a node script which takes a password as an optional argument and will generate one teacher for each school in the database: `node generate-teacher-load-test-data.js`
* To set a custom password (i.e. 'newpassword') run: `node generate-teacher-load-test-data.js newpassword`

## Pupil load test data preparation
* Ensure admin application is running and the migrations have been applied
Expand All @@ -46,35 +57,35 @@ https://jmeter-plugins.org/wiki/Functions/
## Execute pupil load test
* Assuming `jmeter` directory is placed within the load-test directory, execute the following command to run JMeter pupil check load test in CLI mode
* mkdir reports
``* jmeter -n -t ./scenarios/mtc_pupil_check_perf_test.jmx -l reports/pupil-performance-test.csv -Djmeter.save.saveservice.output_format=csv -e -o reports/PupilHTMLReports -Jhost=localhost -Jthreads=3600 -Jramp=50
``* jmeter -n -t ./scenarios/mtc_pupil_check_perf_test.jmx -l reports/pupil-performance-test.csv -Djmeter.save.saveservice.output_format=csv -e -o reports/PupilHTMLReports -JpupilApiHost=localhost -Jthreads=3600 -Jramp=50
``

This command above takes the following arguments:
* -n Run in CLI mode
* -t Test file in jmx format
* -l Report to be stored in csv format
* -D Overwrites the jmeter system properties. In above command we are overwriting the property to save report in csv format
* -e Generate HTML report after load test finishes
* -o Generated HTML Report with visual outputs of the test
* -jhost Admin app Host URL (host is the variable name used in jmeter host field)
* -Jthreads Number of Threads(users) (threads is the variable name used in thread field)
* -Jramp Ramp-up period (ramp is the variable name used for ramp up field)
* `-n` Run in CLI mode
* `-t` Test file in jmx format
* `-l` Report to be stored in csv format
* `-D` Overwrites the jmeter system properties. In above command we are overwriting the property to save report in csv format
* `-e` Generate HTML report after load test finishes
* `-o` Generated HTML Report with visual outputs of the test
* `-JpupilApiHost` Admin app Host URL (pupilApiHost is the variable name used in jmeter host field)
* `-Jthreads` Number of Threads(users) (threads is the variable name used in thread field)
* `-Jramp` Ramp-up period in milliseconds (ramp is the variable name used for ramp up field)

In order to rerun the test execute `undo-generate-pupil-load-test-data.sql` as SA to undo the test data population.

## Execute Admin load test
Assuming `jmeter` directory is placed within the load-test directory, execute the following command to run JMeter Admin load test in CLI mode:

`` jmeter -n -t ../scenarios/mtc_admin_login.jmx -l reports/mtc_admin_test_result.csv -Djmeter.save.saveservice.output_format=csv -e -o reports/MTCAdminHTMLReports -Jhost=admin-as-feb-mtc-staging.azurewebsites.net -Jthreads=80 -Jramp=1600
`` jmeter -n -t ../scenarios/mtc_admin_login.jmx -l reports/mtc_admin_test_result.csv -Djmeter.save.saveservice.output_format=csv -e -o reports/MTCAdminHTMLReports -JadminAppHost=admin-as-feb-mtc-staging.azurewebsites.net -Jthreads=80 -Jramp=1600
``

This command above takes the following arguments:
* -n Run in CLI mode
* -t Test file in jmx format
* -l Report to be stored in csv format
* -D Overwrites the jmeter system properties. in above command we are overwriting the property to save report in csv format
* -e Generate HTML report after load test finishes
* -o Generated HTML Report with visual outputs of the test
* -jhost Admin app Host URL (host is the variable name used in jmeter host field)
* -Jthreads Number of Threads(users) (threads is the variable name used in thread field)
* -Jramp Ramp-up period (ramp is the variable name used for ramp up field)
* `-n` Run in CLI mode
* `-t` Test file in jmx format
* `-l` Report to be stored in csv format
* `-D` Overwrites the jmeter system properties. in above command we are overwriting the property to save report in csv format
* `-e` Generate HTML report after load test finishes
* `-o` Generated HTML Report with visual outputs of the test
* `-JadminAppHost` Admin app Host URL (adminAppHost is the variable name used in jmeter host field)
* `-Jthreads` Number of Threads(users) (threads is the variable name used in thread field)
* `-Jramp` Ramp-up period in milliseconds (ramp is the variable name used for ramp up field)
6 changes: 6 additions & 0 deletions load-test/bin/generate-pupil-api-logins.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,11 @@
'use strict'

/*
NO LONGER USED.
generates sequenced pupil and school pins as a json array.
Created for testing the pupil API in isolation from loader.io.
*/

require('dotenv').config()

const entriesToCreate = process.env.LOAD_COUNT || 1000
Expand Down
11 changes: 6 additions & 5 deletions load-test/bin/generate-pupil-data.js
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
#!/usr/bin/env node

'use strict'

// require('dotenv').config()
Expand All @@ -21,7 +22,7 @@ async function main () {
from [mtc_admin].[school]`)

console.log(`Generating ${pupilCountPerSchool} pupils each for ${schools.length} schools`)
let c = 1;
let c = 1
for (const school of schools) {
await insertPupils(school, 40)
c += 1
Expand Down Expand Up @@ -54,14 +55,14 @@ async function insertPupils (school, count) {
upn
) VALUES`
const pupilData = []
for (let i = 0; i < count; i++ ) {
for (let i = 0; i < count; i++) {
pupilData.push([
`( '${randomDob()}'`,
`'Pupil'`,
`'M'`,
`'${count.toString()}'`,
school.id,
`'${genUPN(school.leaCode, school.estabCode, i)}')`,
`'${genUPN(school.leaCode, school.estabCode, i)}')`
].join(' , '))
}
const sql = `${insert} ${pupilData.join(', \n')}`
Expand All @@ -77,8 +78,8 @@ function randomDob () {

function genUPN (leaCode, estabCode, serial) {
try {
const upn = '' + leaCode.toString() + estabCode + (new Date().getFullYear().toString().substr(-2))
+ serial.toString().padStart(3, '0')
const upn = '' + leaCode.toString() + estabCode + (new Date().getFullYear().toString().substr(-2)) +
serial.toString().padStart(3, '0')
const checkLetter = upnService.calculateCheckLetter(upn)
return checkLetter + upn
} catch (error) {
Expand Down
10 changes: 10 additions & 0 deletions load-test/exec.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
#!/bin/bash

# exit on error
set -e

rm -rf ./reports
rm -rf ./html-report
mkdir reports
mkdir html-report
jmeter -n -t ./scenarios/admin-generate-pins-min.jmx -l reports/mtc_admin_test_result.csv -Djmeter.save.saveservice.output_format=csv -e -o html-report/
Loading

0 comments on commit 0eb9586

Please sign in to comment.