embedded_test_server_unittest.cc revision 90dce4d38c5ff5333bea97d859d4e484e27edf0c
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 = base::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      base::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    base::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<BasicHttpResponse> http_response(new BasicHttpResponse);
95      http_response->set_code(code);
96      http_response->set_content(content);
97      http_response->set_content_type(content_type);
98      return http_response.PassAs<HttpResponse>();
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, ServeFilesFromDirectory) {
150  base::FilePath src_dir;
151  ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &src_dir));
152  server_->ServeFilesFromDirectory(
153      src_dir.AppendASCII("net").AppendASCII("data"));
154
155  scoped_ptr<URLFetcher> fetcher(
156      URLFetcher::Create(server_->GetURL("/test.html"),
157                              URLFetcher::GET,
158                              this));
159  fetcher->SetRequestContext(request_context_getter_.get());
160  fetcher->Start();
161  WaitForResponses(1);
162
163  EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher->GetStatus().status());
164  EXPECT_EQ(SUCCESS, fetcher->GetResponseCode());
165  EXPECT_EQ("<p>Hello World!</p>", GetContentFromFetcher(*fetcher));
166  EXPECT_EQ("", GetContentTypeFromFetcher(*fetcher));
167}
168
169TEST_F(EmbeddedTestServerTest, DefaultNotFoundResponse) {
170  scoped_ptr<URLFetcher> fetcher(
171      URLFetcher::Create(server_->GetURL("/non-existent"),
172                              URLFetcher::GET,
173                              this));
174  fetcher->SetRequestContext(request_context_getter_.get());
175
176  fetcher->Start();
177  WaitForResponses(1);
178  EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher->GetStatus().status());
179  EXPECT_EQ(NOT_FOUND, fetcher->GetResponseCode());
180}
181
182TEST_F(EmbeddedTestServerTest, ConcurrentFetches) {
183  server_->RegisterRequestHandler(
184      base::Bind(&EmbeddedTestServerTest::HandleRequest,
185                 base::Unretained(this),
186                 "/test1",
187                 "Raspberry chocolate",
188                 "text/html",
189                 SUCCESS));
190  server_->RegisterRequestHandler(
191      base::Bind(&EmbeddedTestServerTest::HandleRequest,
192                 base::Unretained(this),
193                 "/test2",
194                 "Vanilla chocolate",
195                 "text/html",
196                 SUCCESS));
197  server_->RegisterRequestHandler(
198      base::Bind(&EmbeddedTestServerTest::HandleRequest,
199                 base::Unretained(this),
200                 "/test3",
201                 "No chocolates",
202                 "text/plain",
203                 NOT_FOUND));
204
205  scoped_ptr<URLFetcher> fetcher1 = scoped_ptr<URLFetcher>(
206      URLFetcher::Create(server_->GetURL("/test1"),
207                              URLFetcher::GET,
208                              this));
209  fetcher1->SetRequestContext(request_context_getter_.get());
210  scoped_ptr<URLFetcher> fetcher2 = scoped_ptr<URLFetcher>(
211      URLFetcher::Create(server_->GetURL("/test2"),
212                              URLFetcher::GET,
213                              this));
214  fetcher2->SetRequestContext(request_context_getter_.get());
215  scoped_ptr<URLFetcher> fetcher3 = scoped_ptr<URLFetcher>(
216      URLFetcher::Create(server_->GetURL("/test3"),
217                              URLFetcher::GET,
218                              this));
219  fetcher3->SetRequestContext(request_context_getter_.get());
220
221  // Fetch the three URLs concurrently.
222  fetcher1->Start();
223  fetcher2->Start();
224  fetcher3->Start();
225  WaitForResponses(3);
226
227  EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher1->GetStatus().status());
228  EXPECT_EQ(SUCCESS, fetcher1->GetResponseCode());
229  EXPECT_EQ("Raspberry chocolate", GetContentFromFetcher(*fetcher1));
230  EXPECT_EQ("text/html", GetContentTypeFromFetcher(*fetcher1));
231
232  EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher2->GetStatus().status());
233  EXPECT_EQ(SUCCESS, fetcher2->GetResponseCode());
234  EXPECT_EQ("Vanilla chocolate", GetContentFromFetcher(*fetcher2));
235  EXPECT_EQ("text/html", GetContentTypeFromFetcher(*fetcher2));
236
237  EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher3->GetStatus().status());
238  EXPECT_EQ(NOT_FOUND, fetcher3->GetResponseCode());
239  EXPECT_EQ("No chocolates", GetContentFromFetcher(*fetcher3));
240  EXPECT_EQ("text/plain", GetContentTypeFromFetcher(*fetcher3));
241}
242
243}  // namespace test_server
244}  // namespace net
245