// Copyright (c) 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 "net/proxy/proxy_resolver_v8_tracing_wrapper.h"

#include <string>

#include "base/files/file_util.h"
#include "base/message_loop/message_loop.h"
#include "base/path_service.h"
#include "base/stl_util.h"
#include "base/strings/string_util.h"
#include "base/strings/stringprintf.h"
#include "base/strings/utf_string_conversions.h"
#include "base/synchronization/waitable_event.h"
#include "base/threading/platform_thread.h"
#include "base/values.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/dns/host_cache.h"
#include "net/dns/mock_host_resolver.h"
#include "net/log/net_log.h"
#include "net/log/test_net_log.h"
#include "net/log/test_net_log_entry.h"
#include "net/log/test_net_log_util.h"
#include "net/proxy/proxy_info.h"
#include "net/proxy/proxy_resolver_error_observer.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace net {

namespace {

class ProxyResolverV8TracingWrapperTest : public testing::Test {
 public:
  void TearDown() override {
    // Drain any pending messages, which may be left over from cancellation.
    // This way they get reliably run as part of the current test, rather than
    // spilling into the next test's execution.
    base::MessageLoop::current()->RunUntilIdle();
  }
};

scoped_refptr<ProxyResolverScriptData> LoadScriptData(const char* filename) {
  base::FilePath path;
  PathService::Get(base::DIR_SOURCE_ROOT, &path);
  path = path.AppendASCII("net");
  path = path.AppendASCII("data");
  path = path.AppendASCII("proxy_resolver_v8_tracing_unittest");
  path = path.AppendASCII(filename);

  // Try to read the file from disk.
  std::string file_contents;
  bool ok = base::ReadFileToString(path, &file_contents);

  // If we can't load the file from disk, something is misconfigured.
  EXPECT_TRUE(ok) << "Failed to read file: " << path.value();

  // Load the PAC script into the ProxyResolver.
  return ProxyResolverScriptData::FromUTF8(file_contents);
}

scoped_ptr<ProxyResolverErrorObserver> ReturnErrorObserver(
    scoped_ptr<ProxyResolverErrorObserver> error_observer) {
  return error_observer;
}

scoped_ptr<ProxyResolver> CreateResolver(
    NetLog* net_log,
    HostResolver* host_resolver,
    scoped_ptr<ProxyResolverErrorObserver> error_observer,
    const char* filename) {
  scoped_ptr<ProxyResolver> resolver;
  ProxyResolverFactoryV8TracingWrapper factory(
      host_resolver, net_log,
      base::Bind(&ReturnErrorObserver, base::Passed(&error_observer)));
  TestCompletionCallback callback;
  scoped_ptr<ProxyResolverFactory::Request> request;
  int rv = factory.CreateProxyResolver(LoadScriptData(filename), &resolver,
                                       callback.callback(), &request);
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(OK, callback.WaitForResult());
  EXPECT_TRUE(resolver);
  return resolver.Pass();
}

class MockErrorObserver : public ProxyResolverErrorObserver {
 public:
  MockErrorObserver() : event_(true, false) {}

  void OnPACScriptError(int line_number, const base::string16& error) override {
    {
      base::AutoLock l(lock_);
      output += base::StringPrintf("Error: line %d: %s\n", line_number,
                                   base::UTF16ToASCII(error).c_str());
    }
    event_.Signal();
  }

  std::string GetOutput() {
    base::AutoLock l(lock_);
    return output;
  }

  void WaitForOutput() { event_.Wait(); }

 private:
  base::Lock lock_;
  std::string output;

  base::WaitableEvent event_;
};

TEST_F(ProxyResolverV8TracingWrapperTest, Simple) {
  TestNetLog log;
  BoundTestNetLog request_log;
  MockCachingHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  scoped_ptr<ProxyResolver> resolver = CreateResolver(
      &log, &host_resolver, make_scoped_ptr(error_observer), "simple.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  int rv =
      resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                               callback.callback(), NULL, request_log.bound());

  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(OK, callback.WaitForResult());

  EXPECT_EQ("foo:99", proxy_info.proxy_server().ToURI());

  EXPECT_EQ(0u, host_resolver.num_resolve());

  // There were no errors.
  EXPECT_EQ("", error_observer->GetOutput());

  // Check the NetLogs -- nothing was logged.
  EXPECT_EQ(0u, log.GetSize());
  EXPECT_EQ(0u, request_log.GetSize());
}

TEST_F(ProxyResolverV8TracingWrapperTest, JavascriptError) {
  TestNetLog log;
  BoundTestNetLog request_log;
  MockCachingHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  scoped_ptr<ProxyResolver> resolver = CreateResolver(
      &log, &host_resolver, make_scoped_ptr(error_observer), "error.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  int rv =
      resolver->GetProxyForURL(GURL("http://throw-an-error/"), &proxy_info,
                               callback.callback(), NULL, request_log.bound());

  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, callback.WaitForResult());

  EXPECT_EQ(0u, host_resolver.num_resolve());

  EXPECT_EQ(
      "Error: line 5: Uncaught TypeError: Cannot read property 'split' "
      "of null\n",
      error_observer->GetOutput());

  // Check the NetLogs -- there was 1 alert and 1 javascript error, and they
  // were output to both the global log, and per-request log.
  TestNetLogEntry::List entries_list[2];
  log.GetEntries(&entries_list[0]);
  request_log.GetEntries(&entries_list[1]);

  for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
    const TestNetLogEntry::List& entries = entries_list[list_i];
    EXPECT_EQ(2u, entries.size());
    EXPECT_TRUE(LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
                                 NetLog::PHASE_NONE));
    EXPECT_TRUE(LogContainsEvent(entries, 1, NetLog::TYPE_PAC_JAVASCRIPT_ERROR,
                                 NetLog::PHASE_NONE));

