From c4e3f272ee3cf8b73ce8755ee130786996285b4c Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Mon, 21 Oct 2024 14:29:39 +0200 Subject: [PATCH 01/18] test(load-tests): add load test for create dialog (serviceowner) --- .../serviceowner/performance/create-dialog.js | 49 +++++++++++++++++++ 1 file changed, 49 insertions(+) create mode 100644 tests/k6/tests/serviceowner/performance/create-dialog.js diff --git a/tests/k6/tests/serviceowner/performance/create-dialog.js b/tests/k6/tests/serviceowner/performance/create-dialog.js new file mode 100644 index 000000000..adcdb027d --- /dev/null +++ b/tests/k6/tests/serviceowner/performance/create-dialog.js @@ -0,0 +1,49 @@ +import { postSO, expect, describe } from "../../../common/testimports.js"; +import { SharedArray } from 'k6/data'; +import papaparse from 'https://jslib.k6.io/papaparse/5.1.1/index.js'; +import { default as dialogToInsert } from '../testdata/01-create-dialog.js'; +import { randomItem } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js'; + +const filenameServiceowners = '../../performancetest_data/.serviceowners-with-tokens.csv'; +const filenameEndusers = '../../performancetest_data/endusers.csv'; + +const serviceOwners = new SharedArray('serviceOwners', function () { + return papaparse.parse(open(filenameServiceowners), { header: true, skipEmptyLines: true }).data; +}); + +const endUsers = new SharedArray('endUsers', function () { + return papaparse.parse(open(filenameEndusers), { header: true, skipEmptyLines: true }).data; + }); + +export let options = { + summaryTrendStats: ['avg', 'min', 'med', 'max', 'p(95)', 'p(99)', 'p(99.5)', 'p(99.9)', 'count'], + thresholds: { + 'http_req_duration{scenario:default}': [`max>=0`], + 'http_req_duration{name:create dialog}': [], + 'http_reqs{name:create dialog}': [], + }, +}; + +export default function() { + if ((options.vus === undefined || options.vus === 1) && (options.iterations === undefined || options.iterations === 1)) { + createDialog(serviceOwners[0], endUsers[0]); + } + else { + while (true) { createDialog(randomItem(serviceOwners), randomItem(endUsers)); } + } + } + +export function createDialog(serviceOwner, endUser) { + var paramsWithToken = { + Headers: { + Authorization: "Bearer " + serviceOwner.token + }, + tags: { name: 'create dialog' } + } + + describe('create dialog', () => { + let r = postSO('dialogs', dialogToInsert(endUser.ssn), paramsWithToken); + expect(r.status, 'response status').to.equal(201); + }); + +} \ No newline at end of file From 6c859ea6859cd8d0584be97cd1ece25cfd83c49b Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Mon, 21 Oct 2024 14:30:42 +0200 Subject: [PATCH 02/18] test(load-tests): add load test for simple search (enduser) --- .../enduser/performance/simple-search.js | 43 +++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100644 tests/k6/tests/enduser/performance/simple-search.js diff --git a/tests/k6/tests/enduser/performance/simple-search.js b/tests/k6/tests/enduser/performance/simple-search.js new file mode 100644 index 000000000..9e11d6df3 --- /dev/null +++ b/tests/k6/tests/enduser/performance/simple-search.js @@ -0,0 +1,43 @@ +import { getEU, expect, expectStatusFor, describe, getEnduserTokenFromGenerator } from "../../../common/testimports.js"; +import { SharedArray } from 'k6/data'; +import papaparse from 'https://jslib.k6.io/papaparse/5.1.1/index.js'; + +const filenameEndusers = '../../performancetest_data/.endusers-with-tokens.csv'; + +const endUsers = new SharedArray('endUsers', function () { + return papaparse.parse(open(filenameEndusers), { header: true, skipEmptyLines: true }).data; + }); + +export let options = { + summaryTrendStats: ['avg', 'min', 'med', 'max', 'p(95)', 'p(99)', 'p(99.5)', 'p(99.9)', 'count'], + thresholds: { + 'http_req_duration{name:simple search}': [], + 'http_reqs{name:simple search}': [], + }, +}; + +export default function() { + if ((options.vus === undefined || options.vus === 1) && (options.iterations === undefined || options.iterations === 1)) { + simpleSearch(endUsers[0]); + } + else { + while (true) { simpleSearch(randomItem(endUsers)); } + } +} + +export function simpleSearch(enduser) { + let paramsWithToken = { + Headers: { + Authorization: "Bearer " + enduser.token + }, + tags: { name: 'simple search' } + } + let defaultParty = "urn:altinn:person:identifier-no:" + enduser.ssn; + let defaultFilter = "?Party=" + defaultParty; + describe('Perform simple dialog list', () => { + let r = getEU('dialogs' + defaultFilter, paramsWithToken); + expectStatusFor(r).to.equal(200); + expect(r, 'response').to.have.validJsonBody(); + }); +} + From 25556e83bcc2db4264b549d6f6871ea183be40c3 Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Mon, 21 Oct 2024 14:44:18 +0200 Subject: [PATCH 03/18] test(load-tests): add option to send end user ssn as parameter to create_dialog --- tests/k6/tests/serviceowner/testdata/01-create-dialog.js | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/k6/tests/serviceowner/testdata/01-create-dialog.js b/tests/k6/tests/serviceowner/testdata/01-create-dialog.js index dffaad574..be4f76b9c 100644 --- a/tests/k6/tests/serviceowner/testdata/01-create-dialog.js +++ b/tests/k6/tests/serviceowner/testdata/01-create-dialog.js @@ -1,10 +1,10 @@ import { uuidv4 } from '../../../common/testimports.js' import { getDefaultEnduserSsn } from "../../../common/token.js"; -export default function () { +export default function (endUser = getDefaultEnduserSsn()) { return { "serviceResource": "urn:altinn:resource:ttd-dialogporten-automated-tests", // urn starting with urn:altinn:resource: - "party": "urn:altinn:person:identifier-no:" + getDefaultEnduserSsn(), // or urn:altinn:organization:identifier-no:<9 digits> + "party": "urn:altinn:person:identifier-no:" + endUser, // or urn:altinn:organization:identifier-no:<9 digits> "status": "new", // valid values: new, inprogress, waiting, signing, cancelled, completed "extendedStatus": "urn:any/valid/uri", "dueAt": "2033-11-25T06:37:54.2920190Z", // must be UTC From 260121144fac2cddc9b40ac25810728e078458be Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Mon, 21 Oct 2024 14:55:31 +0200 Subject: [PATCH 04/18] test(load-tests): add testdata for staging(tt02), only one serviceowner and enduser so far --- tests/k6/tests/performancetest_data/endusers-staging.csv | 2 ++ tests/k6/tests/performancetest_data/serviceowners-staging.csv | 2 ++ 2 files changed, 4 insertions(+) create mode 100644 tests/k6/tests/performancetest_data/endusers-staging.csv create mode 100644 tests/k6/tests/performancetest_data/serviceowners-staging.csv diff --git a/tests/k6/tests/performancetest_data/endusers-staging.csv b/tests/k6/tests/performancetest_data/endusers-staging.csv new file mode 100644 index 000000000..28cf9dcdb --- /dev/null +++ b/tests/k6/tests/performancetest_data/endusers-staging.csv @@ -0,0 +1,2 @@ +ssn,resource,scopes +08895699684,super-simple-service,digdir:dialogporten diff --git a/tests/k6/tests/performancetest_data/serviceowners-staging.csv b/tests/k6/tests/performancetest_data/serviceowners-staging.csv new file mode 100644 index 000000000..449a5e7c6 --- /dev/null +++ b/tests/k6/tests/performancetest_data/serviceowners-staging.csv @@ -0,0 +1,2 @@ +org,orgno,scopes,resource +digdir,991825827,digdir:dialogporten.serviceprovider,super-simple-service From e10b035f390cfc149da5ce8c7d0ff3f91c0b9977 Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Mon, 21 Oct 2024 14:56:36 +0200 Subject: [PATCH 05/18] test(load-tests): add script to generate tokens --- tests/k6/tests/scripts/generate_tokens.sh | 43 +++++++++++++++++++++++ 1 file changed, 43 insertions(+) create mode 100755 tests/k6/tests/scripts/generate_tokens.sh diff --git a/tests/k6/tests/scripts/generate_tokens.sh b/tests/k6/tests/scripts/generate_tokens.sh new file mode 100755 index 000000000..48277bd8a --- /dev/null +++ b/tests/k6/tests/scripts/generate_tokens.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +tokengenuser=${TOKEN_GENERATOR_USERNAME} +tokengenpasswd=${TOKEN_GENERATOR_PASSWORD} +env="" +case $API_ENVIRONMENT in + "test") + env="at21" ;; + "staging") + env="tt02" ;; + "performance") + env="yt01" ;; + *) + echo "Unknown api environment $API_ENVIRONMENT" ;; +esac + +testdatafilepath=$1 +tokens=$2 + +serviceowner_datafile="$testdatafilepath/serviceowners-$API_ENVIRONMENT.csv" +serviceowner_tokenfile="$testdatafilepath/.serviceowners-with-tokens.csv" +enduser_datafile="$testdatafilepath/endusers-$API_ENVIRONMENT.csv" +enduser_tokenfile="$testdatafilepath/.endusers-with-tokens.csv" + +if [ "$tokens" = "both" ] || [ "$tokens" = "enterprise" ]; then + echo "org,orgno,scopes,resource,token" > $serviceowner_tokenfile + while IFS=, read -r org orgno scopes resource + do + url="https://altinn-testtools-token-generator.azurewebsites.net/api/GetEnterpriseToken?org=$org&env=$env&scopes=$scopes&orgno=$orgno&ttl=3600" + token=$(curl -s $url -u "$tokengenuser:$tokengenpasswd" ) + echo "$org,$orgno,$scopes,$resource,$token" >> $serviceowner_tokenfile + done < <(tail -n +2 $serviceowner_datafile) +fi + +if [ "$tokens" = "both" ] || [ "$tokens" = "personal" ]; then + echo "ssn,resource,scopes,token" > $enduser_tokenfile + while IFS=, read -r ssn resource scopes + do + url="https://altinn-testtools-token-generator.azurewebsites.net/api/GetPersonalToken?env=$env&scopes=$scopes&pid=$ssn&ttl=3600" + token=$(curl -s $url -u "$tokengenuser:$tokengenpasswd" ) + echo "$ssn,$resource,$scopes,$token" >> $enduser_tokenfile + done < <(tail -n +2 $enduser_datafile) +fi From 3e1a4d59e2597670125a75d6c811d8162b89a78d Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Mon, 21 Oct 2024 14:58:00 +0200 Subject: [PATCH 06/18] test(load-tests): add environment part of enduser data file --- tests/k6/tests/serviceowner/performance/create-dialog.js | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/k6/tests/serviceowner/performance/create-dialog.js b/tests/k6/tests/serviceowner/performance/create-dialog.js index adcdb027d..807b30ca3 100644 --- a/tests/k6/tests/serviceowner/performance/create-dialog.js +++ b/tests/k6/tests/serviceowner/performance/create-dialog.js @@ -5,7 +5,7 @@ import { default as dialogToInsert } from '../testdata/01-create-dialog.js'; import { randomItem } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js'; const filenameServiceowners = '../../performancetest_data/.serviceowners-with-tokens.csv'; -const filenameEndusers = '../../performancetest_data/endusers.csv'; +const filenameEndusers = `../../performancetest_data/endusers-${__ENV.API_ENVIRONMENT}.csv`; const serviceOwners = new SharedArray('serviceOwners', function () { return papaparse.parse(open(filenameServiceowners), { header: true, skipEmptyLines: true }).data; From f1a5dce127548ec8147bc4855944a43999852e4d Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Mon, 21 Oct 2024 15:01:20 +0200 Subject: [PATCH 07/18] test(load-tests): do not create token if AUthorization given in params.Headers --- tests/k6/common/request.js | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/tests/k6/common/request.js b/tests/k6/common/request.js index 80bb43125..154ff5caf 100644 --- a/tests/k6/common/request.js +++ b/tests/k6/common/request.js @@ -33,11 +33,14 @@ function getServiceOwnerRequestParams(params = null, tokenOptions = null) { } function getEnduserRequestParams(params = null, tokenOptions = null) { + params = params || {}; + const headers = params.Headers || {}; + const hasOverridenAuthorizationHeader = headers.Authorization !== undefined; let defaultParams = { headers: { 'Accept': 'application/json', 'User-Agent': 'dialogporten-k6', - 'Authorization': 'Bearer ' + getEnduserTokenFromGenerator(tokenOptions) + 'Authorization': hasOverridenAuthorizationHeader ? headers.Authorization : 'Bearer ' + getEnduserTokenFromGenerator(tokenOptions) } } From f96e5aa963789ef685b335c59927981e8d05003c Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Mon, 21 Oct 2024 15:05:22 +0200 Subject: [PATCH 08/18] test(load-tests): ignore .secrets and files with tokens --- .gitignore | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/.gitignore b/.gitignore index 8b4c08a26..bedd35f4e 100644 --- a/.gitignore +++ b/.gitignore @@ -374,3 +374,10 @@ FodyWeavers.xsd # MacOS .DS_Store + +# Secrets file used by act +.secrets + +# Generated files with tokens +**/.endusers-with-tokens.csv +**/.serviceowners-with-tokens.csv From 345a738db31bb38c3921fb5f0cb6431b1536830a Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Mon, 21 Oct 2024 15:08:30 +0200 Subject: [PATCH 09/18] test(load-tests): add github actions workflow --- .github/workflows/dispatch-k6-performance.yml | 60 +++++++++++++++++++ .../workflow-run-k6-performance.yml | 55 +++++++++++++++++ 2 files changed, 115 insertions(+) create mode 100644 .github/workflows/dispatch-k6-performance.yml create mode 100644 .github/workflows/performance-workflows/workflow-run-k6-performance.yml diff --git a/.github/workflows/dispatch-k6-performance.yml b/.github/workflows/dispatch-k6-performance.yml new file mode 100644 index 000000000..99d413b9b --- /dev/null +++ b/.github/workflows/dispatch-k6-performance.yml @@ -0,0 +1,60 @@ +name: Run K6 performance test + +on: + workflow_dispatch: + inputs: + apiVersion: + description: 'API Version' + required: true + default: 'v1' + environment: + description: 'Environment' + required: true + default: 'staging' + type: choice + options: + - test + - staging + - performance + tokens: + description: 'Tokens to generate; for create dialog, search, ingen eller begge' + required: true + default: 'both' + type: choice + options: + - both + - enterprise + - personal + - none + vus: + description: 'Number of VUS' + required: true + type: number + default: 10 + duration: + description: 'Duration of test, ie 30s, 1m, 10m' + required: true + default: 1m + type: string + testSuitePath: + description: 'Path to test suite to run' + required: true + default: 'tests/k6/tests/serviceowner/performance/createremove-no-delay.js' + +jobs: + k6-performance: + name: "Run K6 performance test" + uses: ./.github/workflows/performance-workflows/workflow-run-k6-performance.yml + secrets: + TOKEN_GENERATOR_USERNAME: ${{ secrets.TOKEN_GENERATOR_USERNAME }} + TOKEN_GENERATOR_PASSWORD: ${{ secrets.TOKEN_GENERATOR_PASSWORD }} + K6_CLOUD_TOKEN: ${{ secrets.K6_CLOUD_TOKEN }} + K6_CLOUD_PROJECT_ID: ${{ secrets.K6_CLOUD_PROJECT_ID }} + with: + environment: ${{ inputs.environment }} + apiVersion: ${{ inputs.apiVersion }} + testSuitePath: ${{ inputs.testSuitePath }} + vus: ${{ inputs.vus }} + duration: ${{ inputs.duration }} + tokens: ${{ inputs.tokens }} + diff --git a/.github/workflows/performance-workflows/workflow-run-k6-performance.yml b/.github/workflows/performance-workflows/workflow-run-k6-performance.yml new file mode 100644 index 000000000..bd55f70cd --- /dev/null +++ b/.github/workflows/performance-workflows/workflow-run-k6-performance.yml @@ -0,0 +1,55 @@ +name: Run K6 performance tests + +on: + workflow_call: + inputs: + apiVersion: + required: true + type: string + environment: + required: true + type: string + testSuitePath: + required: true + type: string + vus: + required: true + type: number + duration: + required: true + type: string + tokens: + required: true + type: string + secrets: + TOKEN_GENERATOR_USERNAME: + required: true + TOKEN_GENERATOR_PASSWORD: + required: true + K6_CLOUD_TOKEN: + required: true + K6_CLOUD_PROJECT_ID: + required: true + +jobs: + k6-test: + runs-on: ubuntu-latest + permissions: + checks: write + pull-requests: write + steps: + - name: Checkout code + uses: actions/checkout@v4 + - name: Setup k6 + uses: grafana/setup-k6-action@v1 + - name: Run K6 tests (${{ inputs.testSuitePath }}) + run: | + ./tests/k6/tests/scripts/generate_tokens.sh ./tests/k6/tests/performancetest_data ${{ inputs.tokens }} + k6 run ${{ inputs.testSuitePath }} --quiet --log-output=stdout --include-system-env-vars --vus=${{ inputs.vus }} --duration=${{ inputs.duration }} + env: + API_ENVIRONMENT: ${{ inputs.environment }} + API_VERSION: ${{ inputs.apiVersion }} + TOKEN_GENERATOR_USERNAME: ${{ secrets.TOKEN_GENERATOR_USERNAME }} + TOKEN_GENERATOR_PASSWORD: ${{ secrets.TOKEN_GENERATOR_PASSWORD }} + K6_CLOUD_TOKEN: ${{ secrets.K6_CLOUD_TOKEN }} + K6_CLOUD_PROJECT_ID: ${{ secrets.K6_CLOUD_PROJECT_ID }} From d8e238be6442a293c85d5dabdfd416c7099dcc36 Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Tue, 22 Oct 2024 10:19:10 +0200 Subject: [PATCH 10/18] test(load-tests): fix imports; add missing one and remove unused --- tests/k6/tests/enduser/performance/simple-search.js | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/tests/k6/tests/enduser/performance/simple-search.js b/tests/k6/tests/enduser/performance/simple-search.js index 9e11d6df3..f4789547a 100644 --- a/tests/k6/tests/enduser/performance/simple-search.js +++ b/tests/k6/tests/enduser/performance/simple-search.js @@ -1,6 +1,7 @@ -import { getEU, expect, expectStatusFor, describe, getEnduserTokenFromGenerator } from "../../../common/testimports.js"; +import { getEU, expect, expectStatusFor, describe } from "../../../common/testimports.js"; import { SharedArray } from 'k6/data'; import papaparse from 'https://jslib.k6.io/papaparse/5.1.1/index.js'; +import { randomItem } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js'; const filenameEndusers = '../../performancetest_data/.endusers-with-tokens.csv'; From bb982c28f2bb22b74412d197c6e932640cf818aa Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Tue, 22 Oct 2024 15:05:52 +0200 Subject: [PATCH 11/18] Update .github/workflows/dispatch-k6-performance.yml MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Co-authored-by: Ole Jørgen Skogstad --- .github/workflows/dispatch-k6-performance.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dispatch-k6-performance.yml b/.github/workflows/dispatch-k6-performance.yml index 99d413b9b..9d8db0841 100644 --- a/.github/workflows/dispatch-k6-performance.yml +++ b/.github/workflows/dispatch-k6-performance.yml @@ -17,7 +17,7 @@ on: - staging - performance tokens: - description: 'Tokens to generate; for create dialog, search, ingen eller begge' + description: 'Tokens to generate; for create dialog, search, none, or both' required: true default: 'both' type: choice From 9f55f7ff8e582100d58c15650bd16323969e4f0c Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Wed, 23 Oct 2024 10:58:06 +0200 Subject: [PATCH 12/18] made changes proposed by coderabbitai --- tests/k6/tests/scripts/generate_tokens.sh | 57 +++++++++++++++++++++-- 1 file changed, 53 insertions(+), 4 deletions(-) diff --git a/tests/k6/tests/scripts/generate_tokens.sh b/tests/k6/tests/scripts/generate_tokens.sh index 48277bd8a..48e80794d 100755 --- a/tests/k6/tests/scripts/generate_tokens.sh +++ b/tests/k6/tests/scripts/generate_tokens.sh @@ -1,7 +1,27 @@ #!/bin/bash +# Check if required environment variables are set +if [ -z "$TOKEN_GENERATOR_USERNAME" ] || [ -z "$TOKEN_GENERATOR_PASSWORD" ] || [ -z "$API_ENVIRONMENT" ]; then + echo "Error: TOKEN_GENERATOR_USERNAME, TOKEN_GENERATOR_PASSWORD, and API_ENVIRONMENT must be set" + exit 1 +fi + +# Function to display usage information +usage() { + echo "Usage: $0 " + echo " : Path to the test data files" + echo " : Type of tokens to generate (both, enterprise, or personal)" + exit 1 +} + +# Validate arguments +if [ $# -ne 2 ]; then + usage +fi + tokengenuser=${TOKEN_GENERATOR_USERNAME} tokengenpasswd=${TOKEN_GENERATOR_PASSWORD} + env="" case $API_ENVIRONMENT in "test") @@ -11,33 +31,62 @@ case $API_ENVIRONMENT in "performance") env="yt01" ;; *) - echo "Unknown api environment $API_ENVIRONMENT" ;; + echo "Error: Unknown api environment $API_ENVIRONMENT" + exit 1 ;; esac testdatafilepath=$1 tokens=$2 +# Validate tokens argument +if [[ ! "$tokens" =~ ^(both|enterprise|personal)$ ]]; then + echo "Error: Invalid token type. Must be 'both', 'enterprise', or 'personal'." + usage +fi + serviceowner_datafile="$testdatafilepath/serviceowners-$API_ENVIRONMENT.csv" serviceowner_tokenfile="$testdatafilepath/.serviceowners-with-tokens.csv" enduser_datafile="$testdatafilepath/endusers-$API_ENVIRONMENT.csv" enduser_tokenfile="$testdatafilepath/.endusers-with-tokens.csv" if [ "$tokens" = "both" ] || [ "$tokens" = "enterprise" ]; then + if [ ! -f "$serviceowner_datafile" ]; then + echo "Error: Input file not found: $serviceowner_datafile" + exit 1 + fi echo "org,orgno,scopes,resource,token" > $serviceowner_tokenfile while IFS=, read -r org orgno scopes resource do url="https://altinn-testtools-token-generator.azurewebsites.net/api/GetEnterpriseToken?org=$org&env=$env&scopes=$scopes&orgno=$orgno&ttl=3600" - token=$(curl -s $url -u "$tokengenuser:$tokengenpasswd" ) - echo "$org,$orgno,$scopes,$resource,$token" >> $serviceowner_tokenfile + token=$(curl -s -f $url -u "$tokengenuser:$tokengenpasswd" ) + if [ $? -ne 0 ]; then + echo "Error: Failed to generate enterprise token for: $env, $org, $orgno, $scopes " + continue + fi + eval echo "$org,$orgno,$scopes,$resource,$token" >> $serviceowner_tokenfile + if [ $? -ne 0 ]; then + echo "Error: Failed to write enterprise token to file for: $env, $org, $orgno, $scopes" + fi done < <(tail -n +2 $serviceowner_datafile) fi if [ "$tokens" = "both" ] || [ "$tokens" = "personal" ]; then + if [ ! -f "$enduser_datafile" ]; then + echo "Error: Input file not found: $enduser_datafile" + exit 1 + fi echo "ssn,resource,scopes,token" > $enduser_tokenfile while IFS=, read -r ssn resource scopes do url="https://altinn-testtools-token-generator.azurewebsites.net/api/GetPersonalToken?env=$env&scopes=$scopes&pid=$ssn&ttl=3600" - token=$(curl -s $url -u "$tokengenuser:$tokengenpasswd" ) + token=$(curl -s -f $url -u "$tokengenuser:$tokengenpasswd" ) + if [ $? -ne 0 ]; then + echo "Error: Failed to generate personal token for: $ssn, $scopes " + continue + fi echo "$ssn,$resource,$scopes,$token" >> $enduser_tokenfile + if [ $? -ne 0 ]; then + echo "Error: Failed to write personal token to file for: $ssn, $scopes" + fi done < <(tail -n +2 $enduser_datafile) fi From a09f2fa4e8af77b27a888d4098f9d8f8e21d7369 Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Wed, 23 Oct 2024 12:10:50 +0200 Subject: [PATCH 13/18] changed default testSuitePath --- .github/workflows/dispatch-k6-performance.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/dispatch-k6-performance.yml b/.github/workflows/dispatch-k6-performance.yml index 9d8db0841..03f02c471 100644 --- a/.github/workflows/dispatch-k6-performance.yml +++ b/.github/workflows/dispatch-k6-performance.yml @@ -39,7 +39,7 @@ on: testSuitePath: description: 'Path to test suite to run' required: true - default: 'tests/k6/tests/serviceowner/performance/createremove-no-delay.js' + default: 'tests/k6/tests/serviceowner/performance/create-dialog.js' jobs: k6-performance: From e782a2dc54b0d7c2d52fbe548b17ba0857388fdc Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Wed, 23 Oct 2024 12:39:21 +0200 Subject: [PATCH 14/18] changed Headers to headers, as suggested by coderabbitai --- tests/k6/tests/enduser/performance/simple-search.js | 2 +- tests/k6/tests/serviceowner/performance/create-dialog.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/k6/tests/enduser/performance/simple-search.js b/tests/k6/tests/enduser/performance/simple-search.js index f4789547a..363bafbc5 100644 --- a/tests/k6/tests/enduser/performance/simple-search.js +++ b/tests/k6/tests/enduser/performance/simple-search.js @@ -28,7 +28,7 @@ export default function() { export function simpleSearch(enduser) { let paramsWithToken = { - Headers: { + headers: { Authorization: "Bearer " + enduser.token }, tags: { name: 'simple search' } diff --git a/tests/k6/tests/serviceowner/performance/create-dialog.js b/tests/k6/tests/serviceowner/performance/create-dialog.js index 807b30ca3..e7f51c3e8 100644 --- a/tests/k6/tests/serviceowner/performance/create-dialog.js +++ b/tests/k6/tests/serviceowner/performance/create-dialog.js @@ -35,7 +35,7 @@ export default function() { export function createDialog(serviceOwner, endUser) { var paramsWithToken = { - Headers: { + headers: { Authorization: "Bearer " + serviceOwner.token }, tags: { name: 'create dialog' } From 108091c5fe2e15237dbe987ad2d02237f788236a Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Wed, 23 Oct 2024 13:02:01 +0200 Subject: [PATCH 15/18] changed Headers to headers, as suggested by coderabbitai --- tests/k6/common/request.js | 4 ++-- .../tests/serviceowner/performance/createremove-no-delay.js | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/k6/common/request.js b/tests/k6/common/request.js index 154ff5caf..cc2be8457 100644 --- a/tests/k6/common/request.js +++ b/tests/k6/common/request.js @@ -18,7 +18,7 @@ function resolveParams(defaultParams, params) { function getServiceOwnerRequestParams(params = null, tokenOptions = null) { params = params || {}; - const headers = params.Headers || {}; + const headers = params.headers || {}; const hasOverridenAuthorizationHeader = headers.Authorization !== undefined; const defaultParams = { @@ -34,7 +34,7 @@ function getServiceOwnerRequestParams(params = null, tokenOptions = null) { function getEnduserRequestParams(params = null, tokenOptions = null) { params = params || {}; - const headers = params.Headers || {}; + const headers = params.headers || {}; const hasOverridenAuthorizationHeader = headers.Authorization !== undefined; let defaultParams = { headers: { diff --git a/tests/k6/tests/serviceowner/performance/createremove-no-delay.js b/tests/k6/tests/serviceowner/performance/createremove-no-delay.js index 4dbb6b095..27a3a380f 100644 --- a/tests/k6/tests/serviceowner/performance/createremove-no-delay.js +++ b/tests/k6/tests/serviceowner/performance/createremove-no-delay.js @@ -4,7 +4,7 @@ import { default as dialogToInsert } from '../testdata/01-create-dialog.js'; export function setup() { // Get the token during setup stage so that it doesn't interfere with timings return { - Headers: { + headers: { Authorization: "Bearer " + getServiceOwnerTokenFromGenerator() } } From 22d55b810d3fa1d5586608320383138d67c9f70b Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Wed, 23 Oct 2024 13:05:50 +0200 Subject: [PATCH 16/18] Removed while(true) in default function, as suggested by coderabbitai --- tests/k6/tests/enduser/performance/simple-search.js | 2 +- tests/k6/tests/serviceowner/performance/create-dialog.js | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/k6/tests/enduser/performance/simple-search.js b/tests/k6/tests/enduser/performance/simple-search.js index 363bafbc5..250d7808d 100644 --- a/tests/k6/tests/enduser/performance/simple-search.js +++ b/tests/k6/tests/enduser/performance/simple-search.js @@ -22,7 +22,7 @@ export default function() { simpleSearch(endUsers[0]); } else { - while (true) { simpleSearch(randomItem(endUsers)); } + simpleSearch(randomItem(endUsers)); } } diff --git a/tests/k6/tests/serviceowner/performance/create-dialog.js b/tests/k6/tests/serviceowner/performance/create-dialog.js index e7f51c3e8..60aef04e9 100644 --- a/tests/k6/tests/serviceowner/performance/create-dialog.js +++ b/tests/k6/tests/serviceowner/performance/create-dialog.js @@ -29,7 +29,7 @@ export default function() { createDialog(serviceOwners[0], endUsers[0]); } else { - while (true) { createDialog(randomItem(serviceOwners), randomItem(endUsers)); } + createDialog(randomItem(serviceOwners), randomItem(endUsers)); } } From a62d4aa0d3debfa3821f136073ba490628b4719c Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Wed, 23 Oct 2024 13:51:28 +0200 Subject: [PATCH 17/18] removed an eval and store command status before checking, as suggested by coderabbitai --- tests/k6/tests/scripts/generate_tokens.sh | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/tests/k6/tests/scripts/generate_tokens.sh b/tests/k6/tests/scripts/generate_tokens.sh index 48e80794d..06df1ab24 100755 --- a/tests/k6/tests/scripts/generate_tokens.sh +++ b/tests/k6/tests/scripts/generate_tokens.sh @@ -63,8 +63,9 @@ if [ "$tokens" = "both" ] || [ "$tokens" = "enterprise" ]; then echo "Error: Failed to generate enterprise token for: $env, $org, $orgno, $scopes " continue fi - eval echo "$org,$orgno,$scopes,$resource,$token" >> $serviceowner_tokenfile - if [ $? -ne 0 ]; then + echo "$org,$orgno,$scopes,$resource,$token" >> $serviceowner_tokenfile + status=$? + if [ $status -ne 0 ]; then echo "Error: Failed to write enterprise token to file for: $env, $org, $orgno, $scopes" fi done < <(tail -n +2 $serviceowner_datafile) @@ -85,7 +86,8 @@ if [ "$tokens" = "both" ] || [ "$tokens" = "personal" ]; then continue fi echo "$ssn,$resource,$scopes,$token" >> $enduser_tokenfile - if [ $? -ne 0 ]; then + status=$? + if [ $status -ne 0 ]; then echo "Error: Failed to write personal token to file for: $ssn, $scopes" fi done < <(tail -n +2 $enduser_datafile) From 7604ae162c3e6738a7809fce358a3b1ab2b2bbd9 Mon Sep 17 00:00:00 2001 From: Dagfinn Olsen Date: Wed, 23 Oct 2024 14:04:39 +0200 Subject: [PATCH 18/18] Update tests/k6/tests/enduser/performance/simple-search.js Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com> --- .../tests/enduser/performance/simple-search.js | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/tests/k6/tests/enduser/performance/simple-search.js b/tests/k6/tests/enduser/performance/simple-search.js index 250d7808d..be99517b2 100644 --- a/tests/k6/tests/enduser/performance/simple-search.js +++ b/tests/k6/tests/enduser/performance/simple-search.js @@ -6,8 +6,21 @@ import { randomItem } from 'https://jslib.k6.io/k6-utils/1.2.0/index.js'; const filenameEndusers = '../../performancetest_data/.endusers-with-tokens.csv'; const endUsers = new SharedArray('endUsers', function () { - return papaparse.parse(open(filenameEndusers), { header: true, skipEmptyLines: true }).data; - }); + try { + const csvData = papaparse.parse(open(filenameEndusers), { header: true, skipEmptyLines: true }).data; + if (!csvData.length) { + throw new Error('No data found in CSV file'); + } + csvData.forEach((user, index) => { + if (!user.token || !user.ssn) { + throw new Error(`Missing required fields at row ${index + 1}`); + } + }); + return csvData; + } catch (error) { + throw new Error(`Failed to load end users: ${error.message}`); + } +}); export let options = { summaryTrendStats: ['avg', 'min', 'med', 'max', 'p(95)', 'p(99)', 'p(99.5)', 'p(99.9)', 'count'],