From 90651ed6aaae92ce69a1b6b949f31420b1539eac Mon Sep 17 00:00:00 2001 From: Alex Hyett Date: Tue, 26 Sep 2023 11:52:17 +0100 Subject: [PATCH] Add k6 test files --- README.md | 32 +++++++++++++++++++++++++- src/Program.cs | 1 - src/Properties/launchSettings.json | 10 --------- tests/load-test.js | 35 +++++++++++++++++++++++++++++ tests/simple-test.js | 10 +++++++++ tests/soak-test.js | 32 ++++++++++++++++++++++++++ tests/spike-test.js | 36 ++++++++++++++++++++++++++++++ tests/stress-test.js | 36 ++++++++++++++++++++++++++++++ 8 files changed, 180 insertions(+), 12 deletions(-) create mode 100644 tests/load-test.js create mode 100644 tests/simple-test.js create mode 100644 tests/soak-test.js create mode 100644 tests/spike-test.js create mode 100644 tests/stress-test.js diff --git a/README.md b/README.md index 8726eaa..82f9b99 100644 --- a/README.md +++ b/README.md @@ -1,2 +1,32 @@ # performance-testing -The code from my YouTube video on "How to do Performance Testing with k6" +The code from my YouTube video on "How to do Performance Testing with k6" + +You first need to run the API: +```sh +cd src +dotnet run +``` + +Then in a seperate terminal window run the tests using the commands below. + +I have added a HOSTNAME variable to each of the scripts (except simple-test.js) which needs to be added when running them. + +## Stress Test +```sh +k6 run -e HOSTNAME=localhost:5157 tests/stress-test.js +``` + +## Spike Test +```sh +k6 run -e HOSTNAME=localhost:5157 tests/spike-test.js +``` + +## Load Test +```sh +k6 run -e HOSTNAME=localhost:5157 tests/load-test.js +``` + +## Soak Test +```sh +k6 run -e HOSTNAME=localhost:5157 tests/soak-test.js +``` \ No newline at end of file diff --git a/src/Program.cs b/src/Program.cs index 88e6faa..87432e5 100644 --- a/src/Program.cs +++ b/src/Program.cs @@ -1,6 +1,5 @@ var builder = WebApplication.CreateBuilder(args); - builder.Services.AddControllers(); builder.Services.AddEndpointsApiExplorer(); diff --git a/src/Properties/launchSettings.json b/src/Properties/launchSettings.json index faab549..bddefb4 100644 --- a/src/Properties/launchSettings.json +++ b/src/Properties/launchSettings.json @@ -19,16 +19,6 @@ "ASPNETCORE_ENVIRONMENT": "Development" } }, - "https": { - "commandName": "Project", - "dotnetRunMessages": true, - "launchBrowser": true, - "launchUrl": "swagger", - "applicationUrl": "https://localhost:7255;http://localhost:5157", - "environmentVariables": { - "ASPNETCORE_ENVIRONMENT": "Development" - } - }, "IIS Express": { "commandName": "IISExpress", "launchBrowser": true, diff --git a/tests/load-test.js b/tests/load-test.js new file mode 100644 index 0000000..184b14e --- /dev/null +++ b/tests/load-test.js @@ -0,0 +1,35 @@ +import http from 'k6/http'; +import { sleep } from 'k6'; +import { SharedArray } from 'k6/data'; + +export const options = { + stages: [ + { duration: '5m', target: 200 }, // ramp up + { duration: '20m', target: 200 }, // stable + { duration: '5m', target: 0 }, // ramp-down to 0 users + ], + thresholds: { + http_req_duration: ['p(99)<10'], // 99% of requests must complete within 10ms + } +}; + +const dates = new SharedArray('dates', function () { + var dates = []; + var currentDate = new Date(); + var minDate = new Date(); + minDate.setFullYear(currentDate.getFullYear() - 100); + + for (var i = 0; i < 100; i++) { + var randomTime = Math.random() * (currentDate.getTime() - minDate.getTime()); + var randomDate = new Date(minDate.getTime() + randomTime); + dates.push(randomDate.toISOString()); + } + + return dates; +}); + +export default () => { + const randomDate = dates[Math.floor(Math.random() * dates.length)]; + http.get(`http://${__ENV.HOSTNAME}/age/${randomDate}`); + sleep(1); +}; \ No newline at end of file diff --git a/tests/simple-test.js b/tests/simple-test.js new file mode 100644 index 0000000..9dd5aab --- /dev/null +++ b/tests/simple-test.js @@ -0,0 +1,10 @@ +import http from 'k6/http'; + +export const options = { + vus: 1, + duration: '10s' +}; + +export default () => { + http.get('http://localhost:5157/age/1987-09-01'); +}; \ No newline at end of file diff --git a/tests/soak-test.js b/tests/soak-test.js new file mode 100644 index 0000000..f817682 --- /dev/null +++ b/tests/soak-test.js @@ -0,0 +1,32 @@ +import http from 'k6/http'; +import { sleep } from 'k6'; +import { SharedArray } from 'k6/data'; + +export const options = { + stages: [ + { duration: '5m', target: 200 }, // ramp up + { duration: '8h', target: 200 }, // stable + { duration: '5m', target: 0 }, // ramp-down to 0 users + ], +}; + +const dates = new SharedArray('dates', function () { + var dates = []; + var currentDate = new Date(); + var minDate = new Date(); + minDate.setFullYear(currentDate.getFullYear() - 100); + + for (var i = 0; i < 100; i++) { + var randomTime = Math.random() * (currentDate.getTime() - minDate.getTime()); + var randomDate = new Date(minDate.getTime() + randomTime); + dates.push(randomDate.toISOString()); + } + + return dates; +}); + +export default () => { + const randomDate = dates[Math.floor(Math.random() * dates.length)]; + http.get(`http://${__ENV.HOSTNAME}/age/${randomDate}`); + sleep(1); +}; \ No newline at end of file diff --git a/tests/spike-test.js b/tests/spike-test.js new file mode 100644 index 0000000..59317f3 --- /dev/null +++ b/tests/spike-test.js @@ -0,0 +1,36 @@ +import http from 'k6/http'; +import { sleep } from 'k6'; +import { SharedArray } from 'k6/data'; + +export const options = { + stages: [ + { duration: '10s', target: 200 }, // ramp up + { duration: '1m', target: 200 }, // stable + { duration: '10s', target: 2000 }, // ramp up + { duration: '5m', target: 2000 }, // stable + { duration: '10s', target: 200 }, // ramp up + { duration: '1m', target: 200 }, // stable + { duration: '10s', target: 0 }, // ramp-down to 0 users + ], +}; + +const dates = new SharedArray('dates', function () { + var dates = []; + var currentDate = new Date(); + var minDate = new Date(); + minDate.setFullYear(currentDate.getFullYear() - 100); + + for (var i = 0; i < 100; i++) { + var randomTime = Math.random() * (currentDate.getTime() - minDate.getTime()); + var randomDate = new Date(minDate.getTime() + randomTime); + dates.push(randomDate.toISOString()); + } + + return dates; +}); + +export default () => { + const randomDate = dates[Math.floor(Math.random() * dates.length)]; + http.get(`http://${__ENV.HOSTNAME}/age/${randomDate}`); + sleep(1); +}; \ No newline at end of file diff --git a/tests/stress-test.js b/tests/stress-test.js new file mode 100644 index 0000000..2c1781f --- /dev/null +++ b/tests/stress-test.js @@ -0,0 +1,36 @@ +import http from 'k6/http'; +import { sleep } from 'k6'; +import { SharedArray } from 'k6/data'; + +export const options = { + stages: [ + { duration: '1m', target: 200 }, // ramp up + { duration: '5m', target: 200 }, // stable + { duration: '1m', target: 400 }, // ramp up + { duration: '5m', target: 400 }, // stable + { duration: '1m', target: 800 }, // ramp up + { duration: '5m', target: 800 }, // stable + { duration: '5m', target: 0 }, // ramp-down to 0 users + ], +}; + +const dates = new SharedArray('dates', function () { + var dates = []; + var currentDate = new Date(); + var minDate = new Date(); + minDate.setFullYear(currentDate.getFullYear() - 100); + + for (var i = 0; i < 100; i++) { + var randomTime = Math.random() * (currentDate.getTime() - minDate.getTime()); + var randomDate = new Date(minDate.getTime() + randomTime); + dates.push(randomDate.toISOString()); + } + + return dates; +}); + +export default () => { + const randomDate = dates[Math.floor(Math.random() * dates.length)]; + http.get(`http://${__ENV.HOSTNAME}/age/${randomDate}`); + sleep(1); +}; \ No newline at end of file