You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
168 lines
6.0 KiB
168 lines
6.0 KiB
/*
|
|
* Copyright (c) 2017 The WebRTC project authors. All Rights Reserved.
|
|
*
|
|
* Use of this source code is governed by a BSD-style license
|
|
* that can be found in the LICENSE file in the root of the source
|
|
* tree. An additional intellectual property rights grant can be found
|
|
* in the file PATENTS. All contributing project authors may
|
|
* be found in the AUTHORS file in the root of the source tree.
|
|
*/
|
|
|
|
#include "api/rtc_event_log_output_file.h"
|
|
|
|
#include <fstream>
|
|
#include <iterator>
|
|
#include <memory>
|
|
#include <string>
|
|
|
|
#include "rtc_base/checks.h"
|
|
#include "test/gtest.h"
|
|
#include "test/testsupport/file_utils.h"
|
|
|
|
namespace webrtc {
|
|
|
|
class RtcEventLogOutputFileTest : public ::testing::Test {
|
|
public:
|
|
RtcEventLogOutputFileTest() : output_file_name_(GetOutputFilePath()) {
|
|
// Ensure no leftovers from previous runs, which might not have terminated
|
|
// in an orderly fashion.
|
|
remove(output_file_name_.c_str());
|
|
}
|
|
|
|
~RtcEventLogOutputFileTest() override { remove(output_file_name_.c_str()); }
|
|
|
|
protected:
|
|
std::string GetOutputFilePath() const {
|
|
auto test_info = ::testing::UnitTest::GetInstance()->current_test_info();
|
|
return test::OutputPath() + test_info->test_case_name() + test_info->name();
|
|
}
|
|
|
|
std::string GetOutputFileContents() const {
|
|
std::ifstream file(output_file_name_,
|
|
std::ios_base::in | std::ios_base::binary);
|
|
RTC_CHECK(file.is_open());
|
|
RTC_CHECK(file.good());
|
|
std::string file_str((std::istreambuf_iterator<char>(file)),
|
|
std::istreambuf_iterator<char>());
|
|
return file_str;
|
|
}
|
|
|
|
const std::string output_file_name_;
|
|
};
|
|
|
|
TEST_F(RtcEventLogOutputFileTest, NonDefectiveOutputsStartOutActive) {
|
|
auto output_file = std::make_unique<RtcEventLogOutputFile>(output_file_name_);
|
|
EXPECT_TRUE(output_file->IsActive());
|
|
}
|
|
|
|
TEST_F(RtcEventLogOutputFileTest, DefectiveOutputsStartOutInactive) {
|
|
const std::string illegal_filename = "/////////";
|
|
auto output_file = std::make_unique<RtcEventLogOutputFile>(illegal_filename);
|
|
EXPECT_FALSE(output_file->IsActive());
|
|
}
|
|
|
|
// Sanity over opening a file (by filename) with an unlimited size.
|
|
TEST_F(RtcEventLogOutputFileTest, UnlimitedOutputFile) {
|
|
const std::string output_str = "one two three";
|
|
|
|
auto output_file = std::make_unique<RtcEventLogOutputFile>(output_file_name_);
|
|
output_file->Write(output_str);
|
|
output_file.reset(); // Closing the file flushes the buffer to disk.
|
|
|
|
EXPECT_EQ(GetOutputFileContents(), output_str);
|
|
}
|
|
|
|
// Do not allow writing more bytes to the file than
|
|
TEST_F(RtcEventLogOutputFileTest, LimitedOutputFileCappedToCapacity) {
|
|
// Fit two bytes, then the third should be rejected.
|
|
auto output_file =
|
|
std::make_unique<RtcEventLogOutputFile>(output_file_name_, 2);
|
|
|
|
output_file->Write("1");
|
|
output_file->Write("2");
|
|
output_file->Write("3");
|
|
// Unsuccessful writes close the file; no need to delete the output to flush.
|
|
|
|
EXPECT_EQ(GetOutputFileContents(), "12");
|
|
}
|
|
|
|
// Make sure that calls to Write() either write everything to the file, or
|
|
// nothing (short of underlying issues in the module that handles the file,
|
|
// which would be beyond our control).
|
|
TEST_F(RtcEventLogOutputFileTest, DoNotWritePartialLines) {
|
|
const std::string output_str_1 = "0123456789";
|
|
const std::string output_str_2 = "abcdefghij";
|
|
|
|
// Set a file size limit just shy of fitting the entire second line.
|
|
const size_t size_limit = output_str_1.length() + output_str_2.length() - 1;
|
|
auto output_file =
|
|
std::make_unique<RtcEventLogOutputFile>(output_file_name_, size_limit);
|
|
|
|
output_file->Write(output_str_1);
|
|
output_file->Write(output_str_2);
|
|
// Unsuccessful writes close the file; no need to delete the output to flush.
|
|
|
|
EXPECT_EQ(GetOutputFileContents(), output_str_1);
|
|
}
|
|
|
|
TEST_F(RtcEventLogOutputFileTest, UnsuccessfulWriteReturnsFalse) {
|
|
auto output_file =
|
|
std::make_unique<RtcEventLogOutputFile>(output_file_name_, 2);
|
|
EXPECT_FALSE(output_file->Write("abc"));
|
|
}
|
|
|
|
TEST_F(RtcEventLogOutputFileTest, SuccessfulWriteReturnsTrue) {
|
|
auto output_file =
|
|
std::make_unique<RtcEventLogOutputFile>(output_file_name_, 3);
|
|
EXPECT_TRUE(output_file->Write("abc"));
|
|
}
|
|
|
|
// Even if capacity is reached, a successful write leaves the output active.
|
|
TEST_F(RtcEventLogOutputFileTest, FileStillActiveAfterSuccessfulWrite) {
|
|
auto output_file =
|
|
std::make_unique<RtcEventLogOutputFile>(output_file_name_, 3);
|
|
ASSERT_TRUE(output_file->Write("abc"));
|
|
EXPECT_TRUE(output_file->IsActive());
|
|
}
|
|
|
|
// Unsuccessful writes switch the output to inactive, even if capacity has
|
|
// not yet been reached.
|
|
TEST_F(RtcEventLogOutputFileTest, FileInactiveAfterUnsuccessfulWrite) {
|
|
auto output_file =
|
|
std::make_unique<RtcEventLogOutputFile>(output_file_name_, 2);
|
|
ASSERT_FALSE(output_file->Write("abc"));
|
|
EXPECT_FALSE(output_file->IsActive());
|
|
}
|
|
|
|
TEST_F(RtcEventLogOutputFileTest, AllowReasonableFileSizeLimits) {
|
|
auto output_file = std::make_unique<RtcEventLogOutputFile>(
|
|
output_file_name_, RtcEventLogOutputFile::kMaxReasonableFileSize);
|
|
EXPECT_TRUE(output_file->IsActive());
|
|
}
|
|
|
|
#if RTC_DCHECK_IS_ON && GTEST_HAS_DEATH_TEST && !defined(WEBRTC_ANDROID)
|
|
class RtcEventLogOutputFileDeathTest : public RtcEventLogOutputFileTest {};
|
|
|
|
TEST_F(RtcEventLogOutputFileDeathTest, WritingToInactiveFileForbidden) {
|
|
RtcEventLogOutputFile output_file(output_file_name_, 2);
|
|
ASSERT_FALSE(output_file.Write("abc"));
|
|
ASSERT_FALSE(output_file.IsActive());
|
|
EXPECT_DEATH(output_file.Write("abc"), "");
|
|
}
|
|
|
|
TEST_F(RtcEventLogOutputFileDeathTest, DisallowUnreasonableFileSizeLimits) {
|
|
// Keeping in a temporary unique_ptr to make it clearer that the death is
|
|
// triggered by construction, not destruction.
|
|
std::unique_ptr<RtcEventLogOutputFile> output_file;
|
|
auto create_output_file = [&] {
|
|
const size_t unreasonable_size =
|
|
RtcEventLogOutputFile::kMaxReasonableFileSize + 1;
|
|
output_file = std::make_unique<RtcEventLogOutputFile>(output_file_name_,
|
|
unreasonable_size);
|
|
};
|
|
EXPECT_DEATH(create_output_file(), "");
|
|
}
|
|
#endif
|
|
|
|
} // namespace webrtc
|