15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright (c) 2012 The Chromium Authors. All rights reserved.
25821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Use of this source code is governed by a BSD-style license that can be
35821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// found in the LICENSE file.
45821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
55821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/command_line.h"
65821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/memory/ref_counted.h"
7b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "base/message_loop/message_loop_proxy.h"
85821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/synchronization/waitable_event.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/threading/thread.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/values.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/service/cloud_print/cloud_print_url_fetcher.h"
125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "chrome/service/service_process.h"
13b2df76ea8fec9e32f6f3718986dba0d95315b29cTorne (Richard Coles)#include "net/test/spawned_test_server/spawned_test_server.h"
145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_test_util.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_throttler_manager.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
197dbb3d5cf0c15f500944d211057644d6a2f37371Ben Murdoch#include "url/gurl.h"
205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::Time;
225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)using base::TimeDelta;
235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
242a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace cloud_print {
255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
262a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)const base::FilePath::CharType kDocRoot[] =
272a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    FILE_PATH_LITERAL("chrome/test/data");
285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)int g_request_context_getter_instances = 0;
305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TrackingTestURLRequestContextGetter
312a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    : public net::TestURLRequestContextGetter {
325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit TrackingTestURLRequestContextGetter(
345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::MessageLoopProxy* io_message_loop_proxy,
355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      net::URLRequestThrottlerManager* throttler_manager)
365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : TestURLRequestContextGetter(io_message_loop_proxy),
377d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)        throttler_manager_(throttler_manager) {
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_request_context_getter_instances++;
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual net::TestURLRequestContext* GetURLRequestContext() OVERRIDE {
425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!context_.get()) {
432a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      context_.reset(new net::TestURLRequestContext(true));
445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_->set_throttler_manager(throttler_manager_);
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_->Init();
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return context_.get();
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TrackingTestURLRequestContextGetter() {
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_request_context_getter_instances--;
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Not owned here.
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestThrottlerManager* throttler_manager_;
582a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<net::TestURLRequestContext> context_;
595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestCloudPrintURLFetcher : public CloudPrintURLFetcher {
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit TestCloudPrintURLFetcher(
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::MessageLoopProxy* io_message_loop_proxy)
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : io_message_loop_proxy_(io_message_loop_proxy) {
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
682a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual net::URLRequestContextGetter* GetRequestContextGetter() OVERRIDE {
695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new TrackingTestURLRequestContextGetter(
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        io_message_loop_proxy_.get(), throttler_manager());
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestThrottlerManager* throttler_manager() {
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &throttler_manager_;
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TestCloudPrintURLFetcher() {}
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We set this as the throttler manager for the
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TestURLRequestContext we create.
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestThrottlerManager throttler_manager_;
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CloudPrintURLFetcherTest : public testing::Test,
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 public CloudPrintURLFetcherDelegate {
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CloudPrintURLFetcherTest() : max_retries_(0), fetcher_(NULL) { }
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a URLFetcher, using the program's main thread to do IO.
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CreateFetcher(const GURL& url, int max_retries);
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CloudPrintURLFetcher::Delegate
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual CloudPrintURLFetcher::ResponseAction HandleRawResponse(
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLFetcher* source,
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& url,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLRequestStatus& status,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int response_code,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::ResponseCookies& cookies,
1022a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& data) OVERRIDE;
1035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1042a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual CloudPrintURLFetcher::ResponseAction OnRequestAuthError() OVERRIDE {
1055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_FAILURE();
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return CloudPrintURLFetcher::STOP_PROCESSING;
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1092a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual std::string GetAuthHeader() OVERRIDE {
1105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::string();
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy() {
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return io_message_loop_proxy_;
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    testing::Test::SetUp();
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_message_loop_proxy_ = base::MessageLoopProxy::current();
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher_ = NULL;
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Deleting the fetcher causes a task to be posted to the IO thread to
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // release references to the URLRequestContextGetter. We need to run all
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // pending tasks to execute that (this is the IO thread).
129a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    base::MessageLoop::current()->RunUntilIdle();
1305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, g_request_context_getter_instances);
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URLFetcher is designed to run on the main UI thread, but in our tests
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we assume that the current thread is the IO thread where the URLFetcher
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // dispatches its requests to.  When we wish to simulate being used from
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a UI thread, we dispatch a worker thread to do so.
137a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::MessageLoopForIO io_loop_;
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int max_retries_;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Time start_time_;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TestCloudPrintURLFetcher> fetcher_;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CloudPrintURLFetcherBasicTest : public CloudPrintURLFetcherTest {
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CloudPrintURLFetcherBasicTest()
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : handle_raw_response_(false), handle_raw_data_(false) { }
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CloudPrintURLFetcher::Delegate
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual CloudPrintURLFetcher::ResponseAction HandleRawResponse(
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLFetcher* source,
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& url,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLRequestStatus& status,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int response_code,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::ResponseCookies& cookies,
1552a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& data) OVERRIDE;
1565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual CloudPrintURLFetcher::ResponseAction HandleRawData(
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLFetcher* source,
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& url,
1602a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& data) OVERRIDE;
1615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual CloudPrintURLFetcher::ResponseAction HandleJSONData(
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLFetcher* source,
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& url,
1655d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)      base::DictionaryValue* json_data,
1662a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool succeeded) OVERRIDE;
1675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetHandleRawResponse(bool handle_raw_response) {
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handle_raw_response_ = handle_raw_response;
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetHandleRawData(bool handle_raw_data) {
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handle_raw_data_ = handle_raw_data;
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handle_raw_response_;
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handle_raw_data_;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Version of CloudPrintURLFetcherTest that tests overload protection.
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CloudPrintURLFetcherOverloadTest : public CloudPrintURLFetcherTest {
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CloudPrintURLFetcherOverloadTest() : response_count_(0) {
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CloudPrintURLFetcher::Delegate
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual CloudPrintURLFetcher::ResponseAction HandleRawData(
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLFetcher* source,
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& url,
1892a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& data) OVERRIDE;
1905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int response_count_;
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Version of CloudPrintURLFetcherTest that tests backoff protection.
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CloudPrintURLFetcherRetryBackoffTest : public CloudPrintURLFetcherTest {
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CloudPrintURLFetcherRetryBackoffTest() : response_count_(0) {
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CloudPrintURLFetcher::Delegate
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual CloudPrintURLFetcher::ResponseAction HandleRawData(
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLFetcher* source,
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& url,
2052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& data) OVERRIDE;
2065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2072a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnRequestGiveUp() OVERRIDE;
2085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int response_count_;
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintURLFetcherTest::CreateFetcher(const GURL& url, int max_retries) {
2157d4cd473f85ac64c3747c96c277f9e506a0d2246Torne (Richard Coles)  fetcher_ = new TestCloudPrintURLFetcher(io_message_loop_proxy().get());
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Registers an entry for test url. It only allows 3 requests to be sent
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in 200 milliseconds.
219c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<net::URLRequestThrottlerEntry>
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  entry(new net::URLRequestThrottlerEntry(
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fetcher_->throttler_manager(), std::string(), 200, 3, 1, 2.0, 0.0, 256));
222868fa2fe829687343ffae624259930155e16dbd8Torne (Richard Coles)  fetcher_->throttler_manager()->OverrideEntryForTests(url, entry.get());
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  max_retries_ = max_retries;
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  start_time_ = Time::Now();
2260f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)  fetcher_->StartGetRequest(CloudPrintURLFetcher::REQUEST_MAX, url, this,
2270f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                            max_retries_, std::string());
2285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2305821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcher::ResponseAction
2315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcherTest::HandleRawResponse(
2325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::URLFetcher* source,
2335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
2345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::URLRequestStatus& status,
2355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int response_code,
2365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::ResponseCookies& cookies,
2375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& data) {
2385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(status.is_success());
2395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response_code);  // HTTP OK
2405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(data.empty());
2415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CloudPrintURLFetcher::CONTINUE_PROCESSING;
2425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcher::ResponseAction
2455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcherBasicTest::HandleRawResponse(
2465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::URLFetcher* source,
2475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
2485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::URLRequestStatus& status,
2495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    int response_code,
2505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::ResponseCookies& cookies,
2515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& data) {
2525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(status.is_success());
2535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_EQ(200, response_code);  // HTTP OK
2545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(data.empty());
2555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (handle_raw_response_) {
2575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // If the current message loop is not the IO loop, it will be shut down when
2585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // the main loop returns and this thread subsequently goes out of scope.
259a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    io_message_loop_proxy()->PostTask(FROM_HERE,
260a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                      base::MessageLoop::QuitClosure());
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return CloudPrintURLFetcher::STOP_PROCESSING;
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CloudPrintURLFetcher::CONTINUE_PROCESSING;
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcher::ResponseAction
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcherBasicTest::HandleRawData(
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::URLFetcher* source,
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& data) {
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should never get here if we returned true in HandleRawResponse
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_raw_response_);
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (handle_raw_data_) {
274a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    io_message_loop_proxy()->PostTask(FROM_HERE,
275a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                      base::MessageLoop::QuitClosure());
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return CloudPrintURLFetcher::STOP_PROCESSING;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CloudPrintURLFetcher::CONTINUE_PROCESSING;
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcher::ResponseAction
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcherBasicTest::HandleJSONData(
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::URLFetcher* source,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
2855d1f7b1de12d16ceb2c938c56701a3e8bfa558f7Torne (Richard Coles)    base::DictionaryValue* json_data,
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool succeeded) {
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should never get here if we returned true in one of the above methods.
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_raw_response_);
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_raw_data_);
290a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  io_message_loop_proxy()->PostTask(FROM_HERE,
291a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                    base::MessageLoop::QuitClosure());
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CloudPrintURLFetcher::STOP_PROCESSING;
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcher::ResponseAction
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcherOverloadTest::HandleRawData(
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::URLFetcher* source,
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& data) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta one_second = TimeDelta::FromMilliseconds(1000);
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_count_++;
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response_count_ < 20) {
3030f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)    fetcher_->StartGetRequest(CloudPrintURLFetcher::REQUEST_MAX, url, this,
3040f1bc08d4cfcc34181b0b5cbf065c40f687bf740Torne (Richard Coles)                              max_retries_, std::string());
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have already sent 20 requests continuously. And we expect that
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // it takes more than 1 second due to the overload protection settings.
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(Time::Now() - start_time_ >= one_second);
309a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)    io_message_loop_proxy()->PostTask(FROM_HERE,
310a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                      base::MessageLoop::QuitClosure());
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CloudPrintURLFetcher::STOP_PROCESSING;
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcher::ResponseAction
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcherRetryBackoffTest::HandleRawData(
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::URLFetcher* source,
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& data) {
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_count_++;
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First attempt + 11 retries = 12 total responses.
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LE(response_count_, 12);
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CloudPrintURLFetcher::RETRY_REQUEST;
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintURLFetcherRetryBackoffTest::OnRequestGiveUp() {
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It takes more than 200 ms to finish all 11 requests.
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Time::Now() - start_time_ >= TimeDelta::FromMilliseconds(200));
329a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  io_message_loop_proxy()->PostTask(FROM_HERE,
330a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)                                    base::MessageLoop::QuitClosure());
3315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3332a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(CloudPrintURLFetcherBasicTest, HandleRawResponse) {
334c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::SpawnedTestServer test_server(net::SpawnedTestServer::TYPE_HTTP,
335c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     net::SpawnedTestServer::kLocalhost,
336c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     base::FilePath(kDocRoot));
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server.Start());
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetHandleRawResponse(true);
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateFetcher(test_server.GetURL("echo"), 0);
341a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::MessageLoop::current()->Run();
3425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(CloudPrintURLFetcherBasicTest, HandleRawData) {
345c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::SpawnedTestServer test_server(net::SpawnedTestServer::TYPE_HTTP,
346c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     net::SpawnedTestServer::kLocalhost,
347c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     base::FilePath(kDocRoot));
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server.Start());
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetHandleRawData(true);
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateFetcher(test_server.GetURL("echo"), 0);
352a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::MessageLoop::current()->Run();
3535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPrintURLFetcherOverloadTest, Protect) {
356c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::SpawnedTestServer test_server(net::SpawnedTestServer::TYPE_HTTP,
357c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     net::SpawnedTestServer::kLocalhost,
358c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     base::FilePath(kDocRoot));
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server.Start());
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url(test_server.GetURL("defaultresponse"));
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateFetcher(url, 11);
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
364a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::MessageLoop::current()->Run();
3655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(CloudPrintURLFetcherRetryBackoffTest, GiveUp) {
368c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::SpawnedTestServer test_server(net::SpawnedTestServer::TYPE_HTTP,
369c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     net::SpawnedTestServer::kLocalhost,
370c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     base::FilePath(kDocRoot));
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server.Start());
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url(test_server.GetURL("defaultresponse"));
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateFetcher(url, 11);
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
376a93a17c8d99d686bd4a1511e5504e5e6cc9fcadfTorne (Richard Coles)  base::MessageLoop::current()->Run();
3775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3792a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cloud_print
380