cloud_print_url_fetcher_unittest.cc revision c2e0dbddbe15c98d52c4786dac06cb8952a8ae6d
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"
75821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/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"
135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "googleurl/src/gurl.h"
14c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)#include "net/test/spawned_test_server.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_context_getter.h"
165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_status.h"
175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_test_util.h"
185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "net/url_request/url_request_throttler_manager.h"
195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "testing/gtest/include/gtest/gtest.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),
375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        throttler_manager_(throttler_manager),
385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        context_(NULL) {
395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_request_context_getter_instances++;
405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
422a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual net::TestURLRequestContext* GetURLRequestContext() OVERRIDE {
435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    if (!context_.get()) {
442a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      context_.reset(new net::TestURLRequestContext(true));
455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_->set_throttler_manager(throttler_manager_);
465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      context_->Init();
475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    }
485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return context_.get();
495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TrackingTestURLRequestContextGetter() {
535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    g_request_context_getter_instances--;
545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Not owned here.
585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestThrottlerManager* throttler_manager_;
592a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  scoped_ptr<net::TestURLRequestContext> context_;
605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class TestCloudPrintURLFetcher : public CloudPrintURLFetcher {
635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  explicit TestCloudPrintURLFetcher(
655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      base::MessageLoopProxy* io_message_loop_proxy)
665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : io_message_loop_proxy_(io_message_loop_proxy) {
675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
692a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual net::URLRequestContextGetter* GetRequestContextGetter() OVERRIDE {
705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return new TrackingTestURLRequestContextGetter(
715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)        io_message_loop_proxy_.get(), throttler_manager());
725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestThrottlerManager* throttler_manager() {
755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return &throttler_manager_;
765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual ~TestCloudPrintURLFetcher() {}
805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We set this as the throttler manager for the
845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // TestURLRequestContext we create.
855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  net::URLRequestThrottlerManager throttler_manager_;
865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CloudPrintURLFetcherTest : public testing::Test,
895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                                 public CloudPrintURLFetcherDelegate {
905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CloudPrintURLFetcherTest() : max_retries_(0), fetcher_(NULL) { }
925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Creates a URLFetcher, using the program's main thread to do IO.
945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void CreateFetcher(const GURL& url, int max_retries);
955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CloudPrintURLFetcher::Delegate
975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual CloudPrintURLFetcher::ResponseAction HandleRawResponse(
985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLFetcher* source,
995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& url,
1005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLRequestStatus& status,
1015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int response_code,
1025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::ResponseCookies& cookies,
1032a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& data) OVERRIDE;
1045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1052a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual CloudPrintURLFetcher::ResponseAction OnRequestAuthError() OVERRIDE {
1065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    ADD_FAILURE();
1075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return CloudPrintURLFetcher::STOP_PROCESSING;
1085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1102a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual std::string GetAuthHeader() OVERRIDE {
1115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return std::string();
1125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy() {
1155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return io_message_loop_proxy_;
1165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) protected:
1195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void SetUp() {
1205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    testing::Test::SetUp();
1215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_message_loop_proxy_ = base::MessageLoopProxy::current();
1235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual void TearDown() {
1265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher_ = NULL;
1275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // Deleting the fetcher causes a task to be posted to the IO thread to
1285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // release references to the URLRequestContextGetter. We need to run all
1295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // pending tasks to execute that (this is the IO thread).
1302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)    MessageLoop::current()->RunUntilIdle();
1315821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_EQ(0, g_request_context_getter_instances);
1325821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1335821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // URLFetcher is designed to run on the main UI thread, but in our tests
1355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // we assume that the current thread is the IO thread where the URLFetcher
1365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // dispatches its requests to.  When we wish to simulate being used from
1375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // a UI thread, we dispatch a worker thread to do so.
1385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageLoopForIO io_loop_;
1395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<base::MessageLoopProxy> io_message_loop_proxy_;
1405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int max_retries_;
1415821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  Time start_time_;
1425821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  scoped_refptr<TestCloudPrintURLFetcher> fetcher_;
1435821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1445821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CloudPrintURLFetcherBasicTest : public CloudPrintURLFetcherTest {
1465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CloudPrintURLFetcherBasicTest()
1485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      : handle_raw_response_(false), handle_raw_data_(false) { }
1495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CloudPrintURLFetcher::Delegate
1505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual CloudPrintURLFetcher::ResponseAction HandleRawResponse(
1515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLFetcher* source,
1525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& url,
1535821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLRequestStatus& status,
1545821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      int response_code,
1555821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::ResponseCookies& cookies,
1562a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& data) OVERRIDE;
1575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual CloudPrintURLFetcher::ResponseAction HandleRawData(
1595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLFetcher* source,
1605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& url,
1612a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& data) OVERRIDE;
1625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual CloudPrintURLFetcher::ResponseAction HandleJSONData(
1645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLFetcher* source,
1655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& url,
1665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      DictionaryValue* json_data,
1672a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      bool succeeded) OVERRIDE;
1685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetHandleRawResponse(bool handle_raw_response) {
1705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handle_raw_response_ = handle_raw_response;
1715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  void SetHandleRawData(bool handle_raw_data) {
1735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    handle_raw_data_ = handle_raw_data;
1745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handle_raw_response_;
1775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  bool handle_raw_data_;
1785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Version of CloudPrintURLFetcherTest that tests overload protection.
1815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CloudPrintURLFetcherOverloadTest : public CloudPrintURLFetcherTest {
1825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CloudPrintURLFetcherOverloadTest() : response_count_(0) {
1845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
1855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CloudPrintURLFetcher::Delegate
1875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual CloudPrintURLFetcher::ResponseAction HandleRawData(
1885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLFetcher* source,
1895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& url,
1902a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& data) OVERRIDE;
1915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
1935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int response_count_;
1945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
1955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
1965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Version of CloudPrintURLFetcherTest that tests backoff protection.
1975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)class CloudPrintURLFetcherRetryBackoffTest : public CloudPrintURLFetcherTest {
1985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) public:
1995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CloudPrintURLFetcherRetryBackoffTest() : response_count_(0) {
2005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // CloudPrintURLFetcher::Delegate
2035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  virtual CloudPrintURLFetcher::ResponseAction HandleRawData(
2045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const net::URLFetcher* source,
2055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)      const GURL& url,
2062a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)      const std::string& data) OVERRIDE;
2075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2082a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)  virtual void OnRequestGiveUp() OVERRIDE;
2095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles) private:
2115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  int response_count_;
2125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)};
2135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintURLFetcherTest::CreateFetcher(const GURL& url, int max_retries) {
2165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher_ = new TestCloudPrintURLFetcher(io_message_loop_proxy());
2175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // Registers an entry for test url. It only allows 3 requests to be sent
2195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // in 200 milliseconds.
220c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  scoped_refptr<net::URLRequestThrottlerEntry>
221c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  entry(new net::URLRequestThrottlerEntry(
222c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)      fetcher_->throttler_manager(), std::string(), 200, 3, 1, 2.0, 0.0, 256));
2235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher_->throttler_manager()->OverrideEntryForTests(url, entry);
2245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  max_retries_ = max_retries;
2265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  start_time_ = Time::Now();
2275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  fetcher_->StartGetRequest(url, this, 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.
2595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_message_loop_proxy()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
2605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return CloudPrintURLFetcher::STOP_PROCESSING;
2615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CloudPrintURLFetcher::CONTINUE_PROCESSING;
2635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2645821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2655821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcher::ResponseAction
2665821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcherBasicTest::HandleRawData(
2675821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::URLFetcher* source,
2685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
2695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& data) {
2705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should never get here if we returned true in HandleRawResponse
2715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_raw_response_);
2725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (handle_raw_data_) {
2735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_message_loop_proxy()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
2745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    return CloudPrintURLFetcher::STOP_PROCESSING;
2755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
2765821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CloudPrintURLFetcher::CONTINUE_PROCESSING;
2775821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2785821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2795821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcher::ResponseAction
2805821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcherBasicTest::HandleJSONData(
2815821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::URLFetcher* source,
2825821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
2835821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    DictionaryValue* json_data,
2845821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    bool succeeded) {
2855821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // We should never get here if we returned true in one of the above methods.
2865821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_raw_response_);
2875821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_FALSE(handle_raw_data_);
2885821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io_message_loop_proxy()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
2895821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CloudPrintURLFetcher::STOP_PROCESSING;
2905821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
2915821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
2925821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcher::ResponseAction
2935821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcherOverloadTest::HandleRawData(
2945821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::URLFetcher* source,
2955821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
2965821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& data) {
2975821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  const TimeDelta one_second = TimeDelta::FromMilliseconds(1000);
2985821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_count_++;
2995821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  if (response_count_ < 20) {
3005821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    fetcher_->StartGetRequest(url,
3015821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              this,
3025821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              max_retries_,
3035821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)                              std::string());
3045821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  } else {
3055821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // We have already sent 20 requests continuously. And we expect that
3065821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    // it takes more than 1 second due to the overload protection settings.
3075821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    EXPECT_TRUE(Time::Now() - start_time_ >= one_second);
3085821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    io_message_loop_proxy()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
3095821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  }
3105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CloudPrintURLFetcher::STOP_PROCESSING;
3115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3125821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3135821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcher::ResponseAction
3145821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)CloudPrintURLFetcherRetryBackoffTest::HandleRawData(
3155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const net::URLFetcher* source,
3165821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const GURL& url,
3175821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)    const std::string& data) {
3185821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  response_count_++;
3195821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // First attempt + 11 retries = 12 total responses.
3205821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_LE(response_count_, 12);
3215821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  return CloudPrintURLFetcher::RETRY_REQUEST;
3225821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3235821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3245821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)void CloudPrintURLFetcherRetryBackoffTest::OnRequestGiveUp() {
3255821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  // It takes more than 200 ms to finish all 11 requests.
3265821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  EXPECT_TRUE(Time::Now() - start_time_ >= TimeDelta::FromMilliseconds(200));
3275821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  io_message_loop_proxy()->PostTask(FROM_HERE, MessageLoop::QuitClosure());
3285821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3295821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3302a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(CloudPrintURLFetcherBasicTest, HandleRawResponse) {
331c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::SpawnedTestServer test_server(net::SpawnedTestServer::TYPE_HTTP,
332c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     net::SpawnedTestServer::kLocalhost,
333c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     base::FilePath(kDocRoot));
3345821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server.Start());
3355821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetHandleRawResponse(true);
3365821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3375821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateFetcher(test_server.GetURL("echo"), 0);
3385821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageLoop::current()->Run();
3395821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3405821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3412a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(CloudPrintURLFetcherBasicTest, HandleRawData) {
342c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::SpawnedTestServer test_server(net::SpawnedTestServer::TYPE_HTTP,
343c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     net::SpawnedTestServer::kLocalhost,
344c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     base::FilePath(kDocRoot));
3455821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server.Start());
3465821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3475821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  SetHandleRawData(true);
3485821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateFetcher(test_server.GetURL("echo"), 0);
3495821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageLoop::current()->Run();
3505821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3515821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3525821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)TEST_F(CloudPrintURLFetcherOverloadTest, Protect) {
353c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::SpawnedTestServer test_server(net::SpawnedTestServer::TYPE_HTTP,
354c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     net::SpawnedTestServer::kLocalhost,
355c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     base::FilePath(kDocRoot));
3565821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server.Start());
3575821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3585821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url(test_server.GetURL("defaultresponse"));
3595821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateFetcher(url, 11);
3605821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3615821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageLoop::current()->Run();
3625821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3635821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3642a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)TEST_F(CloudPrintURLFetcherRetryBackoffTest, GiveUp) {
365c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)  net::SpawnedTestServer test_server(net::SpawnedTestServer::TYPE_HTTP,
366c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     net::SpawnedTestServer::kLocalhost,
367c2e0dbddbe15c98d52c4786dac06cb8952a8ae6dTorne (Richard Coles)                                     base::FilePath(kDocRoot));
3685821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  ASSERT_TRUE(test_server.Start());
3695821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3705821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  GURL url(test_server.GetURL("defaultresponse"));
3715821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  CreateFetcher(url, 11);
3725821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3735821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)  MessageLoop::current()->Run();
3745821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)}
3755821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
3762a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)}  // namespace cloud_print
377