Skip to content

Commit

Permalink
Add a version of ReadFilesFromDirectory that allows filtering by file…
Browse files Browse the repository at this point in the history
… name.

Based on #1520.

PiperOrigin-RevId: 719678199
  • Loading branch information
lszekeres authored and copybara-github committed Jan 31, 2025
1 parent 44ac6c2 commit 5ecb5ef
Show file tree
Hide file tree
Showing 18 changed files with 333 additions and 188 deletions.
11 changes: 11 additions & 0 deletions common/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -207,6 +207,17 @@ cc_library(
],
)

cc_library(
name = "temp_dir",
srcs = ["temp_dir.cc"],
hdrs = ["temp_dir.h"],
deps = [
"@com_google_absl//absl/log:check",
"@com_google_absl//absl/strings",
"@com_google_absl//absl/strings:string_view",
],
)

### Tests

cc_test(
Expand Down
13 changes: 13 additions & 0 deletions common/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,19 @@ fuzztest_cc_library(
TESTONLY
)

fuzztest_cc_library(
NAME
temp_dir
HDRS
"temp_dir.h"
SRCS
"temp_dir.cc"
DEPS
absl::check
absl::string_view
absl::strings
)

### Tests

fuzztest_cc_test(
Expand Down
32 changes: 32 additions & 0 deletions common/temp_dir.cc
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
#include "./common/temp_dir.h"

#include <filesystem> // NOLINT
#include <system_error> // NOLINT

#include "absl/log/check.h"
#include "absl/strings/str_cat.h"
#include "absl/strings/string_view.h"

namespace fuzztest::internal {

namespace fs = std::filesystem;

TempDir::TempDir(absl::string_view custom_prefix) {
std::error_code error;
absl::string_view prefix = custom_prefix.empty() ? "temp_dir" : custom_prefix;
const fs::path path_template = std::filesystem::temp_directory_path(error) /
absl::StrCat(prefix, "_XXXXXX");
CHECK(!error) << "Failed to get the root temp directory path: "
<< error.message();
path_ = mkdtemp(path_template.string().data());
CHECK(std::filesystem::is_directory(path_));
}

TempDir::~TempDir() {
std::error_code error;
std::filesystem::remove_all(path_, error);
CHECK(!error) << "Unable to clean up temporary dir " << path_ << ": "
<< error.message();
}

} // namespace fuzztest::internal
28 changes: 28 additions & 0 deletions common/temp_dir.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
#ifndef FUZZTEST_COMMON_TEMP_DIR_H_
#define FUZZTEST_COMMON_TEMP_DIR_H_

#include <filesystem> // NOLINT

#include "absl/strings/string_view.h"

namespace fuzztest::internal {

// A helper class for creating a temporary directory. Removes the directory
// when it goes out of scope.
class TempDir {
public:
explicit TempDir(absl::string_view custom_prefix = "");
~TempDir();

TempDir(const TempDir& other) = delete;
TempDir& operator=(const TempDir& other) = delete;

const std::filesystem::path& path() const { return path_; }

private:
std::filesystem::path path_;
};

} // namespace fuzztest::internal

#endif // FUZZTEST_COMMON_TEMP_DIR_H_
2 changes: 2 additions & 0 deletions common/test_util.h
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ std::string GetObjDumpPath();
void PrependDirToPathEnvvar(std::string_view dir);

// Creates or clears a tmp dir in CTOR. The dir will end with `leaf` subdir.
//
// TODO(b/393384208): Merge this with TempDir in temp_dir.h.
class TempDir {
public:
explicit TempDir(std::string_view leaf1, std::string_view leaf2 = "")
Expand Down
2 changes: 2 additions & 0 deletions e2e_tests/BUILD
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ cc_test(
"@com_google_absl//absl/strings:str_format",
"@com_google_absl//absl/time",
"@com_google_fuzztest//centipede:weak_sancov_stubs",
"@com_google_fuzztest//common:temp_dir",
"@com_google_fuzztest//domain_tests:domain_testing",
"@com_google_fuzztest//fuzztest:io",
"@com_google_fuzztest//fuzztest:logging",
Expand Down Expand Up @@ -125,6 +126,7 @@ cc_test(
"@com_google_absl//absl/strings",
"@com_google_absl//absl/time",
"@com_google_fuzztest//centipede:weak_sancov_stubs",
"@com_google_fuzztest//common:temp_dir",
"@com_google_fuzztest//fuzztest:io",
"@com_google_fuzztest//fuzztest:logging",
"@com_google_fuzztest//fuzztest:subprocess",
Expand Down
1 change: 1 addition & 0 deletions e2e_tests/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ target_link_libraries(
fuzztest_subprocess
fuzztest_test_binary_util
fuzztest_type_support
fuzztest_temp_dir
re2
absl::flat_hash_map
absl::strings
Expand Down
23 changes: 12 additions & 11 deletions e2e_tests/corpus_database_test.cc
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
#include "absl/strings/str_join.h"
#include "absl/strings/string_view.h"
#include "absl/time/time.h"
#include "./common/temp_dir.h"
#include "./e2e_tests/test_binary_util.h"
#include "./fuzztest/internal/io.h"
#include "./fuzztest/internal/logging.h"
Expand Down Expand Up @@ -97,7 +98,7 @@ class UpdateCorpusDatabaseTest

static std::string GetCorpusDatabasePath() {
RunUpdateCorpusDatabase();
return std::filesystem::path(temp_dir_->dirname()) / "corpus_database";
return temp_dir_->path() / "corpus_database";
}

static absl::string_view GetUpdateCorpusDatabaseStdErr() {
Expand Down Expand Up @@ -170,7 +171,7 @@ TEST_P(UpdateCorpusDatabaseTest, ResumedFuzzTestRunsForRemainingTime) {
// 1st run that gets interrupted.
RunOptions fst_run_options;
fst_run_options.fuzztest_flags = {
{"corpus_database", corpus_database.dirname()},
{"corpus_database", corpus_database.path()},
{"fuzz_for", "300s"},
};
fst_run_options.timeout = absl::Seconds(10);
Expand All @@ -179,14 +180,14 @@ TEST_P(UpdateCorpusDatabaseTest, ResumedFuzzTestRunsForRemainingTime) {

// Adjust the fuzzing time so that only 1s remains.
const absl::StatusOr<std::string> fuzzing_time_file =
FindFile(corpus_database.dirname(), "fuzzing_time");
FindFile(corpus_database.path().c_str(), "fuzzing_time");
ASSERT_TRUE(fuzzing_time_file.ok()) << fst_std_err;
ASSERT_TRUE(WriteFile(*fuzzing_time_file, "299s"));

// 2nd run that resumes the fuzzing.
RunOptions snd_run_options;
snd_run_options.fuzztest_flags = {
{"corpus_database", corpus_database.dirname()},
{"corpus_database", corpus_database.path()},
{"fuzz_for", "300s"},
};
snd_run_options.timeout = absl::Seconds(10);
Expand All @@ -207,7 +208,7 @@ TEST_P(UpdateCorpusDatabaseTest,
// 1st run that gets interrupted.
RunOptions fst_run_options;
fst_run_options.fuzztest_flags = {
{"corpus_database", corpus_database.dirname()},
{"corpus_database", corpus_database.path()},
{"fuzz_for", "300s"},
{"execution_id", "some_execution_id"},
};
Expand All @@ -218,14 +219,14 @@ TEST_P(UpdateCorpusDatabaseTest,

// Adjust the fuzzing time so that only 1s remains.
const absl::StatusOr<std::string> fuzzing_time_file =
FindFile(corpus_database.dirname(), "fuzzing_time");
FindFile(corpus_database.path().c_str(), "fuzzing_time");
ASSERT_TRUE(fuzzing_time_file.ok()) << fst_std_err;
ASSERT_TRUE(WriteFile(*fuzzing_time_file, "299s"));

// 2nd run that should resume due to the same execution ID.
RunOptions snd_run_options;
snd_run_options.fuzztest_flags = {
{"corpus_database", corpus_database.dirname()},
{"corpus_database", corpus_database.path()},
{"fuzz_for", "300s"},
{"execution_id", "some_execution_id"},
};
Expand All @@ -246,7 +247,7 @@ TEST_P(UpdateCorpusDatabaseTest,
// exeuction with the same ID.
RunOptions thd_run_options;
thd_run_options.fuzztest_flags = {
{"corpus_database", corpus_database.dirname()},
{"corpus_database", corpus_database.path()},
{"fuzz_for", "300s"},
{"execution_id", "some_execution_id"},
};
Expand All @@ -268,7 +269,7 @@ TEST_P(UpdateCorpusDatabaseTest,
// 1st run that gets interrupted.
RunOptions fst_run_options;
fst_run_options.fuzztest_flags = {
{"corpus_database", corpus_database.dirname()},
{"corpus_database", corpus_database.path()},
{"fuzz_for", "300s"},
{"execution_id", "some_execution_id_1"},
};
Expand All @@ -281,7 +282,7 @@ TEST_P(UpdateCorpusDatabaseTest,
// This run should complete within the timeout.
RunOptions snd_run_options;
snd_run_options.fuzztest_flags = {
{"corpus_database", corpus_database.dirname()},
{"corpus_database", corpus_database.path()},
{"fuzz_for", "1s"},
{"execution_id", "some_execution_id_2"},
};
Expand All @@ -297,7 +298,7 @@ TEST_P(UpdateCorpusDatabaseTest,
// 3rd run that should not skip the test due the different execution ID
RunOptions thd_run_options;
thd_run_options.fuzztest_flags = {
{"corpus_database", corpus_database.dirname()},
{"corpus_database", corpus_database.path()},
{"fuzz_for", "300s"},
{"execution_id", "some_execution_id_3"},
};
Expand Down
Loading

0 comments on commit 5ecb5ef

Please sign in to comment.