embedded_test_server_unittest.cc revision b2df76ea8fec9e32f6f3718986dba0d95315b29c
1// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "net/test/embedded_test_server/embedded_test_server.h"
6
7#include "base/stringprintf.h"
8#include "base/threading/thread.h"
9#include "net/http/http_response_headers.h"
10#include "net/test/embedded_test_server/http_request.h"
11#include "net/test/embedded_test_server/http_response.h"
12#include "net/url_request/url_fetcher.h"
13#include "net/url_request/url_fetcher_delegate.h"
14#include "net/url_request/url_request_test_util.h"
15#include "testing/gtest/include/gtest/gtest.h"
16
17namespace net {
18namespace test_server {
19
20namespace {
21
22// Gets the content from the given URLFetcher.
23std::string GetContentFromFetcher(const URLFetcher& fetcher) {
24  std::string result;
25  const bool success = fetcher.GetResponseAsString(&result);
26  EXPECT_TRUE(success);
27  return result;
28}
29
30// Gets the content type from the given URLFetcher.
31std::string GetContentTypeFromFetcher(const URLFetcher& fetcher) {
32  const HttpResponseHeaders* headers = fetcher.GetResponseHeaders();
33  if (headers) {
34    std::string content_type;
35    if (headers->GetMimeType(&content_type))
36      return content_type;
37  }
38  return std::string();
39}
40
41}  // namespace
42
43class EmbeddedTestServerTest : public testing::Test,
44                       public URLFetcherDelegate {
45 public:
46  EmbeddedTestServerTest()
47      : num_responses_received_(0),
48        num_responses_expected_(0),
49        io_thread_("io_thread") {
50  }
51
52  virtual void SetUp() OVERRIDE {
53    base::Thread::Options thread_options;
54    thread_options.message_loop_type = MessageLoop::TYPE_IO;
55    ASSERT_TRUE(io_thread_.StartWithOptions(thread_options));
56
57    request_context_getter_ = new TestURLRequestContextGetter(
58        io_thread_.message_loop_proxy());
59
60    server_.reset(new EmbeddedTestServer(io_thread_.message_loop_proxy()));
61    ASSERT_TRUE(server_->InitializeAndWaitUntilReady());
62  }
63
64  virtual void TearDown() OVERRIDE {
65    ASSERT_TRUE(server_->ShutdownAndWaitUntilComplete());
66  }
67
68  // URLFetcherDelegate override.
69  virtual void OnURLFetchComplete(const URLFetcher* source) OVERRIDE {
70    ++num_responses_received_;
71    if (num_responses_received_ == num_responses_expected_)
72      MessageLoop::current()->Quit();
73  }
74
75  // Waits until the specified number of responses are received.
76  void WaitForResponses(int num_responses) {
77    num_responses_received_ = 0;
78    num_responses_expected_ = num_responses;
79    // Will be terminated in OnURLFetchComplete().
80    MessageLoop::current()->Run();
81  }
82
83  // Handles |request| sent to |path| and returns the response per |content|,
84  // |content type|, and |code|. Saves the request URL for verification.
85  scoped_ptr<HttpResponse> HandleRequest(const std::string& path,
86                                         const std::string& content,
87                                         const std::string& content_type,
88                                         ResponseCode code,
89                                         const HttpRequest& request) {
90    request_relative_url_ = request.relative_url;
91
92    GURL absolute_url = server_->GetURL(request.relative_url);
93    if (absolute_url.path() == path) {
94      scoped_ptr<HttpResponse> http_response(new HttpResponse);
95      http_response->set_code(code);
96      http_response->set_content(content);
97      http_response->set_content_type(content_type);
98      return http_response.Pass();
99    }
100
101    return scoped_ptr<HttpResponse>();
102  }
103
104 protected:
105  int num_responses_received_;
106  int num_responses_expected_;
107  std::string request_relative_url_;
108  base::Thread io_thread_;
109  scoped_refptr<TestURLRequestContextGetter> request_context_getter_;
110  scoped_ptr<EmbeddedTestServer> server_;
111};
112
113TEST_F(EmbeddedTestServerTest, GetBaseURL) {
114  EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%d/", server_->port()),
115                               server_->base_url().spec());
116}
117
118TEST_F(EmbeddedTestServerTest, GetURL) {
119  EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%d/path?query=foo",
120                               server_->port()),
121            server_->GetURL("/path?query=foo").spec());
122}
123
124TEST_F(EmbeddedTestServerTest, RegisterRequestHandler) {
125  server_->RegisterRequestHandler(
126      base::Bind(&EmbeddedTestServerTest::HandleRequest,
127                 base::Unretained(this),
128                 "/test",
129                 "<b>Worked!</b>",
130                 "text/html",
131                 SUCCESS));
132
133  scoped_ptr<URLFetcher> fetcher(
134      URLFetcher::Create(server_->GetURL("/test?q=foo"),
135                              URLFetcher::GET,
136                              this));
137  fetcher->SetRequestContext(request_context_getter_.get());
138  fetcher->Start();
139  WaitForResponses(1);
140
141  EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher->GetStatus().status());
142  EXPECT_EQ(SUCCESS, fetcher->GetResponseCode());
143  EXPECT_EQ("<b>Worked!</b>", GetContentFromFetcher(*fetcher));
144  EXPECT_EQ("text/html", GetContentTypeFromFetcher(*fetcher));
145
146  EXPECT_EQ("/test?q=foo", request_relative_url_);
147}
148
149TEST_F(EmbeddedTestServerTest, DefaultNotFoundResponse) {
150  scoped_ptr<URLFetcher> fetcher(
151      URLFetcher::Create(server_->GetURL("/non-existent"),
152                              URLFetcher::GET,
153                              this));
154  fetcher->SetRequestContext(request_context_getter_.get());
155
156  fetcher->Start();
157  WaitForResponses(1);
158  EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher->GetStatus().status());
159  EXPECT_EQ(NOT_FOUND, fetcher->GetResponseCode());
160}
161
162TEST_F(EmbeddedTestServerTest, ConcurrentFetches) {
163  server_->RegisterRequestHandler(
164      base::Bind(&EmbeddedTestServerTest::HandleRequest,
165                 base::Unretained(this),
166                 "/test1",
167                 "Raspberry chocolate",
168                 "text/html",
169                 SUCCESS));
170  server_->RegisterRequestHandler(
171      base::Bind(&EmbeddedTestServerTest::HandleRequest,
172                 base::Unretained(this),
173                 "/test2",
174                 "Vanilla chocolate",
175                 "text/html",
176                 SUCCESS));
177  server_->RegisterRequestHandler(
178      base::Bind(&EmbeddedTestServerTest::HandleRequest,
179                 base::Unretained(this),
180                 "/test3",
181                 "No chocolates",
182                 "text/plain",
183                 NOT_FOUND));
184
185  scoped_ptr<URLFetcher> fetcher1 = scoped_ptr<URLFetcher>(
186      URLFetcher::Create(server_->GetURL("/test1"),
187                              URLFetcher::GET,
188                              this));
189  fetcher1->SetRequestContext(request_context_getter_.get());
190  scoped_ptr<URLFetcher> fetcher2 = scoped_ptr<URLFetcher>(
191      URLFetcher::Create(server_->GetURL("/test2"),
192                              URLFetcher::GET,
193                              this));
194  fetcher2->SetRequestContext(request_context_getter_.get());
195  scoped_ptr<URLFetcher> fetcher3 = scoped_ptr<URLFetcher>(
196      URLFetcher::Create(server_->GetURL("/test3"),
197                              URLFetcher::GET,
198                              this));
199  fetcher3->SetRequestContext(request_context_getter_.get());
200
201  // Fetch the three URLs concurrently.
202  fetcher1->Start();
203  fetcher2->Start();
204  fetcher3->Start();
205  WaitForResponses(3);
206
207  EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher1->GetStatus().status());
208  EXPECT_EQ(SUCCESS, fetcher1->GetResponseCode());
209  EXPECT_EQ("Raspberry chocolate", GetContentFromFetcher(*fetcher1));
210  EXPECT_EQ("text/html", GetContentTypeFromFetcher(*fetcher1));
211
212  EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher2->GetStatus().status());
213  EXPECT_EQ(SUCCESS, fetcher2->GetResponseCode());
214  EXPECT_EQ("Vanilla chocolate", GetContentFromFetcher(*fetcher2));
215  EXPECT_EQ("text/html", GetContentTypeFromFetcher(*fetcher2));
216
217  EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher3->GetStatus().status());
218  EXPECT_EQ(NOT_FOUND, fetcher3->GetResponseCode());
219  EXPECT_EQ("No chocolates", GetContentFromFetcher(*fetcher3));
220  EXPECT_EQ("text/plain", GetContentTypeFromFetcher(*fetcher3));
221}
222
223}  // namespace test_server
224}  // namespace net
225