// Copyright (c) 2012 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/dns/single_request_host_resolver.h"

#include "net/base/address_list.h"
#include "net/base/net_errors.h"
#include "net/base/test_completion_callback.h"
#include "net/dns/mock_host_resolver.h"
#include "net/log/net_log.h"
#include "testing/gtest/include/gtest/gtest.h"

namespace net {

namespace {

// Helper class used by SingleRequestHostResolverTest.Cancel test.
// It checks that only one request is outstanding at a time, and that
// it is cancelled before the class is destroyed.
class HangingHostResolver : public HostResolver {
 public:
  HangingHostResolver() : outstanding_request_(NULL) {}

  ~HangingHostResolver() override { EXPECT_TRUE(!has_outstanding_request()); }

  bool has_outstanding_request() const {
    return outstanding_request_ != NULL;
  }

  int Resolve(const RequestInfo& info,
              RequestPriority priority,
              AddressList* addresses,
              const CompletionCallback& callback,
              RequestHandle* out_req,
              const BoundNetLog& net_log) override {
    EXPECT_FALSE(has_outstanding_request());
    outstanding_request_ = reinterpret_cast<RequestHandle>(0x1234);
    *out_req = outstanding_request_;

    // Never complete this request! Caller is expected to cancel it
    // before destroying the resolver.
    return ERR_IO_PENDING;
  }

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

  void CancelRequest(RequestHandle req) override {
    EXPECT_TRUE(has_outstanding_request());
    EXPECT_EQ(req, outstanding_request_);
    outstanding_request_ = NULL;
  }

 private:
  RequestHandle outstanding_request_;

  DISALLOW_COPY_AND_ASSIGN(HangingHostResolver);
};

// Test that a regular end-to-end lookup returns the expected result.
TEST(SingleRequestHostResolverTest, NormalResolve) {
  // Create a host resolver dependency that returns address "199.188.1.166"
  // for resolutions of "watsup".
  MockHostResolver resolver;
  resolver.rules()->AddIPLiteralRule("watsup", "199.188.1.166", std::string());

  SingleRequestHostResolver single_request_resolver(&resolver);

  // Resolve "watsup:90" using our SingleRequestHostResolver.
  AddressList addrlist;
  TestCompletionCallback callback;
  HostResolver::RequestInfo request(HostPortPair("watsup", 90));
  int rv = single_request_resolver.Resolve(
      request, DEFAULT_PRIORITY, &addrlist, callback.callback(), BoundNetLog());
  EXPECT_EQ(ERR_IO_PENDING, rv);
  EXPECT_EQ(OK, callback.WaitForResult());

  // Verify that the result is what we specified in the MockHostResolver.
  ASSERT_FALSE(addrlist.empty());
  EXPECT_EQ("199.188.1.166", addrlist.front().ToStringWithoutPort());
}

// Test that the Cancel() method cancels any outstanding request.
TEST(SingleRequestHostResolverTest, Cancel) {
  HangingHostResolver resolver;

  {
    SingleRequestHostResolver single_request_resolver(&resolver);

    // Resolve "watsup:90" using our SingleRequestHostResolver.
    AddressList addrlist;
    TestCompletionCallback callback;
    HostResolver::RequestInfo request(HostPortPair("watsup", 90));
    int rv = single_request_resolver.Resolve(request,
                                             DEFAULT_PRIORITY,
                                             &addrlist,
                                             callback.callback(),
                                             BoundNetLog());
    EXPECT_EQ(ERR_IO_PENDING, rv);
    EXPECT_TRUE(resolver.has_outstanding_request());
  }

  // Now that the SingleRequestHostResolver has been destroyed, the
  // in-progress request should have been aborted.
  EXPECT_FALSE(resolver.has_outstanding_request());
}

// Test that the Cancel() method is a no-op when there is no outstanding
// request.
TEST(SingleRequestHostResolverTest, CancelWhileNoPendingRequest) {
  HangingHostResolver resolver;
  SingleRequestHostResolver single_request_resolver(&resolver);
  single_request_resolver.Cancel();

  // To pass, HangingHostResolver should not have received a cancellation
  // request (since there is nothing to cancel). If it does, it will crash.
}

} // namespace

}  // namespace net
