Skip to content

Commit

Permalink
chore: add performance tests to ci-cd-yt01 workflow (#1595)
Browse files Browse the repository at this point in the history
<!--- Provide a general summary of your changes in the Title above -->
Add performance tests and run these tests in ci-cd-yt01 workflow
## Description

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

## Related Issue(s)
#1540 
- #{issue number}

## Verification

- [ ] **Your** code builds clean without any errors or warnings
- [x] 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)

---------

Co-authored-by: Are Almaas <arealmaas@gmail.com>
  • Loading branch information
dagfinno and arealmaas authored Dec 12, 2024
1 parent 828851e commit f6f33d8
Show file tree
Hide file tree
Showing 7 changed files with 136 additions and 13 deletions.
33 changes: 33 additions & 0 deletions .github/workflows/ci-cd-yt01.yml
Original file line number Diff line number Diff line change
Expand Up @@ -140,6 +140,39 @@ jobs:
checks: write
pull-requests: write

run-performance:
name: "Run K6 performance tests"
# we want the performance tests to be dependent on deployment of infrastructure and apps, but if infrastructure is skipped, we still want to run the tests
if: ${{ always() && !failure() && !cancelled() && (github.event_name == 'workflow_dispatch' || needs.check-for-changes.outputs.hasBackendChanges == 'true' || needs.check-for-changes.outputs.hasInfraChanges == 'true') }}
needs: [deploy-apps, deploy-infra, check-for-changes]
#needs: [deploy-apps, check-for-changes]
uses: ./.github/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 }}

strategy:
max-parallel: 1
matrix:
files:
- tests/k6/tests/serviceowner/serviceOwnerSearchWithThresholds.js
- tests/k6/tests/serviceowner/createDialogWithThresholds.js
- tests/k6/tests/enduser/enduserSearchWithThresholds.js
fail-fast: false
with:
environment: yt01
apiVersion: v1
vus: 1
duration: 30s
tokens: both
numberOfTokens: 100
testSuitePath: ${{ matrix.files }}
permissions:
checks: write
pull-requests: write

send-slack-message-on-failure:
name: Send Slack message on failure
needs: [deploy-infra, deploy-apps, deploy-slack-notifier, run-e2e-tests, publish]
Expand Down
13 changes: 11 additions & 2 deletions .github/workflows/workflow-run-k6-performance.yml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,14 @@ on:
tokens:
required: true
type: string
numberOfTokens:
required: false
type: number
default: 0
ttl:
required: false
type: number
default: 3600
secrets:
TOKEN_GENERATOR_USERNAME:
required: true
Expand All @@ -45,9 +53,10 @@ jobs:
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 }}
./tests/k6/tests/scripts/generate_tokens.sh ./tests/k6/tests/performancetest_data ${{ inputs.tokens }} ${{ inputs.numberOfTokens }} ${{ inputs.ttl }}
echo "Running k6 test suite ${{ inputs.testSuitePath }} with ${{ inputs.vus }} VUs for ${{ inputs.duration }}"
k6 run ${{ inputs.testSuitePath }} --quiet --log-output=stdout --include-system-env-vars \
--vus=${{ inputs.vus }} --duration=${{ inputs.duration }} --out=cloud --out csv=./results.csv
--vus=${{ inputs.vus }} --duration=${{ inputs.duration }} --out csv=./results.csv
grep http_req_duration ./results.csv | sort --field-separator=',' --key=3 -nr | head -10
env:
API_ENVIRONMENT: ${{ inputs.environment }}
Expand Down
28 changes: 28 additions & 0 deletions tests/k6/tests/enduser/enduserSearchWithThresholds.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import { default as run } from "./performance/enduser-search.js";

export let options = {
summaryTrendStats: ['avg', 'min', 'med', 'max', 'p(95)', 'p(99)', 'p(99.5)', 'p(99.9)', 'count'],
vus: 1,
duration: "30s",
thresholds: {
"http_req_duration{name:enduser search}": ["p(95)<300", "p(99)<500"],
"http_req_duration{name:enduser get dialog}": ["p(95)<300", "p(99)<500"],
"http_req_duration{name:enduser get dialog activities}": ["p(95)<300", "p(99)<500"],
"http_req_duration{name:enduser get dialog activity}": ["p(95)<300", "p(99)<500"],
"http_req_duration{name:enduser get seenlogs}": ["p(95)<300", "p(99)<500"],
"http_req_duration{name:enduser get transmissions}": ["p(95)<300", "p(99)<500"],
"http_req_duration{name:enduser get transmission}": ["p(95)<300", "p(99)<500"],
"http_req_duration{name:enduser get labellog}": ["p(95)<300", "p(99)<500"],
"http_reqs{name:enduser search}": [],
"http_reqs{name:enduser get dialog activities}": [],
"http_reqs{name:enduser get dialog activity}": [],
"http_reqs{name:enduser get seenlogs}": [],
"http_reqs{name:enduser get transmissions}": [],
"http_reqs{name:enduser get transmission}": [],
"http_reqs{name:enduser get dialog}": [],
"http_reqs{name:enduser get labellog}": [],
}
}

export default function (data) { run(data); }

16 changes: 8 additions & 8 deletions tests/k6/tests/enduser/performance/enduser-search.js
Original file line number Diff line number Diff line change
Expand Up @@ -8,14 +8,14 @@ const traceCalls = (__ENV.traceCalls ?? 'false') === 'true';
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'],['enduser search',
'get dialog',
'get dialog activities',
'get dialog activity',
'get seenlogs',
'get seenlog',
'get transmissions',
'get transmission',
'get labellog'
'enduser get dialog',
'enduser get dialog activities',
'enduser get dialog activity',
'enduser get seenlogs',
'enduser get seenlog',
'enduser get transmissions',
'enduser get transmission',
'enduser get labellog'
])
};