    EXPECT_EQ("{\"message\":\"Prepare to DIE!\"}", entries[0].GetParamsJson());
    EXPECT_EQ(
        "{\"line_number\":5,\"message\":\"Uncaught TypeError: Cannot "
        "read property 'split' of null\"}",
        entries[1].GetParamsJson());
  }
}

TEST_F(ProxyResolverV8TracingWrapperTest, TooManyAlerts) {
  TestNetLog log;
  BoundTestNetLog request_log;
  MockCachingHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  scoped_ptr<ProxyResolver> resolver =
      CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
                     "too_many_alerts.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  int rv =
      resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                               callback.callback(), NULL, request_log.bound());

  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(OK, callback.WaitForResult());

  // Iteration1 does a DNS resolve
  // Iteration2 exceeds the alert buffer
  // Iteration3 runs in blocking mode and completes
  EXPECT_EQ("foo:3", proxy_info.proxy_server().ToURI());

  EXPECT_EQ(1u, host_resolver.num_resolve());

  // No errors.
  EXPECT_EQ("", error_observer->GetOutput());

  // Check the NetLogs -- the script generated 50 alerts, which were mirrored
  // to both the global and per-request logs.
  TestNetLogEntry::List entries_list[2];
  log.GetEntries(&entries_list[0]);
  request_log.GetEntries(&entries_list[1]);

  for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
    const TestNetLogEntry::List& entries = entries_list[list_i];
    EXPECT_EQ(50u, entries.size());
    for (size_t i = 0; i < entries.size(); ++i) {
      ASSERT_TRUE(LogContainsEvent(
          entries, i, NetLog::TYPE_PAC_JAVASCRIPT_ALERT, NetLog::PHASE_NONE));
    }
  }
}

// Verify that buffered alerts cannot grow unboundedly, even when the message is
// empty string.
TEST_F(ProxyResolverV8TracingWrapperTest, TooManyEmptyAlerts) {
  TestNetLog log;
  BoundTestNetLog request_log;
  MockCachingHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  scoped_ptr<ProxyResolver> resolver =
      CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
                     "too_many_empty_alerts.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  int rv =
      resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                               callback.callback(), NULL, request_log.bound());

  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(OK, callback.WaitForResult());

  EXPECT_EQ("foo:3", proxy_info.proxy_server().ToURI());

  EXPECT_EQ(1u, host_resolver.num_resolve());

  // No errors.
  EXPECT_EQ("", error_observer->GetOutput());

  // Check the NetLogs -- the script generated 50 alerts, which were mirrored
  // to both the global and per-request logs.
  TestNetLogEntry::List entries_list[2];
  log.GetEntries(&entries_list[0]);
  request_log.GetEntries(&entries_list[1]);

  for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
    const TestNetLogEntry::List& entries = entries_list[list_i];
    EXPECT_EQ(1000u, entries.size());
    for (size_t i = 0; i < entries.size(); ++i) {
      ASSERT_TRUE(LogContainsEvent(
          entries, i, NetLog::TYPE_PAC_JAVASCRIPT_ALERT, NetLog::PHASE_NONE));
    }
  }
}

