// Copyright 2014 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/domain_reliability/monitor.h"

#include <stddef.h>

#include <map>
#include <memory>
#include <string>
#include <utility>
#include <vector>

#include "base/bind.h"
#include "base/test/test_simple_task_runner.h"
#include "components/domain_reliability/baked_in_configs.h"
#include "components/domain_reliability/beacon.h"
#include "components/domain_reliability/config.h"
#include "components/domain_reliability/google_configs.h"
#include "components/domain_reliability/test_util.h"
#include "net/base/host_port_pair.h"
#include "net/base/load_flags.h"
#include "net/http/http_response_headers.h"
#include "net/http/http_util.h"
#include "net/url_request/url_request_context_getter.h"
#include "net/url_request/url_request_status.h"
#include "net/url_request/url_request_test_util.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace domain_reliability {

namespace {

typedef std::vector<const DomainReliabilityBeacon*> BeaconVector;

scoped_refptr<net::HttpResponseHeaders> MakeHttpResponseHeaders(
    const std::string& headers) {
  return scoped_refptr<net::HttpResponseHeaders>(
      new net::HttpResponseHeaders(net::HttpUtil::AssembleRawHeaders(
          headers.c_str(), headers.length())));
}

size_t CountQueuedBeacons(DomainReliabilityContext* context) {
  BeaconVector beacons;
  context->GetQueuedBeaconsForTesting(&beacons);
  return beacons.size();
}

}  // namespace

class DomainReliabilityMonitorTest : public testing::Test {
 protected:
  typedef DomainReliabilityMonitor::RequestInfo RequestInfo;

  DomainReliabilityMonitorTest()
      : pref_task_runner_(new base::TestSimpleTaskRunner()),
        network_task_runner_(new base::TestSimpleTaskRunner()),
        url_request_context_getter_(
            new net::TestURLRequestContextGetter(network_task_runner_)),
        time_(new MockTime()),
        monitor_("test-reporter",
                 pref_task_runner_,
                 network_task_runner_,
                 std::unique_ptr<MockableTime>(time_)) {
    monitor_.MoveToNetworkThread();
    monitor_.InitURLRequestContext(url_request_context_getter_);
    monitor_.SetDiscardUploads(false);
  }

  static RequestInfo MakeRequestInfo() {
    RequestInfo request;
    request.status = net::URLRequestStatus();
    request.response_info.socket_address =
        net::HostPortPair::FromString("12.34.56.78:80");
    request.response_info.headers = MakeHttpResponseHeaders(
        "HTTP/1.1 200 OK\n\n");
    request.response_info.was_cached = false;
    request.response_info.network_accessed = true;
    request.response_info.was_fetched_via_proxy = false;
    request.load_flags = 0;
    request.upload_depth = 0;
    return request;
  }

  void OnRequestLegComplete(const RequestInfo& info) {
    monitor_.OnRequestLegComplete(info);
  }

  DomainReliabilityContext* CreateAndAddContext() {
    return monitor_.AddContextForTesting(MakeTestConfig());
  }

  DomainReliabilityContext* CreateAndAddContextForOrigin(const GURL& origin,
                                                         bool wildcard) {
    std::unique_ptr<DomainReliabilityConfig> config(
        MakeTestConfigWithOrigin(origin));
    config->include_subdomains = wildcard;
    return monitor_.AddContextForTesting(std::move(config));
  }

  scoped_refptr<base::TestSimpleTaskRunner> pref_task_runner_;
  scoped_refptr<base::TestSimpleTaskRunner> network_task_runner_;
  scoped_refptr<net::URLRequestContextGetter> url_request_context_getter_;
  MockTime* time_;
  DomainReliabilityMonitor monitor_;
  DomainReliabilityMonitor::RequestInfo request_;
};

