| 1 | import http from "k6/http"; |
| 2 | import { log, check, group, sleep } from "k6"; |
| 3 | import { Rate } from "k6/metrics"; |
| 4 | |
| 5 | // A custom metric to track failure rates |
| 6 | var failureRate = new Rate("check_failure_rate"); |
| 7 | |
| 8 | // Options |
| 9 | export let options = { |
| 10 | stages: [ |
| 11 | // Linearly ramp up from 1 to 20 VUs during first 30s |
| 12 | { target: 20, duration: "30s" }, |
| 13 | // Hold at 50 VUs for the next 1 minute |
| 14 | { target: 20, duration: "1m" }, |
| 15 | // Linearly ramp down from 50 to 0 VUs over the last 10 seconds |
| 16 | { target: 0, duration: "10s" } |
| 17 | ], |
| 18 | thresholds: { |
| 19 | // We want the 95th percentile of all HTTP request durations to be less than 500ms |
| 20 | "http_req_duration": ["p(95)<500"], |
| 21 | // Requests with the fast tag should finish even faster |
| 22 | "http_req_duration{fast:yes}": ["p(99)<250"], |
| 23 | // Thresholds based on the custom metric we defined and use to track application failures |
| 24 | "check_failure_rate": [ |
| 25 | // Global failure rate should be less than 1% |
| 26 | "rate<0.01", |
| 27 | // Abort the test early if it climbs over 5% |
| 28 | { threshold: "rate<=0.05", abortOnFail: true }, |
| 29 | ], |
| 30 | }, |
| 31 | }; |
| 32 | |
| 33 | function rnd(min, max) { |
| 34 | min = Math.ceil(min); |
| 35 | max = Math.floor(max); |
| 36 | return Math.floor(Math.random() * (max - min)) + min; //The maximum is exclusive and the minimum is inclusive |
| 37 | } |
| 38 | |
| 39 | // Main function |
| 40 | export default function () { |
| 41 | // Control what the data request asks for |
| 42 | let charts = [ "example.random" ] |
| 43 | let chartmin = 0; |
| 44 | let chartmax = charts.length - 1; |
| 45 | let aftermin = 60; |
| 46 | let aftermax = 3600; |
| 47 | let beforemin = 3503600; |
| 48 | let beforemax = 3590000; |
| 49 | let pointsmin = 300; |
| 50 | let pointsmax = 3600; |
| 51 | |
| 52 | group("Requests", function () { |
| 53 | // Execute multiple requests in parallel like a browser, to fetch data for the charts. The one taking the longes is the data request. |
| 54 | let resps = http.batch([ |
| 55 | ["GET", "http://localhost:19999/api/v1/info", { tags: { fast: "yes" } }], |
| 56 | ["GET", "http://localhost:19999/api/v1/charts", { tags: { fast: "yes" } }], |
| 57 | ["GET", "http://localhost:19999/api/v1/data?chart="+charts[rnd(chartmin,chartmax)]+"&before=-"+rnd(beforemin,beforemax)+"&after=-"+rnd(aftermin,aftermax)+"&points="+rnd(pointsmin,pointsmax)+"&format=json&group=average>ime=0&options=ms%7Cflip%7Cjsonwrap%7Cnonzero&_="+rnd(1,1000000000000), { }], |
| 58 | ["GET", "http://localhost:19999/api/v1/alarms", { tags: { fast: "yes" } }] |
| 59 | ]); |
| 60 | // Combine check() call with failure tracking |
| 61 | failureRate.add(!check(resps, { |
| 62 | "status is 200": (r) => r[0].status === 200 && r[1].status === 200 |
| 63 | })); |
| 64 | }); |
| 65 | |
| 66 | sleep(Math.random() * 2 + 1); // Random sleep between 1s and 3s |
| 67 | } |