monitoring(testing): link test metrics to build artifacts
This commit is contained in:
parent
cc79f3ebcd
commit
c1ac36df17
@ -183,6 +183,7 @@ def _build_payload(
|
||||
failed_count: int,
|
||||
branch: str,
|
||||
build_number: str,
|
||||
jenkins_job: str,
|
||||
summary: dict | None = None,
|
||||
workspace_line_coverage_percent: float = 0.0,
|
||||
source_lines_over_500: int = 0,
|
||||
@ -195,8 +196,15 @@ def _build_payload(
|
||||
"suite": suite,
|
||||
"branch": branch or "unknown",
|
||||
"build_number": build_number or "unknown",
|
||||
"jenkins_job": jenkins_job or suite,
|
||||
}
|
||||
)
|
||||
test_case_base_labels = {
|
||||
"suite": suite,
|
||||
"branch": branch or "unknown",
|
||||
"build_number": build_number or "unknown",
|
||||
"jenkins_job": jenkins_job or suite,
|
||||
}
|
||||
lines = [
|
||||
"# TYPE platform_quality_gate_runs_total counter",
|
||||
f'platform_quality_gate_runs_total{{suite="{suite}",status="ok"}} {ok_count}',
|
||||
@ -228,12 +236,18 @@ def _build_payload(
|
||||
lines.append("# TYPE platform_quality_gate_test_case_result gauge")
|
||||
if test_cases:
|
||||
for test_name, test_status in test_cases:
|
||||
labels = {
|
||||
**test_case_base_labels,
|
||||
"test": test_name,
|
||||
"status": test_status,
|
||||
}
|
||||
lines.append(
|
||||
f'platform_quality_gate_test_case_result{{suite="{suite}",test="{_escape_label(test_name)}",status="{_escape_label(test_status)}"}} 1'
|
||||
f"platform_quality_gate_test_case_result{_label_str(labels)} 1"
|
||||
)
|
||||
else:
|
||||
labels = {**test_case_base_labels, "test": "__no_test_cases__", "status": "skipped"}
|
||||
lines.append(
|
||||
f'platform_quality_gate_test_case_result{{suite="{suite}",test="__no_test_cases__",status="skipped"}} 1'
|
||||
f"platform_quality_gate_test_case_result{_label_str(labels)} 1"
|
||||
)
|
||||
return "\n".join(lines) + "\n"
|
||||
|
||||
@ -250,6 +264,7 @@ def main() -> int:
|
||||
if branch.startswith("origin/"):
|
||||
branch = branch[len("origin/") :]
|
||||
build_number = os.getenv("BUILD_NUMBER", "")
|
||||
jenkins_job = os.getenv("JOB_NAME", "titan-iac")
|
||||
|
||||
tests = _collect_junit_totals(junit_glob)
|
||||
test_cases = _collect_junit_cases(junit_glob)
|
||||
@ -303,6 +318,7 @@ def main() -> int:
|
||||
failed_count=failed_count,
|
||||
branch=branch,
|
||||
build_number=build_number,
|
||||
jenkins_job=jenkins_job,
|
||||
summary=summary,
|
||||
workspace_line_coverage_percent=workspace_line_coverage_percent,
|
||||
source_lines_over_500=source_lines_over_500,
|
||||
|
||||
@ -920,6 +920,7 @@ def timeseries_panel(
|
||||
targets=None,
|
||||
field_overrides=None,
|
||||
description=None,
|
||||
data_links=None,
|
||||
):
|
||||
"""Return a Grafana time-series panel definition."""
|
||||
target_list = targets if targets is not None else [{"expr": expr, "refId": "A"}]
|
||||
@ -949,6 +950,8 @@ def timeseries_panel(
|
||||
panel["timeFrom"] = time_from
|
||||
if links:
|
||||
panel["links"] = links
|
||||
if data_links:
|
||||
panel["fieldConfig"]["defaults"]["links"] = data_links
|
||||
if description:
|
||||
panel["description"] = description
|
||||
return panel
|
||||
@ -1125,7 +1128,7 @@ def testing_case_variable():
|
||||
"name": "test",
|
||||
"label": "Test Case",
|
||||
"type": "query",
|
||||
"query": f'label_values(platform_quality_gate_test_case_result{{suite=~"${{suite:regex}}",test!="__no_test_cases__",{PLATFORM_TEST_EXPORT_FILTER}}}, test)',
|
||||
"query": f'label_values(platform_quality_gate_test_case_result{{suite=~"${{suite:regex}}",branch=~"${{branch:regex}}",test!="__no_test_cases__",{PLATFORM_TEST_EXPORT_FILTER}}}, test)',
|
||||
"current": {"text": "All", "value": "$__all", "selected": True},
|
||||
"options": [],
|
||||
"hide": 0,
|
||||
@ -1194,6 +1197,36 @@ def jenkins_suite_links(base_var="${jenkins_base}"):
|
||||
return links
|
||||
|
||||
|
||||
def jenkins_artifact_data_links(base_var="${jenkins_base}"):
|
||||
return [
|
||||
{
|
||||
"title": "Open build artifacts",
|
||||
"url": f"{base_var}/job/${{__field.labels.jenkins_job}}/${{__field.labels.build_number}}/artifact/",
|
||||
"targetBlank": True,
|
||||
},
|
||||
{
|
||||
"title": "Open build",
|
||||
"url": f"{base_var}/job/${{__field.labels.jenkins_job}}/${{__field.labels.build_number}}/",
|
||||
"targetBlank": True,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def jenkins_latest_artifact_data_links(base_var="${jenkins_base}"):
|
||||
return [
|
||||
{
|
||||
"title": "Open latest artifacts",
|
||||
"url": f"{base_var}/job/${{__field.labels.jenkins_job}}/lastCompletedBuild/artifact/",
|
||||
"targetBlank": True,
|
||||
},
|
||||
{
|
||||
"title": "Open Jenkins job",
|
||||
"url": f"{base_var}/job/${{__field.labels.jenkins_job}}/",
|
||||
"targetBlank": True,
|
||||
},
|
||||
]
|
||||
|
||||
|
||||
def bargauge_panel(
|
||||
panel_id,
|
||||
title,
|
||||
@ -1209,6 +1242,7 @@ def bargauge_panel(
|
||||
decimals=None,
|
||||
instant=False,
|
||||
overrides=None,
|
||||
data_links=None,
|
||||
):
|
||||
"""Return a bar gauge panel with label-aware reduction."""
|
||||
cleaned_expr = expr.strip()
|
||||
@ -1265,6 +1299,8 @@ def bargauge_panel(
|
||||
panel["fieldConfig"]["defaults"]["decimals"] = decimals
|
||||
if links:
|
||||
panel["links"] = links
|
||||
if data_links:
|
||||
panel["fieldConfig"]["defaults"]["links"] = data_links
|
||||
# Keep bars ordered by value descending for readability.
|
||||
panel["transformations"] = [
|
||||
{
|
||||
@ -3049,7 +3085,7 @@ def build_jobs_dashboard():
|
||||
coverage_metric_selector = f'__name__=~".*_quality_gate_coverage_percent",suite=~"{suite_var}",{exported}'
|
||||
workspace_coverage_selector = f'suite=~"{suite_var}",{exported}'
|
||||
smell_selector = f'suite=~"{suite_var}",{exported}'
|
||||
test_case_selector = f'suite=~"{suite_var}",test=~"{test_var}",test!="__no_test_cases__",{exported}'
|
||||
test_case_selector = f'suite=~"{suite_var}",branch=~"{branch_var}",test=~"{test_var}",test!="__no_test_cases__",{exported}'
|
||||
build_info_selector = f'suite=~"{suite_var}",branch=~"{branch_var}",{exported}'
|
||||
|
||||
suite_universe = " or ".join(
|
||||
@ -3134,28 +3170,28 @@ def build_jobs_dashboard():
|
||||
return f'({core}) or on(suite) (0 * ({suite_universe}))'
|
||||
|
||||
problematic_tests_history_core = (
|
||||
f'topk(12, sum by (suite, test) (increase(platform_quality_gate_test_case_result{{suite=~"{suite_var}",test!="__no_test_cases__",status="failed",{exported}}}[$__interval])))'
|
||||
f'topk(12, sum by (suite, test, jenkins_job) (increase(platform_quality_gate_test_case_result{{suite=~"{suite_var}",branch=~"{branch_var}",test!="__no_test_cases__",status="failed",{exported}}}[$__interval])))'
|
||||
)
|
||||
problematic_tests_history = f"({problematic_tests_history_core}) or on() vector(0)"
|
||||
worst_test_per_suite_core = (
|
||||
f'topk by (suite) (1, sum by (suite, test) (increase(platform_quality_gate_test_case_result{{suite=~"{suite_var}",test!="__no_test_cases__",status="failed",{exported}}}[30d])))'
|
||||
f'topk by (suite) (1, sum by (suite, test, jenkins_job) (increase(platform_quality_gate_test_case_result{{suite=~"{suite_var}",branch=~"{branch_var}",test!="__no_test_cases__",status="failed",{exported}}}[30d])))'
|
||||
)
|
||||
worst_test_per_suite = f"({worst_test_per_suite_core}) or on() vector(0)"
|
||||
selected_test_pass_fail = [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": f'sum by (suite) (increase(platform_quality_gate_test_case_result{{{test_case_selector},status="passed"}}[$__interval])) or on() vector(0)',
|
||||
"legendFormat": "passed · {{suite}}",
|
||||
"expr": f'sum by (suite, test, status, jenkins_job, build_number) (max_over_time(platform_quality_gate_test_case_result{{{test_case_selector},status="passed"}}[$__interval])) or on() vector(0)',
|
||||
"legendFormat": "passed · {{suite}} · #{{build_number}}",
|
||||
},
|
||||
{
|
||||
"refId": "B",
|
||||
"expr": f'sum by (suite) (increase(platform_quality_gate_test_case_result{{{test_case_selector},status="failed"}}[$__interval])) or on() vector(0)',
|
||||
"legendFormat": "failed · {{suite}}",
|
||||
"expr": f'sum by (suite, test, status, jenkins_job, build_number) (max_over_time(platform_quality_gate_test_case_result{{{test_case_selector},status="failed"}}[$__interval])) or on() vector(0)',
|
||||
"legendFormat": "failed · {{suite}} · #{{build_number}}",
|
||||
},
|
||||
{
|
||||
"refId": "C",
|
||||
"expr": f'sum by (suite) (increase(platform_quality_gate_test_case_result{{{test_case_selector},status="skipped"}}[$__interval])) or on() vector(0)',
|
||||
"legendFormat": "skipped · {{suite}}",
|
||||
"expr": f'sum by (suite, test, status, jenkins_job, build_number) (max_over_time(platform_quality_gate_test_case_result{{{test_case_selector},status="skipped"}}[$__interval])) or on() vector(0)',
|
||||
"legendFormat": "skipped · {{suite}} · #{{build_number}}",
|
||||
},
|
||||
]
|
||||
recent_branch_evidence = (
|
||||
@ -3722,6 +3758,7 @@ def build_jobs_dashboard():
|
||||
legend_placement="bottom",
|
||||
legend_calcs=["lastNotNull", "max", "sum"],
|
||||
links=jenkins_suite_links(),
|
||||
data_links=jenkins_latest_artifact_data_links(),
|
||||
)
|
||||
)
|
||||
panels.append(
|
||||
@ -3736,6 +3773,7 @@ def build_jobs_dashboard():
|
||||
legend_placement="bottom",
|
||||
legend_calcs=["lastNotNull", "sum"],
|
||||
links=jenkins_suite_links(),
|
||||
data_links=jenkins_artifact_data_links(),
|
||||
)
|
||||
)
|
||||
panels.append(
|
||||
@ -3751,6 +3789,7 @@ def build_jobs_dashboard():
|
||||
thresholds=failures_thresholds,
|
||||
limit=9,
|
||||
links=jenkins_suite_links(),
|
||||
data_links=jenkins_latest_artifact_data_links(),
|
||||
)
|
||||
)
|
||||
|
||||
@ -3962,8 +4001,8 @@ def build_jobs_dashboard():
|
||||
"templating": {
|
||||
"list": [
|
||||
testing_suite_variable(),
|
||||
testing_case_variable(),
|
||||
testing_branch_variable(),
|
||||
testing_case_variable(),
|
||||
jenkins_base_variable(),
|
||||
]
|
||||
},
|
||||
|
||||
@ -295,8 +295,11 @@ EOF
|
||||
if [ "${status}" != "ok" ]; then
|
||||
gate_glue_check="failed"
|
||||
fi
|
||||
metric_branch="$(printf '%s' "${BRANCH_NAME:-${GIT_BRANCH:-unknown}}" | jq -Rsa . | sed -e 's/^"//' -e 's/"$//')"
|
||||
metric_branch_raw="${BRANCH_NAME:-${GIT_BRANCH:-unknown}}"
|
||||
metric_branch_raw="${metric_branch_raw#origin/}"
|
||||
metric_branch="$(printf '%s' "${metric_branch_raw}" | jq -Rsa . | sed -e 's/^"//' -e 's/"$//')"
|
||||
metric_build_number="$(printf '%s' "${BUILD_NUMBER:-unknown}" | jq -Rsa . | sed -e 's/^"//' -e 's/"$//')"
|
||||
metric_jenkins_job="$(printf '%s' "${JOB_NAME:-data-prepper}" | jq -Rsa . | sed -e 's/^"//' -e 's/"$//')"
|
||||
cat <<METRICS | curl -fsS -X PUT --data-binary @- "${gateway}/metrics/job/platform-quality-ci/suite/${suite}" >/dev/null || \
|
||||
echo "warning: metrics push failed for suite=${suite}" >&2
|
||||
# TYPE platform_quality_gate_runs_total counter
|
||||
@ -312,7 +315,7 @@ platform_quality_gate_workspace_line_coverage_percent{suite="${suite}"} 0
|
||||
# TYPE platform_quality_gate_source_lines_over_500_total gauge
|
||||
platform_quality_gate_source_lines_over_500_total{suite="${suite}"} 0
|
||||
# TYPE platform_quality_gate_build_info gauge
|
||||
platform_quality_gate_build_info{suite="${suite}",branch="${metric_branch}",build_number="${metric_build_number}"} 1
|
||||
platform_quality_gate_build_info{suite="${suite}",branch="${metric_branch}",build_number="${metric_build_number}",jenkins_job="${metric_jenkins_job}"} 1
|
||||
# TYPE data_prepper_quality_gate_checks_total gauge
|
||||
data_prepper_quality_gate_checks_total{suite="${suite}",check="tests",result="not_applicable"} 1
|
||||
data_prepper_quality_gate_checks_total{suite="${suite}",check="coverage",result="not_applicable"} 1
|
||||
@ -322,7 +325,7 @@ data_prepper_quality_gate_checks_total{suite="${suite}",check="gate_glue",result
|
||||
data_prepper_quality_gate_checks_total{suite="${suite}",check="sonarqube",result="${sonarqube_check}"} 1
|
||||
data_prepper_quality_gate_checks_total{suite="${suite}",check="supply_chain",result="${supply_chain_check}"} 1
|
||||
# TYPE platform_quality_gate_test_case_result gauge
|
||||
platform_quality_gate_test_case_result{suite="${suite}",test="__no_test_cases__",status="skipped"} 1
|
||||
platform_quality_gate_test_case_result{suite="${suite}",branch="${metric_branch}",build_number="${metric_build_number}",jenkins_job="${metric_jenkins_job}",test="__no_test_cases__",status="skipped"} 1
|
||||
METRICS
|
||||
'''
|
||||
}
|
||||
|
||||
@ -2060,14 +2060,26 @@
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"expr": "(topk(12, sum by (suite, test) (increase(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",test!=\"__no_test_cases__\",status=\"failed\",exported_job=\"platform-quality-ci\"}[$__interval])))) or on() vector(0)",
|
||||
"expr": "(topk(12, sum by (suite, test, jenkins_job) (increase(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",branch=~\"${branch:regex}\",test!=\"__no_test_cases__\",status=\"failed\",exported_job=\"platform-quality-ci\"}[$__interval])))) or on() vector(0)",
|
||||
"refId": "A",
|
||||
"legendFormat": "{{suite}} \u00b7 {{test}}"
|
||||
}
|
||||
],
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"unit": "none"
|
||||
"unit": "none",
|
||||
"links": [
|
||||
{
|
||||
"title": "Open latest artifacts",
|
||||
"url": "${jenkins_base}/job/${__field.labels.jenkins_job}/lastCompletedBuild/artifact/",
|
||||
"targetBlank": true
|
||||
},
|
||||
{
|
||||
"title": "Open Jenkins job",
|
||||
"url": "${jenkins_base}/job/${__field.labels.jenkins_job}/",
|
||||
"targetBlank": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
@ -2200,23 +2212,35 @@
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "sum by (suite) (increase(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",test=~\"${test:regex}\",test!=\"__no_test_cases__\",exported_job=\"platform-quality-ci\",status=\"passed\"}[$__interval])) or on() vector(0)",
|
||||
"legendFormat": "passed \u00b7 {{suite}}"
|
||||
"expr": "sum by (suite, test, status, jenkins_job, build_number) (max_over_time(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",branch=~\"${branch:regex}\",test=~\"${test:regex}\",test!=\"__no_test_cases__\",exported_job=\"platform-quality-ci\",status=\"passed\"}[$__interval])) or on() vector(0)",
|
||||
"legendFormat": "passed \u00b7 {{suite}} \u00b7 #{{build_number}}"
|
||||
},
|
||||
{
|
||||
"refId": "B",
|
||||
"expr": "sum by (suite) (increase(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",test=~\"${test:regex}\",test!=\"__no_test_cases__\",exported_job=\"platform-quality-ci\",status=\"failed\"}[$__interval])) or on() vector(0)",
|
||||
"legendFormat": "failed \u00b7 {{suite}}"
|
||||
"expr": "sum by (suite, test, status, jenkins_job, build_number) (max_over_time(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",branch=~\"${branch:regex}\",test=~\"${test:regex}\",test!=\"__no_test_cases__\",exported_job=\"platform-quality-ci\",status=\"failed\"}[$__interval])) or on() vector(0)",
|
||||
"legendFormat": "failed \u00b7 {{suite}} \u00b7 #{{build_number}}"
|
||||
},
|
||||
{
|
||||
"refId": "C",
|
||||
"expr": "sum by (suite) (increase(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",test=~\"${test:regex}\",test!=\"__no_test_cases__\",exported_job=\"platform-quality-ci\",status=\"skipped\"}[$__interval])) or on() vector(0)",
|
||||
"legendFormat": "skipped \u00b7 {{suite}}"
|
||||
"expr": "sum by (suite, test, status, jenkins_job, build_number) (max_over_time(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",branch=~\"${branch:regex}\",test=~\"${test:regex}\",test!=\"__no_test_cases__\",exported_job=\"platform-quality-ci\",status=\"skipped\"}[$__interval])) or on() vector(0)",
|
||||
"legendFormat": "skipped \u00b7 {{suite}} \u00b7 #{{build_number}}"
|
||||
}
|
||||
],
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"unit": "none"
|
||||
"unit": "none",
|
||||
"links": [
|
||||
{
|
||||
"title": "Open build artifacts",
|
||||
"url": "${jenkins_base}/job/${__field.labels.jenkins_job}/${__field.labels.build_number}/artifact/",
|
||||
"targetBlank": true
|
||||
},
|
||||
{
|
||||
"title": "Open build",
|
||||
"url": "${jenkins_base}/job/${__field.labels.jenkins_job}/${__field.labels.build_number}/",
|
||||
"targetBlank": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
@ -2347,7 +2371,7 @@
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sort_desc((topk by (suite) (1, sum by (suite, test) (increase(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",test!=\"__no_test_cases__\",status=\"failed\",exported_job=\"platform-quality-ci\"}[30d])))) or on() vector(0))",
|
||||
"expr": "sort_desc((topk by (suite) (1, sum by (suite, test, jenkins_job) (increase(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",branch=~\"${branch:regex}\",test!=\"__no_test_cases__\",status=\"failed\",exported_job=\"platform-quality-ci\"}[30d])))) or on() vector(0))",
|
||||
"refId": "A",
|
||||
"legendFormat": "{{suite}} \u00b7 {{test}}",
|
||||
"instant": true
|
||||
@ -2378,7 +2402,19 @@
|
||||
"value": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"links": [
|
||||
{
|
||||
"title": "Open latest artifacts",
|
||||
"url": "${jenkins_base}/job/${__field.labels.jenkins_job}/lastCompletedBuild/artifact/",
|
||||
"targetBlank": true
|
||||
},
|
||||
{
|
||||
"title": "Open Jenkins job",
|
||||
"url": "${jenkins_base}/job/${__field.labels.jenkins_job}/",
|
||||
"targetBlank": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
@ -3760,10 +3796,10 @@
|
||||
"skipUrlSync": false
|
||||
},
|
||||
{
|
||||
"name": "test",
|
||||
"label": "Test Case",
|
||||
"name": "branch",
|
||||
"label": "Branch",
|
||||
"type": "query",
|
||||
"query": "label_values(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",test!=\"__no_test_cases__\",exported_job=\"platform-quality-ci\"}, test)",
|
||||
"query": "label_values(platform_quality_gate_build_info{suite=~\"${suite:regex}\",exported_job=\"platform-quality-ci\"}, branch)",
|
||||
"current": {
|
||||
"text": "All",
|
||||
"value": "$__all",
|
||||
@ -3779,10 +3815,10 @@
|
||||
"skipUrlSync": false
|
||||
},
|
||||
{
|
||||
"name": "branch",
|
||||
"label": "Branch",
|
||||
"name": "test",
|
||||
"label": "Test Case",
|
||||
"type": "query",
|
||||
"query": "label_values(platform_quality_gate_build_info{suite=~\"${suite:regex}\",exported_job=\"platform-quality-ci\"}, branch)",
|
||||
"query": "label_values(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",branch=~\"${branch:regex}\",test!=\"__no_test_cases__\",exported_job=\"platform-quality-ci\"}, test)",
|
||||
"current": {
|
||||
"text": "All",
|
||||
"value": "$__all",
|
||||
|
||||
@ -2069,14 +2069,26 @@ data:
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"expr": "(topk(12, sum by (suite, test) (increase(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",test!=\"__no_test_cases__\",status=\"failed\",exported_job=\"platform-quality-ci\"}[$__interval])))) or on() vector(0)",
|
||||
"expr": "(topk(12, sum by (suite, test, jenkins_job) (increase(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",branch=~\"${branch:regex}\",test!=\"__no_test_cases__\",status=\"failed\",exported_job=\"platform-quality-ci\"}[$__interval])))) or on() vector(0)",
|
||||
"refId": "A",
|
||||
"legendFormat": "{{suite}} \u00b7 {{test}}"
|
||||
}
|
||||
],
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"unit": "none"
|
||||
"unit": "none",
|
||||
"links": [
|
||||
{
|
||||
"title": "Open latest artifacts",
|
||||
"url": "${jenkins_base}/job/${__field.labels.jenkins_job}/lastCompletedBuild/artifact/",
|
||||
"targetBlank": true
|
||||
},
|
||||
{
|
||||
"title": "Open Jenkins job",
|
||||
"url": "${jenkins_base}/job/${__field.labels.jenkins_job}/",
|
||||
"targetBlank": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
@ -2209,23 +2221,35 @@ data:
|
||||
"targets": [
|
||||
{
|
||||
"refId": "A",
|
||||
"expr": "sum by (suite) (increase(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",test=~\"${test:regex}\",test!=\"__no_test_cases__\",exported_job=\"platform-quality-ci\",status=\"passed\"}[$__interval])) or on() vector(0)",
|
||||
"legendFormat": "passed \u00b7 {{suite}}"
|
||||
"expr": "sum by (suite, test, status, jenkins_job, build_number) (max_over_time(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",branch=~\"${branch:regex}\",test=~\"${test:regex}\",test!=\"__no_test_cases__\",exported_job=\"platform-quality-ci\",status=\"passed\"}[$__interval])) or on() vector(0)",
|
||||
"legendFormat": "passed \u00b7 {{suite}} \u00b7 #{{build_number}}"
|
||||
},
|
||||
{
|
||||
"refId": "B",
|
||||
"expr": "sum by (suite) (increase(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",test=~\"${test:regex}\",test!=\"__no_test_cases__\",exported_job=\"platform-quality-ci\",status=\"failed\"}[$__interval])) or on() vector(0)",
|
||||
"legendFormat": "failed \u00b7 {{suite}}"
|
||||
"expr": "sum by (suite, test, status, jenkins_job, build_number) (max_over_time(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",branch=~\"${branch:regex}\",test=~\"${test:regex}\",test!=\"__no_test_cases__\",exported_job=\"platform-quality-ci\",status=\"failed\"}[$__interval])) or on() vector(0)",
|
||||
"legendFormat": "failed \u00b7 {{suite}} \u00b7 #{{build_number}}"
|
||||
},
|
||||
{
|
||||
"refId": "C",
|
||||
"expr": "sum by (suite) (increase(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",test=~\"${test:regex}\",test!=\"__no_test_cases__\",exported_job=\"platform-quality-ci\",status=\"skipped\"}[$__interval])) or on() vector(0)",
|
||||
"legendFormat": "skipped \u00b7 {{suite}}"
|
||||
"expr": "sum by (suite, test, status, jenkins_job, build_number) (max_over_time(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",branch=~\"${branch:regex}\",test=~\"${test:regex}\",test!=\"__no_test_cases__\",exported_job=\"platform-quality-ci\",status=\"skipped\"}[$__interval])) or on() vector(0)",
|
||||
"legendFormat": "skipped \u00b7 {{suite}} \u00b7 #{{build_number}}"
|
||||
}
|
||||
],
|
||||
"fieldConfig": {
|
||||
"defaults": {
|
||||
"unit": "none"
|
||||
"unit": "none",
|
||||
"links": [
|
||||
{
|
||||
"title": "Open build artifacts",
|
||||
"url": "${jenkins_base}/job/${__field.labels.jenkins_job}/${__field.labels.build_number}/artifact/",
|
||||
"targetBlank": true
|
||||
},
|
||||
{
|
||||
"title": "Open build",
|
||||
"url": "${jenkins_base}/job/${__field.labels.jenkins_job}/${__field.labels.build_number}/",
|
||||
"targetBlank": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
@ -2356,7 +2380,7 @@ data:
|
||||
},
|
||||
"targets": [
|
||||
{
|
||||
"expr": "sort_desc((topk by (suite) (1, sum by (suite, test) (increase(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",test!=\"__no_test_cases__\",status=\"failed\",exported_job=\"platform-quality-ci\"}[30d])))) or on() vector(0))",
|
||||
"expr": "sort_desc((topk by (suite) (1, sum by (suite, test, jenkins_job) (increase(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",branch=~\"${branch:regex}\",test!=\"__no_test_cases__\",status=\"failed\",exported_job=\"platform-quality-ci\"}[30d])))) or on() vector(0))",
|
||||
"refId": "A",
|
||||
"legendFormat": "{{suite}} \u00b7 {{test}}",
|
||||
"instant": true
|
||||
@ -2387,7 +2411,19 @@ data:
|
||||
"value": 5
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"links": [
|
||||
{
|
||||
"title": "Open latest artifacts",
|
||||
"url": "${jenkins_base}/job/${__field.labels.jenkins_job}/lastCompletedBuild/artifact/",
|
||||
"targetBlank": true
|
||||
},
|
||||
{
|
||||
"title": "Open Jenkins job",
|
||||
"url": "${jenkins_base}/job/${__field.labels.jenkins_job}/",
|
||||
"targetBlank": true
|
||||
}
|
||||
]
|
||||
},
|
||||
"overrides": []
|
||||
},
|
||||
@ -3769,10 +3805,10 @@ data:
|
||||
"skipUrlSync": false
|
||||
},
|
||||
{
|
||||
"name": "test",
|
||||
"label": "Test Case",
|
||||
"name": "branch",
|
||||
"label": "Branch",
|
||||
"type": "query",
|
||||
"query": "label_values(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",test!=\"__no_test_cases__\",exported_job=\"platform-quality-ci\"}, test)",
|
||||
"query": "label_values(platform_quality_gate_build_info{suite=~\"${suite:regex}\",exported_job=\"platform-quality-ci\"}, branch)",
|
||||
"current": {
|
||||
"text": "All",
|
||||
"value": "$__all",
|
||||
@ -3788,10 +3824,10 @@ data:
|
||||
"skipUrlSync": false
|
||||
},
|
||||
{
|
||||
"name": "branch",
|
||||
"label": "Branch",
|
||||
"name": "test",
|
||||
"label": "Test Case",
|
||||
"type": "query",
|
||||
"query": "label_values(platform_quality_gate_build_info{suite=~\"${suite:regex}\",exported_job=\"platform-quality-ci\"}, branch)",
|
||||
"query": "label_values(platform_quality_gate_test_case_result{suite=~\"${suite:regex}\",branch=~\"${branch:regex}\",test!=\"__no_test_cases__\",exported_job=\"platform-quality-ci\"}, test)",
|
||||
"current": {
|
||||
"text": "All",
|
||||
"value": "$__all",
|
||||
|
||||
@ -330,6 +330,7 @@ def test_build_payload_includes_canonical_checks():
|
||||
failed_count=2,
|
||||
branch="main",
|
||||
build_number="42",
|
||||
jenkins_job="titan-iac",
|
||||
workspace_line_coverage_percent=95.0,
|
||||
source_lines_over_500=0,
|
||||
check_statuses={
|
||||
@ -358,6 +359,7 @@ def test_build_payload_omits_checks_block_without_check_statuses():
|
||||
failed_count=2,
|
||||
branch="",
|
||||
build_number="",
|
||||
jenkins_job="titan-iac",
|
||||
workspace_line_coverage_percent=0.0,
|
||||
source_lines_over_500=1,
|
||||
)
|
||||
|
||||
@ -49,13 +49,20 @@ def test_build_payload_includes_explicit_test_case_series():
|
||||
failed_count=1,
|
||||
branch="main",
|
||||
build_number="5",
|
||||
jenkins_job="titan-iac",
|
||||
workspace_line_coverage_percent=95.0,
|
||||
source_lines_over_500=0,
|
||||
check_statuses={"tests": "failed"},
|
||||
)
|
||||
|
||||
assert 'platform_quality_gate_test_case_result{suite="titan-iac",test="alpha::case_one",status="failed"} 1' in payload
|
||||
assert 'platform_quality_gate_test_case_result{suite="titan-iac",test="beta::case_two",status="passed"} 1' in payload
|
||||
assert (
|
||||
'platform_quality_gate_test_case_result{suite="titan-iac",branch="main",build_number="5",jenkins_job="titan-iac",test="alpha::case_one",status="failed"} 1'
|
||||
in payload
|
||||
)
|
||||
assert (
|
||||
'platform_quality_gate_test_case_result{suite="titan-iac",branch="main",build_number="5",jenkins_job="titan-iac",test="beta::case_two",status="passed"} 1'
|
||||
in payload
|
||||
)
|
||||
|
||||
|
||||
def test_main_uses_reported_coverage_and_loc_without_fallback(tmp_path: Path, monkeypatch, capsys):
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user