request_sender_unittest.cc revision 1320f92c476a1ad9d19dba2a48c72b75566198e9
15821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)// Copyright 2014 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)
52a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/compiler_specific.h"
62a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/macros.h"
72a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/memory/scoped_ptr.h"
82a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "base/message_loop/message_loop.h"
95821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "base/run_loop.h"
105821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "components/component_updater/request_sender.h"
115821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)#include "components/component_updater/test/test_configurator.h"
122a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "components/component_updater/test/url_request_post_interceptor.h"
132a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "net/url_request/url_fetcher.h"
142a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)#include "testing/gtest/include/gtest/gtest.h"
155821806d5e7f356e8fa4b058a389a808ea183019Torne (Richard Coles)
162a99a7e74a7f215066514fe81d2bfa6639d9edddTorne (Richard Coles)namespace component_updater {
17
18namespace {
19
20const char kUrl1[] = "https://localhost2/path1";
21const char kUrl2[] = "https://localhost2/path2";
22const char kUrlPath1[] = "path1";
23const char kUrlPath2[] = "path2";
24
25}  // namespace
26
27class RequestSenderTest : public testing::Test {
28 public:
29  RequestSenderTest();
30  virtual ~RequestSenderTest();
31
32  // Overrides from testing::Test.
33  virtual void SetUp() OVERRIDE;
34  virtual void TearDown() OVERRIDE;
35
36  void RequestSenderComplete(const net::URLFetcher* source);
37
38 protected:
39  void Quit();
40  void RunThreads();
41  void RunThreadsUntilIdle();
42
43  scoped_ptr<TestConfigurator> config_;
44  scoped_ptr<RequestSender> request_sender_;
45  scoped_ptr<InterceptorFactory> interceptor_factory_;
46
47  URLRequestPostInterceptor* post_interceptor_1;  // Owned by the factory.
48  URLRequestPostInterceptor* post_interceptor_2;  // Owned by the factory.
49
50  const net::URLFetcher* url_fetcher_source_;
51
52 private:
53  base::MessageLoopForIO loop_;
54  base::Closure quit_closure_;
55
56  DISALLOW_COPY_AND_ASSIGN(RequestSenderTest);
57};
58
59RequestSenderTest::RequestSenderTest()
60    : post_interceptor_1(NULL),
61      post_interceptor_2(NULL),
62      url_fetcher_source_(NULL) {
63  net::URLFetcher::SetEnableInterceptionForTests(true);
64}
65
66RequestSenderTest::~RequestSenderTest() {
67  net::URLFetcher::SetEnableInterceptionForTests(false);
68}
69
70void RequestSenderTest::SetUp() {
71  config_.reset(new TestConfigurator(base::MessageLoopProxy::current(),
72                                     base::MessageLoopProxy::current()));
73  interceptor_factory_.reset(
74      new InterceptorFactory(base::MessageLoopProxy::current()));
75  post_interceptor_1 =
76      interceptor_factory_->CreateInterceptorForPath(kUrlPath1);
77  post_interceptor_2 =
78      interceptor_factory_->CreateInterceptorForPath(kUrlPath2);
79  EXPECT_TRUE(post_interceptor_1);
80  EXPECT_TRUE(post_interceptor_2);
81
82  request_sender_.reset();
83}
84
85void RequestSenderTest::TearDown() {
86  request_sender_.reset();
87
88  post_interceptor_1 = NULL;
89  post_interceptor_2 = NULL;
90
91  interceptor_factory_.reset();
92
93  config_.reset();
94
95  RunThreadsUntilIdle();
96}
97
98void RequestSenderTest::RunThreads() {
99  base::RunLoop runloop;
100  quit_closure_ = runloop.QuitClosure();
101  runloop.Run();
102
103  // Since some tests need to drain currently enqueued tasks such as network
104  // intercepts on the IO thread, run the threads until they are
105  // idle. The component updater service won't loop again until the loop count
106  // is set and the service is started.
107  RunThreadsUntilIdle();
108}
109
110void RequestSenderTest::RunThreadsUntilIdle() {
111  base::RunLoop().RunUntilIdle();
112}
113
114void RequestSenderTest::Quit() {
115  if (!quit_closure_.is_null())
116    quit_closure_.Run();
117}
118
119void RequestSenderTest::RequestSenderComplete(const net::URLFetcher* source) {
120  url_fetcher_source_ = source;
121  Quit();
122}
123
124// Tests that when a request to the first url succeeds, the subsequent urls are
125// not tried.
126TEST_F(RequestSenderTest, RequestSendSuccess) {
127  EXPECT_TRUE(post_interceptor_1->ExpectRequest(new PartialMatch("test")));
128
129  std::vector<GURL> urls;
130  urls.push_back(GURL(kUrl1));
131  urls.push_back(GURL(kUrl2));
132  request_sender_.reset(new RequestSender(*config_));
133  request_sender_->Send("test",
134                        urls,
135                        base::Bind(&RequestSenderTest::RequestSenderComplete,
136                                   base::Unretained(this)));
137  RunThreads();
138
139  EXPECT_EQ(1, post_interceptor_1->GetHitCount())
140      << post_interceptor_1->GetRequestsAsString();
141  EXPECT_EQ(1, post_interceptor_1->GetCount())
142      << post_interceptor_1->GetRequestsAsString();
143
144  EXPECT_STREQ("test", post_interceptor_1->GetRequests()[0].c_str());
145  EXPECT_EQ(GURL(kUrl1), url_fetcher_source_->GetOriginalURL());
146  EXPECT_EQ(200, url_fetcher_source_->GetResponseCode());
147}
148
149// Tests that the request succeeds using the second url after the first url
150// has failed.
151TEST_F(RequestSenderTest, RequestSendSuccessWithFallback) {
152  EXPECT_TRUE(post_interceptor_1->ExpectRequest(new PartialMatch("test"), 403));
153  EXPECT_TRUE(post_interceptor_2->ExpectRequest(new PartialMatch("test")));
154
155  std::vector<GURL> urls;
156  urls.push_back(GURL(kUrl1));
157  urls.push_back(GURL(kUrl2));
158  request_sender_.reset(new RequestSender(*config_));
159  request_sender_->Send("test",
160                        urls,
161                        base::Bind(&RequestSenderTest::RequestSenderComplete,
162                                   base::Unretained(this)));
163  RunThreads();
164
165  EXPECT_EQ(1, post_interceptor_1->GetHitCount())
166      << post_interceptor_1->GetRequestsAsString();
167  EXPECT_EQ(1, post_interceptor_1->GetCount())
168      << post_interceptor_1->GetRequestsAsString();
169  EXPECT_EQ(1, post_interceptor_2->GetHitCount())
170      << post_interceptor_2->GetRequestsAsString();
171  EXPECT_EQ(1, post_interceptor_2->GetCount())
172      << post_interceptor_2->GetRequestsAsString();
173
174  EXPECT_STREQ("test", post_interceptor_1->GetRequests()[0].c_str());
175  EXPECT_STREQ("test", post_interceptor_2->GetRequests()[0].c_str());
176  EXPECT_EQ(GURL(kUrl2), url_fetcher_source_->GetOriginalURL());
177  EXPECT_EQ(200, url_fetcher_source_->GetResponseCode());
178}
179
180// Tests that the request fails when both urls have failed.
181TEST_F(RequestSenderTest, RequestSendFailed) {
182  EXPECT_TRUE(post_interceptor_1->ExpectRequest(new PartialMatch("test"), 403));
183  EXPECT_TRUE(post_interceptor_2->ExpectRequest(new PartialMatch("test"), 403));
184
185  std::vector<GURL> urls;
186  urls.push_back(GURL(kUrl1));
187  urls.push_back(GURL(kUrl2));
188  request_sender_.reset(new RequestSender(*config_));
189  request_sender_->Send("test",
190                        urls,
191                        base::Bind(&RequestSenderTest::RequestSenderComplete,
192                                   base::Unretained(this)));
193  RunThreads();
194
195  EXPECT_EQ(1, post_interceptor_1->GetHitCount())
196      << post_interceptor_1->GetRequestsAsString();
197  EXPECT_EQ(1, post_interceptor_1->GetCount())
198      << post_interceptor_1->GetRequestsAsString();
199  EXPECT_EQ(1, post_interceptor_2->GetHitCount())
200      << post_interceptor_2->GetRequestsAsString();
201  EXPECT_EQ(1, post_interceptor_2->GetCount())
202      << post_interceptor_2->GetRequestsAsString();
203
204  EXPECT_STREQ("test", post_interceptor_1->GetRequests()[0].c_str());
205  EXPECT_STREQ("test", post_interceptor_2->GetRequests()[0].c_str());
206  EXPECT_EQ(GURL(kUrl2), url_fetcher_source_->GetOriginalURL());
207  EXPECT_EQ(403, url_fetcher_source_->GetResponseCode());
208}
209
210}  // namespace component_updater
211