Skip to content

Commit 0e962c4

Browse files
Merge pull request #1330 from cloudbees-oss/AIENG-504
[AIENG-504] added never failing tests and longest tests commands
2 parents dd6a739 + 5fccc39 commit 0e962c4

7 files changed

Lines changed: 988 additions & 21 deletions

File tree

smart_tests/commands/view/__init__.py

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
from ... import args4p
22
from ...app import Application
33
from .flaky_tests import flaky_tests
4+
from .longest_tests import longest_tests
5+
from .never_failing_tests import never_failing_tests
46
from .test_results import test_results
57

68

@@ -10,4 +12,6 @@ def view(app: Application):
1012

1113

1214
view.add_command(flaky_tests)
15+
view.add_command(longest_tests)
16+
view.add_command(never_failing_tests)
1317
view.add_command(test_results)

smart_tests/commands/view/flaky_tests.py

Lines changed: 1 addition & 21 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,4 @@
11
import json
2-
import re
32
import sys
43
from http import HTTPStatus
54
from typing import Annotated
@@ -8,30 +7,11 @@
87

98
import smart_tests.args4p.typer as typer
109
from smart_tests.args4p.converters import intType
11-
from smart_tests.args4p.exceptions import BadCmdLineException
1210

1311
from ... import args4p
1412
from ...app import Application
1513
from ...utils.smart_tests_client import SmartTestsClient
16-
from ...utils.typer_types import DateTimeWithTimezone, parse_datetime_with_timezone
17-
18-
19-
def validate_iso_week(value: str) -> str:
20-
"""Validate ISO week format YYYY-Www and week number range (01-53)"""
21-
pattern = r'^\d{4}-W\d{2}$'
22-
if not re.match(pattern, value):
23-
raise BadCmdLineException(
24-
f"Invalid year-week format: '{value}'. Expected format: YYYY-Www (e.g., 2026-W15)"
25-
)
26-
27-
# Extract and validate week number range
28-
week_num = int(value.split('-W')[1])
29-
if week_num < 1 or week_num > 53:
30-
raise BadCmdLineException(
31-
f"Invalid week number: '{value}'. Week must be between 01 and 53"
32-
)
33-
34-
return value
14+
from ...utils.typer_types import DateTimeWithTimezone, parse_datetime_with_timezone, validate_iso_week
3515

3616

