crashpad/client/ios_handler/in_process_handler_test.cc
Justin Cohen afeb19f1d2 ios: Limit intermediate dump processing to 20 files.
Because the intermediate dump directory is expected to be shared,
mitigate any spamming by limiting this to 20. Prioritize our
bundle id intermediate dumps first.

Bug: crashpad: 31
Change-Id: I2888431b8bd2d94f481d2f4ec6e032882dad9698
Reviewed-on: https://chromium-review.googlesource.com/c/crashpad/crashpad/+/3261747
Commit-Queue: Justin Cohen <justincohen@chromium.org>
Reviewed-by: Mark Mentovai <mark@chromium.org>
2021-11-11 11:59:26 +00:00

151 lines
4.6 KiB
C++

// Copyright 2021 The Crashpad Authors. All rights reserved.
//
// 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.
#include "client/ios_handler/in_process_handler.h"
#include "gtest/gtest.h"
#include "test/scoped_temp_dir.h"
#include "test/test_paths.h"
#include "util/file/directory_reader.h"
#include "util/file/filesystem.h"
namespace crashpad {
namespace test {
namespace {
bool CreateFile(const base::FilePath& file) {
ScopedFileHandle fd(LoggingOpenFileForWrite(
file, FileWriteMode::kCreateOrFail, FilePermissions::kOwnerOnly));
EXPECT_TRUE(fd.is_valid());
return fd.is_valid();
}
class InProcessHandlerTest : public testing::Test {
protected:
// testing::Test:
void SetUp() override {
ASSERT_TRUE(
in_process_handler_.Initialize(temp_dir_.path(), "", {}, system_data_));
pending_dir_ = temp_dir_.path().Append("pending-serialized-ios-dump");
bundle_identifier_and_seperator_ = system_data_.BundleIdentifier() + "@";
}
const auto& path() const { return pending_dir_; }
auto& handler() { return in_process_handler_; }
void CreateFiles(int files, int other_files) {
base::FilePath::StringType file_prepend =
FILE_PATH_LITERAL(bundle_identifier_and_seperator_);
base::FilePath::StringType file_name = FILE_PATH_LITERAL("file");
for (int i = 0; i < files; i++) {
std::string i_str = std::to_string(i);
base::FilePath file(file_prepend + file_name + i_str);
CreateFile(path().Append(file));
}
for (int i = 0; i < other_files; i++) {
std::string i_str = std::to_string(i);
base::FilePath file(file_name + i_str);
CreateFile(path().Append(file));
}
}
void VerifyRemainingFileCount(int expected_files_count,
int expected_other_files_count) {
DirectoryReader reader;
ASSERT_TRUE(reader.Open(path()));
DirectoryReader::Result result;
base::FilePath filename;
int files_count = 0;
int other_files_count = 0;
while ((result = reader.NextFile(&filename)) ==
DirectoryReader::Result::kSuccess) {
bool bundle_match =
filename.value().compare(0,
bundle_identifier_and_seperator_.size(),
bundle_identifier_and_seperator_) == 0;
if (bundle_match) {
files_count++;
} else {
other_files_count++;
}
}
EXPECT_EQ(expected_files_count, files_count);
EXPECT_EQ(expected_other_files_count, other_files_count);
}
void ClearFiles() {
DirectoryReader reader;
ASSERT_TRUE(reader.Open(path()));
DirectoryReader::Result result;
base::FilePath filename;
while ((result = reader.NextFile(&filename)) ==
DirectoryReader::Result::kSuccess) {
LoggingRemoveFile(path().Append(filename));
}
}
private:
ScopedTempDir temp_dir_;
base::FilePath pending_dir_;
std::string bundle_identifier_and_seperator_;
internal::IOSSystemDataCollector system_data_;
internal::InProcessHandler in_process_handler_;
};
TEST_F(InProcessHandlerTest, TestPendingFileLimit) {
// Clear this first to blow away the pending file held by InProcessHandler.
ClearFiles();
// Only process other app files.
CreateFiles(0, 20);
handler().ProcessIntermediateDumps({});
VerifyRemainingFileCount(0, 0);
ClearFiles();
// Only process our app files.
CreateFiles(20, 20);
handler().ProcessIntermediateDumps({});
VerifyRemainingFileCount(0, 20);
ClearFiles();
// Process all of our files and 10 remaining.
CreateFiles(10, 30);
handler().ProcessIntermediateDumps({});
VerifyRemainingFileCount(0, 20);
ClearFiles();
// Process 20 our files, leaving 10 remaining, and all other files remaining.
CreateFiles(30, 10);
handler().ProcessIntermediateDumps({});
VerifyRemainingFileCount(10, 10);
ClearFiles();
CreateFiles(0, 0);
handler().ProcessIntermediateDumps({});
VerifyRemainingFileCount(0, 0);
ClearFiles();
CreateFiles(10, 0);
handler().ProcessIntermediateDumps({});
VerifyRemainingFileCount(0, 0);
ClearFiles();
}
} // namespace
} // namespace test
} // namespace crashpad