blob: 4867e22e8c0774d1556084da41a1b3f9a02bfdc2 [file] [log] [blame]
// Copyright 2020 Google LLC
//
// 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
//
// https://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.
#include "fuzzing/replay/file_util.h"
#include <sys/stat.h>
#include <sys/types.h>
#include <cstdlib>
#include <functional>
#include <string>
#include <vector>
#include "absl/strings/str_cat.h"
#include "absl/strings/str_format.h"
#include "absl/strings/string_view.h"
#include "gmock/gmock.h"
#include "gtest/gtest.h"
namespace fuzzing {
namespace {
std::function<void(absl::string_view, const struct stat&)> CollectPathsCallback(
std::vector<std::string>* collected_paths) {
return [collected_paths](absl::string_view path, const struct stat&) {
absl::FPrintF(stderr, "Collected path: %s\n", path);
collected_paths->push_back(std::string(path));
};
}
TEST(YieldFilesTest, ReturnsEmptyResultsOnEmptyDir) {
const std::string root_dir =
absl::StrCat(getenv("TEST_TMPDIR"), "/empty-root");
ASSERT_EQ(mkdir(root_dir.c_str(), 0755), 0);
std::vector<std::string> collected_paths;
const absl::Status status =
YieldFiles(root_dir, CollectPathsCallback(&collected_paths));
EXPECT_TRUE(status.ok());
EXPECT_THAT(collected_paths, testing::IsEmpty());
}
TEST(YieldFilesTest, ReturnsErrorOnMissingDir) {
const std::string missing_dir =
absl::StrCat(getenv("TEST_TMPDIR"), "/missing");
std::vector<std::string> collected_paths;
const absl::Status status =
YieldFiles(missing_dir, CollectPathsCallback(&collected_paths));
EXPECT_FALSE(status.ok());
EXPECT_THAT(status.message(), testing::HasSubstr("could not stat"));
}
TEST(YieldFilesTest, YieldsTopLevelFiles) {
const std::string root_dir =
absl::StrCat(getenv("TEST_TMPDIR"), "/top-level-root");
ASSERT_EQ(mkdir(root_dir.c_str(), 0755), 0);
ASSERT_TRUE(SetFileContents(absl::StrCat(root_dir, "/a"), "foo").ok());
ASSERT_TRUE(SetFileContents(absl::StrCat(root_dir, "/b"), "bar").ok());
ASSERT_TRUE(SetFileContents(absl::StrCat(root_dir, "/c"), "baz").ok());
std::vector<std::string> collected_paths;
const absl::Status status =
YieldFiles(root_dir, CollectPathsCallback(&collected_paths));
EXPECT_TRUE(status.ok());
EXPECT_THAT(collected_paths, testing::SizeIs(3));
}
TEST(YieldFilesTest, YieldsDeepFiles) {
const std::string root_dir =
absl::StrCat(getenv("TEST_TMPDIR"), "/deep-root");
ASSERT_EQ(mkdir(root_dir.c_str(), 0755), 0);
const std::string child_dir = absl::StrCat(root_dir, "/child");
ASSERT_EQ(mkdir(child_dir.c_str(), 0755), 0);
const std::string leaf_dir = absl::StrCat(child_dir, "/leaf");
ASSERT_EQ(mkdir(leaf_dir.c_str(), 0755), 0);
ASSERT_TRUE(SetFileContents(absl::StrCat(root_dir, "/a"), "foo").ok());
ASSERT_TRUE(SetFileContents(absl::StrCat(child_dir, "/b"), "bar").ok());
ASSERT_TRUE(SetFileContents(absl::StrCat(leaf_dir, "/c"), "baz").ok());
ASSERT_TRUE(SetFileContents(absl::StrCat(leaf_dir, "/d"), "boo").ok());
std::vector<std::string> collected_paths;
const absl::Status status =
YieldFiles(root_dir, CollectPathsCallback(&collected_paths));
EXPECT_TRUE(status.ok());
EXPECT_THAT(collected_paths, testing::SizeIs(4));
}
} // namespace
} // namespace fuzzing