Skip to content

Commit 0fc8d30

Browse files
authored
Chore: [AEA-0000] - update run regression (#236)
## Summary - Routine Change ### Details - show links to reports on test failures - generic script that can be run from github or azure - run from tag
1 parent 35fbb96 commit 0fc8d30

File tree

2 files changed

+99
-40
lines changed

2 files changed

+99
-40
lines changed

.github/workflows/run_regression_tests.yml

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,5 +72,10 @@ jobs:
7272
if [[ "$TARGET_ENVIRONMENT" != "prod" && "$TARGET_ENVIRONMENT" != "ref" ]]; then
7373
poetry install
7474
echo Running regression tests in the "$TARGET_ENVIRONMENT" environment
75-
poetry run python run_regression_tests.py --env="$TARGET_ENVIRONMENT" --pr_label="$VERSION_NUMBER" --token=${{ steps.generate-token.outputs.token }}
75+
poetry run python run_regression_tests.py \
76+
--env="$TARGET_ENVIRONMENT" \
77+
--pr_label="$VERSION_NUMBER" \
78+
--token=${{ steps.generate-token.outputs.token }} \
79+
--is_called_from_github=true \
80+
--product=CPTS-UI
7681
fi

scripts/run_regression_tests.py

Lines changed: 93 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -10,27 +10,36 @@
1010
import string
1111
import requests
1212
import time
13+
from requests.auth import HTTPBasicAuth
1314

1415
# This should be set to a known good version of regression test repo
15-
REGRESSION_TESTS_REPO_TAG = "main"
16+
REGRESSION_TESTS_REPO_TAG = "v2.0.8"
1617

1718
GITHUB_API_URL = "https://api.github.com/repos/NHSDigital/electronic-prescription-service-api-regression-tests/actions"
19+
GITHUB_RUN_URL = "https://github.com/NHSDigital/electronic-prescription-service-api-regression-tests/actions/runs"
1820

1921
ENVIRONMENT_NAMES = {
2022
"dev": "INTERNAL-DEV",
2123
"dev-pr": "INTERNAL-DEV",
2224
"qa": "INTERNAL-QA",
2325
"int": "INT",
2426
"ref": "REF",
25-
2627
}
2728

2829

30+
class BearerAuth(requests.auth.AuthBase):
31+
def __init__(self, token):
32+
self.token = token
33+
34+
def __call__(self, r):
35+
r.headers["authorization"] = "Bearer " + self.token
36+
return r
37+
38+
2939
def get_headers():
3040
return {
3141
"Accept": "application/vnd.github+json",
3242
"X-GitHub-Api-Version": "2022-11-28",
33-
"Authorization": f"Bearer {arguments.token}",
3443
}
3544

3645

@@ -45,23 +54,23 @@ def generate_timestamp():
4554
return date_time
4655

4756

48-
def trigger_test_run():
49-
pr_label = arguments.pr_label.lower()
57+
def trigger_test_run(env, pr_label, product, auth_header):
5058
body = {
5159
"ref": "main",
5260
"inputs": {
5361
"id": run_id,
5462
"tags": "@regression",
5563
"environment": ENVIRONMENT_NAMES[arguments.env],
5664
"pull_request_id": pr_label,
57-
"product": "CPTS-UI",
65+
"product": product,
5866
"github_tag": REGRESSION_TESTS_REPO_TAG
5967
},
6068
}
6169

6270
response = requests.post(
6371
url=f"{GITHUB_API_URL}/workflows/regression_tests.yml/dispatches",
6472
headers=get_headers(),
73+
auth=auth_header,
6574
json=body,
6675
)
6776

@@ -71,31 +80,29 @@ def trigger_test_run():
7180
), f"Failed to trigger test run. Expected 204, got {response.status_code}. Response: {response.text}"
7281

7382

74-
def get_workflow_runs():
83+
def get_workflow_runs(auth_header):
7584
print(f"Getting workflow runs after date: {run_date_filter}")
7685
response = requests.get(
7786
f"{GITHUB_API_URL}/runs?created=%3E{run_date_filter}",
7887
headers=get_headers(),
88+
auth=auth_header,
7989
)
8090
assert (
8191
response.status_code == 200
8292
), f"Unable to get workflow runs. Expected 200, got {response.status_code}"
8393
return response.json()["workflow_runs"]
8494

8595

86-
def get_jobs_for_workflow(jobs_url):
96+
def get_jobs_for_workflow(jobs_url, auth_header):
8797
print("Getting jobs for workflow...")
88-
response = requests.get(
89-
jobs_url,
90-
headers=get_headers(),
91-
)
98+
response = requests.get(jobs_url, auth=auth_header)
9299
assert (
93100
response.status_code == 200
94101
), f"Unable to get workflow jobs. Expected 200, got {response.status_code}"
95102
return response.json()["jobs"]
96103

97104

98-
def find_workflow():
105+
def find_workflow(auth_header):
99106
max_attempts = 5
100107
current_attempt = 0
101108

@@ -104,55 +111,64 @@ def find_workflow():
104111
current_attempt = current_attempt + 1
105112
print(f"Attempt {current_attempt}")
106113

