Home | History | Annotate | Download | only in embedded_test_server
      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/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"
     16 
     17 namespace net {
     18 namespace test_server {
     19 
     20 namespace {
     21 
     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;
     28 }
     29 
     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;
     37   }
     38   return std::string();
     39 }
     40 
     41 }  // namespace
     42 
     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") {
     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                                          HttpStatusCode 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 
    113 TEST_F(EmbeddedTestServerTest, GetBaseURL) {
    114   EXPECT_EQ(base::StringPrintf("http://127.0.0.1:%d/", server_->port()),
    115                                server_->base_url().spec());
    116 }
    117 
    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());
    122 }
    123 
    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));
    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(HTTP_OK, 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 
    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"));
    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(HTTP_OK, fetcher->GetResponseCode());
    165   EXPECT_EQ("<p>Hello World!</p>", GetContentFromFetcher(*fetcher));
    166   EXPECT_EQ("", GetContentTypeFromFetcher(*fetcher));
    167 }
    168 
    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());
    175 
    176   fetcher->Start();
    177   WaitForResponses(1);
    178   EXPECT_EQ(URLRequestStatus::SUCCESS, fetcher->GetStatus().status());
    179   EXPECT_EQ(HTTP_NOT_FOUND, fetcher->GetResponseCode());
    180 }
    181 
    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));
    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(HTTP_OK, 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(HTTP_OK, 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(HTTP_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