// 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.h"

#include <string>

#include "base/files/file_util.h"
#include "base/path_service.h"
#include "base/run_loop.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/proxy/proxy_info.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "url/gurl.h"

namespace net {

namespace {

class ProxyResolverV8TracingTest : 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::RunLoop().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);
}

class MockBindings {
 public:
  explicit MockBindings(HostResolver* host_resolver)
      : host_resolver_(host_resolver), event_(true, false) {}

  void Alert(const base::string16& message) {
    base::AutoLock l(lock_);
    alerts_.push_back(base::UTF16ToASCII(message));
  }
  void OnError(int line_number, const base::string16& error) {
    base::AutoLock l(lock_);
    errors_.push_back(std::make_pair(line_number, base::UTF16ToASCII(error)));
    event_.Signal();
  }

  HostResolver* host_resolver() { return host_resolver_; }

  std::vector<std::string> GetAlerts() {
    base::AutoLock l(lock_);
    return alerts_;
  }

  std::vector<std::pair<int, std::string>> GetErrors() {
    base::AutoLock l(lock_);
    return errors_;
  }

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

  scoped_ptr<ProxyResolverV8Tracing::Bindings> CreateBindings() {
    return make_scoped_ptr(new ForwardingBindings(this));
  }

 private:
  class ForwardingBindings : public ProxyResolverV8Tracing::Bindings {
   public:
    ForwardingBindings(MockBindings* bindings) : bindings_(bindings) {}

    // ProxyResolverV8Tracing::Bindings overrides.
    void Alert(const base::string16& message) override {
      bindings_->Alert(message);
    }

    void OnError(int line_number, const base::string16& error) override {
      bindings_->OnError(line_number, error);
    }

    BoundNetLog GetBoundNetLog() override { return BoundNetLog(); }

    HostResolver* GetHostResolver() override {
      return bindings_->host_resolver();
    }

   private:
    MockBindings* bindings_;
  };

  base::Lock lock_;
  std::vector<std::string> alerts_;
  std::vector<std::pair<int, std::string>> errors_;
  HostResolver* const host_resolver_;

  base::WaitableEvent event_;
};

scoped_ptr<ProxyResolverV8Tracing> CreateResolver(
    scoped_ptr<ProxyResolverV8Tracing::Bindings> bindings,
    const char* filename) {
  scoped_ptr<ProxyResolverV8Tracing> resolver;
  scoped_ptr<ProxyResolverV8TracingFactory> factory(
      ProxyResolverV8TracingFactory::Create());
  TestCompletionCallback callback;
  scoped_ptr<ProxyResolverFactory::Request> request;
  factory->CreateProxyResolverV8Tracing(LoadScriptData(filename),
                                        bindings.Pass(), &resolver,
                                        callback.callback(), &request);
  EXPECT_EQ(OK, callback.WaitForResult());
  EXPECT_TRUE(resolver);
  return resolver.Pass();
}

TEST_F(ProxyResolverV8TracingTest, Simple) {
  MockCachingHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

  scoped_ptr<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "simple.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                           callback.callback(), NULL,
                           mock_bindings.CreateBindings());

  EXPECT_EQ(OK, callback.WaitForResult());

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

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

  // There were no alerts or errors.
  EXPECT_TRUE(mock_bindings.GetAlerts().empty());
  EXPECT_TRUE(mock_bindings.GetErrors().empty());
}

TEST_F(ProxyResolverV8TracingTest, JavascriptError) {
  MockCachingHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

  scoped_ptr<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "error.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  resolver->GetProxyForURL(GURL("http://throw-an-error/"), &proxy_info,
                           callback.callback(), NULL,
                           mock_bindings.CreateBindings());

  EXPECT_EQ(ERR_PAC_SCRIPT_FAILED, callback.WaitForResult());

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

  // Check the output -- there was 1 alert and 1 javascript error.
  ASSERT_EQ(1u, mock_bindings.GetAlerts().size());
  EXPECT_EQ("Prepare to DIE!", mock_bindings.GetAlerts()[0]);
  ASSERT_EQ(1u, mock_bindings.GetErrors().size());
  EXPECT_EQ(5, mock_bindings.GetErrors()[0].first);
  EXPECT_EQ("Uncaught TypeError: Cannot read property 'split' of null",
            mock_bindings.GetErrors()[0].second);
}

