Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 0 additions & 1 deletion .bazelignore
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@
.ci/micromamba
test/unit/external_repository
7 changes: 5 additions & 2 deletions BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -41,8 +41,11 @@ toolchain(
toolchain_type = ":toolchain_type",
)

# Repository root marker, used by the buildifier test to find the workspace
# Repository root marker, used by the buildifier test and external_repository test
exports_files(
["MODULE.bazel"],
visibility = ["//test/buildifier:__pkg__"],
visibility = [
"//test/buildifier:__pkg__",
"//test/unit/external_repository:__pkg__",
],
)
69 changes: 33 additions & 36 deletions test/unit/external_repository/BUILD
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
# Copyright 2023 Ericsson AB
# Copyright 2026 Ericsson AB
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
Expand All @@ -13,49 +13,46 @@
# limitations under the License.

load(
"@rules_cc//cc:defs.bzl",
"cc_binary",
"cc_library",
)
load(
"@rules_codechecker//:defs.bzl",
"codechecker_test",
"compile_commands",
"//test/unit/external_repository:external_test.bzl",
"external_test",
)

# This is the important bit -- not only do we have an external dependency here
# in the form of external_lib, but is also an implementation_dep. This is a
# tricky edge case we need to handle.
cc_library(
name = "intermediate_lib",
srcs = ["intermediate.cpp"],
hdrs = ["intermediate.h"],
implementation_deps = ["@external_lib//:lib"],
visibility = ["//visibility:public"],
exports_files([
"external_test_runner.py",
"main.cc",
"intermediate.cpp",
"intermediate.h",
])

external_test(
name = "compile_commands_isystem_test",
action = "build",
contains = [
"-isystem external/external_lib[~+]/include",
"-isystem bazel-out/k8-fastbuild/bin/external/external_lib[~+]/include",
],
output_file = "bazel-bin/compile_commands_isystem/compile_commands.json",
target = ":compile_commands_isystem",
)

cc_binary(
name = "isystem_impl_dep",
srcs = ["main.cc"],
deps = [":intermediate_lib"],
external_test(
name = "codechecker_external_deps_test",
target = ":codechecker_external_deps",
)

compile_commands(
name = "compile_commands_isystem",
targets = [
":isystem_impl_dep",
],
external_test(
name = "per_file_external_deps_test",
target = ":per_file_external_deps",
)

codechecker_test(
name = "codechecker_external_deps",
tags = ["manual"],
targets = ["isystem_impl_dep"],
external_test(
name = "codechecker_external_include_paths_test",
extra_flags = ["--features=external_include_paths"],
target = ":codechecker_external_deps",
)

codechecker_test(
name = "per_file_external_deps",
per_file = True,
tags = ["manual"],
targets = ["isystem_impl_dep"],
external_test(
name = "per_file_external_include_paths_test",
extra_flags = ["--features=external_include_paths"],
target = ":per_file_external_deps",
)
33 changes: 0 additions & 33 deletions test/unit/external_repository/MODULE.bazel

This file was deleted.

1 change: 0 additions & 1 deletion test/unit/external_repository/WORKSPACE

This file was deleted.

13 changes: 0 additions & 13 deletions test/unit/external_repository/__init__.py

This file was deleted.

116 changes: 116 additions & 0 deletions test/unit/external_repository/external_test.bzl
Original file line number Diff line number Diff line change
@@ -0,0 +1,116 @@
# Copyright 2026 Ericsson AB
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.

"""
Macro for external repository integration tests.

Each external_test() generates a py_test that:
1. Creates a temporary Bazel workspace with external dependencies
2. Runs a bazel command inside it
3. Asserts on exit code and optionally on output file contents

Example:
external_test(
name = "codechecker_external_deps_test",
target = ":codechecker_external_deps",
)

external_test(
name = "compile_commands_test",
action = "build",
target = ":compile_commands_isystem",
output_file = "bazel-bin/compile_commands_isystem/compile_commands.json",
contains = ["-isystem external/external_lib"],
)
"""

load("@rules_python//python:py_test.bzl", "py_test")

# Source files that get copied into the generated workspace root
_SRCS = [
"//test/unit/external_repository:main.cc",
"//test/unit/external_repository:intermediate.cpp",
"//test/unit/external_repository:intermediate.h",
]

def external_test(
name,
target,
action = "test",
extra_flags = [],
expected_exit_code = 0,
output_file = None,
contains = None,
tags = [],
size = "large",
**kwargs):
"""Generate a py_test that runs a bazel command in a temp workspace.

Args:
name: Test name.
target: Bazel target to act on (e.g. ":codechecker_external_deps").
action: Bazel action to run (default: "test").
extra_flags: Additional flags to pass to the bazel command.
expected_exit_code: Expected exit code (default: 0).
output_file: Optional relative path to an output file to check.
contains: Optional list of regex patterns to find in the output file.
tags: Additional test tags.
size: Test size (default: large).
**kwargs: Forwarded to py_test.
"""
if type(contains) == "string":
contains = [contains]
if type(extra_flags) == "string":
extra_flags = [extra_flags]

python_args = [
"--repo_root",
"$(rootpath //:MODULE.bazel)",
"--action",
action,
"--target",
target,
"--expected_exit_code",
str(expected_exit_code),
]

# Source files
python_args.append("--srcs")
for src in _SRCS:
python_args.append("$(rootpath {})".format(src))

# Output file assertions
if output_file:
python_args.extend(["--output_file", output_file])
if contains:
python_args.append("--contains")
python_args.extend(["'{}'".format(pat) for pat in contains])

# Extra flags go after -- to avoid argparse confusion with --flags
if extra_flags:
python_args.append("--")
python_args.extend(extra_flags)

py_test(
name = name,
srcs = ["//test/unit/external_repository:external_test_runner.py"],
main = "//test/unit/external_repository:external_test_runner.py",
args = python_args,
data = _SRCS + ["//:MODULE.bazel"],
# No other way to ensure integrated bazel can find the repository
local = True,
size = size,
tags = tags,
**kwargs
)
Loading
Loading