// This test runs a PAC script that issues a sequence of DNS resolves. The test
// verifies the final result, and that the underlying DNS resolver received
// the correct set of queries.
TEST_F(ProxyResolverV8TracingWrapperTest, Dns) {
  TestNetLog log;
  BoundTestNetLog request_log;
  MockCachingHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  host_resolver.rules()->AddRuleForAddressFamily("host1", ADDRESS_FAMILY_IPV4,
                                                 "166.155.144.44");
  host_resolver.rules()->AddIPLiteralRule("host1", "::1,192.168.1.1",
                                          std::string());
  host_resolver.rules()->AddSimulatedFailure("host2");
  host_resolver.rules()->AddRule("host3", "166.155.144.33");
  host_resolver.rules()->AddRule("host5", "166.155.144.55");
  host_resolver.rules()->AddSimulatedFailure("host6");
  host_resolver.rules()->AddRuleForAddressFamily("*", ADDRESS_FAMILY_IPV4,
                                                 "122.133.144.155");
  host_resolver.rules()->AddRule("*", "133.122.100.200");

  scoped_ptr<ProxyResolver> resolver = CreateResolver(
      &log, &host_resolver, make_scoped_ptr(error_observer), "dns.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  int rv =
      resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                               callback.callback(), NULL, request_log.bound());

  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(OK, callback.WaitForResult());

  // The test does 13 DNS resolution, however only 7 of them are unique.
  EXPECT_EQ(7u, host_resolver.num_resolve());

  const char* kExpectedResult =
      "122.133.144.155-"  // myIpAddress()
      "null-"             // dnsResolve('')
      "__1_192.168.1.1-"  // dnsResolveEx('host1')
      "null-"             // dnsResolve('host2')
      "166.155.144.33-"   // dnsResolve('host3')
      "122.133.144.155-"  // myIpAddress()
      "166.155.144.33-"   // dnsResolve('host3')
      "__1_192.168.1.1-"  // dnsResolveEx('host1')
      "122.133.144.155-"  // myIpAddress()
      "null-"             // dnsResolve('host2')
      "-"                 // dnsResolveEx('host6')
      "133.122.100.200-"  // myIpAddressEx()
      "166.155.144.44"    // dnsResolve('host1')
      ":99";

  EXPECT_EQ(kExpectedResult, proxy_info.proxy_server().ToURI());

  // No errors.
  EXPECT_EQ("", error_observer->GetOutput());

  // Check the NetLogs -- the script generated 1 alert, mirrored to both
  // the per-request and global logs.
  TestNetLogEntry::List entries_list[2];
  log.GetEntries(&entries_list[0]);
  request_log.GetEntries(&entries_list[1]);

  for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
    const TestNetLogEntry::List& entries = entries_list[list_i];
    EXPECT_EQ(1u, entries.size());
    EXPECT_TRUE(LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
                                 NetLog::PHASE_NONE));
    EXPECT_EQ("{\"message\":\"iteration: 7\"}", entries[0].GetParamsJson());
  }
}

// This test runs a PAC script that does "myIpAddress()" followed by
// "dnsResolve()". This requires 2 restarts. However once the HostResolver's
// cache is warmed, subsequent calls should take 0 restarts.
TEST_F(ProxyResolverV8TracingWrapperTest, DnsChecksCache) {
  TestNetLog log;
  BoundTestNetLog request_log;
  MockCachingHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  host_resolver.rules()->AddRule("foopy", "166.155.144.11");
  host_resolver.rules()->AddRule("*", "122.133.144.155");

  scoped_ptr<ProxyResolver> resolver = CreateResolver(
      &log, &host_resolver, make_scoped_ptr(error_observer), "simple_dns.js");

  TestCompletionCallback callback1;
  TestCompletionCallback callback2;
  ProxyInfo proxy_info;

  int rv =
      resolver->GetProxyForURL(GURL("http://foopy/req1"), &proxy_info,
                               callback1.callback(), NULL, request_log.bound());

  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(OK, callback1.WaitForResult());

  // The test does 2 DNS resolutions.
  EXPECT_EQ(2u, host_resolver.num_resolve());

  // The first request took 2 restarts, hence on g_iteration=3.
  EXPECT_EQ("166.155.144.11:3", proxy_info.proxy_server().ToURI());

  rv =
      resolver->GetProxyForURL(GURL("http://foopy/req2"), &proxy_info,
                               callback2.callback(), NULL, request_log.bound());

  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(OK, callback2.WaitForResult());

  EXPECT_EQ(4u, host_resolver.num_resolve());

  // This time no restarts were required, so g_iteration incremented by 1.
  EXPECT_EQ("166.155.144.11:4", proxy_info.proxy_server().ToURI());

  // No errors.
  EXPECT_EQ("", error_observer->GetOutput());

  EXPECT_EQ(0u, log.GetSize());
  EXPECT_EQ(0u, request_log.GetSize());
}

// This test runs a weird PAC script that was designed to defeat the DNS tracing
// optimization. The proxy resolver should detect the inconsistency and
// fall-back to synchronous mode execution.
TEST_F(ProxyResolverV8TracingWrapperTest, FallBackToSynchronous1) {
  TestNetLog log;
  BoundTestNetLog request_log;
  MockCachingHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  host_resolver.rules()->AddRule("host1", "166.155.144.11");
  host_resolver.rules()->AddRule("crazy4", "133.199.111.4");
  host_resolver.rules()->AddRule("*", "122.133.144.155");

  scoped_ptr<ProxyResolver> resolver =
      CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
                     "global_sideffects1.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  int rv =
      resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                               callback.callback(), NULL, request_log.bound());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(OK, callback.WaitForResult());

  // The script itself only does 2 DNS resolves per execution, however it
  // constructs the hostname using a global counter which changes on each
  // invocation.
  EXPECT_EQ(3u, host_resolver.num_resolve());

  EXPECT_EQ("166.155.144.11-133.199.111.4:100",
            proxy_info.proxy_server().ToURI());

  // No errors.
  EXPECT_EQ("", error_observer->GetOutput());

  // Check the NetLogs -- the script generated 1 alert, mirrored to both
  // the per-request and global logs.
  TestNetLogEntry::List entries_list[2];
  log.GetEntries(&entries_list[0]);
  request_log.GetEntries(&entries_list[1]);

  for (size_t list_i = 0; list_i < arraysize(entries_list); list_i++) {
    const TestNetLogEntry::List& entries = entries_list[list_i];
    EXPECT_EQ(1u, entries.size());
    EXPECT_TRUE(LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
                                 NetLog::PHASE_NONE));
    EXPECT_EQ("{\"message\":\"iteration: 4\"}", entries[0].GetParamsJson());
  }
}

