Skip to content

Commit

Permalink
feat(performance): create a k6 purge script to run after creating dia…
Browse files Browse the repository at this point in the history
…logs (#1435)

A script that purges dialogs created by performance tests. Much is
copied from common/sentinel.js, but that script didn't quite fit in.
Purges max 200 in one run, searching and purging is time-consuming at
the moment

## Description

<!--- Describe your changes in detail -->

## Related Issue(s)

- #1326 

## Verification

- [ ] **Your** code builds clean without any errors or warnings
- [ ] Manual testing done (required)
- [ ] Relevant automated test added (if you find this hard, leave it and
we'll help out)

## Documentation

- [ ] Documentation is updated (either in `docs`-directory, Altinnpedia
or a separate linked PR in
[altinn-studio-docs.](https://github.com/Altinn/altinn-studio-docs), if
applicable)


<!-- This is an auto-generated comment: release notes by coderabbit.ai
-->
## Summary by CodeRabbit

## Summary by CodeRabbit

- **New Features**
- Introduced a new script to automatically purge uncleaned dialogs after
tests, enhancing test environment management.
  
- **Bug Fixes**
- Improved error handling for API responses during the purging process,
ensuring more reliable cleanup operations.
<!-- end of auto-generated comment: release notes by coderabbit.ai -->

---------

Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
  • Loading branch information
dagfinno and coderabbitai[bot] authored Nov 11, 2024
1 parent 3bac598 commit 9555d78
Showing 1 changed file with 132 additions and 0 deletions.
132 changes: 132 additions & 0 deletions tests/k6/tests/serviceowner/performance/purge-dialogs.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,132 @@
/**
* This script purges dialogs that have not been cleaned up by the tests.
* The script is intended to be run after the main tests have completed.
*
* The script retrieves all dialogs that contain a sentinel value in the search query.
* It then purges these dialogs.
*
* Run: k6 run tests/k6/tests/serviceowner/performance/purge-dialogs.js -e env=yt01
*/
import { getSO, purgeSO } from '../../../common/request.js';
import { serviceOwners } from '../../performancetest_common/readTestdata.js';
import { expect, expectStatusFor } from "../../../common/testimports.js";
import { getDefaultThresholds } from '../../performancetest_common/getDefaultThresholds.js';
import { describe } from '../../../common/describe.js';
import { sentinelValue } from '../../../common/config.js';

/**
* Retrieves the dialog ids to purge.
*
* @param {Object} serviceOwner - The service owner object.
* @returns {Array} - The dialog ids to purge.
*/
function getDialogs(serviceOwner) {
var paramsWithToken = {
headers: {
Authorization: "Bearer " + serviceOwner.token
}
}
let hasNextPage = false;
let continuationToken = "";
let dialogIdsToPurge = [];
do {
let r = getSO('dialogs/?Search=' + sentinelValue + continuationToken, paramsWithToken);
expectStatusFor(r).to.equal(200);
expect(r, 'response').to.have.validJsonBody();
let response = r.json();
if (response.items && response.items.length > 0) {
response.items.forEach((item) => {
dialogIdsToPurge.push(item.id);
});
if (response.continuationToken) {
continuationToken = "&continuationToken=" + response.continuationToken;
} else {
continuationToken = "";
}
}
console.log("Found " + dialogIdsToPurge.length + " unpurged dialogs");
if (dialogIdsToPurge.length < 200) {
hasNextPage = response.hasNextPage;
}
else {
hasNextPage = false;
}
} while (hasNextPage);
return dialogIdsToPurge;
}

export let options = {
summaryTrendStats: ['avg', 'min', 'med', 'max', 'p(95)', 'p(99)', 'p(99.5)', 'p(99.9)', 'count'],
thresholds: getDefaultThresholds(['http_req_duration', 'http_reqs'],[
'purge dialog'
]),
setupTimeout: '4m',
};

export function setup() {
let data = [];
if (!serviceOwners || serviceOwners.length === 0) {
throw new Error('No service owners loaded for testing');
}
for (const serviceOwner of serviceOwners) {
let dialogIdsToPurge = getDialogs(serviceOwner);
data.push({token: serviceOwner.token, dialogIdsToPurge: dialogIdsToPurge});
}

return data;
}

/**
* Purges dialogs.
* In single user mode, the first service owner is used. Only one iteration is performed.
* In multi user mode, all service owners are used.
*/
export default function(serviceOwners) {
if (!serviceOwners || serviceOwners.length === 0) {
throw new Error('No service owners loaded for testing');
}

const isSingleUserMode = (options.vus ?? 1) === 1 && (options.iterations ?? 1) === 1 && (options.duration ?? 0) === 0;
if (isSingleUserMode) {
purgeDialogs(serviceOwners[0]);
}
else {
for (const serviceOwner of serviceOwners) {
purgeDialogs(serviceOwner);
}
}
}

/**
* Purges dialogs.
*
* @param {Object} serviceOwner - The service owner object.
*/
export function purgeDialogs(serviceOwner) {
var paramsWithToken = {
headers: {
Authorization: "Bearer " + serviceOwner.token
},
tags: { name: 'purge dialog' }
}
describe('Post run: checking for unpurged dialogs', () => {
let dialogIdsToPurge = serviceOwner.dialogIdsToPurge;
if (dialogIdsToPurge.length > 0) {
console.error("Found " + dialogIdsToPurge.length + " unpurged dialogs, make sure that all tests clean up after themselves. Purging ...");
for(var i = dialogIdsToPurge.length - 1; i>=0; i--) {
let r = purgeSO('dialogs/' + dialogIdsToPurge[i], paramsWithToken);
if (r.status != 204) {
console.error("Failed to purge dialog with id: " + dialogIdsToPurge[i]);
console.log(r);
}
else {
console.log("Purged dialog with id: " + dialogIdsToPurge[i]);
dialogIdsToPurge.splice(i, 1);
}
}
}

// Fail the test after purging for visibility
expect(dialogIdsToPurge.length, 'unpurged dialogs').to.equal(0);
});
}

0 comments on commit 9555d78

Please sign in to comment.