Skip to content

Commit

Permalink
selective execution of e2e-tests
Browse files Browse the repository at this point in the history
  • Loading branch information
tisutisu committed Feb 7, 2025
1 parent 54c1b06 commit 16542b0
Show file tree
Hide file tree
Showing 3 changed files with 110 additions and 6 deletions.
15 changes: 9 additions & 6 deletions .tekton/pull-request.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,9 @@ spec:
- check_partner_tasks := strings.any_prefix_match(input, ["partners/", "hack/", ".tekton/"])
runAfter:
- build-appstudio-utils
workspaces:
- name: source
workspace: workspace
- name: task-lint-check
when:
- input: "tasks"
Expand Down Expand Up @@ -208,9 +211,9 @@ spec:
- name: source
- name: e2e-tests
when:
- input: "e2e_tests"
- input: "execute_e2e"
operator: "in"
values: ["$(tasks.task-switchboard.results.bindings[*])"]
values: ["$(tasks.task-switchboard.results.run-e2e)"]
params:
- name: e2e_test_namespace
value: $(params.e2e_test_namespace)
Expand Down Expand Up @@ -286,9 +289,9 @@ spec:
finally:
- name: e2e-cleanup
when:
- input: "e2e_tests"
- input: "execute_e2e"
operator: "in"
values: ["$(tasks.task-switchboard.results.bindings[*])"]
values: ["$(tasks.task-switchboard.results.run-e2e)"]
params:
- name: e2e_test_namespace
value: $(params.e2e_test_namespace)
Expand All @@ -306,9 +309,9 @@ spec:
oc delete --ignore-not-found eventlisteners --all -n $(params.e2e_test_namespace)
- name: pull-request-status-message
when:
- input: "tasks_pipelines"
- input: "execute_e2e"
operator: "in"
values: ["$(tasks.task-switchboard.results.bindings[*])"]
values: ["$(tasks.task-switchboard.results.run-e2e)"]
taskRef:
resolver: git
params:
Expand Down
95 changes: 95 additions & 0 deletions .tekton/scripts/determine-if-e2e-execution-needed.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,95 @@
#!/usr/bin/env python3

import os
import sys
import json
import urllib.error
import urllib.request
import subprocess

# Pipelines currently covered by e2e tests
pipelines_covered_by_e2e = ["docker-build", "docker-build-oci-ta", "docker-build-multi-platform-oci-ta", "fbc-builder"]

# Task list which are covered by e2e tests, generated dynamically
tasks_covered_by_e2e = []

# Otherthan tasks and pipelines, related files for which e2e tests needs to be executed
files_covered_by_e2e = [".tekton/pull-request.yaml", ".tekton/tasks/e2e-test.yaml", ".tekton/scripts/determine-if-e2e-execution-needed.py"]

def add_only_unique_task_names(task_list):
for task_name in task_list:
if task_name not in tasks_covered_by_e2e:
tasks_covered_by_e2e.append(task_name)

def get_tasks_covered_by_e2e():
for pipeline_name in pipelines_covered_by_e2e:
pipeline_path = f"pipelines/{pipeline_name}/{pipeline_name}.yaml"
# Get the task names from pipeline spec
result = subprocess.run([f"yq -e '.spec.tasks[].taskRef.name' {pipeline_path}"], shell=True, capture_output=True, text=True)
if result.stderr != "":
print(f"[ERROR] failed to get tasks inside spec.tasks: {result.stderr}")
sys.exit(1)
output = result.stdout
task_names = output.split()
add_only_unique_task_names(task_names)
# Get the task names from pipeline finally
result = subprocess.run([f"yq -e '.spec.finally[].taskRef.name' {pipeline_path}"], shell=True, capture_output=True, text=True)
if result.stderr != "":
print(f"[ERROR] failed to get tasks inside .spec.finally: {result.stderr}")
sys.exit(1)
output = result.stdout
task_names = output.split()
add_only_unique_task_names(task_names)

def get_changed_files_from_pr(pull_number):
updated_files = []
token = os.environ["GITHUB_TOKEN"]
headers = {"Authorization": "Bearer " + token}
base_url = "https://api.github.com"
repo = "konflux-ci/build-definitions"
url = f"{base_url}/repos/{repo}/pulls/{pull_number}/files"
req = urllib.request.Request(url=url, method="GET", headers=headers)
try:
with urllib.request.urlopen(req) as resp:
if resp.status != 200:
print(f"[ERROR] Unknown response status code: {resp.status}")
sys.exit(1)
response_in_json = json.loads(resp.read())
for object in response_in_json:
updated_files.append(object['filename'])
except urllib.error.HTTPError as e:
print(f"[ERROR] got error response: {e.read()} with status {e.code}")
sys.exit(1)
return updated_files

def does_updated_files_covered_by_e2e(updated_files):
required_to_run_e2e = False
for file_path in updated_files:
if file_path.startswith("task/"):
task_name = file_path.split("/")[1]
if task_name in tasks_covered_by_e2e:
required_to_run_e2e = True
break
elif file_path.startswith("pipelines/"):
pipeline_name = file_path.split("/")[1]
if pipeline_name in pipelines_covered_by_e2e:
required_to_run_e2e = True
break
elif file_path in files_covered_by_e2e:
required_to_run_e2e = True
break
else:
print("No need to run e2e tests")
return required_to_run_e2e

if __name__ == '__main__':
if len(sys.argv) != 2:
print("[ERROR] provide correct number of arguments")
pr_number = sys.argv[1]
get_tasks_covered_by_e2e()
updated_files = get_changed_files_from_pr(pr_number)
required_to_run_e2e = does_updated_files_covered_by_e2e(updated_files)
if required_to_run_e2e:
print("execute_e2e")
else:
print("dont_execute_e2e")
6 changes: 6 additions & 0 deletions .tekton/tasks/task-switchboard.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ spec:
results:
- name: bindings
type: array
- name: run-e2e
type: string
steps:
- name: evaluate
image: $(params.utils_image)
Expand All @@ -32,6 +34,7 @@ spec:
key: "git-provider-token"
args:
- "$(params.expressions[*])"
workingDir: $(workspaces.source.path)/source
script: |
#!/bin/bash
set -o errexit
Expand All @@ -53,3 +56,6 @@ spec:
'data[_]' \
| jq '[.result.[].expressions.[].value | to_entries | .[] | select(.value == true) | .key]' \
| tee "$(results.bindings.path)"
# Output is "execute_e2e" or "dont_execute_e2e" based on files changed in pr
.tekton/scripts/determine-if-e2e-execution-needed.py "${pr_number}" | tr -d '\n' | tee "$(results.run-e2e.path)"

0 comments on commit 16542b0

Please sign in to comment.