// This test runs a weird PAC script that was designed to defeat the DNS tracing
// optimization. The proxy resolver should detect the inconsistency and
// fall-back to synchronous mode execution.
TEST_F(ProxyResolverV8TracingWrapperTest, FallBackToSynchronous2) {
  TestNetLog log;
  BoundTestNetLog request_log;
  MockCachingHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  host_resolver.rules()->AddRule("host1", "166.155.144.11");
  host_resolver.rules()->AddRule("host2", "166.155.144.22");
  host_resolver.rules()->AddRule("host3", "166.155.144.33");
  host_resolver.rules()->AddRule("host4", "166.155.144.44");
  host_resolver.rules()->AddRule("*", "122.133.144.155");

  scoped_ptr<ProxyResolver> resolver =
      CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
                     "global_sideffects2.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  int rv =
      resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                               callback.callback(), NULL, request_log.bound());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(OK, callback.WaitForResult());

  EXPECT_EQ(3u, host_resolver.num_resolve());

  EXPECT_EQ("166.155.144.44:100", proxy_info.proxy_server().ToURI());

  // No errors.
  EXPECT_EQ("", error_observer->GetOutput());

  // Check the NetLogs -- nothing was logged.
  EXPECT_EQ(0u, log.GetSize());
  EXPECT_EQ(0u, request_log.GetSize());
}

// This test runs a weird PAC script that yields a never ending sequence
// of DNS resolves when restarting. Running it will hit the maximum
// DNS resolves per request limit (20) after which every DNS resolve will
// fail.
TEST_F(ProxyResolverV8TracingWrapperTest, InfiniteDNSSequence) {
  TestNetLog log;
  BoundTestNetLog request_log;
  MockCachingHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  host_resolver.rules()->AddRule("host*", "166.155.144.11");
  host_resolver.rules()->AddRule("*", "122.133.144.155");

  scoped_ptr<ProxyResolver> resolver =
      CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
                     "global_sideffects3.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  int rv =
      resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                               callback.callback(), NULL, request_log.bound());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(OK, callback.WaitForResult());

  EXPECT_EQ(20u, host_resolver.num_resolve());

  EXPECT_EQ(
      "166.155.144.11-166.155.144.11-166.155.144.11-166.155.144.11-"
      "166.155.144.11-166.155.144.11-166.155.144.11-166.155.144.11-"
      "166.155.144.11-166.155.144.11-166.155.144.11-166.155.144.11-"
      "166.155.144.11-166.155.144.11-166.155.144.11-166.155.144.11-"
      "166.155.144.11-166.155.144.11-166.155.144.11-166.155.144.11-"
      "null:21",
      proxy_info.proxy_server().ToURI());

  // No errors.
  EXPECT_EQ("", error_observer->GetOutput());

  // Check the NetLogs -- 1 alert was logged.
  EXPECT_EQ(1u, log.GetSize());
  EXPECT_EQ(1u, request_log.GetSize());
}

// This test runs a weird PAC script that yields a never ending sequence
// of DNS resolves when restarting. Running it will hit the maximum
// DNS resolves per request limit (20) after which every DNS resolve will
// fail.
TEST_F(ProxyResolverV8TracingWrapperTest, InfiniteDNSSequence2) {
  TestNetLog log;
  BoundTestNetLog request_log;
  MockCachingHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  host_resolver.rules()->AddRule("host*", "166.155.144.11");
  host_resolver.rules()->AddRule("*", "122.133.144.155");

  scoped_ptr<ProxyResolver> resolver =
      CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
                     "global_sideffects4.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  int rv =
      resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                               callback.callback(), NULL, request_log.bound());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(OK, callback.WaitForResult());

  EXPECT_EQ(20u, host_resolver.num_resolve());

  EXPECT_EQ("null21:34", proxy_info.proxy_server().ToURI());

  // No errors.
  EXPECT_EQ("", error_observer->GetOutput());

  // Check the NetLogs -- 1 alert was logged.
  EXPECT_EQ(1u, log.GetSize());
  EXPECT_EQ(1u, request_log.GetSize());
}

