Skip to content
Open
Show file tree
Hide file tree
Changes from 2 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
38 changes: 38 additions & 0 deletions .bazelrc
Original file line number Diff line number Diff line change
Expand Up @@ -341,4 +341,42 @@ build:io_uring --//bazel:io_uring=True
test --test_env=REDPANDA_RNG_SEEDING_MODE
test --test_env=REDPANDA_DEBUG_TEST_HOOKS

# =================================
# FuzzTest (Google FuzzTest)
# =================================
# We define our own config rather than using the generated fuzztest.bazelrc
# because FuzzTest's coverage runtime (__sanitizer_cov_8bit_counters_init)
# only tracks a single counter region. The generated config instruments
# every TU via a global --copt, causing external deps to register their
# counters first and shadow our code (0 edges covered). Our config applies
# coverage only to src/v/ via per_file_copt so only Redpanda code is tracked.

# ASan (from fuzztest.bazelrc, duplicated here so we don't need try-import)
build:fuzztest --linkopt=-fsanitize=address
build:fuzztest --copt=-fsanitize=address
build:fuzztest --copt=-DADDRESS_SANITIZER

# Common fuzztest defines
build:fuzztest --copt=-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION
build:fuzztest --copt=-UNDEBUG

# Link statically
build:fuzztest --dynamic_mode=off

# Seastar requires system allocator under ASan
build:fuzztest --@seastar//:system_allocator=True
build:fuzztest --linkopt=-fsanitize-link-c++-runtime

# Coverage instrumentation ONLY for src/v/ (not global --copt).
build:fuzztest --per_file_copt=src/v/.*@-fsanitize-coverage=inline-8bit-counters
build:fuzztest --per_file_copt=src/v/.*@-fsanitize-coverage=trace-cmp
build:fuzztest --per_file_copt=src/v/.*@-fsanitize-coverage=pc-table

# Suppress warnings from FuzzTest headers included in our source files.
# Two patterns: one for files with "fuzztest" in the path (including the
# external fuzztest repo itself), one for *_pbt.cc files which include
# fuzztest headers but don't have "fuzztest" in their filename.
build --per_file_copt=.*fuzztest.*@-Wno-nullability-completeness,-Wno-unused-parameter,-Wno-deprecated-declarations,-Wno-sign-compare
build --per_file_copt=.*_pbt\.cc@-Wno-deprecated-declarations,-Wno-sign-compare,-Wno-unused-parameter,-Wno-nullability-completeness
Comment on lines +379 to +380
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The build --per_file_copt warning suppressions are applied globally (no :fuzztest config qualifier), and the .*_pbt\.cc regex is especially broad. This risks masking real warnings in non-fuzz builds and in any future file that happens to match the pattern. Prefer scoping these suppressions to a dedicated config (e.g. build:fuzztest) and/or narrowing the regex to the specific fuzz/PBT sources, or moving the suppressions into the redpanda_cc_fuzztest macro/targets via copts so they only affect fuzztest binaries.

Suggested change
build --per_file_copt=.*fuzztest.*@-Wno-nullability-completeness,-Wno-unused-parameter,-Wno-deprecated-declarations,-Wno-sign-compare
build --per_file_copt=.*_pbt\.cc@-Wno-deprecated-declarations,-Wno-sign-compare,-Wno-unused-parameter,-Wno-nullability-completeness
build:fuzztest --per_file_copt=.*fuzztest.*@-Wno-nullability-completeness,-Wno-unused-parameter,-Wno-deprecated-declarations,-Wno-sign-compare
build:fuzztest --per_file_copt=.*_pbt\.cc@-Wno-deprecated-declarations,-Wno-sign-compare,-Wno-unused-parameter,-Wno-nullability-completeness

Copilot uses AI. Check for mistakes.

try-import %workspace%/user.bazelrc
1 change: 1 addition & 0 deletions MODULE.bazel
Original file line number Diff line number Diff line change
Expand Up @@ -59,6 +59,7 @@ bazel_dep(name = "zstd", version = "1.5.7")
bazel_dep(name = "patchelf", version = "0.18.0")
bazel_dep(name = "bzip2", version = "1.0.8.bcr.2")
bazel_dep(name = "googleapis", version = "0.0.0-20250703-f9d6fe4a")
bazel_dep(name = "fuzztest", version = "20260219.0")

