mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-22 01:59:26 +00:00
If the shotgun tests are executed for MRs, compare it against the MR's base rather than the previous release. Only fail the job in case the performance drops (pass on performance improvements). Note that start_in optimization was removed, since it isn't properly supported with rules as of February 2025 (https://gitlab.com/gitlab-org/gitlab/-/issues/424203). Without this optimization, container test images are likely to be re-built unnecessarily when testing different protocols. A workaround for the .gitlab-ci.yml exists, but the extra complexity doesn't seem justified. The container image builds might change or be optimized in the future, so let's just go with the build duplication for now.
107 lines
3.1 KiB
Python
Executable File
107 lines
3.1 KiB
Python
Executable File
#!/usr/bin/env python3
|
|
|
|
# Copyright (C) Internet Systems Consortium, Inc. ("ISC")
|
|
#
|
|
# SPDX-License-Identifier: MPL-2.0
|
|
#
|
|
# This Source Code Form is subject to the terms of the Mozilla Public
|
|
# License, v. 2.0. If a copy of the MPL was not distributed with this
|
|
# file, you can obtain one at https://mozilla.org/MPL/2.0/.
|
|
#
|
|
# See the COPYRIGHT file distributed with this work for additional
|
|
# information regarding copyright ownership.
|
|
|
|
import os
|
|
import sys
|
|
import time
|
|
|
|
import gitlab
|
|
|
|
|
|
def init_gitlab_project():
|
|
if os.getenv("CI_SERVER_URL", None) is not None:
|
|
url = os.getenv("CI_SERVER_URL")
|
|
job_token = os.environ["CI_JOB_TOKEN"]
|
|
gl = gitlab.Gitlab(url, job_token=job_token)
|
|
else: # running locally on dev machine
|
|
gl = gitlab.Gitlab.from_config()
|
|
return gl.projects.get("isc-projects/bind9-shotgun-ci")
|
|
|
|
|
|
def parse_parent_pipeline_id():
|
|
if len(sys.argv) != 2:
|
|
raise RuntimeError("usage: util/ci-wait-shotgun.py PIPELINE_ID")
|
|
try:
|
|
return int(sys.argv[1])
|
|
except ValueError as exc:
|
|
raise RuntimeError("error: PIPELINE_ID must be a number") from exc
|
|
|
|
|
|
def wait_until(callback, timeout=1800, retry=10):
|
|
start = time.time()
|
|
while time.time() - start < timeout:
|
|
if callback():
|
|
return
|
|
time.sleep(retry)
|
|
raise RuntimeError(f"error: timed out after {timeout}s")
|
|
|
|
|
|
def get_child_pipeline_id(project, pipeline_id):
|
|
pipeline = project.pipelines.get(pipeline_id)
|
|
|
|
def pipeline_finished():
|
|
pipeline.refresh()
|
|
return pipeline.finished_at is not None
|
|
|
|
wait_until(pipeline_finished, timeout=6600)
|
|
|
|
bridges = pipeline.bridges.list()
|
|
if len(bridges) != 1:
|
|
raise RuntimeError("error: expected exactly one child pipeline")
|
|
return bridges[0].downstream_pipeline["id"]
|
|
|
|
|
|
def get_postproc_job(project, pipeline_id):
|
|
pipeline = project.pipelines.get(pipeline_id)
|
|
postproc_job = None
|
|
|
|
def job_finished():
|
|
nonlocal postproc_job
|
|
for job in pipeline.jobs.list(get_all=True):
|
|
if job.name == "postproc":
|
|
postproc_job = job
|
|
if postproc_job is None:
|
|
raise RuntimeError("error: failed to find 'postproc' job in child pipeline")
|
|
return postproc_job.finished_at is not None
|
|
|
|
wait_until(job_finished)
|
|
return postproc_job
|
|
|
|
|
|
def evaluate_postproc_job(job):
|
|
print(f"postproc job URL: {job.web_url}")
|
|
index_url = (
|
|
"https://isc-projects.gitlab-pages.isc.org/-/"
|
|
f"bind9-shotgun-ci/-/jobs/{job.id}/artifacts/index.html"
|
|
)
|
|
if job.status in ["success", "failed"]:
|
|
print(f"result for manual inspection: {index_url}")
|
|
if job.status != "success":
|
|
raise RuntimeError("error: 'postproc' job didn't succeed")
|
|
|
|
|
|
def main():
|
|
project = init_gitlab_project()
|
|
parent_pipeline_id = parse_parent_pipeline_id()
|
|
child_pipeline_id = get_child_pipeline_id(project, parent_pipeline_id)
|
|
postproc_job = get_postproc_job(project, child_pipeline_id)
|
|
evaluate_postproc_job(postproc_job)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
try:
|
|
main()
|
|
except RuntimeError as err:
|
|
print(err)
|
|
sys.exit(1)
|