namespace {

TEST_F(DomainReliabilityMonitorTest, Create) {
}

TEST_F(DomainReliabilityMonitorTest, NoContext) {
  DomainReliabilityContext* context = CreateAndAddContext();

  RequestInfo request = MakeRequestInfo();
  request.url = GURL("http://no-context/");
  OnRequestLegComplete(request);

  EXPECT_EQ(0u, CountQueuedBeacons(context));
}

TEST_F(DomainReliabilityMonitorTest, NetworkFailure) {
  DomainReliabilityContext* context = CreateAndAddContext();

  RequestInfo request = MakeRequestInfo();
  request.url = GURL("http://example/");
  request.status = net::URLRequestStatus::FromError(net::ERR_CONNECTION_RESET);
  request.response_info.headers = nullptr;
  OnRequestLegComplete(request);

  EXPECT_EQ(1u, CountQueuedBeacons(context));
}

TEST_F(DomainReliabilityMonitorTest, GoAwayWithPortMigrationDetected) {
  DomainReliabilityContext* context = CreateAndAddContext();

  RequestInfo request = MakeRequestInfo();
  request.url = GURL("http://example/");
  request.details.quic_port_migration_detected = true;
  request.response_info.headers = nullptr;
  OnRequestLegComplete(request);

  EXPECT_EQ(1u, CountQueuedBeacons(context));
}

TEST_F(DomainReliabilityMonitorTest, ServerFailure) {
  DomainReliabilityContext* context = CreateAndAddContext();

  RequestInfo request = MakeRequestInfo();
  request.url = GURL("http://example/");
  request.response_info.headers =
      MakeHttpResponseHeaders("HTTP/1.1 500 :(\n\n");
  OnRequestLegComplete(request);

  EXPECT_EQ(1u, CountQueuedBeacons(context));
}

// Make sure the monitor does not log requests that did not access the network.
TEST_F(DomainReliabilityMonitorTest, DidNotAccessNetwork) {
  DomainReliabilityContext* context = CreateAndAddContext();

  RequestInfo request = MakeRequestInfo();
  request.url = GURL("http://example/");
  request.response_info.network_accessed = false;
  OnRequestLegComplete(request);

  EXPECT_EQ(0u, CountQueuedBeacons(context));
}

// Make sure the monitor does not log requests that don't send cookies.
TEST_F(DomainReliabilityMonitorTest, DoNotSendCookies) {
  DomainReliabilityContext* context = CreateAndAddContext();

  RequestInfo request = MakeRequestInfo();
  request.url = GURL("http://example/");
  request.load_flags = net::LOAD_DO_NOT_SEND_COOKIES;
  OnRequestLegComplete(request);

  EXPECT_EQ(0u, CountQueuedBeacons(context));
}

// Make sure the monitor does not log a network-local error.
TEST_F(DomainReliabilityMonitorTest, LocalError) {
  DomainReliabilityContext* context = CreateAndAddContext();

  RequestInfo request = MakeRequestInfo();
  request.url = GURL("http://example/");
  request.status =
      net::URLRequestStatus::FromError(net::ERR_PROXY_CONNECTION_FAILED);
  OnRequestLegComplete(request);

  EXPECT_EQ(0u, CountQueuedBeacons(context));
}

// Make sure the monitor does not log the proxy's IP if one was used.
TEST_F(DomainReliabilityMonitorTest, WasFetchedViaProxy) {
  DomainReliabilityContext* context = CreateAndAddContext();

  RequestInfo request = MakeRequestInfo();
  request.url = GURL("http://example/");
  request.status = net::URLRequestStatus::FromError(net::ERR_CONNECTION_RESET);
  request.response_info.socket_address =
      net::HostPortPair::FromString("127.0.0.1:3128");
  request.response_info.was_fetched_via_proxy = true;
  OnRequestLegComplete(request);

  BeaconVector beacons;
  context->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());
  EXPECT_TRUE(beacons[0]->server_ip.empty());
}

// Make sure the monitor does not log the cached IP returned after a successful
// cache revalidation request.
TEST_F(DomainReliabilityMonitorTest,
       NoCachedIPFromSuccessfulRevalidationRequest) {
  std::unique_ptr<DomainReliabilityConfig> config = MakeTestConfig();
  config->success_sample_rate = 1.0;
  DomainReliabilityContext* context =
      monitor_.AddContextForTesting(std::move(config));

  RequestInfo request = MakeRequestInfo();
  request.url = GURL("http://example/");
  request.response_info.was_cached = true;
  OnRequestLegComplete(request);

  BeaconVector beacons;
  context->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());
  EXPECT_TRUE(beacons[0]->server_ip.empty());
}

// Make sure the monitor does not log the cached IP returned with a failed
// cache revalidation request.
TEST_F(DomainReliabilityMonitorTest, NoCachedIPFromFailedRevalidationRequest) {
  DomainReliabilityContext* context = CreateAndAddContext();

  RequestInfo request = MakeRequestInfo();
  request.url = GURL("http://example/");
  request.response_info.was_cached = true;
  request.status =
      net::URLRequestStatus::FromError(net::ERR_NAME_RESOLUTION_FAILED);
  OnRequestLegComplete(request);

  BeaconVector beacons;
  context->GetQueuedBeaconsForTesting(&beacons);
  EXPECT_EQ(1u, beacons.size());
  EXPECT_TRUE(beacons[0]->server_ip.empty());
}

TEST_F(DomainReliabilityMonitorTest, AtLeastOneBakedInConfig) {
  DCHECK(kBakedInJsonConfigs[0] != nullptr);
}

// Will fail when baked-in configs expire, as a reminder to update them.
// (Contact juliatuttle@chromium.org if this starts failing.)
TEST_F(DomainReliabilityMonitorTest, AddBakedInConfigs) {
  // AddBakedInConfigs DCHECKs that the baked-in configs parse correctly, so
  // this unittest will fail if someone tries to add an invalid config to the
  // source tree.
  monitor_.AddBakedInConfigs();

  // Count the number of baked-in configs.
  size_t num_baked_in_configs = 0;
  for (const char* const* p = kBakedInJsonConfigs; *p; ++p)
    ++num_baked_in_configs;

  // Also count the Google configs stored in abbreviated form.
  std::vector<DomainReliabilityConfig*> google_configs;
  GetAllGoogleConfigs(&google_configs);
  size_t num_google_configs = google_configs.size();
  STLDeleteElements(&google_configs);

  // The monitor should have contexts for all of the baked-in configs.
  EXPECT_EQ(num_baked_in_configs + num_google_configs,
            monitor_.contexts_size_for_testing());
}

