Promote RtcEventLogOutputFile to api/

Preparation for deleting PeerConnectionInterface::StartRtcEventLog
method with a PlatformFile argument.

Bug: webrtc:6463
Change-Id: Ia9fa1d99a3d87f3bf193e73382690b782ffea65c
Reviewed-on: https://webrtc-review.googlesource.com/c/src/+/135285
Commit-Queue: Niels Moller <nisse@webrtc.org>
Reviewed-by: Björn Terelius <terelius@webrtc.org>
Reviewed-by: Karl Wiberg <kwiberg@webrtc.org>
Cr-Commit-Position: refs/heads/master@{#27879}
diff --git a/api/rtc_event_log_output_file_unittest.cc b/api/rtc_event_log_output_file_unittest.cc
new file mode 100644
index 0000000..bffda0c
--- /dev/null
+++ b/api/rtc_event_log_output_file_unittest.cc
@@ -0,0 +1,168 @@
+/*
+ *  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 "absl/memory/memory.h"
+#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 =
+      absl::make_unique<RtcEventLogOutputFile>(output_file_name_);
+  EXPECT_TRUE(output_file->IsActive());
+}
+
+TEST_F(RtcEventLogOutputFileTest, DefectiveOutputsStartOutInactive) {
+  const std::string illegal_filename = "/////////";
+  auto output_file = absl::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 =
+      absl::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 =
+      absl::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 =
+      absl::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 =
+      absl::make_unique<RtcEventLogOutputFile>(output_file_name_, 2);
+  EXPECT_FALSE(output_file->Write("abc"));
+}
+
+TEST_F(RtcEventLogOutputFileTest, SuccessfulWriteReturnsTrue) {
+  auto output_file =
+      absl::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 =
+      absl::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 =
+      absl::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 = absl::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)
+TEST_F(RtcEventLogOutputFileTest, 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(RtcEventLogOutputFileTest, 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 = absl::make_unique<RtcEventLogOutputFile>(output_file_name_,
+                                                           unreasonable_size);
+  };
+  EXPECT_DEATH(create_output_file(), "");
+}
+#endif
+
+}  // namespace webrtc