TEST_F(ProxyResolverV8TracingTest, TooManyAlerts) {
  MockCachingHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

  scoped_ptr<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "too_many_alerts.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                           callback.callback(), NULL,
                           mock_bindings.CreateBindings());

  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_TRUE(mock_bindings.GetErrors().empty());

  // Check the alerts -- the script generated 50 alerts.
  std::vector<std::string> alerts = mock_bindings.GetAlerts();
  ASSERT_EQ(50u, alerts.size());
  for (size_t i = 0; i < alerts.size(); i++) {
    EXPECT_EQ("Gee, all these alerts are silly!", alerts[i]);
  }
}

// Verify that buffered alerts cannot grow unboundedly, even when the message is
// empty string.
TEST_F(ProxyResolverV8TracingTest, TooManyEmptyAlerts) {
  MockCachingHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

  scoped_ptr<ProxyResolverV8Tracing> resolver = CreateResolver(
      mock_bindings.CreateBindings(), "too_many_empty_alerts.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                           callback.callback(), NULL,
                           mock_bindings.CreateBindings());

  EXPECT_EQ(OK, callback.WaitForResult());

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

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

  // No errors.
  EXPECT_TRUE(mock_bindings.GetErrors().empty());

  // Check the alerts -- the script generated 1000 alerts.
  std::vector<std::string> alerts = mock_bindings.GetAlerts();
  ASSERT_EQ(1000u, alerts.size());
  for (size_t i = 0; i < alerts.size(); i++) {
    EXPECT_EQ("", alerts[i]);
  }
}

// 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(ProxyResolverV8TracingTest, Dns) {
  MockCachingHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

  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<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "dns.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                           callback.callback(), NULL,
                           mock_bindings.CreateBindings());

  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_TRUE(mock_bindings.GetErrors().empty());

  // The script generated 1 alert.
  ASSERT_EQ(1u, mock_bindings.GetAlerts().size());
  EXPECT_EQ("iteration: 7", mock_bindings.GetAlerts()[0]);
}

// 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(ProxyResolverV8TracingTest, DnsChecksCache) {
  MockCachingHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

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

  scoped_ptr<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "simple_dns.js");

  TestCompletionCallback callback1;
  TestCompletionCallback callback2;
  ProxyInfo proxy_info;

  resolver->GetProxyForURL(GURL("http://foopy/req1"), &proxy_info,
                           callback1.callback(), NULL,
                           mock_bindings.CreateBindings());

  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());

  resolver->GetProxyForURL(GURL("http://foopy/req2"), &proxy_info,
                           callback2.callback(), NULL,
                           mock_bindings.CreateBindings());

  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());

  // There were no alerts or errors.
  EXPECT_TRUE(mock_bindings.GetAlerts().empty());
  EXPECT_TRUE(mock_bindings.GetErrors().empty());
}

// 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(ProxyResolverV8TracingTest, FallBackToSynchronous1) {
  MockCachingHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

  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<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "global_sideffects1.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                           callback.callback(), NULL,
                           mock_bindings.CreateBindings());
  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_TRUE(mock_bindings.GetErrors().empty());

  ASSERT_EQ(1u, mock_bindings.GetAlerts().size());
  EXPECT_EQ("iteration: 4", mock_bindings.GetAlerts()[0]);
}

// 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(ProxyResolverV8TracingTest, FallBackToSynchronous2) {
  MockCachingHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

  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<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "global_sideffects2.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                           callback.callback(), NULL,
                           mock_bindings.CreateBindings());
  EXPECT_EQ(OK, callback.WaitForResult());

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

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

  // There were no alerts or errors.
  EXPECT_TRUE(mock_bindings.GetAlerts().empty());
  EXPECT_TRUE(mock_bindings.GetErrors().empty());
}

// 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(ProxyResolverV8TracingTest, InfiniteDNSSequence) {
  MockCachingHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

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

  scoped_ptr<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "global_sideffects3.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                           callback.callback(), NULL,
                           mock_bindings.CreateBindings());
  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_TRUE(mock_bindings.GetErrors().empty());

  // 1 alert.
  EXPECT_EQ(1u, mock_bindings.GetAlerts().size());
  EXPECT_EQ("iteration: 21", mock_bindings.GetAlerts()[0]);
}