TEST_F(DomainReliabilityMonitorTest, ClearBeacons) {
  DomainReliabilityContext* context = CreateAndAddContext();

  // Initially the monitor should have just the test context, with no beacons.
  EXPECT_EQ(1u, monitor_.contexts_size_for_testing());
  EXPECT_EQ(0u, CountQueuedBeacons(context));

  // Add a beacon.
  RequestInfo request = MakeRequestInfo();
  request.url = GURL("http://example/");
  request.status = net::URLRequestStatus::FromError(net::ERR_CONNECTION_RESET);
  OnRequestLegComplete(request);

  // Make sure it was added.
  EXPECT_EQ(1u, CountQueuedBeacons(context));

  monitor_.ClearBrowsingData(CLEAR_BEACONS);

  // Make sure the beacon was cleared, but not the contexts.
  EXPECT_EQ(1u, monitor_.contexts_size_for_testing());
  EXPECT_EQ(0u, CountQueuedBeacons(context));
}

TEST_F(DomainReliabilityMonitorTest, ClearContexts) {
  CreateAndAddContext();

  // Initially the monitor should have just the test context.
  EXPECT_EQ(1u, monitor_.contexts_size_for_testing());

  monitor_.ClearBrowsingData(CLEAR_CONTEXTS);

  // Clearing contexts should leave the monitor with none.
  EXPECT_EQ(0u, monitor_.contexts_size_for_testing());
}

TEST_F(DomainReliabilityMonitorTest, WildcardMatchesSelf) {
  DomainReliabilityContext* context =
      CreateAndAddContextForOrigin(GURL("https://wildcard/"), true);

  RequestInfo request = MakeRequestInfo();
  request.url = GURL("http://wildcard/");
  request.status = net::URLRequestStatus::FromError(net::ERR_CONNECTION_RESET);
  OnRequestLegComplete(request);

  EXPECT_EQ(1u, CountQueuedBeacons(context));
}

TEST_F(DomainReliabilityMonitorTest, WildcardMatchesSubdomain) {
  DomainReliabilityContext* context =
      CreateAndAddContextForOrigin(GURL("https://wildcard/"), true);

  RequestInfo request = MakeRequestInfo();
  request.url = GURL("http://test.wildcard/");
  request.status = net::URLRequestStatus::FromError(net::ERR_CONNECTION_RESET);
  OnRequestLegComplete(request);

  EXPECT_EQ(1u, CountQueuedBeacons(context));
}

TEST_F(DomainReliabilityMonitorTest, WildcardDoesntMatchSubsubdomain) {
  DomainReliabilityContext* context =
      CreateAndAddContextForOrigin(GURL("https://wildcard/"), true);

  RequestInfo request = MakeRequestInfo();
  request.url = GURL("http://test.test.wildcard/");
  request.status = net::URLRequestStatus::FromError(net::ERR_CONNECTION_RESET);
  OnRequestLegComplete(request);

  EXPECT_EQ(0u, CountQueuedBeacons(context));
}

TEST_F(DomainReliabilityMonitorTest, WildcardPrefersSelfToParentWildcard) {
  DomainReliabilityContext* context1 =
      CreateAndAddContextForOrigin(GURL("https://test.wildcard/"), false);
  DomainReliabilityContext* context2 =
      CreateAndAddContextForOrigin(GURL("https://wildcard/"), true);

  RequestInfo request = MakeRequestInfo();
  request.url = GURL("http://test.wildcard/");
  request.status = net::URLRequestStatus::FromError(net::ERR_CONNECTION_RESET);
  OnRequestLegComplete(request);

  EXPECT_EQ(1u, CountQueuedBeacons(context1));
  EXPECT_EQ(0u, CountQueuedBeacons(context2));
}

TEST_F(DomainReliabilityMonitorTest,
    WildcardPrefersSelfWildcardToParentWildcard) {
  DomainReliabilityContext* context1 =
      CreateAndAddContextForOrigin(GURL("https://test.wildcard/"), true);
  DomainReliabilityContext* context2 =
      CreateAndAddContextForOrigin(GURL("https://wildcard/"), true);

  RequestInfo request = MakeRequestInfo();
  request.url = GURL("http://test.wildcard/");
  request.status = net::URLRequestStatus::FromError(net::ERR_CONNECTION_RESET);
  OnRequestLegComplete(request);

  EXPECT_EQ(1u, CountQueuedBeacons(context1));
  EXPECT_EQ(0u, CountQueuedBeacons(context2));
}

}  // namespace

}  // namespace domain_reliability