bazel_dep(name = "buildifier_prebuilt", version = "8.2.0.2", dev_dependency = True)
single_version_override(
Expand Down
813 changes: 403 additions & 410 deletions MODULE.bazel.lock

Large diffs are not rendered by default.

28 changes: 28 additions & 0 deletions bazel/test.bzl
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,34 @@ def redpanda_cc_fuzz_test(
custom_args = args,
)

def redpanda_cc_fuzztest(
name,
timeout,
srcs = [],
defines = [],
deps = [],
args = [],
env = {},
cpu = None,
memory = None,
data = [],
tags = []):
_redpanda_cc_unit_test(
Comment on lines +333 to +345
Copy link

Copilot AI Apr 15, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

redpanda_cc_fuzztest is named very similarly to the existing redpanda_cc_fuzz_test helper but behaves differently (unit-test wrapper vs libFuzzer-style target). This is easy to confuse at call sites and is inconsistent with the underscore-separated naming used by the other helpers in this file. Consider renaming to something more explicit (e.g. redpanda_cc_fuzztest_gtest / redpanda_cc_fuzztest_unit_test) or otherwise making the distinction unambiguous in the API.

Copilot uses AI. Check for mistakes.
dash_dash_protocol = False,
name = name,
timeout = timeout,
srcs = srcs,
defines = defines,
cpu = cpu,
memory = memory,
deps = deps,
custom_args = args,
env = env,
data = data,
local_defines = ["IS_GTEST"],
tags = tags,
)

def redpanda_cc_btest_no_seastar(
name,
timeout,
Expand Down
85 changes: 85 additions & 0 deletions fuzztest.bazelrc
Original file line number Diff line number Diff line change
@@ -0,0 +1,85 @@
### DO NOT EDIT. Generated file.
#
# To regenerate, run the following from your project's workspace:
#
# bazel run @com_google_fuzztest//bazel:setup_configs > fuzztest.bazelrc
#
# And don't forget to add the following to your project's .bazelrc:
#
# try-import %workspace%/fuzztest.bazelrc

### Common options.
#
# Do not use directly.

# Standard define for \"ifdef-ing\" any fuzz test specific code.
build:fuzztest-common --copt=-DFUZZING_BUILD_MODE_UNSAFE_FOR_PRODUCTION

# In fuzz tests, we want to catch assertion violations even in optimized builds.
build:fuzztest-common --copt=-UNDEBUG

# Enable libc++ assertions.
# See https://libcxx.llvm.org/UsingLibcxx.html#enabling-the-safe-libc-mode
build:fuzztest-common --copt=-D_LIBCPP_ENABLE_ASSERTIONS=1

### ASan (Address Sanitizer) build configuration.
#
# Use with: --config=asan

build:asan --linkopt=-fsanitize=address
build:asan --copt=-fsanitize=address

# We rely on the following flag instead of the compiler provided
# __has_feature(address_sanitizer) to know that we have an ASAN build even in
# the uninstrumented runtime.
build:asan --copt=-DADDRESS_SANITIZER

### FuzzTest build configuration.
#
# Use with: --config=fuzztest
#
# Note that this configuration includes the ASan configuration.

build:fuzztest --config=asan
build:fuzztest --config=fuzztest-common

# Link statically.
build:fuzztest --dynamic_mode=off

# We apply coverage tracking instrumentation to everything but Centipede and the
# FuzzTest framework itself (including GoogleTest and GoogleMock).
build:fuzztest --copt=-fsanitize-coverage=inline-8bit-counters,trace-cmp,pc-table
build:fuzztest --per_file_copt=common/.*,fuzztest/.*,centipede/.*,-centipede/.*fuzz_target,googletest/.*,googlemock/.*@-fsanitize-coverage=0

### Experimental FuzzTest build configuration.
#
# Use with: --config=fuzztest-experimental
#
# Use this instead of --config=fuzztest when building test binaries to run with
# Centipede. Eventually, this will be consolidated with --config=fuzztest.
# Note that this configuration doesn't include the ASan configuration. If you
# want to use both, you can use --config=fuzztest-experimental --config=asan.

build:fuzztest-experimental --config=fuzztest-common
build:fuzztest-experimental --@com_google_fuzztest//fuzztest:centipede_integration

# Generate line tables for debugging.
build:fuzztest-experimental --copt=-gline-tables-only
build:fuzztest-experimental --strip=never

# Prevent memcmp & co from being inlined.
build:fuzztest-experimental --copt=-fno-builtin

# Disable heap checking.
build:fuzztest-experimental --copt=-DHEAPCHECK_DISABLE

# Link statically.
build:fuzztest-experimental --dynamic_mode=off

# We apply coverage tracking instrumentation to everything but Centipede and the
# FuzzTest framework itself (including GoogleTest and GoogleMock).
# TODO(b/374840534): Add -fsanitize-coverage=control-flow once we start building
# with clang 16+.
build:fuzztest-experimental --copt=-fsanitize-coverage=trace-pc-guard,pc-table,trace-loads,trace-cmp
build:fuzztest-experimental --per_file_copt=common/.*,fuzztest/.*,centipede/.*,-centipede/.*fuzz_target,googletest/.*,googlemock/.*@-fsanitize-coverage=0

17 changes: 16 additions & 1 deletion src/v/container/tests/BUILD
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
load("//bazel:test.bzl", "redpanda_cc_bench", "redpanda_cc_btest", "redpanda_cc_gtest", "redpanda_test_cc_library")
load("//bazel:test.bzl", "redpanda_cc_bench", "redpanda_cc_btest", "redpanda_cc_fuzztest", "redpanda_cc_gtest", "redpanda_test_cc_library")

redpanda_cc_gtest(
name = "chunked_hash_map_test",
Expand Down Expand Up @@ -141,6 +141,21 @@ redpanda_cc_gtest(
],
)

redpanda_cc_fuzztest(
name = "chunked_pbt",
timeout = "short",
srcs = ["chunked_pbt.cc"],
cpu = 1,
memory = "128MiB",
deps = [
"//src/v/container:chunked_hash_map",
"//src/v/container:chunked_vector",
"//src/v/test_utils:fuzztest",
"@fuzztest//fuzztest",
"@googletest//:gtest",
],
)

redpanda_cc_bench(
name = "priority_queue_rpbench",
srcs = [
Expand Down
Loading