3717
@args4p.command(help="View flaky test data with weekly scores")
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import json
2+
import sys
3+
from http import HTTPStatus
4+
from typing import Annotated
5+
6+
import click
7+
8+
import smart_tests.args4p.typer as typer
9+
from smart_tests.args4p.converters import intType
10+
11+
from ... import args4p
12+
from ...app import Application
13+
from ...utils.smart_tests_client import SmartTestsClient
14+
from ...utils.typer_types import DateTimeWithTimezone, parse_datetime_with_timezone, validate_iso_week
15+
16+
17+
@args4p.command(help="View longest running test data with weekly scores")
18+
def longest_tests(
19+
app: Application,
20+
year_week: Annotated[str | None, typer.Option(
21+
"--year-week",
22+
help="Specific ISO week for longest running tests (e.g., '2026-W15')",
23+
type=validate_iso_week,
24+
metavar="YYYY-Www"
25+
)] = None,
26+
weeks: Annotated[int | None, typer.Option(
27+
"--weeks",
28+
help="Number of weeks to retrieve (default: 1, max: 12)",
29+
type=intType(min=1, max=12),
30+
metavar="N"
31+
)] = None,
32+
from_date: Annotated[DateTimeWithTimezone | None, typer.Option(
33+
"--from",
34+
help="Start date/time (ISO 8601 format, e.g., '2026-04-08' or '2026-04-08T00:00:00Z')",
35+
type=parse_datetime_with_timezone,
36+
metavar="DATE"
37+
)] = None,
38+
to_date: Annotated[DateTimeWithTimezone | None, typer.Option(
39+
"--to",
40+
help="End date/time (ISO 8601 format, e.g., '2026-04-14' or '2026-04-14T23:59:59Z')",
41+
type=parse_datetime_with_timezone,
42+
metavar="DATE"
43+
)] = None,
44+
test_path: Annotated[str | None, typer.Option(
45+
"--test-path",
46+
help="Test path filter (full path string, e.g., 'class=MyTest')",
47+
metavar="NAME"
48+
)] = None,
49+
limit: Annotated[int | None, typer.Option(
50+
"--limit",
51+
help="Max results to return per week (default: 50, max: 500)",
52+
type=intType(min=1, max=500),
53+
metavar="N"
54+
)] = None,
55+
):
56+
"""View longest running tests with weekly trends"""
57+
client = SmartTestsClient(app=app)
58+
59+
params = {}
60+
if year_week:
61+
params["year-week"] = year_week
62+
if weeks:
63+
params["weeks"] = str(weeks)
64+
if from_date:
65+
params["from"] = from_date.datetime().strftime("%Y-%m-%d")
66+
if to_date:
67+
params["to"] = to_date.datetime().strftime("%Y-%m-%d")
68+
if test_path:
69+
params["test-path"] = test_path
70+
if limit:
71+
params["limit"] = str(limit)
72+
73+
try:
74+
res = client.request("get", "view/longest-tests", params=params)
75+
76+
if res.status_code == HTTPStatus.NOT_FOUND:
77+
click.secho(
78+
"No longest running test data found. Check your filters and try again.",
79+
fg='yellow', err=True
80+
)
81+
sys.exit(1)
82+
83+
res.raise_for_status()
84+
response_json = res.json()
85+
86+
click.echo(json.dumps(response_json, indent=2))
87+
88+
except Exception as e:
89+
client.print_exception_and_recover(
90+
e,
91+
"Warning: failed to retrieve longest running tests from server"
92+
)
93+
sys.exit(1)
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
import json
2+
import sys
3+
from http import HTTPStatus
4+
from typing import Annotated
5+
6+
import click
7+
8+
import smart_tests.args4p.typer as typer
9+
from smart_tests.args4p.converters import intType
10+
11+
from ... import args4p
12+
from ...app import Application
13+
from ...utils.smart_tests_client import SmartTestsClient
14+
from ...utils.typer_types import DateTimeWithTimezone, parse_datetime_with_timezone, validate_iso_week
15+
16+
17+
@args4p.command(help="View never failing test data with weekly scores")
18+
def never_failing_tests(
19+
app: Application,
20+
year_week: Annotated[str | None, typer.Option(
21+
"--year-week",
22+
help="Specific ISO week for never failing tests (e.g., '2026-W15')",
23+
type=validate_iso_week,
24+
metavar="YYYY-Www"
25+
)] = None,
26+
weeks: Annotated[int | None, typer.Option(
27+
"--weeks",
28+
help="Number of weeks to retrieve (default: 1, max: 12)",
29+
type=intType(min=1, max=12),
30+
metavar="N"
31+
)] = None,
32+
from_date: Annotated[DateTimeWithTimezone | None, typer.Option(
33+
"--from",
34+
help="Start date/time (ISO 8601 format, e.g., '2026-04-08' or '2026-04-08T00:00:00Z')",
35+
type=parse_datetime_with_timezone,
36+
metavar="DATE"
37+
)] = None,
38+
to_date: Annotated[DateTimeWithTimezone | None, typer.Option(
39+
"--to",
40+
help="End date/time (ISO 8601 format, e.g., '2026-04-14' or '2026-04-14T23:59:59Z')",
41+
type=parse_datetime_with_timezone,
42+
metavar="DATE"
43+
)] = None,
44+
test_path: Annotated[str | None, typer.Option(
45+
"--test-path",
46+
help="Test path filter (full path string, e.g., 'class=MyTest')",
47+
metavar="NAME"
48+
)] = None,
49+
limit: Annotated[int | None, typer.Option(
50+
"--limit",
51+
help="Max results to return per week (default: 50, max: 500)",
52+
type=intType(min=1, max=500),
53+
metavar="N"
54+
)] = None,
55+
):
56+
"""View never failing tests with weekly trends"""
57+
client = SmartTestsClient(app=app)
58+
59+
params = {}
60+
if year_week:
61+
params["year-week"] = year_week
62+
if weeks:
63+
params["weeks"] = str(weeks)
64+
if from_date:
65+
params["from"] = from_date.datetime().strftime("%Y-%m-%d")
66+
if to_date:
67+
params["to"] = to_date.datetime().strftime("%Y-%m-%d")
68+
if test_path:
69+
params["test-path"] = test_path
70+
if limit:
71+
params["limit"] = str(limit)
72+
73+
try:
74+
res = client.request("get", "view/never-failing-tests", params=params)
75+
76+
if res.status_code == HTTPStatus.NOT_FOUND:
77+
click.secho(
78+
"No never failing test data found. Check your filters and try again.",
79+
fg='yellow', err=True
80+
)
81+
sys.exit(1)
82+
83+
res.raise_for_status()
84+
response_json = res.json()
85+
86+
click.echo(json.dumps(response_json, indent=2))
87+
88+
except Exception as e:
89+
client.print_exception_and_recover(
90+
e,
91+
"Warning: failed to retrieve never failing tests from server"
92+
)
93+
sys.exit(1)

smart_tests/utils/typer_types.py

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -237,5 +237,22 @@ def _datetime_with_tz_compat(value: str):
237237
return dt_obj.dt
238238

239239

240+
def validate_iso_week(value: str) -> str:
241+
"""Validate ISO week format YYYY-Www and week number range (01-53)"""
242+
pattern = r'^\d{4}-W\d{2}$'
243+
if not re.match(pattern, value):
244+
raise BadCmdLineException(
245+
f"Invalid year-week format: '{value}'. Expected format: YYYY-Www (e.g., 2026-W15)"
246+
)
247+
248+
week_num = int(value.split('-W')[1])
249+
if week_num < 1 or week_num > 53:
250+
raise BadCmdLineException(
251+
f"Invalid week number: '{value}'. Week must be between 01 and 53"
252+
)
253+
254+
return value
255+
256+
240257
KEY_VALUE = _key_value_compat
241258
DATETIME_WITH_TZ = _datetime_with_tz_compat

0 commit comments

Comments
 (0)