void DnsDuringInitHelper(bool synchronous_host_resolver) {
  TestNetLog log;
  BoundTestNetLog request_log;
  MockCachingHostResolver host_resolver;
  host_resolver.set_synchronous_mode(synchronous_host_resolver);
  MockErrorObserver* error_observer = new MockErrorObserver;

  host_resolver.rules()->AddRule("host1", "91.13.12.1");
  host_resolver.rules()->AddRule("host2", "91.13.12.2");

  scoped_ptr<ProxyResolver> resolver =
      CreateResolver(&log, &host_resolver, make_scoped_ptr(error_observer),
                     "dns_during_init.js");

  // Initialization did 2 dnsResolves.
  EXPECT_EQ(2u, host_resolver.num_resolve());

  host_resolver.rules()->ClearRules();
  host_resolver.GetHostCache()->clear();

  host_resolver.rules()->AddRule("host1", "145.88.13.3");
  host_resolver.rules()->AddRule("host2", "137.89.8.45");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  int rv =
      resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                               callback.callback(), NULL, request_log.bound());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(OK, callback.WaitForResult());

  // Fetched host1 and host2 again, since the ones done during initialization
  // should not have been cached.
  EXPECT_EQ(4u, host_resolver.num_resolve());

  EXPECT_EQ("91.13.12.1-91.13.12.2-145.88.13.3-137.89.8.45:99",
            proxy_info.proxy_server().ToURI());

  // Check the NetLogs -- the script generated 2 alerts during initialization.
  EXPECT_EQ(0u, request_log.GetSize());
  TestNetLogEntry::List entries;
  log.GetEntries(&entries);

  ASSERT_EQ(2u, entries.size());
  EXPECT_TRUE(LogContainsEvent(entries, 0, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
                               NetLog::PHASE_NONE));
  EXPECT_TRUE(LogContainsEvent(entries, 1, NetLog::TYPE_PAC_JAVASCRIPT_ALERT,
                               NetLog::PHASE_NONE));

  EXPECT_EQ("{\"message\":\"Watsup\"}", entries[0].GetParamsJson());
  EXPECT_EQ("{\"message\":\"Watsup2\"}", entries[1].GetParamsJson());
}

// Tests a PAC script which does DNS resolves during initialization.
TEST_F(ProxyResolverV8TracingWrapperTest, DnsDuringInit) {
  // Test with both both a host resolver that always completes asynchronously,
  // and then again with one that completes synchronously.
  DnsDuringInitHelper(false);
  DnsDuringInitHelper(true);
}

void CrashCallback(int) {
  // Be extra sure that if the callback ever gets invoked, the test will fail.
  CHECK(false);
}

// Start some requests, cancel them all, and then destroy the resolver.
// Note the execution order for this test can vary. Since multiple
// threads are involved, the cancellation may be received a different
// times.
TEST_F(ProxyResolverV8TracingWrapperTest, CancelAll) {
  MockCachingHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  host_resolver.rules()->AddSimulatedFailure("*");

  scoped_ptr<ProxyResolver> resolver = CreateResolver(
      nullptr, &host_resolver, make_scoped_ptr(error_observer), "dns.js");

  const size_t kNumRequests = 5;
  ProxyInfo proxy_info[kNumRequests];
  ProxyResolver::RequestHandle request[kNumRequests];

  for (size_t i = 0; i < kNumRequests; ++i) {
    int rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info[i],
                                      base::Bind(&CrashCallback), &request[i],
                                      BoundNetLog());
    EXPECT_EQ(ERR_IO_PENDING, rv);
  }

  for (size_t i = 0; i < kNumRequests; ++i) {
    resolver->CancelRequest(request[i]);
  }
}

// Note the execution order for this test can vary. Since multiple
// threads are involved, the cancellation may be received a different
// times.
TEST_F(ProxyResolverV8TracingWrapperTest, CancelSome) {
  MockCachingHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  host_resolver.rules()->AddSimulatedFailure("*");

  scoped_ptr<ProxyResolver> resolver = CreateResolver(
      nullptr, &host_resolver, make_scoped_ptr(error_observer), "dns.js");

  ProxyInfo proxy_info1;
  ProxyInfo proxy_info2;
  ProxyResolver::RequestHandle request1;
  ProxyResolver::RequestHandle request2;
  TestCompletionCallback callback;

  int rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info1,
                                    base::Bind(&CrashCallback), &request1,
                                    BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info2,
                                callback.callback(), &request2, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  resolver->CancelRequest(request1);

  EXPECT_EQ(OK, callback.WaitForResult());
}

// Cancel a request after it has finished running on the worker thread, and has
// posted a task the completion task back to origin thread.
TEST_F(ProxyResolverV8TracingWrapperTest, CancelWhilePendingCompletionTask) {
  MockCachingHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  host_resolver.rules()->AddSimulatedFailure("*");

  scoped_ptr<ProxyResolver> resolver = CreateResolver(
      nullptr, &host_resolver, make_scoped_ptr(error_observer), "error.js");

  ProxyInfo proxy_info1;
  ProxyInfo proxy_info2;
  ProxyInfo proxy_info3;
  ProxyResolver::RequestHandle request1;
  ProxyResolver::RequestHandle request2;
  ProxyResolver::RequestHandle request3;
  TestCompletionCallback callback;

  int rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info1,
                                    base::Bind(&CrashCallback), &request1,
                                    BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  rv = resolver->GetProxyForURL(GURL("http://throw-an-error/"), &proxy_info2,
                                callback.callback(), &request2, BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  // Wait until the first request has finished running on the worker thread.
  // (The second request will output an error).
  error_observer->WaitForOutput();

  // Cancel the first request, while it has a pending completion task on
  // the origin thread.
  resolver->CancelRequest(request1);

  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, callback.WaitForResult());

  // Start another request, to make sure it is able to complete.
  rv = resolver->GetProxyForURL(GURL("http://i-have-no-idea-what-im-doing/"),
                                &proxy_info3, callback.callback(), &request3,
                                BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);

  EXPECT_EQ(OK, callback.WaitForResult());

  EXPECT_EQ("i-approve-this-message:42", proxy_info3.proxy_server().ToURI());
}