107-
workflow_runs = get_workflow_runs()
114+
workflow_runs = get_workflow_runs(auth_header)
108115
for workflow in workflow_runs:
109116
time.sleep(3)
110117
current_workflow_id = workflow["id"]
111118
jobs_url = workflow["jobs_url"]
112119

113-
list_of_jobs = get_jobs_for_workflow(jobs_url)
114-
if is_correct_job(list_of_jobs) is True:
115-
print(f"Workflow Job found! Using ID: {current_workflow_id}")
116-
return current_workflow_id
120+
list_of_jobs = get_jobs_for_workflow(jobs_url, auth_header)
121+
122+
if list_of_jobs:
123+
job = list_of_jobs[0]
124+
steps = job["steps"]
125+
126+
if len(steps) >= 2:
127+
third_step = steps[2]
128+
if third_step["name"] == run_id:
129+
print(f"Workflow Job found! Using ID: {current_workflow_id}")
130+
return current_workflow_id
131+
else:
132+
print("Not enough steps have been executed for this run yet...")
133+
else:
134+
print("Jobs for this workflow run haven't populated yet...")
117135
print(
118136
"Processed all available workflows but no jobs were matching the Unique ID were found!"
119137
)
120138

121139

122-
def is_correct_job(list_of_jobs):
123-
job = list_of_jobs[0]
124-
steps = job["steps"]
125-
126-
if len(steps) >= 2:
127-
third_step = steps[2]
128-
if third_step["name"] == run_id:
129-
return True
140+
def get_auth_header(is_called_from_github, token, user):
141+
if (is_called_from_github):
142+
return BearerAuth(token)
130143
else:
131-
print("Jobs for this workflow run haven't populated yet...")
144+
user_credentials = user.split(":")
145+
return HTTPBasicAuth(user_credentials[0], user_credentials[1])
132146

133147

134-
def get_job():
148+
def get_job(auth_header):
135149
job_request_url = f"{GITHUB_API_URL}/runs/{workflow_id}/jobs"
136-
job_response = requests.get(job_request_url, headers=get_headers())
150+
job_response = requests.get(
151+
job_request_url,
152+
headers=get_headers(),
153+
auth=auth_header,
154+
)
137155

138156
return job_response.json()["jobs"][0]
139157

140158

141-
def check_job():
159+
def check_job(auth_header):
142160
print("Checking job status, please wait...")
143161
print("Current status:", end=" ")
144-
job = get_job()
162+
job = get_job(auth_header)
145163
job_status = job["status"]
146164

147165
while job_status != "completed":
148166
print(job_status)
149167
time.sleep(10)
150-
job = get_job()
168+
job = get_job(auth_header)
151169
job_status = job["status"]
152170

153-
assert (
154-
job["conclusion"] == "success"
155-
), "The regressions test step failed! There are likely test failures."
171+
return job["conclusion"]
156172

157173

158174
if __name__ == "__main__":
@@ -169,14 +185,52 @@ def check_job():
169185
help="Please provide the environment you wish to run in.",
170186
)
171187
parser.add_argument(
172-
"--token", required=True, help="Please provide the authentication token."
188+
"--user", required=False, help="Please provide the user credentials."
173189
)
190+
parser.add_argument(
191+
'--is_called_from_github',
192+
default=False,
193+
type=lambda x: (str(x).lower() == 'true'),
194+
help="If this is being called from github actions rather than azure"
195+
)
196+
parser.add_argument(
197+
"--product", required=True, help="Please provide the product to run the tests for."
198+
)
199+
parser.add_argument(
200+
"--token", required=False, help="Please provide the authentication token."
201+
)
202+
174203
arguments = parser.parse_args()
204+
205+
print(f"pr_label: {arguments.pr_label}")
206+
print(f"env: {arguments.env}")
207+
print(f"is_called_from_github: {arguments.is_called_from_github}")
208+
print(f"product: {arguments.product}")
209+
print(f"regression_tests_repo_tag: {REGRESSION_TESTS_REPO_TAG}")
210+
175211
run_id = generate_unique_run_id()
176212
run_date_filter = generate_timestamp()
213+
auth_header = get_auth_header(arguments.is_called_from_github, arguments.token, arguments.user)
214+
215+
pr_label = arguments.pr_label.lower()
216+
trigger_test_run(
217+
arguments.env,
218+
pr_label,
219+
arguments.product,
220+
auth_header
221+
)
177222

178-
trigger_test_run()
223+
workflow_id = find_workflow(auth_header)
224+
job_status = check_job(auth_header)
225+
if job_status != "success":
226+
if arguments.pr_label:
227+
pr_label = arguments.pr_label.lower()
228+
env = f"PULL-REQUEST/{pr_label}"
229+
else:
230+
env = arguments.env.upper()
231+
print("The regressions test step failed! There are likely test failures.")
232+
print(f"See {GITHUB_RUN_URL}/{workflow_id}/ for run details)")
233+
print(f"See https://nhsdigital.github.io/eps-test-reports/{arguments.product}/{env}/ for allure report")
234+
raise Exception("Regression test failed")
179235

180-
workflow_id = find_workflow()
181-
check_job()
182236
print("Success!")

0 commit comments

Comments
 (0)