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