mirror of
https://gitlab.isc.org/isc-projects/bind9
synced 2025-08-22 10:10:06 +00:00
The shotgun performance tests are executed in a different repository, in a couple of different pipelines. To hide away the complexity, this script takes the pipeline ID of the triggered pipeline and then takes care of the rest - waits for the pipeline to finish, locates the child pipeline and the relevant results. The output from this script is a convenient link to the charts with the results once they're available. GitLab also has a mechanism which can wait for another pipeline. However, it can't be utilized here, since there are variables which need to be passed in when the pipeline is triggered (like protocol to be tested, load, runtime etc.). This isn't currently supported by the GitLab feature.
105 lines
3.0 KiB
Python
Executable File
105 lines
3.0 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=3000)
|
|
|
|
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):
|
|
if job.status != "success":
|
|
raise RuntimeError("error: 'postproc' job didn't succeed")
|
|
index_url = (
|
|
"https://isc-projects.gitlab-pages.isc.org/-/"
|
|
f"bind9-shotgun-ci/-/jobs/{job.id}/artifacts/index.html"
|
|
)
|
|
print(f"Result ready for manual inspection: {index_url}")
|
|
|
|
|
|
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)
|