// This implementation of HostResolver allows blocking until a resolve request
// has been received. The resolve requests it receives will never be completed.
class BlockableHostResolver : public HostResolver {
 public:
  BlockableHostResolver()
      : num_cancelled_requests_(0), waiting_for_resolve_(false) {}

  int Resolve(const RequestInfo& info,
              RequestPriority priority,
              AddressList* addresses,
              const CompletionCallback& callback,
              RequestHandle* out_req,
              const BoundNetLog& net_log) override {
    EXPECT_FALSE(callback.is_null());
    EXPECT_TRUE(out_req);

    if (!action_.is_null())
      action_.Run();

    // Indicate to the caller that a request was received.
    EXPECT_TRUE(waiting_for_resolve_);
    base::MessageLoop::current()->Quit();

    // This line is intentionally after action_.Run(), since one of the
    // tests does a cancellation inside of Resolve(), and it is more
    // interesting if *out_req hasn't been written yet at that point.
    *out_req = reinterpret_cast<RequestHandle*>(1);  // Magic value.

    // Return ERR_IO_PENDING as this request will NEVER be completed.
    // Expectation is for the caller to later cancel the request.
    return ERR_IO_PENDING;
  }

  int ResolveFromCache(const RequestInfo& info,
                       AddressList* addresses,
                       const BoundNetLog& net_log) override {
    NOTREACHED();
    return ERR_DNS_CACHE_MISS;
  }

  void CancelRequest(RequestHandle req) override {
    EXPECT_EQ(reinterpret_cast<RequestHandle*>(1), req);
    num_cancelled_requests_++;
  }

  void SetAction(const base::Callback<void(void)>& action) { action_ = action; }

  // Waits until Resolve() has been called.
  void WaitUntilRequestIsReceived() {
    waiting_for_resolve_ = true;
    base::MessageLoop::current()->Run();
    DCHECK(waiting_for_resolve_);
    waiting_for_resolve_ = false;
  }

  int num_cancelled_requests() const { return num_cancelled_requests_; }

 private:
  int num_cancelled_requests_;
  bool waiting_for_resolve_;
  base::Callback<void(void)> action_;
};

// This cancellation test exercises a more predictable cancellation codepath --
// when the request has an outstanding DNS request in flight.
TEST_F(ProxyResolverV8TracingWrapperTest,
       CancelWhileOutstandingNonBlockingDns) {
  BlockableHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  scoped_ptr<ProxyResolver> resolver = CreateResolver(
      nullptr, &host_resolver, make_scoped_ptr(error_observer), "dns.js");

  ProxyInfo proxy_info1;
  ProxyInfo proxy_info2;
  ProxyResolver::RequestHandle request1;
  ProxyResolver::RequestHandle request2;

  int rv = resolver->GetProxyForURL(GURL("http://foo/req1"), &proxy_info1,
                                    base::Bind(&CrashCallback), &request1,
                                    BoundNetLog());

  EXPECT_EQ(ERR_IO_PENDING, rv);

  host_resolver.WaitUntilRequestIsReceived();

  rv = resolver->GetProxyForURL(GURL("http://foo/req2"), &proxy_info2,
                                base::Bind(&CrashCallback), &request2,
                                BoundNetLog());

  EXPECT_EQ(ERR_IO_PENDING, rv);

  host_resolver.WaitUntilRequestIsReceived();

  resolver->CancelRequest(request1);
  resolver->CancelRequest(request2);

  EXPECT_EQ(2, host_resolver.num_cancelled_requests());

  // After leaving this scope, the ProxyResolver is destroyed.
  // This should not cause any problems, as the outstanding work
  // should have been cancelled.
}

void CancelRequestAndPause(ProxyResolver* resolver,
                           ProxyResolver::RequestHandle request) {
  resolver->CancelRequest(request);

  // Sleep for a little bit. This makes it more likely for the worker
  // thread to have returned from its call, and serves as a regression
  // test for http://crbug.com/173373.
  base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(30));
}

