blob: f0ba6ef38e91e6c91dd60b77e53369c8b843589e [file] [log] [blame]
// Copyright 2018 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/chrome_cleaner/logging/safe_browsing_reporter.h"
#include <memory>
#include <string>
#include <utility>
#include "base/bind.h"
#include "base/run_loop.h"
#include "base/test/task_environment.h"
#include "base/test/test_simple_task_runner.h"
#include "chrome/chrome_cleaner/http/mock_http_agent_factory.h"
#include "chrome/chrome_cleaner/logging/test_utils.h"
#include "components/chrome_cleaner/public/constants/result_codes.h"
#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
#include "testing/gmock/include/gmock/gmock.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace chrome_cleaner {
namespace {
const char kSerializedReport[] = "I'm a serialized report!";
const char kTestSafeBrowsingUrl[] = "https://sb.google.com/yay";
void NoSleep(base::TimeDelta) {}
} // namespace
using ::testing::_;
using ::testing::Return;
class SafeBrowsingReporterTest : public testing::Test {
public:
// SafeBrowsingReporter::OnResultCallback:
void OnReportUploadResult(base::OnceClosure run_loop_quit,
SafeBrowsingReporter::Result result,
const std::string& serialized_report,
std::unique_ptr<ChromeFoilResponse> response) {
result_ = result;
report_upload_result_called_ = true;
if (response.get())
response->SerializeToString(&response_string_);
std::move(run_loop_quit).Run();
}
void SetUp() override {
SafeBrowsingReporter::SetHttpAgentFactoryForTesting(
http_agent_factory_.get());
SafeBrowsingReporter::SetSleepCallbackForTesting(
base::BindRepeating(&NoSleep));
SafeBrowsingReporter::SetNetworkCheckerForTesting(&network_checker_);
}
void TearDown() override {
SafeBrowsingReporter::SetNetworkCheckerForTesting(nullptr);
SafeBrowsingReporter::SetHttpAgentFactoryForTesting(nullptr);
}
protected:
SafeBrowsingReporterTest()
: task_environment_(base::test::TaskEnvironment::MainThreadType::UI) {}
// Uploads a report and waits for OnReportUploadResult to be called.
void DoUploadReport(const std::string& serialized_report) {
base::RunLoop run_loop;
SafeBrowsingReporter::UploadReport(
base::BindRepeating(&SafeBrowsingReporterTest::OnReportUploadResult,
base::Unretained(this), run_loop.QuitClosure()),
kTestSafeBrowsingUrl, serialized_report, TRAFFIC_ANNOTATION_FOR_TESTS);
run_loop.Run();
}
// Needed for the current task runner to be available.
base::test::TaskEnvironment task_environment_;
// |result_| and |response_string_| are set in |OnReportUploadResult| and used
// to confirm that the upload succeeded or failed appropriately.
SafeBrowsingReporter::Result result_{
SafeBrowsingReporter::Result::UPLOAD_INTERNAL_ERROR};
std::string response_string_;
MockHttpAgentConfig config_;
std::unique_ptr<HttpAgentFactory> http_agent_factory_{
std::make_unique<MockHttpAgentFactory>(&config_)};
MockNetworkChecker network_checker_;
// Confirm the execution of |OnReportUploadResult| and that |result_| and
// |response_string_| are valid.
bool report_upload_result_called_{false};
private:
DISALLOW_COPY_AND_ASSIGN(SafeBrowsingReporterTest);
};
TEST_F(SafeBrowsingReporterTest, Success) {
MockHttpAgentConfig::Calls calls(HttpStatus::kOk);
ChromeFoilResponse response;
response.set_token("Token");
std::string response_string;
response.SerializeToString(&response_string);
calls.read_data_result = response_string;
config_.AddCalls(calls);
DoUploadReport(kSerializedReport);
ASSERT_GT(config_.num_request_data(), 0u);
EXPECT_EQ(kSerializedReport, config_.request_data(0).body);
EXPECT_EQ(SafeBrowsingReporter::Result::UPLOAD_SUCCESS, result_);
EXPECT_EQ(response_string_, response_string);
EXPECT_TRUE(report_upload_result_called_);
}
TEST_F(SafeBrowsingReporterTest, Failure) {
MockHttpAgentConfig::Calls calls(HttpStatus::kOk);
calls.request_succeeds = false;
// Request fails on all tries. No retry without log lines.
config_.AddCalls(calls);
config_.AddCalls(calls);
config_.AddCalls(calls);
DoUploadReport(kSerializedReport);
EXPECT_EQ(SafeBrowsingReporter::Result::UPLOAD_REQUEST_FAILED, result_);
EXPECT_TRUE(response_string_.empty());
EXPECT_EQ(config_.num_request_data(), 3UL);
EXPECT_TRUE(report_upload_result_called_);
}
TEST_F(SafeBrowsingReporterTest, RetryOnlyOnceWhenFailing) {
MockHttpAgentConfig::Calls calls_failed(HttpStatus::kNotFound);
// Fail on every try with the same error.
config_.AddCalls(calls_failed);
config_.AddCalls(calls_failed);
config_.AddCalls(calls_failed);
DoUploadReport(kSerializedReport);
EXPECT_EQ(SafeBrowsingReporter::Result::UPLOAD_REQUEST_FAILED, result_);
EXPECT_TRUE(report_upload_result_called_);
ASSERT_EQ(3u, config_.num_request_data());
// Expect all requests to have the same contents.
EXPECT_EQ(config_.request_data(0).body, config_.request_data(1).body);
EXPECT_EQ(config_.request_data(0).body, config_.request_data(2).body);
}
TEST_F(SafeBrowsingReporterTest, WaitForSafeBrowsing) {
MockHttpAgentConfig::Calls calls(HttpStatus::kOk);
ChromeFoilResponse response;
response.set_token("Token");
std::string response_string;
response.SerializeToString(&response_string);
calls.read_data_result = response_string;
config_.AddCalls(calls);
// Safe Browsing is initially not reachable, but waiting for it result in
// it becoming reachable. Everything should succeed.
network_checker_.SetIsSafeBrowsingReachableResult(false);
network_checker_.SetWaitForSafeBrowsingResult(true);
DoUploadReport(kSerializedReport);
ASSERT_GT(config_.num_request_data(), 0u);
EXPECT_EQ(kSerializedReport, config_.request_data(0).body);
EXPECT_EQ(SafeBrowsingReporter::Result::UPLOAD_SUCCESS, result_);
EXPECT_EQ(response_string_, response_string);
EXPECT_TRUE(report_upload_result_called_);
}
TEST_F(SafeBrowsingReporterTest, NoNetwork) {
MockHttpAgentConfig::Calls calls(HttpStatus::kOk);
config_.AddCalls(calls);
// Safe Browsing never becomes reachable, and WaitForSafeBrowsing times
// out. UPLOAD_NO_NETWORK should be the result code, and the callback should
// have run anyway.
network_checker_.SetIsSafeBrowsingReachableResult(false);
network_checker_.SetWaitForSafeBrowsingResult(false);
DoUploadReport(kSerializedReport);
ASSERT_EQ(config_.num_request_data(), 0u);
EXPECT_EQ(SafeBrowsingReporter::Result::UPLOAD_NO_NETWORK, result_);
EXPECT_TRUE(report_upload_result_called_);
}
} // namespace chrome_cleaner