aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--.github/scripts/prescan-go-coverage-ubuntu.sh12
-rwxr-xr-x.github/workflows/gerrit-opa-performance-test.yaml4
-rwxr-xr-x.github/workflows/gerrit-opa-stability-test.yaml4
-rw-r--r--.github/workflows/security-audits.yaml17
-rw-r--r--test/README.md37
-rw-r--r--testsuites/run-s3p-test.sh57
6 files changed, 87 insertions, 44 deletions
diff --git a/.github/scripts/prescan-go-coverage-ubuntu.sh b/.github/scripts/prescan-go-coverage-ubuntu.sh
new file mode 100644
index 0000000..f7e9d55
--- /dev/null
+++ b/.github/scripts/prescan-go-coverage-ubuntu.sh
@@ -0,0 +1,12 @@
+# SPDX-License-Identifier: Apache-2.0
+# SPDX-FileCopyrightText: 2025 The Linux Foundation
+
+#!/bin/bash
+echo "--> prescan-go-coverage-ubuntu.sh"
+
+set -ex
+
+# Test and coverage
+go test -p 1 ./... -coverprofile=coverage.out
+
+echo "--> prescan-go-coverage-ubuntu.sh ends"
diff --git a/.github/workflows/gerrit-opa-performance-test.yaml b/.github/workflows/gerrit-opa-performance-test.yaml
index b105f0b..54855dd 100755
--- a/.github/workflows/gerrit-opa-performance-test.yaml
+++ b/.github/workflows/gerrit-opa-performance-test.yaml
@@ -70,7 +70,7 @@ on:
# Run everyday at 16:30 UTC
schedule:
- cron: '30 16 * * *'
-
+
jobs:
run-s3p-tests:
runs-on: ubuntu-22.04
@@ -80,7 +80,7 @@ jobs:
- name: Run S3P script
working-directory: ${{ github.workspace }}/testsuites
- run: sudo bash ./run-s3p-test.sh run performance
+ run: sudo bash ./run-s3p-test.sh performance
- name: Archive result jtl
uses: actions/upload-artifact@v4
diff --git a/.github/workflows/gerrit-opa-stability-test.yaml b/.github/workflows/gerrit-opa-stability-test.yaml
index 65e269d..09db4c5 100755
--- a/.github/workflows/gerrit-opa-stability-test.yaml
+++ b/.github/workflows/gerrit-opa-stability-test.yaml
@@ -70,7 +70,7 @@ on:
# Run everyday at 16:30 UTC
schedule:
- cron: '30 16 * * *'
-
+
jobs:
run-s3p-tests:
runs-on: ubuntu-22.04
@@ -80,7 +80,7 @@ jobs:
- name: Run S3P script
working-directory: ${{ github.workspace }}/testsuites
- run: sudo bash ./run-s3p-test.sh run stability
+ run: sudo bash ./run-s3p-test.sh stability
- name: Archive result jtl
uses: actions/upload-artifact@v4
diff --git a/.github/workflows/security-audits.yaml b/.github/workflows/security-audits.yaml
index 77c7534..0160ed8 100644
--- a/.github/workflows/security-audits.yaml
+++ b/.github/workflows/security-audits.yaml
@@ -26,18 +26,18 @@ on:
permissions: {}
jobs:
- sonatype-lifecycle:
- name: "Sonatype Lifecycle"
- # yamllint disable-line rule:line-length
- uses: lfit/releng-reusable-workflows/.github/workflows/reuse-sonatype-lifecycle.yaml@83e3ea0dcbfb1e8c707b0284ae7e7c376b0e27d4 # v0.2.7
- secrets:
- NEXUS_IQ_PASSWORD: ${{ secrets.NEXUS_IQ_PASSWORD }}
+ #sonatype-lifecycle:
+ # name: "Sonatype Lifecycle"
+ # # yamllint disable-line rule:line-length
+ # uses: lfit/releng-reusable-workflows/.github/workflows/reuse-sonatype-lifecycle.yaml@83e3ea0dcbfb1e8c707b0284ae7e7c376b0e27d4 # v0.2.7
+ # secrets:
+ # NEXUS_IQ_PASSWORD: ${{ secrets.NEXUS_IQ_PASSWORD }}
# Scan results are found at: https://sonarcloud.io/login
sonarqube-cloud:
name: "SonarQube Cloud"
# yamllint disable-line rule:line-length
- uses: lfit/releng-reusable-workflows/.github/workflows/reuse-sonarqube-cloud.yaml@83e3ea0dcbfb1e8c707b0284ae7e7c376b0e27d4 # v0.2.7
+ uses: lfit/releng-reusable-workflows/.github/workflows/reuse-sonarqube-cloud.yaml@ac846b1cfeaf3a7cac6f28413a5206afc9951464 # v0.2.11
permissions:
# Needed to upload the results to code-scanning dashboard.
security-events: write
@@ -48,3 +48,6 @@ jobs:
# actions: read
secrets:
SONAR_TOKEN: ${{ secrets.SONAR_TOKEN }}
+ with:
+ BUILD_WRAPPER_URL: https://raw.githubusercontent.com/onap/policy-opa-pdp/refs/heads/master/.github/scripts/prescan-go-coverage-ubuntu.sh
+ BUILD_WRAPPER_OUT_DIR: .
diff --git a/test/README.md b/test/README.md
index 90660e0..3c52d41 100644
--- a/test/README.md
+++ b/test/README.md
@@ -1,5 +1,18 @@
# Testing OPA
+## Ports Exposed by OPA in CSIT and K8s Cluster Environment:
+
+<CSIT docker-compose environment:>
+ 30012 port is exposed,below curl urls for OPA would point to the same.
+<K8s environment:>
+ 8282 port since it is a ClusterIP Service.
+ port forwarding can be done with below sample commands while testing
+ --------------------------------------------------------------------
+ kubectl port-forward --namespace onap service/policy-pap 30003:6969 &
+ kubectl port-forward --namespace onap service/policy-api 30002:6969 &
+ kubectl port-forward --namespace onap service/policy-opa-pdp 30012:8282 &
+ --------------------------------------------------------------------
+
## Curl URL For Deployment.
1. `curl -u 'policyadmin:zb!XztG34' -X POST -H "Content-Type":"application/yaml" --data-binary @toscapolicies/role/policy_role.yaml http://localhost:30002/policy/api/v1/policytypes/onap.policies.native.opa/versions/1.0.0/policies`
@@ -14,65 +27,65 @@
`curl -v -u 'policyadmin:zb!XztG34' -X POST -H "Content-Type":"application/json" -d @{"groups": [{"name": "opaGroup","deploymentSubgroups": [{"pdpType": "opa","action": "DELETE","policies": [{"name": "role","version": "2.0.2"}]}]}]} http://localhost:30003/policy/pap/v1/pdps/deployments/batch`
-## Decision API Response
+## Decision API Response
## Output For Policy: access_method with empty filter
-curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : [""], "policyName":"access_method","input":{"method":"POST","path":["users"]}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision
+curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : [""], "policyName":"access_method","input":{"method":"POST","path":["users"]}}' -X POST http://0.0.0.0:30012/policy/pdpo/v1/decision
{"output":{"allow":true},"policyName":"access_method"}
## Output For Policy: access_method with filter allow
-curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : ["allow"], "policyName":"access_method","input":{"method":"POST","path":["users"]}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision
+curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : ["allow"], "policyName":"access_method","input":{"method":"POST","path":["users"]}}' -X POST http://0.0.0.0:30012/policy/pdpo/v1/decision
{"output":{"allow":true},"policyName":"access_method"}
## Output For Policy: role with filter allow
-curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyName":"role", "policyFilter": ["allow"], "input":{"user":"alice","action":"write","object":"id123","type":"dog"}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision
+curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyName":"role", "policyFilter": ["allow"], "input":{"user":"alice","action":"write","object":"id123","type":"dog"}}' -X POST http://0.0.0.0:30012/policy/pdpo/v1/decision
{"output":{"allow":true},"policyName":"role"}
## Output For policy: role with empty filter
-curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyName":"role", "policyFilter": [""], "input":{"user":"alice","action":"write","object":"id123","type":"dog"}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision
+curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyName":"role", "policyFilter": [""], "input":{"user":"alice","action":"write","object":"id123","type":"dog"}}' -X POST http://0.0.0.0:30012/policy/pdpo/v1/decision
{"output":{"allow":true,"user_is_admin":true,"user_is_granted":[]},"policyName":"role"}
## Output For policy: role with filter not matching the allowable filters
-curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyName":"role", "policyFilter": ["abc"], "input":{"user":"alice","action":"write","object":"id123","type":"dog"}}' -X POST http://0.0.0.0:8282/policy/pdpo/v1/decision
+curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyName":"role", "policyFilter": ["abc"], "input":{"user":"alice","action":"write","object":"id123","type":"dog"}}' -X POST http://0.0.0.0:30012/policy/pdpo/v1/decision
{"output":null,"policyName":"role","statusMessage":"Policy Filter(s) not matching, Valid Filter(s) are: [allow, user_is_admin, user_is_granted]"}
## Output For Policy: blacklist with filter module_allow
-curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : ["module_allow"], "policyName":"blacklist","input":{"vfmodule":["the-vfmodule-where-root-is-true","another-vfmodule-where-root-is-true" ] }}' -X POST http://localhost:8282/policy/pdpo/v1/decision
+curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : ["module_allow"], "policyName":"blacklist","input":{"vfmodule":["the-vfmodule-where-root-is-true","another-vfmodule-where-root-is-true" ] }}' -X POST http://localhost:30012/policy/pdpo/v1/decision
{"output":{"module_allow":{"another-vfmodule-where-root-is-true":true,"the-vfmodule-where-root-is-true":true}},"policyName":"blacklist"}
## Output For Policy: blacklist with Empty Filter
- curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : [""], "policyName":"blacklist","input":{"vfmodule":["the-vfmodule-where-root-is-true","another-vfmodule-where-root-is-true" ] }}' -X POST http://localhost:8282/policy/pdpo/v1/decision
+ curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : [""], "policyName":"blacklist","input":{"vfmodule":["the-vfmodule-where-root-is-true","another-vfmodule-where-root-is-true" ] }}' -X POST http://localhost:30012/policy/pdpo/v1/decision
{"output":{"module_allow":{"another-vfmodule-where-root-is-true":true,"the-vfmodule-where-root-is-true":true}},"policyName":"blacklist"}
## Output For Policy: monitor with filter result
-curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : ["result"], "policyName":"monitor","input":{ "domain": "measurementsForVfScaling", "eventName": "Measurement_vGMUX","controlLoopSchemaType": "VNF","policyScope": "DCAE","policyName": "DCAE.Config_tca-hi-lo","policyVersion": "v0.0.1", "version": "1.0.2","controlname": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e","thresholdValue": 0}}' -X POST http://localhost:8282/policy/pdpo/v1/decision
+curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : ["result"], "policyName":"monitor","input":{ "domain": "measurementsForVfScaling", "eventName": "Measurement_vGMUX","controlLoopSchemaType": "VNF","policyScope": "DCAE","policyName": "DCAE.Config_tca-hi-lo","policyVersion": "v0.0.1", "version": "1.0.2","controlname": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e","thresholdValue": 0}}' -X POST http://localhost:30012/policy/pdpo/v1/decision
{"output":{"result":[{"closedLoopEventStatus":"ABATED","severity":"MAJOR"}]},"policyName":"monitor"}
## Output For Policy: monitor with empty filter
-curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : [""], "policyName":"monitor","input":{ "domain": "measurementsForVfScaling", "eventName": "Measurement_vGMUX","controlLoopSchemaType": "VNF","policyScope": "DCAE","policyName": "DCAE.Config_tca-hi-lo","policyVersion": "v0.0.1", "version": "1.0.2","controlname": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e","thresholdValue": 0}}' -X POST http://localhost:8282/policy/pdpo/v1/decision
+curl -u 'policyadmin:zb!XztG34' -H 'Content-Type: application/json' -H 'Accept: application/json' -d '{"onapName":"CDS","onapComponent":"CDS","onapInstance":"CDS","currentDate": "2024-11-22", "currentTime": "08:26:41.857Z", "timeZone": "UTC", "timeOffset": "+05:30", "currentDateTime": "2025-01-17T08:26:41.857Z", "policyFilter" : [""], "policyName":"monitor","input":{ "domain": "measurementsForVfScaling", "eventName": "Measurement_vGMUX","controlLoopSchemaType": "VNF","policyScope": "DCAE","policyName": "DCAE.Config_tca-hi-lo","policyVersion": "v0.0.1", "version": "1.0.2","controlname": "ControlLoop-vCPE-48f0c2c3-a172-4192-9ae3-052274181b6e","thresholdValue": 0}}' -X POST http://localhost:30012/policy/pdpo/v1/decision
{"output":{"result":[{"closedLoopEventStatus":"ABATED","severity":"MAJOR"}]},"policyName":"monitor
## HealthCheck API Call With Response
-curl -u 'policyadmin:zb!XztG34' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -X GET http://0.0.0.0:8282/policy/pdpo/v1/healthcheck
+curl -u 'policyadmin:zb!XztG34' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -X GET http://0.0.0.0:30012/policy/pdpo/v1/healthcheck
{"code":200,"healthy":true,"message":"alive","name":"opa-ea84b1ff-00de-4bf6-a039-222e4511d0a1","url":"self"}
## Statistics API Call With Response
-curl -u 'policyadmin:zb!XztG34' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -X GET http://0.0.0.0:8282/policy/pdpo/v1/statistics
+curl -u 'policyadmin:zb!XztG34' --header 'X-ONAP-RequestID:8e6f784e-c9cb-42f6-bcc9-edb5d0af1ce1' -X GET http://0.0.0.0:30012/policy/pdpo/v1/statistics
{"code":200,"decisionFailureCount":0,"decisionSuccessCount":0,"deployFailureCount":0,"deploySuccessCount":0, "totalErrorCount":0,"totalPoliciesCount":0,"totalPolicyTypesCount":1,"undeployFailureCount":0,"undeploySuccessCount":0}
diff --git a/testsuites/run-s3p-test.sh b/testsuites/run-s3p-test.sh
index 85b9f08..5cf9267 100644
--- a/testsuites/run-s3p-test.sh
+++ b/testsuites/run-s3p-test.sh
@@ -1,6 +1,6 @@
#!/bin/bash
# ============LICENSE_START=======================================================
-# Copyright (C) 2024 Deutsche Telekom Intellectual Property. All rights reserved.
+# Copyright (C) 2024-2025 Deutsche Telekom Intellectual Property. All rights reserved.
# ================================================================================
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
@@ -22,28 +22,43 @@ if [ -z "${WORKSPACE}" ]; then
export WORKSPACE=$(git rev-parse --show-toplevel)
fi
+export PROJECT="opa"
export TESTDIR=${WORKSPACE}/testsuites
export OPA_PERF_TEST_FILE=$TESTDIR/performance/src/main/resources/testplans/perf.jmx
export OPA_STAB_TEST_FILE=$TESTDIR/stability/src/main/resources/testplans/stability.jmx
-if [ $1 == "run" ]
-then
-
- mkdir automate-s3p-test;cd automate-s3p-test;
- git clone "https://gerrit.onap.org/r/policy/docker"
- cd docker/csit
-
- if [ $2 == "performance" ]
- then
- bash start-s3p-tests.sh run $OPA_PERF_TEST_FILE opa-pdp;
- elif [ $2 == "stability" ]
- then
- bash start-s3p-tests.sh run $OPA_STAB_TEST_FILE opa-pdp;
- else
- echo "echo Invalid arguments provided. Usage: $0 [option..] {performance | stability}"
- fi
-
-else
- echo "Invalid arguments provided. Usage: $0 [option..] {run | uninstall}"
-fi
+function run_tests() {
+ local test_file=$1
+
+ mkdir -p automate-s3p-test
+ cd automate-s3p-test || exit 1
+ git clone "https://gerrit.onap.org/r/policy/docker"
+ cd docker/csit || exit 1
+
+ bash run-s3p-tests.sh test "$test_file" $PROJECT
+}
+
+function clean() {
+ cd $TESTDIR/automate-s3p-test/docker/csit
+ bash run-s3p-tests.sh clean
+}
+
+echo "================================="
+echo "Triggering S3P test for: $PROJECT"
+echo "================================="
+case $1 in
+ performance)
+ run_tests "$OPA_PERF_TEST_FILE"
+ ;;
+ stability)
+ run_tests "$OPA_STAB_TEST_FILE"
+ ;;
+ clean)
+ clean
+ ;;
+ *)
+ echo "Invalid arguments provided. Usage: $0 {performance | stability | clean}"
+ exit 1
+ ;;
+esac