// In non-blocking mode, the worker thread actually does block for
// a short time to see if the result is in the DNS cache. Test
// cancellation while the worker thread is waiting on this event.
TEST_F(ProxyResolverV8TracingWrapperTest, CancelWhileBlockedInNonBlockingDns) {
  BlockableHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  scoped_ptr<ProxyResolver> resolver = CreateResolver(
      nullptr, &host_resolver, make_scoped_ptr(error_observer), "dns.js");

  ProxyInfo proxy_info;
  ProxyResolver::RequestHandle request;

  int rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                                    base::Bind(&CrashCallback), &request,
                                    BoundNetLog());

  EXPECT_EQ(ERR_IO_PENDING, rv);

  host_resolver.SetAction(
      base::Bind(CancelRequestAndPause, resolver.get(), request));

  host_resolver.WaitUntilRequestIsReceived();

  // At this point the host resolver ran Resolve(), and should have cancelled
  // the request.

  EXPECT_EQ(1, host_resolver.num_cancelled_requests());
}

// Cancel the request while there is a pending DNS request, however before
// the request is sent to the host resolver.
TEST_F(ProxyResolverV8TracingWrapperTest, CancelWhileBlockedInNonBlockingDns2) {
  MockCachingHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  scoped_ptr<ProxyResolver> resolver = CreateResolver(
      nullptr, &host_resolver, make_scoped_ptr(error_observer), "dns.js");

  ProxyInfo proxy_info;
  ProxyResolver::RequestHandle request;

  int rv = resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                                    base::Bind(&CrashCallback), &request,
                                    BoundNetLog());

  EXPECT_EQ(ERR_IO_PENDING, rv);

  // Wait a bit, so the DNS task has hopefully been posted. The test will
  // work whatever the delay is here, but it is most useful if the delay
  // is large enough to allow a task to be posted back.
  base::PlatformThread::Sleep(base::TimeDelta::FromMilliseconds(10));
  resolver->CancelRequest(request);

  EXPECT_EQ(0u, host_resolver.num_resolve());
}

TEST_F(ProxyResolverV8TracingWrapperTest,
       CancelCreateResolverWhileOutstandingBlockingDns) {
  BlockableHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  ProxyResolverFactoryV8TracingWrapper factory(
      &host_resolver, nullptr,
      base::Bind(&ReturnErrorObserver,
                 base::Passed(make_scoped_ptr(error_observer))));

  scoped_ptr<ProxyResolver> resolver;
  scoped_ptr<ProxyResolverFactory::Request> request;
  int rv = factory.CreateProxyResolver(LoadScriptData("dns_during_init.js"),
                                       &resolver, base::Bind(&CrashCallback),
                                       &request);
  EXPECT_EQ(ERR_IO_PENDING, rv);

  host_resolver.WaitUntilRequestIsReceived();

  request.reset();
  EXPECT_EQ(1, host_resolver.num_cancelled_requests());
}

TEST_F(ProxyResolverV8TracingWrapperTest,
       DeleteFactoryWhileOutstandingBlockingDns) {
  BlockableHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  scoped_ptr<ProxyResolver> resolver;
  scoped_ptr<ProxyResolverFactory::Request> request;
  {
    ProxyResolverFactoryV8TracingWrapper factory(
        &host_resolver, nullptr,
        base::Bind(&ReturnErrorObserver,
                   base::Passed(make_scoped_ptr(error_observer))));

    int rv = factory.CreateProxyResolver(LoadScriptData("dns_during_init.js"),
                                         &resolver, base::Bind(&CrashCallback),
                                         &request);
    EXPECT_EQ(ERR_IO_PENDING, rv);
    host_resolver.WaitUntilRequestIsReceived();
  }
  EXPECT_EQ(1, host_resolver.num_cancelled_requests());
}

TEST_F(ProxyResolverV8TracingWrapperTest, ErrorLoadingScript) {
  BlockableHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  ProxyResolverFactoryV8TracingWrapper factory(
      &host_resolver, nullptr,
      base::Bind(&ReturnErrorObserver,
                 base::Passed(make_scoped_ptr(error_observer))));

  scoped_ptr<ProxyResolver> resolver;
  scoped_ptr<ProxyResolverFactory::Request> request;
  TestCompletionCallback callback;
  int rv =
      factory.CreateProxyResolver(LoadScriptData("error_on_load.js"), &resolver,
                                  callback.callback(), &request);
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, callback.WaitForResult());
  EXPECT_FALSE(resolver);
}