Expand Down
23 changes: 20 additions & 3 deletions tests/k6/tests/scripts/generate_tokens.sh
Original file line number Diff line number Diff line change
Expand Up @@ -11,11 +11,14 @@ usage() {
echo "Usage: $0 <testdatafilepath> <tokens>"
echo " <testdatafilepath>: Path to the test data files"
echo " <tokens>: Type of tokens to generate (both, enterprise, or personal)"
echo " <limit>: limit number of tokens to generate. 0 means generate all"
echo " <ttl>: Time to live in seconds for the generated tokens"
echo "Example: $0 /path/to/testdata both 10 3600"
exit 1
}

# Validate arguments
if [ $# -ne 2 ]; then
if [ $# -ne 4 ]; then
usage
fi

Expand All @@ -37,6 +40,8 @@ esac

testdatafilepath=$1
tokens=$2
limit=$3
ttl=$4

# Validate tokens argument
if [[ ! "$tokens" =~ ^(both|enterprise|personal)$ ]]; then
Expand All @@ -55,9 +60,13 @@ if [ "$tokens" = "both" ] || [ "$tokens" = "enterprise" ]; then
exit 1
fi
echo "org,orgno,scopes,resource,token" > $serviceowner_tokenfile
generated=0
while IFS=, read -r org orgno scopes resource
do
url="https://altinn-testtools-token-generator.azurewebsites.net/api/GetEnterpriseToken?org=$org&env=$env&orgno=$orgno&ttl=3600"
if [ $limit -gt 0 ] && [ $generated -ge $limit ]; then
break
fi
url="https://altinn-testtools-token-generator.azurewebsites.net/api/GetEnterpriseToken?org=$org&env=$env&orgno=$orgno&ttl=$ttl"
token=$(curl -s -f --get --data-urlencode "scopes=$scopes" $url -u "$tokengenuser:$tokengenpasswd" )
if [ $? -ne 0 ]; then
echo "Error: Failed to generate enterprise token for: $env, $org, $orgno, $scopes "
Expand All @@ -67,6 +76,8 @@ if [ "$tokens" = "both" ] || [ "$tokens" = "enterprise" ]; then
status=$?
if [ $status -ne 0 ]; then
echo "Error: Failed to write enterprise token to file for: $env, $org, $orgno, $scopes"
else
((generated++))
fi
done < <(tail -n +2 $serviceowner_datafile)
fi
Expand All @@ -77,9 +88,13 @@ if [ "$tokens" = "both" ] || [ "$tokens" = "personal" ]; then
exit 1
fi
echo "ssn,resource,scopes,token" > $enduser_tokenfile
generated=0
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"
if [ $limit -gt 0 ] && [ $generated -ge $limit ]; then
break
fi
url="https://altinn-testtools-token-generator.azurewebsites.net/api/GetPersonalToken?env=$env&scopes=$scopes&pid=$ssn&ttl=$ttl"
token=$(curl -s -f $url -u "$tokengenuser:$tokengenpasswd" )
if [ $? -ne 0 ]; then
echo "Error: Failed to generate personal token for: $ssn, $scopes "
Expand All @@ -89,6 +104,8 @@ if [ "$tokens" = "both" ] || [ "$tokens" = "personal" ]; then
status=$?
if [ $status -ne 0 ]; then
echo "Error: Failed to write personal token to file for: $ssn, $scopes"
else
((generated++))
fi
done < <(tail -n +2 $enduser_datafile)
fi
12 changes: 12 additions & 0 deletions tests/k6/tests/serviceowner/createDialogWithThresholds.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
import { default as run } from "./performance/create-dialog.js";

export let options = {
summaryTrendStats: ['avg', 'min', 'med', 'max', 'p(95)', 'p(99)', 'p(99.5)', 'p(99.9)', 'count'],
vus: 1,
duration: "30s",
thresholds: {
"http_req_duration": ["p(95)<300", "p(99)<500"],
}
}

export default function (data) { run(data); }
24 changes: 24 additions & 0 deletions tests/k6/tests/serviceowner/serviceOwnerSearchWithThresholds.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import { default as run } from "./performance/serviceowner-search.js";

export let options = {
summaryTrendStats: ['avg', 'min', 'med', 'max', 'p(95)', 'p(99)', 'p(99.5)', 'p(99.9)', 'count'],
vus: 1,
duration: "30s",
thresholds: {
"http_req_duration{name:serviceowner search}": ["p(95)<100", "p(99)<300"],
"http_req_duration{name:get dialog activities}": ["p(95)<100", "p(99)<300"],
"http_req_duration{name:get dialog activity}": ["p(95)<100", "p(99)<300"],
"http_req_duration{name:get seenlogs}": ["p(95)<100", "p(99)<300"],
"http_req_duration{name:get transmissions}": ["p(95)<100", "p(99)<300"],
"http_req_duration{name:get transmission}": ["p(95)<100", "p(99)<300"],
"http_reqs{name:get dialog activities}": [],
"http_reqs{name:get dialog activity}": [],
"http_reqs{name:get seenlogs}": [],
"http_reqs{name:get transmissions}": [],
"http_reqs{name:get transmission}": [],
"http_reqs{name:serviceowner search}": [],
}
}

export default function (data) { run(data); }

0 comments on commit f6f33d8

Please sign in to comment.