| Index: chrome/browser/extensions/api/feedback_private/feedback_private_api_unittest.cc
|
| diff --git a/chrome/browser/extensions/api/feedback_private/feedback_private_api_unittest.cc b/chrome/browser/extensions/api/feedback_private/feedback_private_api_unittest.cc
|
| new file mode 100644
|
| index 0000000000000000000000000000000000000000..583bcd5d6c43e9caf09a43635ebb7634d8d8caab
|
| --- /dev/null
|
| +++ b/chrome/browser/extensions/api/feedback_private/feedback_private_api_unittest.cc
|
| @@ -0,0 +1,242 @@
|
| +// 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 "chrome/browser/extensions/api/feedback_private/feedback_private_api.h"
|
| +
|
| +#include "base/macros.h"
|
| +#include "base/message_loop/message_loop.h"
|
| +#include "base/strings/stringprintf.h"
|
| +#include "base/task_scheduler/post_task.h"
|
| +#include "base/values.h"
|
| +#include "chrome/browser/extensions/api/feedback_private/log_source_resource.h"
|
| +#include "chrome/browser/extensions/api/feedback_private/single_log_source_factory.h"
|
| +#include "extensions/browser/api_unittest.h"
|
| +
|
| +namespace extensions {
|
| +
|
| +namespace {
|
| +
|
| +using api::feedback_private::ReadLogSourceParams;
|
| +using system_logs::SingleLogSource;
|
| +using system_logs::SystemLogsResponse;
|
| +using SupportedSource = system_logs::SingleLogSource::SupportedSource;
|
| +
|
| +// A dummy SingleLogSource that does not require real system logs to be
|
| +// available during testing.
|
| +class TestSingleLogSource : public SingleLogSource {
|
| + public:
|
| + explicit TestSingleLogSource(SupportedSource type)
|
| + : SingleLogSource(type), call_count_(0) {}
|
| +
|
| + ~TestSingleLogSource() override {}
|
| +
|
| + // Fetch() will return a single different string each time, in the following
|
| + // sequence: "a", "bb", "ccc", until a string of 26 z's. Will never return an
|
| + // empty result.
|
| + void Fetch(const system_logs::SysLogsSourceCallback& callback) override {
|
| + int count_modulus = call_count_ % kNumCharsToIterate;
|
| + std::string result(count_modulus + 1, kInitialChar + count_modulus);
|
| + CHECK_GT(result.size(), 0U);
|
| + ++call_count_;
|
| +
|
| + SystemLogsResponse* result_map = new SystemLogsResponse;
|
| + result_map->emplace("", result);
|
| +
|
| + // Do not directly pass the result to the callback, because that's not how
|
| + // log sources actually work. Instead, simulate the asynchronous operation
|
| + // of a SingleLogSource by invoking the callback separately.
|
| + base::PostDelayedTaskWithTraits(
|
| + FROM_HERE, base::TaskPriority::BACKGROUND,
|
| + base::Bind(callback, base::Owned(result_map)),
|
| + base::TimeDelta::FromMilliseconds(0));
|
| + }
|
| +
|
| + // Instantiates a new instance of this class. Does not retain ownership. Used
|
| + // to create a Callback that can be used to override the default behavior of
|
| + // SingleLogSourceFactory.
|
| + static SingleLogSource* Create(SupportedSource type) {
|
| + return new TestSingleLogSource(type);
|
| + }
|
| +
|
| + private:
|
| + // Iterate over the whole lowercase alphabet, starting from 'a'.
|
| + const int kNumCharsToIterate = 26;
|
| + const char kInitialChar = 'a';
|
| +
|
| + // Keep track of how many times Fetch() has been called, in order to determine
|
| + // its behavior each time.
|
| + int call_count_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(TestSingleLogSource);
|
| +};
|
| +
|
| +} // namespace
|
| +
|
| +class FeedbackApiUnittest : public ApiUnitTest {
|
| + public:
|
| + FeedbackApiUnittest()
|
| + : create_callback_(base::Bind(&TestSingleLogSource::Create)) {}
|
| + ~FeedbackApiUnittest() override {}
|
| +
|
| + void SetUp() override {
|
| + ApiUnitTest::SetUp();
|
| +
|
| + SingleLogSourceFactory::InitForTesting(&create_callback_);
|
| + }
|
| +
|
| + void TearDown() override {
|
| + SingleLogSourceFactory::InitForTesting(nullptr);
|
| + LogSourceAccessManager::SetRateLimitingTimeoutForTesting(nullptr);
|
| +
|
| + ApiUnitTest::TearDown();
|
| + }
|
| +
|
| + // Runs the feedbackPrivate.readLogSource() function. See API function
|
| + // definition for argument descriptions. Attempts to interpret the result as
|
| + // the following ListValue:
|
| + // [ int result_reader_id, [ string result_string ] ].
|
| + //
|
| + // Note that the second argument of the result is a list of strings, but the
|
| + // test class TestSingleLogSource always returns a list containing a single
|
| + // string.
|
| + //
|
| + // If the result does follow the above format, returns the reader ID and
|
| + // string value.
|
| + //
|
| + // Returns failure if the result does not conform to the above format, or is
|
| + // otherwise invalid.
|
| + testing::AssertionResult RunReadLogSourceFunction(
|
| + const ReadLogSourceParams& params,
|
| + int* result_reader_id,
|
| + std::string* result_string) {
|
| + std::unique_ptr<base::Value> result = RunFunctionAndReturnValue(
|
| + new FeedbackPrivateReadLogSourceFunction(),
|
| + ParamsToJSON(params));
|
| +
|
| + if (!result)
|
| + return testing::AssertionFailure() << "No result";
|
| +
|
| + base::ListValue* list = nullptr;
|
| + if (!result->GetAsList(&list)) {
|
| + return testing::AssertionFailure() << "Result was not a list.";
|
| + }
|
| + if (list->GetSize() != 2) {
|
| + return testing::AssertionFailure() << "Expected result length=2, actual="
|
| + << list->GetSize();
|
| + }
|
| + if (!list->GetInteger(0, result_reader_id)) {
|
| + return testing::AssertionFailure() << "Could not read argument 0 as int.";
|
| + }
|
| +
|
| + base::ListValue* string_list = nullptr;
|
| + if (!list->GetList(1, &string_list)) {
|
| + return testing::AssertionFailure()
|
| + << "Could not read argument 1 as list.";
|
| + }
|
| + if (string_list->GetSize() != 1) {
|
| + return testing::AssertionFailure()
|
| + << "Argument 1 list expected to have size=1, actual="
|
| + << string_list->GetSize();
|
| + }
|
| + if (!string_list->GetString(0, result_string)) {
|
| + return testing::AssertionFailure()
|
| + << "Could not read argument 1 list's argument 0 as string.";
|
| + }
|
| +
|
| + return testing::AssertionSuccess();
|
| + }
|
| +
|
| + private:
|
| + // Converts |params| to a string containing a JSON dictionary within an
|
| + // argument list.
|
| + std::string ParamsToJSON(const ReadLogSourceParams& params) {
|
| + return base::StringPrintf(
|
| + "[{\"source\": \"%s\","
|
| + " \"incremental\": %s,"
|
| + " \"readerId\": %u}]",
|
| + api::feedback_private::ToString(params.source).c_str(),
|
| + params.incremental ? "true" : "false",
|
| + params.reader_id ? *params.reader_id : 0);
|
| + }
|
| +
|
| + SingleLogSourceFactory::CreateCallback create_callback_;
|
| +
|
| + DISALLOW_COPY_AND_ASSIGN(FeedbackApiUnittest);
|
| +};
|
| +
|
| +TEST_F(FeedbackApiUnittest, ReadLogSourceNonIncremental) {
|
| + const base::TimeDelta timeout(base::TimeDelta::FromMilliseconds(0));
|
| + LogSourceAccessManager::SetRateLimitingTimeoutForTesting(&timeout);
|
| +
|
| + ReadLogSourceParams params;
|
| + params.source = api::feedback_private::LOG_SOURCE_MESSAGES;
|
| + params.incremental = false;
|
| +
|
| + // Test multiple non-incremental reads.
|
| + int result_reader_id = -1;
|
| + std::string result_string;
|
| + EXPECT_TRUE(
|
| + RunReadLogSourceFunction(params, &result_reader_id, &result_string));
|
| + EXPECT_EQ(0, result_reader_id);
|
| + EXPECT_EQ("a", result_string);
|
| +
|
| + result_reader_id = -1;
|
| + result_string.clear();
|
| + EXPECT_TRUE(
|
| + RunReadLogSourceFunction(params, &result_reader_id, &result_string));
|
| + EXPECT_EQ(0, result_reader_id);
|
| + EXPECT_EQ("a", result_string);
|
| +
|
| + result_reader_id = -1;
|
| + result_string.clear();
|
| + EXPECT_TRUE(
|
| + RunReadLogSourceFunction(params, &result_reader_id, &result_string));
|
| + EXPECT_EQ(0, result_reader_id);
|
| + EXPECT_EQ("a", result_string);
|
| +}
|
| +
|
| +TEST_F(FeedbackApiUnittest, ReadLogSourceIncremental) {
|
| + const base::TimeDelta timeout(base::TimeDelta::FromMilliseconds(0));
|
| + LogSourceAccessManager::SetRateLimitingTimeoutForTesting(&timeout);
|
| +
|
| + ReadLogSourceParams params;
|
| + params.source = api::feedback_private::LOG_SOURCE_MESSAGES;
|
| + params.incremental = true;
|
| +
|
| + int result_reader_id = 0;
|
| + std::string result_string;
|
| + EXPECT_TRUE(
|
| + RunReadLogSourceFunction(params, &result_reader_id, &result_string));
|
| + EXPECT_EQ(1, result_reader_id);
|
| + EXPECT_EQ("a", result_string);
|
| + params.reader_id.reset(new int(result_reader_id));
|
| +
|
| + EXPECT_TRUE(
|
| + RunReadLogSourceFunction(params, &result_reader_id, &result_string));
|
| + EXPECT_EQ(1, result_reader_id);
|
| + EXPECT_EQ("bb", result_string);
|
| +
|
| + EXPECT_TRUE(
|
| + RunReadLogSourceFunction(params, &result_reader_id, &result_string));
|
| + EXPECT_EQ(1, result_reader_id);
|
| + EXPECT_EQ("ccc", result_string);
|
| +
|
| + // End the incremental read.
|
| + params.incremental = false;
|
| + EXPECT_TRUE(
|
| + RunReadLogSourceFunction(params, &result_reader_id, &result_string));
|
| + EXPECT_EQ(0, result_reader_id);
|
| + EXPECT_EQ("dddd", result_string);
|
| +
|
| + // Start a new incremental read.
|
| + params.incremental = true;
|
| + *params.reader_id = 0;
|
| + EXPECT_TRUE(
|
| + RunReadLogSourceFunction(params, &result_reader_id, &result_string));
|
| + // The reader ID should be incremented.
|
| + EXPECT_EQ(2, result_reader_id);
|
| + EXPECT_EQ("a", result_string);
|
| +}
|
| +
|
| +} // namespace extensions
|
|
|