// This tests that the execution of a PAC script is terminated when the DNS
// dependencies are missing. If the test fails, then it will hang.
TEST_F(ProxyResolverV8TracingWrapperTest, Terminate) {
  TestNetLog log;
  BoundTestNetLog request_log;
  MockCachingHostResolver host_resolver;
  MockErrorObserver* error_observer = new MockErrorObserver;

  host_resolver.rules()->AddRule("host1", "182.111.0.222");
  host_resolver.rules()->AddRule("host2", "111.33.44.55");

  scoped_ptr<ProxyResolver> resolver = CreateResolver(
      &log, &host_resolver, make_scoped_ptr(error_observer), "terminate.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  int rv =
      resolver->GetProxyForURL(GURL("http://foopy/req1"), &proxy_info,
                               callback.callback(), NULL, request_log.bound());

  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(OK, callback.WaitForResult());

  // The test does 2 DNS resolutions.
  EXPECT_EQ(2u, host_resolver.num_resolve());

  EXPECT_EQ("foopy:3", proxy_info.proxy_server().ToURI());

  // No errors.
  EXPECT_EQ("", error_observer->GetOutput());

  EXPECT_EQ(0u, log.GetSize());
  EXPECT_EQ(0u, request_log.GetSize());
}

// Tests that multiple instances of ProxyResolverV8TracingWrapper can coexist
// and run correctly at the same time. This is relevant because at the moment
// (time this test was written) each ProxyResolverV8TracingWrapper creates its
// own thread to run V8 on, however each thread is operating on the same
// v8::Isolate.
TEST_F(ProxyResolverV8TracingWrapperTest, MultipleResolvers) {
  // ------------------------
  // Setup resolver0
  // ------------------------
  MockHostResolver host_resolver0;
  host_resolver0.rules()->AddRuleForAddressFamily("host1", ADDRESS_FAMILY_IPV4,
                                                  "166.155.144.44");
  host_resolver0.rules()->AddIPLiteralRule("host1", "::1,192.168.1.1",
                                           std::string());
  host_resolver0.rules()->AddSimulatedFailure("host2");
  host_resolver0.rules()->AddRule("host3", "166.155.144.33");
  host_resolver0.rules()->AddRule("host5", "166.155.144.55");
  host_resolver0.rules()->AddSimulatedFailure("host6");
  host_resolver0.rules()->AddRuleForAddressFamily("*", ADDRESS_FAMILY_IPV4,
                                                  "122.133.144.155");
  host_resolver0.rules()->AddRule("*", "133.122.100.200");
  scoped_ptr<ProxyResolver> resolver0 =
      CreateResolver(nullptr, &host_resolver0,
                     make_scoped_ptr(new MockErrorObserver), "dns.js");

  // ------------------------
  // Setup resolver1
  // ------------------------
  scoped_ptr<ProxyResolver> resolver1 =
      CreateResolver(nullptr, &host_resolver0,
                     make_scoped_ptr(new MockErrorObserver), "dns.js");

  // ------------------------
  // Setup resolver2
  // ------------------------
  scoped_ptr<ProxyResolver> resolver2 =
      CreateResolver(nullptr, &host_resolver0,
                     make_scoped_ptr(new MockErrorObserver), "simple.js");

  // ------------------------
  // Setup resolver3
  // ------------------------
  MockHostResolver host_resolver3;
  host_resolver3.rules()->AddRule("foo", "166.155.144.33");
  scoped_ptr<ProxyResolver> resolver3 =
      CreateResolver(nullptr, &host_resolver3,
                     make_scoped_ptr(new MockErrorObserver), "simple_dns.js");

  // ------------------------
  // Queue up work for each resolver (which will be running in parallel).
  // ------------------------

  ProxyResolver* resolver[] = {
      resolver0.get(), resolver1.get(), resolver2.get(), resolver3.get(),
  };

  const size_t kNumResolvers = arraysize(resolver);
  const size_t kNumIterations = 20;
  const size_t kNumResults = kNumResolvers * kNumIterations;
  TestCompletionCallback callback[kNumResults];
  ProxyInfo proxy_info[kNumResults];

  for (size_t i = 0; i < kNumResults; ++i) {
    size_t resolver_i = i % kNumResolvers;
    int rv = resolver[resolver_i]->GetProxyForURL(
        GURL("http://foo/"), &proxy_info[i], callback[i].callback(), NULL,
        BoundNetLog());
    EXPECT_EQ(ERR_IO_PENDING, rv);
  }

  // ------------------------
  // Verify all of the results.
  // ------------------------

  const char* kExpectedForDnsJs =
      "122.133.144.155-"  // myIpAddress()
      "null-"             // dnsResolve('')
      "__1_192.168.1.1-"  // dnsResolveEx('host1')
      "null-"             // dnsResolve('host2')
      "166.155.144.33-"   // dnsResolve('host3')
      "122.133.144.155-"  // myIpAddress()
      "166.155.144.33-"   // dnsResolve('host3')
      "__1_192.168.1.1-"  // dnsResolveEx('host1')
      "122.133.144.155-"  // myIpAddress()
      "null-"             // dnsResolve('host2')
      "-"                 // dnsResolveEx('host6')
      "133.122.100.200-"  // myIpAddressEx()
      "166.155.144.44"    // dnsResolve('host1')
      ":99";

  for (size_t i = 0; i < kNumResults; ++i) {
    size_t resolver_i = i % kNumResolvers;
    EXPECT_EQ(OK, callback[i].WaitForResult());

    std::string proxy_uri = proxy_info[i].proxy_server().ToURI();

    if (resolver_i == 0 || resolver_i == 1) {
      EXPECT_EQ(kExpectedForDnsJs, proxy_uri);
    } else if (resolver_i == 2) {
      EXPECT_EQ("foo:99", proxy_uri);
    } else if (resolver_i == 3) {
      EXPECT_EQ("166.155.144.33:",
                proxy_uri.substr(0, proxy_uri.find(':') + 1));
    } else {
      NOTREACHED();
    }
  }
}

}  // namespace

}  // namespace net
