Add include.
[chromium-blink-merge.git] / net / test / embedded_test_server / embedded_test_server_unittest.cc
blobe1021173ef2132214359173f8288feaa31bac561
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.
5 #include "net/test/embedded_test_server/embedded_test_server.h"
7 #include "base/strings/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"
17 namespace net {
18 namespace test_server {
20 namespace {
22 // Gets the content from the given URLFetcher.
23 std::string GetContentFromFetcher(const URLFetcher& fetcher) {
24 std::string result;
25 const bool success = fetcher.GetResponseAsString(&result);
26 EXPECT_TRUE(success);
27 return result;
30 // Gets the content type from the given URLFetcher.
31 std::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;
38 return std::string();
41 } // namespace
43 class 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") {
52 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));
57 request_context_getter_ = new TestURLRequestContextGetter(
58 io_thread_.message_loop_proxy());
60 server_.reset(new EmbeddedTestServer);
61 ASSERT_TRUE(server_->InitializeAndWaitUntilReady());
64 void TearDown() override {
65 ASSERT_TRUE(server_->ShutdownAndWaitUntilComplete());
68 // URLFetcherDelegate override.
69 void OnURLFetchComplete(const URLFetcher* source) override {
70 ++num_responses_received_;
71 if (num_responses_received_ == num_responses_expected_)
72 base::MessageLoop::current()->Quit();
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();
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 HttpStatusCode code,
89 const HttpRequest& request) {
90 request_relative_url_ = request.relative_url;
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.Pass();
101 return nullptr;
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_;
113 TEST_F(EmbeddedTestServerTest, GetBaseURL) {
114 EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%d/", server_->port()),
115 server_->base_url().spec());
118 TEST_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());
124 TEST_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 HTTP_OK));
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);
141 EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher->GetStatus().status());
142 EXPECT_EQ(HTTP_OK, fetcher->GetResponseCode());
143 EXPECT_EQ("<b>Worked!</b>", GetContentFromFetcher(*fetcher));
144 EXPECT_EQ("text/html", GetContentTypeFromFetcher(*fetcher));
146 EXPECT_EQ("/test?q=foo", request_relative_url_);
149 TEST_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"));
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);
163 EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher->GetStatus().status());
164 EXPECT_EQ(HTTP_OK, fetcher->GetResponseCode());
165 EXPECT_EQ("<p>Hello World!</p>", GetContentFromFetcher(*fetcher));
166 EXPECT_EQ("", GetContentTypeFromFetcher(*fetcher));
169 TEST_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());
176 fetcher->Start();
177 WaitForResponses(1);
178 EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher->GetStatus().status());
179 EXPECT_EQ(HTTP_NOT_FOUND, fetcher->GetResponseCode());
182 TEST_F(EmbeddedTestServerTest, ConcurrentFetches) {
183 server_->RegisterRequestHandler(
184 base::Bind(&EmbeddedTestServerTest::HandleRequest,
185 base::Unretained(this),
186 "/test1",
187 "Raspberry chocolate",
188 "text/html",
189 HTTP_OK));
190 server_->RegisterRequestHandler(
191 base::Bind(&EmbeddedTestServerTest::HandleRequest,
192 base::Unretained(this),
193 "/test2",
194 "Vanilla chocolate",
195 "text/html",
196 HTTP_OK));
197 server_->RegisterRequestHandler(
198 base::Bind(&EmbeddedTestServerTest::HandleRequest,
199 base::Unretained(this),
200 "/test3",
201 "No chocolates",
202 "text/plain",
203 HTTP_NOT_FOUND));
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());
221 // Fetch the three URLs concurrently.
222 fetcher1->Start();
223 fetcher2->Start();
224 fetcher3->Start();
225 WaitForResponses(3);
227 EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher1->GetStatus().status());
228 EXPECT_EQ(HTTP_OK, fetcher1->GetResponseCode());
229 EXPECT_EQ("Raspberry chocolate", GetContentFromFetcher(*fetcher1));
230 EXPECT_EQ("text/html", GetContentTypeFromFetcher(*fetcher1));
232 EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher2->GetStatus().status());
233 EXPECT_EQ(HTTP_OK, fetcher2->GetResponseCode());
234 EXPECT_EQ("Vanilla chocolate", GetContentFromFetcher(*fetcher2));
235 EXPECT_EQ("text/html", GetContentTypeFromFetcher(*fetcher2));
237 EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher3->GetStatus().status());
238 EXPECT_EQ(HTTP_NOT_FOUND, fetcher3->GetResponseCode());
239 EXPECT_EQ("No chocolates", GetContentFromFetcher(*fetcher3));
240 EXPECT_EQ("text/plain", GetContentTypeFromFetcher(*fetcher3));
243 // Below test exercises EmbeddedTestServer's ability to cope with the situation
244 // where there is no MessageLoop available on the thread at EmbeddedTestServer
245 // initialization and/or destruction.
247 typedef std::tr1::tuple<bool, bool> ThreadingTestParams;
249 class EmbeddedTestServerThreadingTest
250 : public testing::TestWithParam<ThreadingTestParams> {};
252 class EmbeddedTestServerThreadingTestDelegate
253 : public base::PlatformThread::Delegate,
254 public URLFetcherDelegate {
255 public:
256 EmbeddedTestServerThreadingTestDelegate(
257 bool message_loop_present_on_initialize,
258 bool message_loop_present_on_shutdown)
259 : message_loop_present_on_initialize_(message_loop_present_on_initialize),
260 message_loop_present_on_shutdown_(message_loop_present_on_shutdown) {}
262 // base::PlatformThread::Delegate:
263 void ThreadMain() override {
264 scoped_refptr<base::SingleThreadTaskRunner> io_thread_runner;
265 base::Thread io_thread("io_thread");
266 base::Thread::Options thread_options;
267 thread_options.message_loop_type = base::MessageLoop::TYPE_IO;
268 ASSERT_TRUE(io_thread.StartWithOptions(thread_options));
269 io_thread_runner = io_thread.message_loop_proxy();
271 scoped_ptr<base::MessageLoop> loop;
272 if (message_loop_present_on_initialize_)
273 loop.reset(new base::MessageLoopForIO);
275 // Create the test server instance.
276 EmbeddedTestServer server;
277 base::FilePath src_dir;
278 ASSERT_TRUE(PathService::Get(base::DIR_SOURCE_ROOT, &src_dir));
279 ASSERT_TRUE(server.InitializeAndWaitUntilReady());
281 // Make a request and wait for the reply.
282 if (!loop)
283 loop.reset(new base::MessageLoopForIO);
285 scoped_ptr<URLFetcher> fetcher(URLFetcher::Create(
286 server.GetURL("/test?q=foo"), URLFetcher::GET, this));
287 fetcher->SetRequestContext(
288 new TestURLRequestContextGetter(loop->message_loop_proxy()));
289 fetcher->Start();
290 loop->Run();
291 fetcher.reset();
293 // Shut down.
294 if (message_loop_present_on_shutdown_)
295 loop.reset();
297 ASSERT_TRUE(server.ShutdownAndWaitUntilComplete());
300 // URLFetcherDelegate override.
301 void OnURLFetchComplete(const URLFetcher* source) override {
302 base::MessageLoop::current()->Quit();
305 private:
306 bool message_loop_present_on_initialize_;
307 bool message_loop_present_on_shutdown_;
309 DISALLOW_COPY_AND_ASSIGN(EmbeddedTestServerThreadingTestDelegate);
312 TEST_P(EmbeddedTestServerThreadingTest, RunTest) {
313 // The actual test runs on a separate thread so it can screw with the presence
314 // of a MessageLoop - the test suite already sets up a MessageLoop for the
315 // main test thread.
316 base::PlatformThreadHandle thread_handle;
317 EmbeddedTestServerThreadingTestDelegate delegate(
318 std::tr1::get<0>(GetParam()),
319 std::tr1::get<1>(GetParam()));
320 ASSERT_TRUE(base::PlatformThread::Create(0, &delegate, &thread_handle));
321 base::PlatformThread::Join(thread_handle);
324 INSTANTIATE_TEST_CASE_P(EmbeddedTestServerThreadingTestInstantiation,
325 EmbeddedTestServerThreadingTest,
326 testing::Combine(testing::Bool(), testing::Bool()));
328 } // namespace test_server
329 } // namespace net