Skip to content

Commit ff915db

Browse files
authored
Split Python tests to reduce run time (#8419)
1 parent fedacba commit ff915db

16 files changed

+196
-23
lines changed

.github/data/matrix-smoke-nap.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -61,7 +61,7 @@
6161
"image": "ubi-9-plus-nap",
6262
"type": "plus",
6363
"nap_modules": "dos",
64-
"marker": "'dos_learning or otel'",
64+
"marker": "'dos_learning'",
6565
"platforms": "linux/amd64"
6666
},
6767
{

.github/data/matrix-smoke-oss.json

Lines changed: 28 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -36,38 +36,59 @@
3636
"platforms": "linux/arm64, linux/amd64"
3737
},
3838
{
39-
"label": "policies 1/2",
39+
"label": "policies 1/4",
4040
"image": "alpine",
4141
"type": "oss",
4242
"marker": "'policies and not policies_rl and not policies_ac and not policies_jwt and not policies_mtls and not policies_cache'",
4343
"platforms": "linux/arm64, linux/amd64"
4444
},
4545
{
46-
"label": "policies 2/2",
46+
"label": "policies 2/4",
4747
"image": "alpine",
4848
"type": "oss",
49-
"marker": "'policies_rl or policies_ac or policies_jwt or policies_mtls or policies_cache or otel'",
49+
"marker": "'policies_ac or policies_jwt'",
5050
"platforms": "linux/arm64, linux/amd64"
5151
},
5252
{
53-
"label": "VS 1/3",
53+
"label": "policies 3/4",
54+
"image": "alpine",
55+
"type": "oss",
56+
"marker": "'policies_rl'",
57+
"platforms": "linux/arm64, linux/amd64"
58+
},
59+
{
60+
"label": "policies 4/4",
61+
"image": "alpine",
62+
"type": "oss",
63+
"marker": "'policies_mtls or policies_cache or otel'",
64+
"platforms": "linux/arm64, linux/amd64"
65+
},
66+
{
67+
"label": "VS 1/4",
5468
"image": "debian",
5569
"type": "oss",
5670
"marker": "'vs and not vs_ipv6 and not vs_rewrite and not vs_responses and not vs_grpc and not vs_redirects and not vs_externalname and not vs_externaldns and not vs_certmanager and not vs_api and not vs_backup and not vs_use_cluster_ip and not vs_canary and not vs_upstream and not vs_config_map'",
5771
"platforms": "linux/arm64, linux/amd64"
5872
},
5973
{
60-
"label": "VS 2/3",
74+
"label": "VS 2/4",
6175
"image": "debian",
6276
"type": "oss",
6377
"marker": "'vs_grpc or vs_redirects or vs_externalname or vs_externaldns or vs_api or vs_backup or vs_use_cluster_ip or vs_canary or vs_upstream or vs_config_map'",
6478
"platforms": "linux/arm64, linux/amd64"
6579
},
6680
{
67-
"label": "VS 3/3",
81+
"label": "VS 3/4",
82+
"image": "debian",
83+
"type": "oss",
84+
"marker": "'vs_responses or vs_ipv6 or vs_rewrite'",
85+
"platforms": "linux/arm64, linux/amd64"
86+
},
87+
{
88+
"label": "VS 4/4",
6889
"image": "debian",
6990
"type": "oss",
70-
"marker": "'vs_responses or vs_ipv6 or vs_rewrite or vs_certmanager or otel'",
91+
"marker": "'vs_certmanager or otel'",
7192
"platforms": "linux/arm64, linux/amd64"
7293
},
7394
{

.github/data/matrix-smoke-plus.json

Lines changed: 57 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -1,42 +1,70 @@
11
{
22
"images": [
33
{
4-
"label": "VS 1/3",
4+
"label": "VS 1/5",
55
"image": "debian-plus",
66
"type": "plus",
7-
"marker": "'vs and not vs_ipv6 and not vs_rewrite and not vs_responses and not vs_grpc and not vs_redirects and not vs_externalname and not vs_externaldns and not vs_certmanager and not vs_api and not vs_backup and not vs_use_cluster_ip and not vs_canary and not vs_upstream and not vs_config_map'",
7+
"marker": "'vs and not vs_ipv6 and not vs_rewrite and not vs_responses and not vs_grpc and not vs_redirects and not vs_externalname and not vs_externaldns and not vs_certmanager and not vs_api and not vs_backup and not vs_use_cluster_ip and not vs_canary and not vs_upstream and not vs_config_map and not vs_listeners'",
88
"platforms": "linux/arm64, linux/amd64"
99
},
1010
{
11-
"label": "VS 2/3",
11+
"label": "VS 2/5",
1212
"image": "debian-plus",
1313
"type": "plus",
1414
"marker": "'vs_grpc or vs_redirects or vs_externalname or vs_externaldns or vs_api or vs_backup or vs_use_cluster_ip or vs_canary or vs_upstream or vs_config_map'",
1515
"platforms": "linux/arm64, linux/amd64"
1616
},
1717
{
18-
"label": "VS 3/3",
18+
"label": "VS 3/5",
1919
"image": "debian-plus",
2020
"type": "plus",
21-
"marker": "'vs_responses or vs_ipv6 or vs_rewrite or vs_certmanager'",
21+
"marker": "'vs_responses or vs_ipv6 or vs_rewrite'",
2222
"platforms": "linux/arm64, linux/amd64"
2323
},
2424
{
25-
"label": "TS",
25+
"label": "VS 4/5",
2626
"image": "debian-plus",
2727
"type": "plus",
28-
"marker": "'ts or otel'",
28+
"marker": "'vs_certmanager'",
2929
"platforms": "linux/arm64, linux/amd64"
3030
},
3131
{
32-
"label": "ingresses 1/2",
32+
"label": "VS 5/5",
33+
"image": "debian-plus",
34+
"type": "plus",
35+
"marker": "'vs_listeners'",
36+
"platforms": "linux/arm64, linux/amd64"
37+
},
38+
{
39+
"label": "TS 1/2",
40+
"image": "debian-plus",
41+
"type": "plus",
42+
"marker": "'ts and not ts_tcp and not ts_udp'",
43+
"platforms": "linux/arm64, linux/amd64"
44+
},
45+
{
46+
"label": "TS 2/2",
47+
"image": "debian-plus",
48+
"type": "plus",
49+
"marker": "'ts_tcp or ts_udp or otel'",
50+
"platforms": "linux/arm64, linux/amd64"
51+
},
52+
{
53+
"label": "ingresses 1/3",
3354
"image": "alpine-plus",
3455
"type": "plus",
35-
"marker": "'ingresses and not annotations and not basic_auth and not hsts and not watch_namespace and not wildcard_tls'",
56+
"marker": "'ingresses and not annotations and not basic_auth and not hsts and not watch_namespace and not wildcard_tls and not ingresses_smoke and not ingresses_jwt'",
3657
"platforms": "linux/arm64, linux/amd64"
3758
},
3859
{
39-
"label": "ingresses 2/2",
60+
"label": "ingresses 2/3",
61+
"image": "alpine-plus",
62+
"type": "plus",
63+
"marker": "'ingresses_smoke or ingresses_jwt'",
64+
"platforms": "linux/arm64, linux/amd64"
65+
},
66+
{
67+
"label": "ingresses 3/3",
4068
"image": "alpine-plus-fips",
4169
"type": "plus",
4270
"marker": "'annotations or basic_auth or hsts or watch_namespace or wildcard_tls'",
@@ -64,24 +92,38 @@
6492
"platforms": "linux/arm64, linux/amd64"
6593
},
6694
{
67-
"label": "policies 1/3",
95+
"label": "policies 1/5",
6896
"image": "ubi-9-plus",
6997
"type": "plus",
7098
"marker": "'policies and not policies_ac and not policies_jwt and not policies_mtls and not policies_rl and not policies_cache'",
7199
"platforms": "linux/arm64, linux/amd64"
72100
},
73101
{
74-
"label": "policies 2/3",
102+
"label": "policies 2/5",
103+
"image": "ubi-9-plus",
104+
"type": "plus",
105+
"marker": "'policies_ac or policies_mtls or policies_cache'",
106+
"platforms": "linux/arm64, linux/amd64"
107+
},
108+
{
109+
"label": "policies 3/5",
110+
"image": "ubi-9-plus",
111+
"type": "plus",
112+
"marker": "'policies_jwt or otel'",
113+
"platforms": "linux/arm64, linux/amd64"
114+
},
115+
{
116+
"label": "policies 4/5",
75117
"image": "ubi-9-plus",
76118
"type": "plus",
77-
"marker": "'policies_ac or policies_jwt or policies_mtls or otel'",
119+
"marker": "'policies_rl_vs'",
78120
"platforms": "linux/arm64, linux/amd64"
79121
},
80122
{
81-
"label": "policies 3/3",
123+
"label": "policies 5/5",
82124
"image": "ubi-9-plus",
83125
"type": "plus",
84-
"marker": "'policies_rl or policies_cache'",
126+
"marker": "'policies_rl_vsr'",
85127
"platforms": "linux/arm64, linux/amd64"
86128
},
87129
{

pyproject.toml

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,11 +45,15 @@ markers = [
4545
"dos_learning",
4646
"hsts",
4747
"ingresses",
48+
"ingresses_jwt",
49+
"ingresses_smoke",
4850
"multi_ns",
4951
"oidc",
5052
"otel",
5153
"policies",
5254
"policies_rl",
55+
"policies_rl_vs",
56+
"policies_rl_vsr",
5357
"policies_jwt",
5458
"policies_ac",
5559
"policies_mtls",
@@ -60,6 +64,8 @@ markers = [
6064
"smoke",
6165
"startup",
6266
"ts",
67+
"ts_tcp",
68+
"ts_udp",
6369
"upgrade",
6470
"vs",
6571
"vs_api",
@@ -75,6 +81,7 @@ markers = [
7581
"vs_certmanager",
7682
"vs_config_map",
7783
"vs_grpc",
84+
"vs_listeners",
7885
"vs_upstream",
7986
"vs_use_cluster_ip",
8087
"vsr",

tests/scripts/longest_test_job.py

Lines changed: 90 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,90 @@
1+
#!/usr/bin/env python3
2+
3+
import argparse
4+
5+
from github import Auth, Github
6+
7+
# parse args
8+
parser = argparse.ArgumentParser()
9+
parser.add_argument("-t", "--token", required=True, help="GitHub access token")
10+
parser.add_argument("-o", "--owner", required=False, default="nginx", help="GitHub repository owner")
11+
parser.add_argument("-r", "--repo", help="GitHub repository name", required=False, default="kubernetes-ingress")
12+
parser.add_argument("-w", "--workflow", help="GitHub Actions workflow name", required=False, default="CI")
13+
parser.add_argument("-b", "--branch", help="GitHub repository branch", required=False, default="main")
14+
parser.add_argument(
15+
"-d", "--duration", help="Minimum duration of jobs in seconds", required=False, default=900, type=int
16+
)
17+
args = parser.parse_args()
18+
TOKEN = args.token
19+
OWNER = args.owner
20+
REPO = args.repo
21+
BRANCH = args.branch
22+
DURATION = args.duration
23+
WORKFLOW = args.workflow
24+
25+
26+
def get_github_handle(token):
27+
# Authenticate to GitHub
28+
auth = Auth.Token(token)
29+
g = Github(auth=auth)
30+
if g is None:
31+
return None
32+
return g
33+
34+
35+
def get_github_repo(owner, repo, handle):
36+
# Get the repository
37+
repository = handle.get_repo(f"{owner}/{repo}")
38+
return repository
39+
40+
41+
def get_workflow_runs(repo, workflow_name, branch=None):
42+
workflows = repo.get_workflows()
43+
for workflow in workflows:
44+
if workflow.name == workflow_name:
45+
return workflow.get_runs(branch=branch, status="completed")
46+
return None
47+
48+
49+
def get_run_branch_jobs(runs):
50+
results = {}
51+
for run in runs:
52+
results[run.id] = run.jobs()
53+
return results
54+
55+
56+
def get_run_durations(runs):
57+
results = {}
58+
for run in runs:
59+
results[run.id] = run.timing().run_duration_ms / 1000
60+
return results
61+
62+
63+
def convert_seconds(seconds):
64+
minutes, remaining_seconds = divmod(seconds, 60)
65+
hour, minutes = divmod(minutes, 60)
66+
return "%d:%02d:%02d" % (hour, minutes, remaining_seconds)
67+
68+
69+
g = get_github_handle(TOKEN)
70+
if g is None:
71+
print("Failed to authenticate to GitHub")
72+
exit(1)
73+
r = get_github_repo(OWNER, REPO, g)
74+
75+
# Get the latest workflow runs
76+
runs = get_workflow_runs(r, WORKFLOW, branch=BRANCH)
77+
if not runs:
78+
print("No workflow runs found.")
79+
exit(1)
80+
wj = get_run_branch_jobs(runs)
81+
wd = get_run_durations(runs)
82+
for run_id in sorted(wj.keys()):
83+
duration = wd.get(run_id)
84+
print(f"Workflow Run ID: {run_id}, Duration: {convert_seconds(duration)}")
85+
for job in wj[run_id]:
86+
job_duration = (job.completed_at - job.started_at).total_seconds()
87+
if job.status == "completed" and job.conclusion == "success" and job_duration > DURATION:
88+
print(f" Job: {job.name}, Duration: {convert_seconds(job_duration)}, URL: {job.html_url}")
89+
90+
g.close()

tests/suite/test_jwt_auth_mergeable.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -195,6 +195,7 @@ def get_token_from_file(token_type) -> str:
195195

196196

197197
@pytest.mark.ingresses
198+
@pytest.mark.ingresses_jwt
198199
@pytest.mark.skip_for_nginx_oss
199200
class TestJWTAuthMergeableMinions:
200201
def test_jwt_auth_response_codes_and_location(self, kube_apis, jwt_auth_setup, test_namespace):

tests/suite/test_jwt_policies_jwksuri.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -171,6 +171,7 @@ def fin():
171171

172172
@pytest.mark.skip_for_nginx_oss
173173
@pytest.mark.policies
174+
@pytest.mark.policies_jwt
174175
@pytest.mark.parametrize(
175176
"crd_ingress_controller, virtual_server_setup",
176177
[

tests/suite/test_jwt_secrets.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -93,6 +93,7 @@ def fin():
9393

9494

9595
@pytest.mark.ingresses
96+
@pytest.mark.ingresses_jwt
9697
@pytest.mark.skip_for_nginx_oss
9798
class TestJWTSecrets:
9899
def test_response_code_200_and_server_name(self, jwt_secrets_setup, jwt_secret):

tests/suite/test_policy_ingress_class.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818

1919

2020
@pytest.mark.policies
21+
@pytest.mark.policies_rl
2122
@pytest.mark.parametrize(
2223
"crd_ingress_controller, virtual_server_setup",
2324
[

tests/suite/test_rl_policies.py

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -100,6 +100,7 @@
100100

101101
@pytest.mark.policies
102102
@pytest.mark.policies_rl
103+
@pytest.mark.policies_rl_vs
103104
@pytest.mark.parametrize(
104105
"crd_ingress_controller, virtual_server_setup",
105106
[
@@ -636,6 +637,7 @@ def test_rl_policy_jwt_claim_sub(
636637

637638
@pytest.mark.policies
638639
@pytest.mark.policies_rl
640+
@pytest.mark.policies_rl_vs
639641
@pytest.mark.parametrize(
640642
"crd_ingress_controller, virtual_server_setup",
641643
[

0 commit comments

Comments
 (0)