diff --git a/buildbot/pipeline/__init__.py b/buildbot/pipeline/__init__.py index 336bac2..e02c6ac 100644 --- a/buildbot/pipeline/__init__.py +++ b/buildbot/pipeline/__init__.py @@ -14,6 +14,7 @@ import pipeline.code_benchmark import pipeline.code_deploy import pipeline.code_bpy_deploy import pipeline.code_store +import pipeline.code_test_coverage import pipeline.doc_api import pipeline.doc_manual import pipeline.doc_developer @@ -30,6 +31,7 @@ def populate(devops_env_id): pipeline.code_deploy, pipeline.code_bpy_deploy, pipeline.code_store, + pipeline.code_test_coverage, pipeline.doc_api, pipeline.doc_manual, pipeline.doc_developer, diff --git a/buildbot/pipeline/code_test_coverage.py b/buildbot/pipeline/code_test_coverage.py new file mode 100644 index 0000000..7db305e --- /dev/null +++ b/buildbot/pipeline/code_test_coverage.py @@ -0,0 +1,74 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: 2011-2024 Blender Authors +# + +import pathlib +from functools import partial + +import buildbot.plugins +from buildbot.plugins import steps as plugins_steps + +import conf.branches +import conf.worker +import pipeline.common + + +def create_deliver_step(devops_env_id): + worker_config = conf.worker.get_config(devops_env_id) + + file_size_in_mb = 500 * 1024 * 1024 + worker_source_path = pathlib.Path(f"../../../../git/blender-vdev/build_debug/coverage/report") + master_dest_path = worker_config.buildbot_download_folder / "daily" / "coverage" + + return plugin_steps.DirectoryUpload( + name="deliver", + maxsize=file_size_in_mb, + workersrc=f"{worker_source_path}", + masterdst=f"{master_dest_path}", + ) + + +def populate(devops_env_id): + properties = [ + buildbot.plugins.util.StringParameter( + name="commit_id", + label="Commit:", + required=True, + size=80, + default="HEAD", + ), + buildbot.plugins.util.BooleanParameter( + name="needs_gpu_binaries", + label="GPU binaries -> build Cycles GPU kernels", + required=True, + strict=True, + default=True, + hide=True, + ), + ] + + return pipeline.common.create_pipeline( + devops_env_id, + "code-test-coverage", + "code_test_coverage.py", + [ + "configure-machine", + "update-code", + "compile-code", + "compile-install", + "test-code", + "coverage", + partial(create_deliver_step, devops_env_id), + "clean", + ], + {"vdev": "main"}, + properties, + "blender.git", + ["linux-x86_64-code-gpu"], + # Compile GPU step needs a long timeout. + default_step_timeout_in_seconds=90 * 60, + variations=["linux"], + nightly_properties={"commit_id": "HEAD", "needs_gpu_binaries": True}, + hour=7, + minute=30, + ) diff --git a/buildbot/worker/blender/__init__.py b/buildbot/worker/blender/__init__.py index 57e78d3..e181dc4 100644 --- a/buildbot/worker/blender/__init__.py +++ b/buildbot/worker/blender/__init__.py @@ -22,6 +22,7 @@ class CodeBuilder(worker.utils.Builder): self.needs_gpu_binaries = args.needs_gpu_binaries self.needs_gpu_tests = args.needs_gpu_tests self.needs_ninja = True + self.needs_code_coverage = False self.python_module = args.python_module self.build_configuration = args.build_configuration diff --git a/buildbot/worker/blender/compile.py b/buildbot/worker/blender/compile.py index 7319ae5..bae8f97 100644 --- a/buildbot/worker/blender/compile.py +++ b/buildbot/worker/blender/compile.py @@ -218,6 +218,14 @@ def get_cmake_options(builder: worker.blender.CodeBuilder) -> worker.utils.CmdSe options += [f"-DWITH_GTESTS={with_gtests_state}"] + with_code_coverage = "ON" if builder.needs_code_coverage else "OFF" + options += [f"-DWITH_COMPILER_CODE_COVERAGE={with_code_coverage}"] + + # TODO: Remove before merge. + options += ["-DWITH_CYCLES_DEVICE_OPTIX=OFF"] + options += ["-DWITH_JACK=OFF"] + options += ["-DWITH_PULSEAUDIO=OFF"] + if builder.platform == "windows": if builder.architecture != "arm64": # CUDA + HIP + oneAPI on Windows diff --git a/buildbot/worker/blender/test_coverage.py b/buildbot/worker/blender/test_coverage.py new file mode 100644 index 0000000..7dc0627 --- /dev/null +++ b/buildbot/worker/blender/test_coverage.py @@ -0,0 +1,27 @@ +# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: 2011-2024 Blender Authors +# + +import os +import pathlib +import sys + +import conf.worker + +import worker.blender +import worker.utils + + +def test_coverage(builder: worker.blender.CodeBuilder) -> None: + builder.setup_build_environment() + os.chdir(builder.build_dir) + + coverage_script = builder.blender_dir / "tests" / "coverage" / "coverage.py" + + cmd = [ + sys.executable, + coverage_script, + "report", + "--no-browser", + ] + worker.utils.call(cmd) diff --git a/buildbot/worker/code_test_coverage.py b/buildbot/worker/code_test_coverage.py new file mode 100755 index 0000000..65a4556 --- /dev/null +++ b/buildbot/worker/code_test_coverage.py @@ -0,0 +1,46 @@ +#!/usr/bin/env python3 +# SPDX-License-Identifier: GPL-2.0-or-later +# SPDX-FileCopyrightText: 2011-2024 Blender Authors +# + +import argparse +import pathlib +import sys + +from collections import OrderedDict + +sys.path.append(str(pathlib.Path(__file__).resolve().parent.parent)) + +import worker.configure +import worker.utils + +import worker.blender +import worker.blender.test_coverage +import worker.blender.compile +import worker.blender.update +import worker.blender.test + + +class TestCoverageBuilder(worker.blender.CodeBuilder): + def __init__(self, args: argparse.Namespace): + super().__init__(args) + self.needs_code_coverage = True + self.setup_track_path() + + +if __name__ == "__main__": + steps: worker.utils.BuilderSteps = OrderedDict() + steps["configure-machine"] = worker.configure.configure_machine + steps["update-code"] = worker.blender.update.update + steps["compile-code"] = worker.blender.compile.compile_code + steps["compile-install"] = worker.blender.compile.compile_install + steps["test-code"] = worker.blender.test.test + steps["coverage"] = worker.blender.test_coverage.test_coverage + steps["clean"] = worker.blender.CodeBuilder.clean + + parser = worker.blender.create_argument_parser(steps=steps) + + args = parser.parse_args() + args.build_configuration = "debug" + builder = TestCoverageBuilder(args) + builder.run(args.step, steps)