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 "base/message_loop/message_loop.h" 6#include "base/test/test_simple_task_runner.h" 7#include "content/browser/streams/stream.h" 8#include "content/browser/streams/stream_registry.h" 9#include "content/browser/streams/stream_url_request_job.h" 10#include "content/browser/streams/stream_write_observer.h" 11#include "net/base/request_priority.h" 12#include "net/http/http_byte_range.h" 13#include "net/http/http_response_headers.h" 14#include "net/url_request/url_request.h" 15#include "net/url_request/url_request_context.h" 16#include "net/url_request/url_request_job_factory_impl.h" 17#include "net/url_request/url_request_test_util.h" 18#include "testing/gtest/include/gtest/gtest.h" 19 20namespace content { 21 22namespace { 23 24const int kBufferSize = 1024; 25const char kTestData1[] = "Hello"; 26const char kTestData2[] = "Here it is data."; 27 28const GURL kStreamURL("blob://stream"); 29 30} // namespace 31 32class StreamURLRequestJobTest : public testing::Test { 33 public: 34 // A simple ProtocolHandler implementation to create StreamURLRequestJob. 35 class MockProtocolHandler : 36 public net::URLRequestJobFactory::ProtocolHandler { 37 public: 38 MockProtocolHandler(StreamRegistry* registry) : registry_(registry) {} 39 40 // net::URLRequestJobFactory::ProtocolHandler override. 41 virtual net::URLRequestJob* MaybeCreateJob( 42 net::URLRequest* request, 43 net::NetworkDelegate* network_delegate) const OVERRIDE { 44 scoped_refptr<Stream> stream = registry_->GetStream(request->url()); 45 if (stream.get()) 46 return new StreamURLRequestJob(request, network_delegate, stream); 47 return NULL; 48 } 49 50 private: 51 StreamRegistry* registry_; 52 }; 53 54 StreamURLRequestJobTest() {} 55 56 virtual void SetUp() { 57 registry_.reset(new StreamRegistry()); 58 59 url_request_job_factory_.SetProtocolHandler( 60 "blob", new MockProtocolHandler(registry_.get())); 61 url_request_context_.set_job_factory(&url_request_job_factory_); 62 } 63 64 virtual void TearDown() { 65 } 66 67 void TestSuccessRequest(const GURL& url, 68 const std::string& expected_response) { 69 TestRequest("GET", url, net::HttpRequestHeaders(), 200, expected_response); 70 } 71 72 void TestRequest(const std::string& method, 73 const GURL& url, 74 const net::HttpRequestHeaders& extra_headers, 75 int expected_status_code, 76 const std::string& expected_response) { 77 net::TestDelegate delegate; 78 request_ = url_request_context_.CreateRequest( 79 url, net::DEFAULT_PRIORITY, &delegate, NULL); 80 request_->set_method(method); 81 if (!extra_headers.IsEmpty()) 82 request_->SetExtraRequestHeaders(extra_headers); 83 request_->Start(); 84 85 base::MessageLoop::current()->RunUntilIdle(); 86 87 // Verify response. 88 EXPECT_TRUE(request_->status().is_success()); 89 ASSERT_TRUE(request_->response_headers()); 90 EXPECT_EQ(expected_status_code, 91 request_->response_headers()->response_code()); 92 EXPECT_EQ(expected_response, delegate.data_received()); 93 } 94 95 protected: 96 base::MessageLoopForIO message_loop_; 97 scoped_ptr<StreamRegistry> registry_; 98 99 net::URLRequestContext url_request_context_; 100 net::URLRequestJobFactoryImpl url_request_job_factory_; 101 scoped_ptr<net::URLRequest> request_; 102}; 103 104TEST_F(StreamURLRequestJobTest, TestGetSimpleDataRequest) { 105 scoped_refptr<Stream> stream( 106 new Stream(registry_.get(), NULL, kStreamURL)); 107 108 scoped_refptr<net::StringIOBuffer> buffer( 109 new net::StringIOBuffer(kTestData1)); 110 111 stream->AddData(buffer, buffer->size()); 112 stream->Finalize(); 113 114 TestSuccessRequest(kStreamURL, kTestData1); 115} 116 117TEST_F(StreamURLRequestJobTest, TestGetLargeStreamRequest) { 118 scoped_refptr<Stream> stream( 119 new Stream(registry_.get(), NULL, kStreamURL)); 120 121 std::string large_data; 122 large_data.reserve(kBufferSize * 5); 123 for (int i = 0; i < kBufferSize * 5; ++i) 124 large_data.append(1, static_cast<char>(i % 256)); 125 126 scoped_refptr<net::StringIOBuffer> buffer( 127 new net::StringIOBuffer(large_data)); 128 129 stream->AddData(buffer, buffer->size()); 130 stream->Finalize(); 131 TestSuccessRequest(kStreamURL, large_data); 132} 133 134TEST_F(StreamURLRequestJobTest, TestGetNonExistentStreamRequest) { 135 net::TestDelegate delegate; 136 request_ = url_request_context_.CreateRequest( 137 kStreamURL, net::DEFAULT_PRIORITY, &delegate, NULL); 138 request_->set_method("GET"); 139 request_->Start(); 140 141 base::MessageLoop::current()->RunUntilIdle(); 142 143 // Verify response. 144 EXPECT_FALSE(request_->status().is_success()); 145} 146 147TEST_F(StreamURLRequestJobTest, TestRangeDataRequest) { 148 scoped_refptr<Stream> stream( 149 new Stream(registry_.get(), NULL, kStreamURL)); 150 151 scoped_refptr<net::StringIOBuffer> buffer( 152 new net::StringIOBuffer(kTestData2)); 153 154 stream->AddData(buffer, buffer->size()); 155 stream->Finalize(); 156 157 net::HttpRequestHeaders extra_headers; 158 extra_headers.SetHeader(net::HttpRequestHeaders::kRange, 159 net::HttpByteRange::Bounded(0, 3).GetHeaderValue()); 160 TestRequest("GET", kStreamURL, extra_headers, 161 200, std::string(kTestData2, 4)); 162} 163 164TEST_F(StreamURLRequestJobTest, TestInvalidRangeDataRequest) { 165 scoped_refptr<Stream> stream( 166 new Stream(registry_.get(), NULL, kStreamURL)); 167 168 scoped_refptr<net::StringIOBuffer> buffer( 169 new net::StringIOBuffer(kTestData2)); 170 171 stream->AddData(buffer, buffer->size()); 172 stream->Finalize(); 173 174 net::HttpRequestHeaders extra_headers; 175 extra_headers.SetHeader(net::HttpRequestHeaders::kRange, 176 net::HttpByteRange::Bounded(1, 3).GetHeaderValue()); 177 TestRequest("GET", kStreamURL, extra_headers, 405, std::string()); 178} 179 180} // namespace content 181