11name : Performance
2+ run-name : Test ${{ inputs.testToRun }} against ${{ inputs.URN }}
23
34on :
45 push :
2930 duration :
3031 description : " Optional (default 3600) Duration of nurse journey test, in seconds. This will include ramp-up."
3132 required : false
32- type : string
33- default : ' 3600'
33+ type : number
34+ default : 3600
3435 threads :
3536 description : " Optional (default 70) Threads to run. Equivalent to the number of nurses using the system."
3637 required : false
37- type : string
38- default : ' 70 '
38+ type : number
39+ default : 70
3940 ramp_up :
4041 description : " Optional (default 900) Ramp-up time in seconds. Threads will be gradually started up over this time."
4142 required : false
43+ type : number
44+ default : 900
45+ vaccination_loop :
46+ description : " Optional (default 20) Vaccination loop (nurse journey only). The number of vaccinations each nurse will perform before logging and back in again."
47+ required : false
48+ type : number
49+ default : 20
4250 type : string
4351 default : ' 900'
4452 row_count :
@@ -58,164 +66,111 @@ on:
5866 default : ' qa.mavistesting.com'
5967
6068jobs :
61- nurse_journey_performance_test :
69+ check-image-presence :
70+ name : Check if docker image already exists
6271 runs-on : ubuntu-latest
63-
64- if : ${{ github.event_name == 'workflow_dispatch' }}
65-
66- env :
67- jmeter_version : 5.6.3
68- cmdrunner_version : 2.3
69- jmeter_plugins_manager_version : 1.7.0
70- jmeter_plugins : jpgc-udp,jpgc-graphs-basic,jpgc-dummy,bzm-random-csv,jpgc-sts
71- # jmeter_home: ${{ github.workspace }}/jmeter-${{ env.jmeter_version }}
72-
72+ permissions :
73+ id-token : write
74+ outputs :
75+ build-needed : ${{ steps.check-image.outputs.build-needed }}
7376 steps :
74- - uses : actions/checkout@v5
75-
76- - name : Cache jmeter
77- id : cache-jmeter
78- uses : actions/cache@v4
79- env :
80- cache-name : cache-jmeter
77+ - name : Configure AWS Credentials
78+ uses : aws-actions/configure-aws-credentials@v5
8179 with :
82- path : jmeter
83- key : jmeter
84-
85- # Having run each step separately, it's only the curl request that takes time. So including the unzip and move means I can cache the 'jmeter' folder entirely
86- # STS also requires some files in the jmeter folder, but I don't want those cached so the 'touch' commands are being included in the plugins step
87- # Finally move some of the report generator options into the jmeter folder to simplify the jmeter command in each execution step
88-
89- - name : Install JMeter
90- if : ${{ steps.cache-jmeter.outputs.cache-hit != 'true'}}
91- run : |
92- curl -sSO https://archive.apache.org/dist/jmeter/binaries/apache-jmeter-${{ env.jmeter_version }}.tgz
93- tar xzf apache-jmeter-${{ env.jmeter_version }}.tgz
94- mv apache-jmeter-${{ env.jmeter_version }} jmeter
95- curl -sSO --output-dir jmeter/lib https://repo1.maven.org/maven2/kg/apc/cmdrunner/${{ env.cmdrunner_version }}/cmdrunner-${{ env.cmdrunner_version }}.jar
96- curl -LsS --output jmeter/lib/ext/jmeter-plugins-manager-${{ env.jmeter_plugins_manager_version }}.jar https://jmeter-plugins.org/get/
97- java -cp jmeter/lib/ext/jmeter-plugins-manager-${{ env.jmeter_plugins_manager_version }}.jar org.jmeterplugins.repository.PluginManagerCMDInstaller
98- chmod +x jmeter/bin/PluginsManagerCMD.sh
99-
100- - name : Install JMeter plugins
101- if : env.jmeter_plugins != ''
80+ role-to-assume : arn:aws:iam::393416225559:role/GitHubPerformancetestRole
81+ aws-region : eu-west-2
82+ - name : Check if image exists
83+ id : check-image
10284 run : |
103- if [ -x "$(command -v parallel)" ]; then
104- echo "Using GNU parallel to install plugins"
105- parallel -d, -j 5 -n 1 jmeter/bin/PluginsManagerCMD.sh install {} ::: ${{ env.jmeter_plugins }}
85+ if aws ecr describe-images --repository-name performancetest --image-ids imageTag=${{ github.sha }} > /dev/null 2>&1; then
86+ echo "Docker image with given tag already exists"
10687 else
107- echo "GNU parallel not found, installing plugins sequentially"
108- IFS=',' read -ra PLUGINS <<< "${{ env.jmeter_plugins }}"
109- for plugin in "${PLUGINS[@]}"; do
110- jmeter/bin/PluginsManagerCMD.sh install $plugin
111- done
88+ echo "Docker image does not exist. Build needed"
89+ echo "build-needed=true" >> $GITHUB_OUTPUT
11290 fi
113- curl -sSO --output-dir jmeter/lib https://repo1.maven.org/maven2/org/apache/tika/tika-app/1.28.5/tika-app-1.28.5.jar
114- sed -i '/<Logger name="org.apache.jmeter.junit" level="debug" \/>/a \ <Logger name="org.apache.jmeter.protocol.http.sampler.HTTPSamplerBase" level="info" additivity="false"\/>' jmeter/bin/log4j2.xml
115- sed -i '$ajmeterPlugin.sts.loadAndRunOnStartup=true \njmeterPlugin.sts.port=9191 \njmeterPlugin.sts.daemon=false \njsr223.init.file=jmeter/bin/simple-table-server.groovy' jmeter/bin/user.properties
116- sed -i '$ajmeter.reportgenerator.report_title="MAVIS test report" \njmeter.reportgenerator.overall_granularity=10000 \njmeter.reportgenerator.sample_filter="^.*[^0-9]$"' jmeter/bin/user.properties
117- touch jmeter/consents.txt
118- touch jmeter/vaccinations.txt
119-
120- - name : Set timestamp
121- id : timestamp
122- run : echo "timestamp=$(date '+%Y%m%d%H%M%S')" >> $GITHUB_ENV
123-
124- - name : Create new cohort file
125- if : inputs.runImport == true
126- run : |
127- mkdir -p generate-cohort-output
128- generate_cohort_output_dir=generate-cohort-output
129- jmeter/bin/jmeter -n -t performance-tests/STS/generate-cohort.jmx \
130- -l $generate_cohort_output_dir/samples.jtl \
131- -j $generate_cohort_output_dir/jmeter.log \
132- -JAuthToken=${{secrets.HTTP_AUTH_TOKEN_FOR_TESTS}} \
133- -JURN=${{inputs.URN}} \
134- -JBaseURL=${{inputs.BaseURL}} \
135- -JRowCount=${{inputs.row_count}}
136-
137- - name : Run file import for new file
138- if : inputs.runImport == true
139- run : |
140- mkdir -p import-output
141- import_output_dir=import-output
142- jmeter/bin/jmeter -n -t performance-tests/STS/upload-cohort-data.jmx \
143- -l $import_output_dir/samples.jtl \
144- -j $import_output_dir/jmeter.log \
145- -JAuthToken=${{secrets.HTTP_AUTH_TOKEN_FOR_TESTS}} \
146- -JUser=${{inputs.user}} \
147- -JBaseURL=${{inputs.BaseURL}} \
148- -JInputFile="cohortnew.csv"
149-
150- - name : Run Consent Journey
151- if : inputs.runConsent == true
152- run : |
153- mkdir -p consent-output
154- consent_output_dir=consent-output
155- jmeter/bin/jmeter -n -t performance-tests/STS/consent-journey.jmx \
156- -l $consent_output_dir/samples.jtl \
157- -j $consent_output_dir/jmeter.log \
158- -e -o $consent_output_dir/consent-report \
159- -Jjmeter.reportgenerator.report_title="MAVIS test report" \
160- -Jjmeter.reportgenerator.overall_granularity=10000 \
161- -Jjmeter.reportgenerator.sample_filter="^.*[^0-9]$" \
162- -JAuthToken=${{secrets.HTTP_AUTH_TOKEN_FOR_TESTS}} \
163- -JLoops=-1 \
164- -JThreads=5 \
165- -JRampUp=60 \
166- -JDuration=${{inputs.duration}} \
167- -JUser=${{inputs.user}} \
168- -JBaseURL=${{inputs.BaseURL}} \
169- -JURN=${{inputs.URN}}
170-
171- - name : Upload consent journey JMeter output
172- if : inputs.runConsent == true
173- uses : actions/upload-artifact@v5
91+ build-and-push :
92+ needs : check-image-presence
93+ if : needs.check-image-presence.outputs.build-needed == 'true'
94+ runs-on : ubuntu-latest
95+ permissions :
96+ id-token : write
97+ steps :
98+ - name : Checkout code
99+ uses : actions/checkout@v5
100+ - name : Configure AWS Credentials
101+ uses : aws-actions/configure-aws-credentials@v5
174102 with :
175- name : jmeter-consent-journey-output-${{ env.timestamp }}
176- path : consent-output
177- if-no-files-found : warn
178-
179- - name : Run nurse Journey
180- if : inputs.runNurse == true
103+ role-to-assume : arn:aws:iam::393416225559:role/GitHubPerformancetestRole
104+ aws-region : eu-west-2
105+ - name : Login to ECR
106+ id : login-ecr
107+ uses : aws-actions/amazon-ecr-login@v2
108+ - name : Build and push performancetest docker image
181109 run : |
182- mkdir -p nurse-output
183- nurse_output_dir=nurse-output
184- jmeter/bin/jmeter -n -t performance-tests/STS/nurse-journey.jmx \
185- -l $nurse_output_dir/samples.jtl \
186- -j $nurse_output_dir/jmeter.log \
187- -e -o $nurse_output_dir/report \
188- -Jjmeter.reportgenerator.report_title="MAVIS test report" \
189- -Jjmeter.reportgenerator.overall_granularity=10000 \
190- -Jjmeter.reportgenerator.sample_filter="^.*[^0-9]$" \
191- -JAuthToken=${{secrets.HTTP_AUTH_TOKEN_FOR_TESTS}} \
192- -JLoops=-1 \
193- -JThreads=${{inputs.threads}} \
194- -JRampUp=${{inputs.ramp_up}} \
195- -JDuration=${{inputs.duration}} \
196- -JUser=${{inputs.user}} \
197- -JBaseURL=${{inputs.BaseURL}} \
198- -JURN=${{inputs.URN}}
199-
200- - name : Upload nurse journey JMeter output
201- if : inputs.runNurse == true
202- uses : actions/upload-artifact@v5
110+ cd performance-tests
111+ docker build -t "393416225559.dkr.ecr.eu-west-2.amazonaws.com/performancetest:${{ github.sha }}" .
112+ docker push "393416225559.dkr.ecr.eu-west-2.amazonaws.com/performancetest:${{ github.sha }}"
113+ run-performance-test :
114+ needs : [build-and-push, check-image-presence]
115+ if : ${{ !cancelled() &&
116+ (needs.build-and-push.result == 'success' || needs.check-image-presence.result == 'success') }}
117+ runs-on : ubuntu-latest
118+ permissions :
119+ id-token : write
120+ timeout-minutes : 180
121+ steps :
122+ - uses : actions/checkout@v5
123+ - name : Configure AWS credentials
124+ uses : aws-actions/configure-aws-credentials@v5
203125 with :
204- name : jmeter-nurse-journey-output-${{ env.timestamp }}
205- path : nurse-output
206- if-no-files-found : warn
207-
208- - name : Publish report to GH Pages
209- if : inputs.runNurse == true
210- uses : peaceiris/actions-gh-pages@v4
126+ role-to-assume : arn:aws:iam::393416225559:role/GitHubPerformancetestRole
127+ aws-region : eu-west-2
128+ - name : Create task definition
129+ id : create-task-definition
130+ uses : aws-actions/amazon-ecs-render-task-definition@v1
211131 with :
212- github_token : ${{ secrets.GITHUB_TOKEN }}
213- publish_branch : gh-pages
214- publish_dir : nurse-output/report
215- destination_dir : JMeter/report-${{ env.timestamp }}
216- keep_files : true
217-
218- - name : Set Job Summary
132+ task-definition-family : " performancetest-task-definition-template"
133+ container-name : " performancetest-container"
134+ image : " 393416225559.dkr.ecr.eu-west-2.amazonaws.com/performancetest:${{ github.sha }}"
135+ environment-variables : |
136+ TEST_TO_RUN=${{ inputs.testToRun }}
137+ URN=${{ inputs.URN }}
138+ DURATION=${{ inputs.duration }}
139+ THREADS=${{ inputs.threads }}
140+ RAMP_UP=${{ inputs.ramp_up }}
141+ VACCINATION_LOOP=${{ inputs.vaccination_loop }}
142+ ROW_COUNT=${{ inputs.row_count }}
143+ secrets : |
144+ AUTH_TOKEN=arn:aws:secretsmanager:eu-west-2:393416225559:secret:performancetest/auth-token
145+ - name : Register task definition
146+ id : register-task-definition
147+ run : |
148+ file_path="performancetest-task-definition.json"
149+ family_name="performancetest-task-definition"
150+ echo "$(jq --arg f "$family_name" '.family = $f' "${{ steps.create-task-definition.outputs.task-definition }}")" > "$file_path"
151+ task_definition_arn=$(aws ecs register-task-definition \
152+ --cli-input-json file://$file_path \
153+ --query 'taskDefinition.taskDefinitionArn' \
154+ --output text
155+ )
156+ echo "task_definition_arn=$task_definition_arn" >> $GITHUB_OUTPUT
157+ - name : Run ECS Task
158+ id : run-task
219159 run : |
220- echo "Test report URL is https://nhsdigital.github.io/manage-vaccinations-in-schools-testing/JMeter/report-${{ env.timestamp }}/" >> $GITHUB_STEP_SUMMARY
160+ echo "Starting ECS task for ${{ inputs.testToRun }} test against URN: ${{ inputs.URN }}"
161+
162+ # Prepare network configuration
163+ subnet_id=$(aws ec2 describe-subnets --filters Name=tag:Name,Values=performancetest-subnet --query 'Subnets[0].SubnetId' --output text)
164+ security_group_id=$(aws ec2 describe-security-groups --filters Name=group-name,Values=performancetest-sg --query 'SecurityGroups[0].GroupId' --output text)
221165
166+ aws ecs run-task \
167+ --cluster performancetest \
168+ --task-definition ${{ steps.register-task-definition.outputs.task_definition_arn }} \
169+ --launch-type FARGATE \
170+ --network-configuration "awsvpcConfiguration={subnets=[$subnet_id],securityGroups=[$security_group_id],assignPublicIp=ENABLED}" \
171+ --overrides '{
172+ "containerOverrides": [{
173+ "name": "performancetest-container"
174+ }]
175+ }'
176+
0 commit comments