blob: ce1174af76e74d4ccc8b742a09d0bd74fbec4d08 [file] [log] [blame]
// 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 "components/upload_list/text_log_upload_list.h"
#include <string>
#include "base/files/file_path.h"
#include "base/files/file_util.h"
#include "base/files/scoped_temp_dir.h"
#include "base/macros.h"
#include "base/memory/ref_counted.h"
#include "base/run_loop.h"
#include "base/strings/string_number_conversions.h"
#include "base/test/scoped_task_environment.h"
#include "base/time/time.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace {
const char kTestUploadTime[] = "1234567890";
const char kTestUploadId[] = "0123456789abcdef";
const char kTestLocalID[] = "fedcba9876543210";
const char kTestCaptureTime[] = "2345678901";
class TextLogUploadListTest : public testing::Test {
public:
TextLogUploadListTest() = default;
void SetUp() override {
ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
}
protected:
void WriteUploadLog(const std::string& log_data) {
ASSERT_GT(base::WriteFile(log_path(), log_data.c_str(),
static_cast<int>(log_data.size())),
0);
}
base::FilePath log_path() {
return temp_dir_.GetPath().Append(FILE_PATH_LITERAL("uploads.log"));
}
private:
base::test::ScopedTaskEnvironment scoped_task_environment_;
base::ScopedTempDir temp_dir_;
DISALLOW_COPY_AND_ASSIGN(TextLogUploadListTest);
};
// These tests test that UploadList can parse a vector of log entry strings of
// various formats to a vector of UploadInfo objects. See the UploadList
// declaration for a description of the log entry string formats.
// Test log entry string with upload time and upload ID.
// This is the format that crash reports are stored in.
TEST_F(TextLogUploadListTest, ParseUploadTimeUploadId) {
std::string test_entry = kTestUploadTime;
test_entry += ",";
test_entry.append(kTestUploadId);
WriteUploadLog(test_entry);
scoped_refptr<TextLogUploadList> upload_list =
new TextLogUploadList(log_path());
base::RunLoop run_loop;
upload_list->Load(run_loop.QuitClosure());
run_loop.Run();
std::vector<UploadList::UploadInfo> uploads;
upload_list->GetUploads(999, &uploads);
EXPECT_EQ(1u, uploads.size());
double time_double = uploads[0].upload_time.ToDoubleT();
EXPECT_STREQ(kTestUploadTime, base::DoubleToString(time_double).c_str());
EXPECT_STREQ(kTestUploadId, uploads[0].upload_id.c_str());
EXPECT_STREQ("", uploads[0].local_id.c_str());
time_double = uploads[0].capture_time.ToDoubleT();
EXPECT_STREQ("0", base::DoubleToString(time_double).c_str());
}
// Test log entry string with upload time, upload ID and local ID.
// This is the old format that WebRTC logs were stored in.
TEST_F(TextLogUploadListTest, ParseUploadTimeUploadIdLocalId) {
std::string test_entry = kTestUploadTime;
test_entry += ",";
test_entry.append(kTestUploadId);
test_entry += ",";
test_entry.append(kTestLocalID);
WriteUploadLog(test_entry);
scoped_refptr<TextLogUploadList> upload_list =
new TextLogUploadList(log_path());
base::RunLoop run_loop;
upload_list->Load(run_loop.QuitClosure());
run_loop.Run();
std::vector<UploadList::UploadInfo> uploads;
upload_list->GetUploads(999, &uploads);
EXPECT_EQ(1u, uploads.size());
double time_double = uploads[0].upload_time.ToDoubleT();
EXPECT_STREQ(kTestUploadTime, base::DoubleToString(time_double).c_str());
EXPECT_STREQ(kTestUploadId, uploads[0].upload_id.c_str());
EXPECT_STREQ(kTestLocalID, uploads[0].local_id.c_str());
time_double = uploads[0].capture_time.ToDoubleT();
EXPECT_STREQ("0", base::DoubleToString(time_double).c_str());
}
// Test log entry string with upload time, upload ID and capture time.
// This is the format that WebRTC logs that only have been uploaded only are
// stored in.
TEST_F(TextLogUploadListTest, ParseUploadTimeUploadIdCaptureTime) {
std::string test_entry = kTestUploadTime;
test_entry += ",";
test_entry.append(kTestUploadId);
test_entry += ",,";
test_entry.append(kTestCaptureTime);
WriteUploadLog(test_entry);
scoped_refptr<TextLogUploadList> upload_list =
new TextLogUploadList(log_path());
base::RunLoop run_loop;
upload_list->Load(run_loop.QuitClosure());
run_loop.Run();
std::vector<UploadList::UploadInfo> uploads;
upload_list->GetUploads(999, &uploads);
EXPECT_EQ(1u, uploads.size());
double time_double = uploads[0].upload_time.ToDoubleT();
EXPECT_STREQ(kTestUploadTime, base::DoubleToString(time_double).c_str());
EXPECT_STREQ(kTestUploadId, uploads[0].upload_id.c_str());
EXPECT_STREQ("", uploads[0].local_id.c_str());
time_double = uploads[0].capture_time.ToDoubleT();
EXPECT_STREQ(kTestCaptureTime, base::DoubleToString(time_double).c_str());
}
// Test log entry string with local ID and capture time.
// This is the format that WebRTC logs that only are stored locally are stored
// in.
TEST_F(TextLogUploadListTest, ParseLocalIdCaptureTime) {
std::string test_entry = ",,";
test_entry.append(kTestLocalID);
test_entry += ",";
test_entry.append(kTestCaptureTime);
WriteUploadLog(test_entry);
scoped_refptr<TextLogUploadList> upload_list =
new TextLogUploadList(log_path());
base::RunLoop run_loop;
upload_list->Load(run_loop.QuitClosure());
run_loop.Run();
std::vector<UploadList::UploadInfo> uploads;
upload_list->GetUploads(999, &uploads);
EXPECT_EQ(1u, uploads.size());
double time_double = uploads[0].upload_time.ToDoubleT();
EXPECT_STREQ("0", base::DoubleToString(time_double).c_str());
EXPECT_STREQ("", uploads[0].upload_id.c_str());
EXPECT_STREQ(kTestLocalID, uploads[0].local_id.c_str());
time_double = uploads[0].capture_time.ToDoubleT();
EXPECT_STREQ(kTestCaptureTime, base::DoubleToString(time_double).c_str());
}
// Test log entry string with upload time, upload ID, local ID and capture
// time.
// This is the format that WebRTC logs that are stored locally and have been
// uploaded are stored in.
TEST_F(TextLogUploadListTest, ParseUploadTimeUploadIdLocalIdCaptureTime) {
std::string test_entry = kTestUploadTime;
test_entry += ",";
test_entry.append(kTestUploadId);
test_entry += ",";
test_entry.append(kTestLocalID);
test_entry += ",";
test_entry.append(kTestCaptureTime);
WriteUploadLog(test_entry);
scoped_refptr<TextLogUploadList> upload_list =
new TextLogUploadList(log_path());
base::RunLoop run_loop;
upload_list->Load(run_loop.QuitClosure());
run_loop.Run();
std::vector<UploadList::UploadInfo> uploads;
upload_list->GetUploads(999, &uploads);
EXPECT_EQ(1u, uploads.size());
double time_double = uploads[0].upload_time.ToDoubleT();
EXPECT_STREQ(kTestUploadTime, base::DoubleToString(time_double).c_str());
EXPECT_STREQ(kTestUploadId, uploads[0].upload_id.c_str());
EXPECT_STREQ(kTestLocalID, uploads[0].local_id.c_str());
time_double = uploads[0].capture_time.ToDoubleT();
EXPECT_STREQ(kTestCaptureTime, base::DoubleToString(time_double).c_str());
}
TEST_F(TextLogUploadListTest, ParseMultipleEntries) {
std::string test_entry;
for (int i = 1; i <= 4; ++i) {
test_entry.append(kTestUploadTime);
test_entry += ",";
test_entry.append(kTestUploadId);
test_entry += ",";
test_entry.append(kTestLocalID);
test_entry += ",";
test_entry.append(kTestCaptureTime);
test_entry += "\n";
}
WriteUploadLog(test_entry);
scoped_refptr<TextLogUploadList> upload_list =
new TextLogUploadList(log_path());
base::RunLoop run_loop;
upload_list->Load(run_loop.QuitClosure());
run_loop.Run();
std::vector<UploadList::UploadInfo> uploads;
upload_list->GetUploads(999, &uploads);
EXPECT_EQ(4u, uploads.size());
for (size_t i = 0; i < uploads.size(); ++i) {
double time_double = uploads[i].upload_time.ToDoubleT();
EXPECT_STREQ(kTestUploadTime, base::DoubleToString(time_double).c_str());
EXPECT_STREQ(kTestUploadId, uploads[i].upload_id.c_str());
EXPECT_STREQ(kTestLocalID, uploads[i].local_id.c_str());
time_double = uploads[i].capture_time.ToDoubleT();
EXPECT_STREQ(kTestCaptureTime, base::DoubleToString(time_double).c_str());
}
}
TEST_F(TextLogUploadListTest, ParseWithState) {
std::string test_entry;
for (int i = 1; i <= 4; ++i) {
test_entry.append(kTestUploadTime);
test_entry += ",";
test_entry.append(kTestUploadId);
test_entry += ",";
test_entry.append(kTestLocalID);
test_entry += ",";
test_entry.append(kTestCaptureTime);
test_entry += ",";
test_entry.append(base::IntToString(
static_cast<int>(UploadList::UploadInfo::State::Uploaded)));
test_entry += "\n";
}
WriteUploadLog(test_entry);
scoped_refptr<TextLogUploadList> upload_list =
new TextLogUploadList(log_path());
base::RunLoop run_loop;
upload_list->Load(run_loop.QuitClosure());
run_loop.Run();
std::vector<UploadList::UploadInfo> uploads;
upload_list->GetUploads(999, &uploads);
EXPECT_EQ(4u, uploads.size());
for (size_t i = 0; i < uploads.size(); ++i) {
double time_double = uploads[i].upload_time.ToDoubleT();
EXPECT_STREQ(kTestUploadTime, base::DoubleToString(time_double).c_str());
EXPECT_STREQ(kTestUploadId, uploads[i].upload_id.c_str());
EXPECT_STREQ(kTestLocalID, uploads[i].local_id.c_str());
time_double = uploads[i].capture_time.ToDoubleT();
EXPECT_STREQ(kTestCaptureTime, base::DoubleToString(time_double).c_str());
EXPECT_EQ(UploadList::UploadInfo::State::Uploaded, uploads[i].state);
}
}
// https://crbug.com/597384
TEST_F(TextLogUploadListTest, SimultaneousAccess) {
std::string test_entry = kTestUploadTime;
test_entry += ",";
test_entry.append(kTestUploadId);
test_entry += ",";
test_entry.append(kTestLocalID);
test_entry += ",";
test_entry.append(kTestCaptureTime);
WriteUploadLog(test_entry);
scoped_refptr<TextLogUploadList> upload_list =
new TextLogUploadList(log_path());
// Queue up a bunch of loads, waiting only for the first one to complete.
base::RunLoop run_loop;
upload_list->Load(run_loop.QuitClosure());
run_loop.Run();
for (int i = 1; i <= 20; ++i) {
upload_list->Load(base::OnceClosure());
}
// Read the list a few times to try and race one of the loads above.
for (int i = 1; i <= 4; ++i) {
std::vector<UploadList::UploadInfo> uploads;
upload_list->GetUploads(999, &uploads);
EXPECT_EQ(1u, uploads.size());
double time_double = uploads[0].upload_time.ToDoubleT();
EXPECT_STREQ(kTestUploadTime, base::DoubleToString(time_double).c_str());
EXPECT_STREQ(kTestUploadId, uploads[0].upload_id.c_str());
EXPECT_STREQ(kTestLocalID, uploads[0].local_id.c_str());
time_double = uploads[0].capture_time.ToDoubleT();
EXPECT_STREQ(kTestCaptureTime, base::DoubleToString(time_double).c_str());
}
}
} // namespace