Skip to content

Commit

Permalink
Cleanup auth and readme
Browse files Browse the repository at this point in the history
  • Loading branch information
mikevespi committed Dec 20, 2024
1 parent a5e1d7d commit 684b378
Show file tree
Hide file tree
Showing 6 changed files with 96 additions and 52 deletions.
44 changes: 31 additions & 13 deletions performance/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@
Performance testing of this app was done using k6 by Grafana (https://k6.io/). Frontend performance
tests made use of the k6 browser testing tools (https://grafana.com/docs/k6/latest/using-k6-browser/).

## Running the Tests

Backend and frontend have thier own test scripts, and their own make commands to run.
For the most accurate results, it is generally best to run one scenario at a time. Note that if running multiple test
scenarios at once, such as hitting several endpoints continuously, each test will have its own set of the number of
users specified in the stages, so change the numbers as needed.

## Setup

In order to configure the tests, the following settings are available:
Expand All @@ -15,32 +22,43 @@ In order to configure the tests, the following settings are available:
- HOST: set in the `Makefile`, this points to the server being tested. Front- and back-end each have a value.
- REQUESTS_PER_SECOND: set i the `Makefile`, this dictates the rate that the requests will be made at.
** Important: if setting above 50rps, alert platform services first **
- Credentials and request headers: set in `common/auth.js` these are the credentials used to run the tests. User
credentials will need to be added for the browser test. A valid auth token is needed for the protocol level tets.
- Credentials and tokens: set in `common/auth.js` these are the credentials used to run the tests. User
credentials will need to be added for the browser test. A valid auth token & refresh token are needed for the
protocol level tets.
- Tests: determining which tests will run in a given suite is done by simply commenting out tests that you want skipped
in the respective `frontend_script.js` or `backend_script.js` file. Comment out the tests entry in both `options.scenario`
and the corresponding if statement in the default function.
in the respective `frontend_script.js` or `backend_script.js` file. Comment out the tests entry in both
`options.scenario` and the corresponding if statement in the default function.

## Running the Tests
### Token and Credentials

Backend and frontend have thier own test scripts, and their own make commands to run.
Valid user credentials with the appropriate roles are required for the browser tests, along with that users officer ID
from the officer table. For the protocol level tests a token and refresh token that are valid at the time of running
the test will be needed, and the tests will refresh the values as they run. The logic for this can be found in
`backend_script.js` and `frontend_script.js`. The initial values for the token and refresh token can be found be loggin
into the environment that is being used for the load test and copying the values out of the response of the network
call titled `token` from browser tools network tab. If you leave an instance open in your browser these network
requests will continue to be made with the latest token, which can save time between tests. Once the rest of the setup
is done and you are ready to run the tests, copy the latest values into `common/auth.js` and don't forget to save.

### Locally
### Running from Local

1. Install k6 - https://k6.io/docs/get-started/installation/

2. If results files already exist in `/performance/k6_results` consider dating them or moving them, or else they will be
2. If results files already exist in `/performance/k6_results` rename or move them, or else they will be
overwritten.

3. Configure the tests (see "Setup" above) to be pointed at the correct servers with the desired load and scenarios.
The load is set for the front- and backend separately in the Makefile, be sure to set the correct one.

4. Ensure that the servers being used for testing are running and ready with the correct test data, and setup any
monitoring needed during the testing. It is a good idea to watch resource usage on the machine running the tests as
well just to ensure that its own resource constraints are not affecting results.
cluster / resource monitoring needed during the testing. It is a good idea to watch resource usage on the machine
running the tests as well just to ensure that its own resource constraints are not affecting results.

5. From the `/performance` directory, run either `make bakend_perf_test` or `make frontend_perf_test` depending on
which suite you are running. (If running one of the more intensive tests such as `spike` or `stress`, it is
recommended that a `test_run` is done first to ensure that everything is working as intended.)
5. From the `/performance` directory, run `make bakend_perf_test` or `make frontend_perf_test` depending on
which suite you are running. To run the frontend browser test with a regular browser, instead run
`K6_BROWSER_HEADLESS=false make frontend_perf_test` however this is very resource intesive to do with more than one
virtual user so adjust the number of vus. If running one of the more intensive tests such as `spike` or
`stress`, it is recommended that a `test_run` is done first to ensure that everything is working as intended.

6. When the tests finish, k6 will present you with a summary of the test in the terminal that ran the tests, it is
recommended to copy the summary into a text file. The detailed results can be found in `/performance/k6_results/`.
36 changes: 18 additions & 18 deletions performance/backend_script.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ import {
mapSearchWithCMFilter,
} from "./tests/backend/mapSearch.js";
import { getComplaintDetails, addAndRemoveComplaintOutcome } from "./tests/backend/complaint_details.js";
import { INITIAL_COS_TOKEN, INITIAL_COS_REFRESH_TOKEN, generateRequestConfig } from "./common/auth.js";
import { INITIAL_TOKEN, INITIAL_REFRESH_TOKEN, generateRequestConfig } from "./common/auth.js";

const defaultOptions = {
executor: "ramping-vus",
Expand Down Expand Up @@ -52,9 +52,9 @@ export const options = {
*/

const TOKEN_REFRESH_TIME = 60;
var cosToken = INITIAL_COS_TOKEN;
var cosRefreshToken = INITIAL_COS_REFRESH_TOKEN;
var cosRequestConfig = generateRequestConfig(cosToken);
var token = INITIAL_TOKEN;
var refreshToken = INITIAL_REFRESH_TOKEN;
var requestConfig = generateRequestConfig(token);

export default function () {
const HOST = __ENV.SERVER_HOST;
Expand All @@ -64,46 +64,46 @@ export default function () {
"https://dev.loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/token",
{
grant_type: "refresh_token",
refresh_token: cosRefreshToken,
refresh_token: refreshToken,
client_id: "compliance-and-enforcement-digital-services-web-4794",
},
);

cosToken = JSON.parse(refreshRes.body).access_token;
cosRefreshToken = JSON.parse(refreshRes.body).refresh_token;
cosRequestConfig = generateRequestConfig(cosToken);
token = JSON.parse(refreshRes.body).access_token;
refreshToken = JSON.parse(refreshRes.body).refresh_token;
requestConfig = generateRequestConfig(token);
}
// search
if (exec.scenario.name === "searchWithDefaultFilters") {
searchWithDefaultFilters(HOST, cosRequestConfig);
searchWithDefaultFilters(HOST, requestConfig);
}
if (exec.scenario.name === "searchWithoutFilters") {
searchWithoutFilters(HOST, cosRequestConfig);
searchWithoutFilters(HOST, requestConfig);
}
if (exec.scenario.name === "openSearchWithoutFilters") {
openSearchWithoutFilters(HOST, cosRequestConfig);
openSearchWithoutFilters(HOST, requestConfig);
}
if (exec.scenario.name === "searchWithCMFilter") {
searchWithCMFilter(HOST, cosRequestConfig);
searchWithCMFilter(HOST, requestConfig);
}
// map search
if (exec.scenario.name === "mapSearchDefaultFilters") {
mapSearchDefaultFilters(HOST, cosRequestConfig);
mapSearchDefaultFilters(HOST, requestConfig);
}
if (exec.scenario.name === "mapSearchAllOpenComplaints") {
mapSearchAllOpenComplaints(HOST, cosRequestConfig);
mapSearchAllOpenComplaints(HOST, requestConfig);
}
if (exec.scenario.name === "mapSearchAllComplaints") {
mapSearchAllComplaints(HOST, cosRequestConfig);
mapSearchAllComplaints(HOST, requestConfig);
}
if (exec.scenario.name === "mapSearchWithCMFilter") {
mapSearchWithCMFilter(HOST, cosRequestConfig);
mapSearchWithCMFilter(HOST, requestConfig);
}
// complaint details
if (exec.scenario.name === "getComplaintDetails") {
getComplaintDetails(HOST, cosRequestConfig);
getComplaintDetails(HOST, requestConfig);
}
if (exec.scenario.name === "addAndRemoveComplaintOutcome") {
addAndRemoveComplaintOutcome(HOST, cosRequestConfig);
addAndRemoveComplaintOutcome(HOST, requestConfig);
}
}
17 changes: 2 additions & 15 deletions performance/common/auth.js
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
export const INITIAL_COS_TOKEN = "";
export const INITIAL_COS_REFRESH_TOKEN = "";
export const INITIAL_TOKEN = "";
export const INITIAL_REFRESH_TOKEN = "";

export const COS_USER_CREDS = {
username: "",
Expand All @@ -15,16 +15,3 @@ export const generateRequestConfig = (token) => {
},
};
};

const CEEB_USER_TOKEN = "xxxxxxx";
export const CEEB_USER_CREDS = {
username: "",
password: "",
};

export const CEEB_USER_HEADERS = {
headers: {
"Content-Type": "application/json",
Authorization: `Bearer ${CEEB_USER_TOKEN}`,
},
};
2 changes: 1 addition & 1 deletion performance/common/params.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ export const STAGES = {
// Test run stages to make sure all scenarios are working
test_run: [
{ duration: "5s", target: TEST_RUN_USERS },
{ duration: "5s", target: TEST_RUN_USERS },
{ duration: "10s", target: TEST_RUN_USERS },
{ duration: "5s", target: 0 },
],

Expand Down
28 changes: 25 additions & 3 deletions performance/frontend_script.js
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
import exec from "k6/execution";
import http from "k6/http";
import { browserTest } from "./tests/frontend/browser.js";
import { protocolTest } from "./tests/frontend/protocol.js";
import { INITIAL_TOKEN, INITIAL_REFRESH_TOKEN, generateRequestConfig } from "./common/auth.js";

/**
* To run with an open browser, prepend the make command with K6_BROWSER_HEADLESS=false
Expand Down Expand Up @@ -30,19 +32,39 @@ export const options = {
},
protocolTest: {
executor: "constant-vus",
vus: 5,
duration: "30s",
vus: 1,
duration: "20s",
},
},
};

const TOKEN_REFRESH_TIME = 60;
var token = INITIAL_TOKEN;
var refreshToken = INITIAL_REFRESH_TOKEN;
var requestConfig = generateRequestConfig(token);

export default function () {
const HOST = __ENV.APP_HOST;
// Refresh the token if necessary based on iteration number, refresh time and rate of requests
if (__ITER === 0 || __ITER % (__ENV.RPS * TOKEN_REFRESH_TIME) === 0) {
const refreshRes = http.post(
"https://dev.loginproxy.gov.bc.ca/auth/realms/standard/protocol/openid-connect/token",
{
grant_type: "refresh_token",
refresh_token: refreshToken,
client_id: "compliance-and-enforcement-digital-services-web-4794",
},
);

token = JSON.parse(refreshRes.body).access_token;
refreshToken = JSON.parse(refreshRes.body).refresh_token;
requestConfig = generateRequestConfig(token);
}
if (exec.scenario.name === "browserTest") {
browserTest(HOST);
}

if (exec.scenario.name === "protocolTest") {
protocolTest(HOST);
protocolTest(HOST, requestConfig);
}
}
21 changes: 19 additions & 2 deletions performance/tests/frontend/protocol.js
Original file line number Diff line number Diff line change
@@ -1,8 +1,25 @@
import http from "k6/http";
import { check } from "k6";

export function protocolTest() {
const res = http.get("http://localhost:3001/");
export function protocolTest(host, requestConfig) {
const res = http.get(host + "/static/js/bundle.js", {
headers: {
...requestConfig.headers,
Accept:
"text/html,application/xhtml+xml,application/xml;q=0.9,image/avif,image/webp,image/apng,*/*;q=0.8,application/signed-exchange;v=b3;q=0.7",
"Accept-Encoding": "gzip, deflate, br, zstd",
"Accept-Language": "en-US,en;q=0.9",
"Cache-Control": "no-cache",
Connection: "keep-alive",
Host: "localhost:3001",
Pragma: "no-cache",
"Sec-Fetch-Dest": "document",
"Sec-Fetch-Mode": "navigate",
"Sec-Fetch-Site": "same-origin",
"Sec-Fetch-User": 1,
"Upgrade-Insecure-Requests": 1,
},
});
check(res, {
"status is 200": (res) => res.status === 200,
});
Expand Down

0 comments on commit 684b378

Please sign in to comment.