diff options
-rw-r--r-- | chrome/browser/media/webrtc_log_uploader.cc | 51 | ||||
-rw-r--r-- | chrome/browser/media/webrtc_log_uploader.h | 24 | ||||
-rw-r--r-- | chrome/browser/media/webrtc_log_uploader_unittest.cc | 110 | ||||
-rw-r--r-- | chrome/chrome_tests_unit.gypi | 2 |
4 files changed, 183 insertions, 4 deletions
diff --git a/chrome/browser/media/webrtc_log_uploader.cc b/chrome/browser/media/webrtc_log_uploader.cc index d369f8c7..9b915cd 100644 --- a/chrome/browser/media/webrtc_log_uploader.cc +++ b/chrome/browser/media/webrtc_log_uploader.cc @@ -4,9 +4,17 @@ #include "chrome/browser/media/webrtc_log_uploader.h" +#include "base/file_util.h" +#include "base/files/file_path.h" #include "base/logging.h" +#include "base/path_service.h" #include "base/shared_memory.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" #include "base/strings/stringprintf.h" +#include "base/time/time.h" +#include "chrome/browser/media/webrtc_log_upload_list.h" +#include "chrome/common/chrome_paths.h" #include "chrome/common/chrome_version_info.h" #include "chrome/common/partial_circular_buffer.h" #include "content/public/browser/browser_thread.h" @@ -24,6 +32,7 @@ namespace { const int kLogCountLimit = 5; const uint32 kIntermediateCompressionBufferBytes = 256 * 1024; // 256 KB +const int kLogListLimitLines = 50; const char kUploadURL[] = "https://clients2.google.com/cr/report"; const char kUploadContentType[] = "multipart/form-data"; @@ -35,13 +44,20 @@ const char kMultipartBoundary[] = WebRtcLogUploader::WebRtcLogUploader() : log_count_(0), post_data_(NULL) { + base::FilePath log_dir_path; + PathService::Get(chrome::DIR_USER_DATA, &log_dir_path); + upload_list_path_ = + log_dir_path.AppendASCII(WebRtcLogUploadList::kWebRtcLogListFilename); } -WebRtcLogUploader::~WebRtcLogUploader() { -} +WebRtcLogUploader::~WebRtcLogUploader() {} void WebRtcLogUploader::OnURLFetchComplete( const net::URLFetcher* source) { + int response_code = source->GetResponseCode(); + std::string report_id; + if (response_code == 200 && source->GetResponseAsString(&report_id)) + AddUploadedLogInfoToUploadListFile(report_id); } void WebRtcLogUploader::OnURLFetchUploadProgress( @@ -205,3 +221,34 @@ void WebRtcLogUploader::DecreaseLogCount() { DCHECK(content::BrowserThread::CurrentlyOn(content::BrowserThread::UI)); --log_count_; } + +void WebRtcLogUploader::AddUploadedLogInfoToUploadListFile( + const std::string& report_id) { + std::string contents; + bool read_ok = file_util::ReadFileToString(upload_list_path_, &contents); + DPCHECK(read_ok); + + // Limit the number of log entries to |kLogListLimitLines| - 1, to make room + // for the new entry. Each line including the last ends with a '\n', so hit + // n will be before line n-1 (from the back). + int lf_count = 0; + int i = contents.size() - 1; + for (; i >= 0 && lf_count < kLogListLimitLines; --i) { + if (contents[i] == '\n') + ++lf_count; + } + if (lf_count >= kLogListLimitLines) { + // + 1 to compensate for the for loop decrease before the conditional + // check and + 1 to get the length. + contents.erase(0, i + 2); + } + + // Write the Unix time and report ID to the log list file. + base::Time time_now = base::Time::Now(); + contents += base::DoubleToString(time_now.ToDoubleT()) + + "," + report_id + '\n'; + + int written = file_util::WriteFile(upload_list_path_, &contents[0], + contents.size()); + DPCHECK(written == static_cast<int>(contents.size())); +} diff --git a/chrome/browser/media/webrtc_log_uploader.h b/chrome/browser/media/webrtc_log_uploader.h index 2833a86..ecd53d6 100644 --- a/chrome/browser/media/webrtc_log_uploader.h +++ b/chrome/browser/media/webrtc_log_uploader.h @@ -9,6 +9,7 @@ #include <vector> #include "base/basictypes.h" +#include "base/gtest_prod_util.h" #include "base/memory/ref_counted.h" #include "base/platform_file.h" #include "net/url_request/url_fetcher_delegate.h" @@ -27,8 +28,9 @@ typedef struct z_stream_s z_stream; class WebRtcLogURLRequestContextGetter; // WebRtcLogUploader uploads WebRTC logs, keeps count of how many logs have -// been started and denies further logs if a limit is reached. There must only -// be one object of this type. +// been started and denies further logs if a limit is reached. It also adds +// the timestamp and report ID of the uploded log to a text file. There must +// only be one object of this type. class WebRtcLogUploader : public net::URLFetcherDelegate { public: WebRtcLogUploader(); @@ -60,6 +62,9 @@ class WebRtcLogUploader : public net::URLFetcherDelegate { } private: + FRIEND_TEST_ALL_PREFIXES(WebRtcLogUploaderTest, + AddUploadedLogInfoToUploadListFile); + // Sets up a multipart body to be uploaded. The body is produced according // to RFC 2046. void SetupMultipart(std::string* post_data, uint8* log_buffer, @@ -73,7 +78,22 @@ class WebRtcLogUploader : public net::URLFetcherDelegate { void ResizeForNextOutput(std::string* post_data, z_stream* stream); void DecreaseLogCount(); + // Append information (time and report ID) about this uploaded log to a log + // list file, limited to |kLogListLimitLines| entries. This list is used for + // viewing the uploaded logs under chrome://webrtc-logs, see + // WebRtcLogUploadList. The list has the format + // time,id + // time,id + // etc. + // where each line represents an uploaded log and "time" is Unix time. + void AddUploadedLogInfoToUploadListFile(const std::string& report_id); + + void SetUploadPathForTesting(const base::FilePath& path) { + upload_list_path_ = path; + } + int log_count_; + base::FilePath upload_list_path_; // For testing purposes, see OverrideUploadWithBufferForTesting. Only accessed // on the FILE thread. diff --git a/chrome/browser/media/webrtc_log_uploader_unittest.cc b/chrome/browser/media/webrtc_log_uploader_unittest.cc new file mode 100644 index 0000000..935ec60 --- /dev/null +++ b/chrome/browser/media/webrtc_log_uploader_unittest.cc @@ -0,0 +1,110 @@ +// Copyright 2013 The Chromium Authors. All rights reserved. +// Use of this source code is governed by a BSD-style license that can be +// found in the LICENSE file. + +#include <string> + +#include "base/file_util.h" +#include "base/files/file_path.h" +#include "base/logging.h" +#include "base/platform_file.h" +#include "base/strings/string_number_conversions.h" +#include "base/strings/string_split.h" +#include "base/time/time.h" +#include "chrome/browser/media/webrtc_log_uploader.h" +#include "testing/gtest/include/gtest/gtest.h" + +const char kTestReportId[] = "123456789"; +const char kTestTime[] = "987654321"; + +class WebRtcLogUploaderTest : public testing::Test { + public: + WebRtcLogUploaderTest() {} + + bool VerifyNumberOfLinesAndContentsOfLastLine(int expected_lines) { + std::string contents; + int read = file_util::ReadFileToString(test_list_path_, &contents); + EXPECT_GT(read, 0); + if (read <= 0) + return false; + + // Verify expected number of lines. Since every line should end with '\n', + // there should be an additional empty line after splitting. + std::vector<std::string> lines; + base::SplitString(contents, '\n', &lines); + EXPECT_EQ(expected_lines + 1, static_cast<int>(lines.size())); + if (expected_lines + 1 != static_cast<int>(lines.size())) + return false; + EXPECT_TRUE(lines[expected_lines].empty()); + + // Verify the contents of the last line. The time (line_parts[0]) is the + // time when the info was written to the file which we don't know, so just + // verify that it's not empty. + std::vector<std::string> line_parts; + base::SplitString(lines[expected_lines - 1], ',', &line_parts); + EXPECT_EQ(2u, line_parts.size()); + if (2u != line_parts.size()) + return false; + EXPECT_FALSE(line_parts[0].empty()); + EXPECT_STREQ(kTestReportId, line_parts[1].c_str()); + + return true; + } + + bool AddLinesToTestFile(int number_of_lines) { + int flags = base::PLATFORM_FILE_OPEN | + base::PLATFORM_FILE_APPEND; + base::PlatformFileError error = base::PLATFORM_FILE_OK; + base::PlatformFile test_list_file = + base::CreatePlatformFile(test_list_path_, flags, NULL, &error); + EXPECT_EQ(base::PLATFORM_FILE_OK, error); + EXPECT_NE(base::kInvalidPlatformFileValue, test_list_file); + if (base::PLATFORM_FILE_OK != error || + base::kInvalidPlatformFileValue == test_list_file) { + return false; + } + + for (int i = 0; i < number_of_lines; ++i) { + EXPECT_EQ(static_cast<int>(sizeof(kTestTime)) - 1, + base::WritePlatformFileAtCurrentPos(test_list_file, + kTestTime, + sizeof(kTestTime) - 1)); + EXPECT_EQ(1, base::WritePlatformFileAtCurrentPos(test_list_file, ",", 1)); + EXPECT_EQ(static_cast<int>(sizeof(kTestReportId)) - 1, + base::WritePlatformFileAtCurrentPos(test_list_file, + kTestReportId, + sizeof(kTestReportId) - 1)); + EXPECT_EQ(1, base::WritePlatformFileAtCurrentPos(test_list_file, + "\n", 1)); + } + EXPECT_TRUE(base::ClosePlatformFile(test_list_file)); + + return true; + } + + base::FilePath test_list_path_; +}; + +TEST_F(WebRtcLogUploaderTest, AddUploadedLogInfoToUploadListFile) { + ASSERT_TRUE(file_util::CreateTemporaryFile(&test_list_path_)); + scoped_ptr<WebRtcLogUploader> webrtc_log_uploader_( + new WebRtcLogUploader()); + webrtc_log_uploader_->SetUploadPathForTesting(test_list_path_); + + webrtc_log_uploader_->AddUploadedLogInfoToUploadListFile(kTestReportId); + webrtc_log_uploader_->AddUploadedLogInfoToUploadListFile(kTestReportId); + ASSERT_TRUE(VerifyNumberOfLinesAndContentsOfLastLine(2)); + + const int expected_line_limit = 50; + ASSERT_TRUE(AddLinesToTestFile(expected_line_limit - 2)); + ASSERT_TRUE(VerifyNumberOfLinesAndContentsOfLastLine(expected_line_limit)); + + webrtc_log_uploader_->AddUploadedLogInfoToUploadListFile(kTestReportId); + ASSERT_TRUE(VerifyNumberOfLinesAndContentsOfLastLine(expected_line_limit)); + + ASSERT_TRUE(AddLinesToTestFile(10)); + ASSERT_TRUE(VerifyNumberOfLinesAndContentsOfLastLine(60)); + + webrtc_log_uploader_->AddUploadedLogInfoToUploadListFile(kTestReportId); + ASSERT_TRUE(VerifyNumberOfLinesAndContentsOfLastLine(expected_line_limit)); +} diff --git a/chrome/chrome_tests_unit.gypi b/chrome/chrome_tests_unit.gypi index 5ea050e..29de0c9 100644 --- a/chrome/chrome_tests_unit.gypi +++ b/chrome/chrome_tests_unit.gypi @@ -948,6 +948,7 @@ 'browser/managed_mode/managed_user_registration_service_unittest.cc', 'browser/managed_mode/managed_user_service_unittest.cc', 'browser/managed_mode/managed_user_refresh_token_fetcher_unittest.cc', + 'browser/media/webrtc_log_uploader_unittest.cc', 'browser/media_galleries/fileapi/native_media_file_util_unittest.cc', 'browser/media_galleries/linux/mtp_device_object_enumerator_unittest.cc', 'browser/media_galleries/mac/mtp_device_delegate_impl_mac_unittest.mm', @@ -2119,6 +2120,7 @@ }], ['enable_webrtc==0', { 'sources!': [ + 'browser/media/webrtc_log_uploader_unittest.cc', 'renderer/media/chrome_webrtc_log_message_delegate_unittest.cc', ], }], |