Skip to content

Commit 8e69766

Browse files
fniksiccopybara-github
authored andcommitted
Fix the test filter in the reported reproduction command.
Use the same regression test name in the filter as during the GoogleTest test registration. To achieve this, I had to refactor the code a little bit. PiperOrigin-RevId: 894213037
1 parent 4b43388 commit 8e69766

File tree

6 files changed

+68
-41
lines changed

6 files changed

+68
-41
lines changed

fuzztest/internal/BUILD

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -224,14 +224,12 @@ cc_library(
224224
":configuration",
225225
":corpus_database",
226226
":flag_name",
227-
":io",
228227
":registry",
229228
":runtime",
230229
"@abseil-cpp//absl/status:statusor",
231230
"@abseil-cpp//absl/strings",
232231
"@abseil-cpp//absl/strings:str_format",
233232
"@abseil-cpp//absl/strings:string_view",
234-
"@com_google_fuzztest//common:crashing_input_filename",
235233
"@com_google_fuzztest//common:logging",
236234
"@googletest//:gtest",
237235
] + select({
@@ -405,6 +403,7 @@ cc_library(
405403
"@abseil-cpp//absl/time",
406404
"@abseil-cpp//absl/types:span",
407405
"@com_google_fuzztest//common:bazel",
406+
"@com_google_fuzztest//common:crashing_input_filename",
408407
"@com_google_fuzztest//common:logging",
409408
"@com_google_fuzztest//fuzztest/internal/domains:core_domains_impl",
410409
],
@@ -417,6 +416,7 @@ cc_test(
417416
":configuration",
418417
":runtime",
419418
":test_protobuf_cc_proto",
419+
"@abseil-cpp//absl/status:statusor",
420420
"@abseil-cpp//absl/strings",
421421
"@abseil-cpp//absl/time",
422422
"@com_google_fuzztest//fuzztest:domain_core",

fuzztest/internal/CMakeLists.txt

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -185,15 +185,13 @@ fuzztest_cc_library(
185185
fuzztest::configuration
186186
fuzztest::corpus_database
187187
fuzztest::flag_name
188-
fuzztest::io
189188
fuzztest::registry
190189
fuzztest::runtime
191190
GTest::gtest
192191
absl::statusor
193192
absl::strings
194193
absl::str_format
195194
absl::string_view
196-
fuzztest::crashing_input_filename
197195
fuzztest::common_logging
198196
)
199197

@@ -359,11 +357,11 @@ fuzztest_cc_library(
359357
fuzztest::fixture_driver
360358
fuzztest::flag_name
361359
fuzztest::io
362-
fuzztest::common_logging
360+
fuzztest::logging
363361
fuzztest::printer
364362
fuzztest::registration
365-
fuzztest::seed_seq
366363
fuzztest::sanitizer_interface
364+
fuzztest::seed_seq
367365
fuzztest::serialization
368366
fuzztest::status
369367
absl::core_headers
@@ -380,7 +378,8 @@ fuzztest_cc_library(
380378
absl::time
381379
absl::span
382380
fuzztest::bazel
383-
fuzztest::logging
381+
fuzztest::common_logging
382+
fuzztest::crashing_input_filename
384383
fuzztest::core_domains_impl
385384
)
386385

@@ -393,10 +392,11 @@ fuzztest_cc_test(
393392
fuzztest::configuration
394393
fuzztest::runtime
395394
fuzztest::test_protobuf_cc_proto
395+
GTest::gmock_main
396+
absl::statusor
396397
absl::strings
397398
absl::time
398399
fuzztest::domain_core
399-
GTest::gmock_main
400400
)
401401

402402
fuzztest_cc_library(

fuzztest/internal/googletest_adaptor.cc

Lines changed: 21 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,6 @@
33

44
#include <cstdlib>
55
#include <string>
6-
#include <string_view>
76
#include <type_traits>
87
#include <utility>
98
#include <vector>
@@ -13,12 +12,10 @@
1312
#include "absl/strings/str_cat.h"
1413
#include "absl/strings/str_format.h"
1514
#include "absl/strings/string_view.h"
16-
#include "./common/crashing_input_filename.h"
1715
#include "./common/logging.h"
1816
#include "./fuzztest/internal/configuration.h"
1917
#include "./fuzztest/internal/corpus_database.h"
2018
#include "./fuzztest/internal/flag_name.h"
21-
#include "./fuzztest/internal/io.h"
2219
#include "./fuzztest/internal/registry.h"
2320
#include "./fuzztest/internal/runtime.h"
2421

@@ -48,16 +45,29 @@ namespace {
4845
template <typename T>
4946
void RegisterFuzzTestAsGTest(int* argc, char*** argv, FuzzTest& test,
5047
const Configuration& configuration,
51-
absl::string_view suffix = "") {
48+
absl::string_view crashing_input_path = "") {
5249
auto fixture_factory = [argc, argv, &test,
53-
configuration = configuration]() -> T* {
54-
return new ::fuzztest::internal::GTest_TestAdaptor(test, argc, argv,
55-
configuration);
50+
configuration = configuration]() mutable -> T* {
51+
return new ::fuzztest::internal::GTest_TestAdaptor(
52+
test, argc, argv, std::move(configuration));
5653
};
57-
const std::string test_name_with_suffix =
58-
absl::StrCat(test.test_name(), suffix);
54+
if (crashing_input_path.empty()) {
55+
::testing::RegisterTest(test.suite_name().c_str(), test.test_name().c_str(),
56+
nullptr, nullptr, test.file().c_str(), test.line(),
57+
std::move(fixture_factory));
58+
return;
59+
}
60+
const absl::StatusOr<std::string> regression_test_name =
61+
RegressionTestNameForCrashingInput(test.test_name(), crashing_input_path);
62+
if (!regression_test_name.ok()) {
63+
FUZZTEST_LOG(WARNING)
64+
<< "Failed to get regression test name for crashing input "
65+
<< crashing_input_path << ". Not registering a regression test for it. "
66+
<< "Status: " << regression_test_name.status();
67+
return;
68+
}
5969
::testing::RegisterTest(
60-
test.suite_name().c_str(), test_name_with_suffix.c_str(), nullptr,
70+
test.suite_name().c_str(), regression_test_name->c_str(), nullptr,
6171
nullptr, test.file().c_str(), test.line(), std::move(fixture_factory));
6272
}
6373

@@ -77,19 +87,7 @@ void RegisterSeparateRegressionTestForEachCrashingInput(
7787
for (const std::string& input : crash_inputs) {
7888
Configuration updated_configuration = configuration;
7989
updated_configuration.crashing_input_to_reproduce = input;
80-
absl::string_view file_name = Basename(input);
81-
const absl::StatusOr<InputFileComponents> components =
82-
ParseCrashingInputFilename(
83-
std::string_view{file_name.data(), file_name.size()});
84-
if (!components.ok()) {
85-
FUZZTEST_LOG(WARNING)
86-
<< "Failed to parse crashing input filename " << file_name
87-
<< ". Not registering a regression test for it. Status: "
88-
<< components.status();
89-
continue;
90-
}
91-
const std::string suffix = absl::StrCat("/Regression/", components->bug_id);
92-
RegisterFuzzTestAsGTest<T>(argc, argv, test, updated_configuration, suffix);
90+
RegisterFuzzTestAsGTest<T>(argc, argv, test, updated_configuration, input);
9391
}
9492
}
9593

fuzztest/internal/runtime.cc

Lines changed: 14 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@
5757
#include "absl/time/time.h"
5858
#include "absl/types/span.h"
5959
#include "./common/bazel.h"
60+
#include "./common/crashing_input_filename.h"
6061
#include "./common/logging.h"
6162
#include "./fuzztest/internal/configuration.h"
6263
#include "./fuzztest/internal/corpus_database.h"
@@ -92,11 +93,6 @@ constexpr size_t kValueMaxPrintLength = 2048;
9293
constexpr absl::string_view kTrimIndicator = " ...<value too long>";
9394
constexpr absl::string_view kReproducerDirName = "fuzztest_repro";
9495

95-
std::string GetFilterForCrashingInput(absl::string_view test_name,
96-
absl::string_view crashing_input_path) {
97-
return absl::StrCat(test_name, "/Regression/", Basename(crashing_input_path));
98-
}
99-
10096
// Returns a reproduction command for replaying
10197
// `configuration.crashing_input_to_reproduce` or `reproducer_path` from a
10298
// command line, using the `configuration.reproduction_command_template`.
@@ -130,11 +126,13 @@ std::string GetReproductionCommand(const Configuration* configuration,
130126
}
131127
std::vector<std::string> extra_args = {absl::StrCat(
132128
"--test_arg=--", FUZZTEST_FLAG_PREFIX, "corpus_database=", corpus_db)};
129+
const absl::StatusOr<std::string> test_filter =
130+
RegressionTestNameForCrashingInput(
131+
test_name, *configuration->crashing_input_to_reproduce);
132+
FUZZTEST_CHECK(test_filter.ok());
133133
return absl::StrReplaceAll(
134134
command_template,
135-
{{kTestFilterPlaceholder,
136-
GetFilterForCrashingInput(
137-
test_name, *configuration->crashing_input_to_reproduce)},
135+
{{kTestFilterPlaceholder, *test_filter},
138136
{kExtraArgsPlaceholder, absl::StrJoin(extra_args, " ")}});
139137
} else {
140138
return absl::StrReplaceAll(
@@ -1352,4 +1350,12 @@ bool FuzzTestFuzzerImpl::RunInFuzzingMode(int* /*argc*/, char*** /*argv*/,
13521350
return success;
13531351
}
13541352

1353+
absl::StatusOr<std::string> RegressionTestNameForCrashingInput(
1354+
absl::string_view test_name, absl::string_view crashing_input_path) {
1355+
absl::StatusOr<InputFileComponents> components = ParseCrashingInputFilename(
1356+
std::string_view{crashing_input_path.data(), crashing_input_path.size()});
1357+
if (!components.ok()) return std::move(components).status();
1358+
return absl::StrCat(test_name, "/Regression/", components->bug_id);
1359+
}
1360+
13551361
} // namespace fuzztest::internal

fuzztest/internal/runtime.h

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -442,8 +442,13 @@ class FuzzTestFuzzerImpl : public FuzzTestFuzzer {
442442
// A reproduction command template will include these placeholders. These
443443
// placeholders then will be replaced by the proper test filter when creating
444444
// the final reproduction command from the template.
445-
static constexpr absl::string_view kTestFilterPlaceholder = "$TEST_FILTER";
446-
static constexpr absl::string_view kExtraArgsPlaceholder = "$EXTRA_ARGS";
445+
inline constexpr absl::string_view kTestFilterPlaceholder = "$TEST_FILTER";
446+
inline constexpr absl::string_view kExtraArgsPlaceholder = "$EXTRA_ARGS";
447+
448+
// Returns the name of a regression test that replays `test_name` on the
449+
// crashing input at `crashing_input_path`.
450+
absl::StatusOr<std::string> RegressionTestNameForCrashingInput(
451+
absl::string_view test_name, absl::string_view crashing_input_path);
447452

448453
} // namespace internal
449454
} // namespace fuzztest

fuzztest/internal/runtime_test.cc

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919
#include <utility>
2020

2121
#include "gtest/gtest.h"
22+
#include "absl/status/statusor.h"
2223
#include "absl/strings/match.h"
2324
#include "absl/time/time.h"
2425
#include "./fuzztest/domain_core.h"
@@ -94,5 +95,22 @@ For reproducing findings please rely on file based reproduction.
9495
EXPECT_EQ(get_failure(), "");
9596
}
9697

98+
TEST(RegressionTestNameForCrashingInputTest,
99+
ReturnsRegressionTestNameForValidInputFilename) {
100+
const absl::StatusOr<std::string> regression_test_name =
101+
RegressionTestNameForCrashingInput("MySuite.MyTest",
102+
"/path/to/bug_id-crash_sig-input_sig");
103+
ASSERT_TRUE(regression_test_name.ok());
104+
EXPECT_EQ(*regression_test_name, "MySuite.MyTest/Regression/bug_id");
105+
}
106+
107+
TEST(RegressionTestNameForCrashingInputTest,
108+
ReturnsErrorForInvalidInputFilename) {
109+
const absl::StatusOr<std::string> regression_test_name =
110+
RegressionTestNameForCrashingInput("MySuite.MyTest",
111+
"single_dash-is_invalid");
112+
ASSERT_FALSE(regression_test_name.ok());
113+
}
114+
97115
} // namespace
98116
} // namespace fuzztest::internal

0 commit comments

Comments
 (0)