// 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(ProxyResolverV8TracingTest, InfiniteDNSSequence2) {
  MockCachingHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

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

  scoped_ptr<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "global_sideffects4.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                           callback.callback(), NULL,
                           mock_bindings.CreateBindings());
  EXPECT_EQ(OK, callback.WaitForResult());

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

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

  // No errors.
  EXPECT_TRUE(mock_bindings.GetErrors().empty());

  // 1 alert.
  EXPECT_EQ(1u, mock_bindings.GetAlerts().size());
  EXPECT_EQ("iteration: 21", mock_bindings.GetAlerts()[0]);
}

void DnsDuringInitHelper(bool synchronous_host_resolver) {
  MockCachingHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);
  host_resolver.set_synchronous_mode(synchronous_host_resolver);

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

  scoped_ptr<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "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;

  resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                           callback.callback(), NULL,
                           mock_bindings.CreateBindings());
  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());

  // 2 alerts.
  ASSERT_EQ(2u, mock_bindings.GetAlerts().size());
  EXPECT_EQ("Watsup", mock_bindings.GetAlerts()[0]);
  EXPECT_EQ("Watsup2", mock_bindings.GetAlerts()[1]);
}

// Tests a PAC script which does DNS resolves during initialization.
TEST_F(ProxyResolverV8TracingTest, 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(ProxyResolverV8TracingTest, CancelAll) {
  MockCachingHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

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

  scoped_ptr<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "dns.js");

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

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

  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(ProxyResolverV8TracingTest, CancelSome) {
  MockCachingHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

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

  scoped_ptr<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "dns.js");

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

  resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info1,
                           base::Bind(&CrashCallback), &request1,
                           mock_bindings.CreateBindings());
  resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info2,
                           callback.callback(), &request2,
                           mock_bindings.CreateBindings());

  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(ProxyResolverV8TracingTest, CancelWhilePendingCompletionTask) {
  MockCachingHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

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

  scoped_ptr<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "error.js");

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

  resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info1,
                           base::Bind(&CrashCallback), &request1,
                           mock_bindings.CreateBindings());

  resolver->GetProxyForURL(GURL("http://throw-an-error"), &proxy_info2,
                           callback.callback(), &request2,
                           mock_bindings.CreateBindings());

  // Wait until the first request has finished running on the worker thread.
  // (The second request will output an error).
  mock_bindings.WaitForError();

  // 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.
  resolver->GetProxyForURL(GURL("http://i-have-no-idea-what-im-doing/"),
                           &proxy_info3, callback.callback(), &request3,
                           mock_bindings.CreateBindings());

  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(ProxyResolverV8TracingTest, CancelWhileOutstandingNonBlockingDns) {
  BlockableHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

  scoped_ptr<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "dns.js");

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

  resolver->GetProxyForURL(GURL("http://foo/req1"), &proxy_info1,
                           base::Bind(&CrashCallback), &request1,
                           mock_bindings.CreateBindings());

  host_resolver.WaitUntilRequestIsReceived();

  resolver->GetProxyForURL(GURL("http://foo/req2"), &proxy_info2,
                           base::Bind(&CrashCallback), &request2,
                           mock_bindings.CreateBindings());

  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(ProxyResolverV8Tracing* 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(ProxyResolverV8TracingTest, CancelWhileBlockedInNonBlockingDns) {
  BlockableHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

  scoped_ptr<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "dns.js");

  ProxyInfo proxy_info;
  ProxyResolver::RequestHandle request;

  resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                           base::Bind(&CrashCallback), &request,
                           mock_bindings.CreateBindings());

  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(ProxyResolverV8TracingTest, CancelWhileBlockedInNonBlockingDns2) {
  MockCachingHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

  scoped_ptr<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "dns.js");

  ProxyInfo proxy_info;
  ProxyResolver::RequestHandle request;

  resolver->GetProxyForURL(GURL("http://foo/"), &proxy_info,
                           base::Bind(&CrashCallback), &request,
                           mock_bindings.CreateBindings());

  // 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(ProxyResolverV8TracingTest,
       CancelCreateResolverWhileOutstandingBlockingDns) {
  BlockableHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

  scoped_ptr<ProxyResolverV8TracingFactory> factory(
      ProxyResolverV8TracingFactory::Create());
  scoped_ptr<ProxyResolverV8Tracing> resolver;
  scoped_ptr<ProxyResolverFactory::Request> request;
  factory->CreateProxyResolverV8Tracing(
      LoadScriptData("dns_during_init.js"), mock_bindings.CreateBindings(),
      &resolver, base::Bind(&CrashCallback), &request);

  host_resolver.WaitUntilRequestIsReceived();

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

TEST_F(ProxyResolverV8TracingTest, DeleteFactoryWhileOutstandingBlockingDns) {
  BlockableHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

  scoped_ptr<ProxyResolverV8Tracing> resolver;
  scoped_ptr<ProxyResolverFactory::Request> request;
  {
    scoped_ptr<ProxyResolverV8TracingFactory> factory(
        ProxyResolverV8TracingFactory::Create());

    factory->CreateProxyResolverV8Tracing(
        LoadScriptData("dns_during_init.js"), mock_bindings.CreateBindings(),
        &resolver, base::Bind(&CrashCallback), &request);
    host_resolver.WaitUntilRequestIsReceived();
  }
  EXPECT_EQ(1, host_resolver.num_cancelled_requests());
}

TEST_F(ProxyResolverV8TracingTest, ErrorLoadingScript) {
  BlockableHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

  scoped_ptr<ProxyResolverV8TracingFactory> factory(
      ProxyResolverV8TracingFactory::Create());
  scoped_ptr<ProxyResolverV8Tracing> resolver;
  scoped_ptr<ProxyResolverFactory::Request> request;
  TestCompletionCallback callback;
  factory->CreateProxyResolverV8Tracing(
      LoadScriptData("error_on_load.js"), mock_bindings.CreateBindings(),
      &resolver, callback.callback(), &request);

  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(ProxyResolverV8TracingTest, Terminate) {
  MockCachingHostResolver host_resolver;
  MockBindings mock_bindings(&host_resolver);

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

  scoped_ptr<ProxyResolverV8Tracing> resolver =
      CreateResolver(mock_bindings.CreateBindings(), "terminate.js");

  TestCompletionCallback callback;
  ProxyInfo proxy_info;

  resolver->GetProxyForURL(GURL("http://foopy/req1"), &proxy_info,
                           callback.callback(), NULL,
                           mock_bindings.CreateBindings());
  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 or alerts.
  EXPECT_TRUE(mock_bindings.GetErrors().empty());
  EXPECT_TRUE(mock_bindings.GetAlerts().empty());
}

// Tests that multiple instances of ProxyResolverV8Tracing can coexist and run
// correctly at the same time. This is relevant because at the moment (time
// this test was written) each ProxyResolverV8Tracing creates its own thread to
// run V8 on, however each thread is operating on the same v8::Isolate.
TEST_F(ProxyResolverV8TracingTest, MultipleResolvers) {
  // ------------------------
  // Setup resolver0
  // ------------------------
  MockHostResolver host_resolver0;
  MockBindings mock_bindings0(&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<ProxyResolverV8Tracing> resolver0 =
      CreateResolver(mock_bindings0.CreateBindings(), "dns.js");

  // ------------------------
  // Setup resolver1
  // ------------------------
  scoped_ptr<ProxyResolverV8Tracing> resolver1 =
      CreateResolver(mock_bindings0.CreateBindings(), "dns.js");

  // ------------------------
  // Setup resolver2
  // ------------------------
  scoped_ptr<ProxyResolverV8Tracing> resolver2 =
      CreateResolver(mock_bindings0.CreateBindings(), "simple.js");

  // ------------------------
  // Setup resolver3
  // ------------------------
  MockHostResolver host_resolver3;
  MockBindings mock_bindings3(&host_resolver3);
  host_resolver3.rules()->AddRule("foo", "166.155.144.33");
  scoped_ptr<ProxyResolverV8Tracing> resolver3 =
      CreateResolver(mock_bindings3.CreateBindings(), "simple_dns.js");

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

  ProxyResolverV8Tracing* 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;
    resolver[resolver_i]->GetProxyForURL(
        GURL("http://foo/"), &proxy_info[i], callback[i].callback(), NULL,
        resolver_i == 3 ? mock_bindings3.CreateBindings()
                        : mock_bindings0.CreateBindings());
  }

  // ------------------------
  // 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
