simple_data_source_unittest.cc revision dc0f95d653279beabeb9817299e2902918ba123e
1// Copyright (c) 2011 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 "media/base/filters.h" 6#include "media/base/mock_callback.h" 7#include "media/base/mock_filter_host.h" 8#include "media/base/mock_filters.h" 9#include "net/base/net_errors.h" 10#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h" 11#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h" 12#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLLoader.h" 13#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLRequest.h" 14#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h" 15#include "webkit/glue/media/simple_data_source.h" 16#include "webkit/mocks/mock_webframe.h" 17#include "webkit/mocks/mock_weburlloader.h" 18 19using ::testing::_; 20using ::testing::DoAll; 21using ::testing::InSequence; 22using ::testing::Invoke; 23using ::testing::NiceMock; 24using ::testing::NotNull; 25using ::testing::Return; 26using ::testing::SetArgumentPointee; 27using ::testing::StrictMock; 28using ::testing::WithArgs; 29 30using WebKit::WebURLError; 31using WebKit::WebURLLoader; 32using WebKit::WebURLRequest; 33using WebKit::WebURLResponse; 34 35namespace webkit_glue { 36 37static const int kDataSize = 1024; 38static const char kHttpUrl[] = "http://test"; 39static const char kHttpsUrl[] = "https://test"; 40static const char kFileUrl[] = "file://test"; 41static const char kDataUrl[] = 42 "data:text/plain;base64,YWJjZGVmZ2hpamtsbW5vcHFyc3R1dnd4eXoK"; 43static const char kDataUrlDecoded[] = "abcdefghijklmnopqrstuvwxyz"; 44static const char kInvalidUrl[] = "whatever://test"; 45static const char kHttpRedirectToSameDomainUrl1[] = "http://test/ing"; 46static const char kHttpRedirectToSameDomainUrl2[] = "http://test/ing2"; 47static const char kHttpRedirectToDifferentDomainUrl1[] = "http://test2"; 48static const char kHttpRedirectToDifferentDomainUrl2[] = "http://test2/ing"; 49 50class SimpleDataSourceTest : public testing::Test { 51 public: 52 SimpleDataSourceTest() { 53 for (int i = 0; i < kDataSize; ++i) { 54 data_[i] = i; 55 } 56 } 57 58 virtual ~SimpleDataSourceTest() { 59 } 60 61 void InitializeDataSource(const char* url, 62 media::MockCallback* callback) { 63 gurl_ = GURL(url); 64 65 frame_.reset(new NiceMock<MockWebFrame>()); 66 url_loader_ = new NiceMock<MockWebURLLoader>(); 67 68 data_source_ = new SimpleDataSource(MessageLoop::current(), 69 frame_.get()); 70 71 // There is no need to provide a message loop to data source. 72 data_source_->set_host(&host_); 73 data_source_->SetURLLoaderForTest(url_loader_); 74 75 data_source_->Initialize(url, callback); 76 MessageLoop::current()->RunAllPending(); 77 } 78 79 void RequestSucceeded(bool is_loaded) { 80 WebURLResponse response(gurl_); 81 response.setExpectedContentLength(kDataSize); 82 83 data_source_->didReceiveResponse(NULL, response); 84 int64 size; 85 EXPECT_TRUE(data_source_->GetSize(&size)); 86 EXPECT_EQ(kDataSize, size); 87 88 for (int i = 0; i < kDataSize; ++i) { 89 data_source_->didReceiveData(NULL, data_ + i, 1); 90 } 91 92 EXPECT_CALL(host_, SetLoaded(is_loaded)); 93 94 InSequence s; 95 EXPECT_CALL(host_, SetTotalBytes(kDataSize)); 96 EXPECT_CALL(host_, SetBufferedBytes(kDataSize)); 97 98 data_source_->didFinishLoading(NULL, 0); 99 100 // Let the tasks to be executed. 101 MessageLoop::current()->RunAllPending(); 102 } 103 104 void RequestFailed() { 105 InSequence s; 106 EXPECT_CALL(host_, SetError(media::PIPELINE_ERROR_NETWORK)); 107 108 WebURLError error; 109 error.reason = net::ERR_FAILED; 110 data_source_->didFail(NULL, error); 111 112 // Let the tasks to be executed. 113 MessageLoop::current()->RunAllPending(); 114 } 115 116 void Redirect(const char* url) { 117 GURL redirectUrl(url); 118 WebKit::WebURLRequest newRequest(redirectUrl); 119 WebKit::WebURLResponse redirectResponse(gurl_); 120 121 data_source_->willSendRequest(url_loader_, newRequest, redirectResponse); 122 123 MessageLoop::current()->RunAllPending(); 124 } 125 126 void DestroyDataSource() { 127 data_source_->Stop(media::NewExpectedCallback()); 128 MessageLoop::current()->RunAllPending(); 129 130 data_source_ = NULL; 131 } 132 133 void AsyncRead() { 134 for (int i = 0; i < kDataSize; ++i) { 135 uint8 buffer[1]; 136 137 EXPECT_CALL(*this, ReadCallback(1)); 138 data_source_->Read( 139 i, 1, buffer, 140 NewCallback(this, &SimpleDataSourceTest::ReadCallback)); 141 EXPECT_EQ(static_cast<uint8>(data_[i]), buffer[0]); 142 } 143 } 144 145 MOCK_METHOD1(ReadCallback, void(size_t size)); 146 147 protected: 148 GURL gurl_; 149 scoped_ptr<MessageLoop> message_loop_; 150 NiceMock<MockWebURLLoader>* url_loader_; 151 scoped_refptr<SimpleDataSource> data_source_; 152 StrictMock<media::MockFilterHost> host_; 153 scoped_ptr<NiceMock<MockWebFrame> > frame_; 154 155 char data_[kDataSize]; 156 157 DISALLOW_COPY_AND_ASSIGN(SimpleDataSourceTest); 158}; 159 160TEST_F(SimpleDataSourceTest, InitializeHTTP) { 161 InitializeDataSource(kHttpUrl, media::NewExpectedCallback()); 162 RequestSucceeded(false); 163 DestroyDataSource(); 164} 165 166TEST_F(SimpleDataSourceTest, InitializeHTTPS) { 167 InitializeDataSource(kHttpsUrl, media::NewExpectedCallback()); 168 RequestSucceeded(false); 169 DestroyDataSource(); 170} 171 172TEST_F(SimpleDataSourceTest, InitializeFile) { 173 InitializeDataSource(kFileUrl, media::NewExpectedCallback()); 174 RequestSucceeded(true); 175 DestroyDataSource(); 176} 177 178TEST_F(SimpleDataSourceTest, InitializeData) { 179 frame_.reset(new NiceMock<MockWebFrame>()); 180 url_loader_ = new NiceMock<MockWebURLLoader>(); 181 182 data_source_ = new SimpleDataSource(MessageLoop::current(), 183 frame_.get()); 184 EXPECT_TRUE(data_source_->IsUrlSupported(kDataUrl)); 185 186 // There is no need to provide a message loop to data source. 187 data_source_->set_host(&host_); 188 data_source_->SetURLLoaderForTest(url_loader_); 189 190 EXPECT_CALL(host_, SetLoaded(true)); 191 EXPECT_CALL(host_, SetTotalBytes(sizeof(kDataUrlDecoded))); 192 EXPECT_CALL(host_, SetBufferedBytes(sizeof(kDataUrlDecoded))); 193 194 data_source_->Initialize(kDataUrl, media::NewExpectedCallback()); 195 MessageLoop::current()->RunAllPending(); 196 197 DestroyDataSource(); 198} 199 200TEST_F(SimpleDataSourceTest, RequestFailed) { 201 InitializeDataSource(kHttpUrl, media::NewExpectedCallback()); 202 RequestFailed(); 203 DestroyDataSource(); 204} 205 206TEST_F(SimpleDataSourceTest, StopWhenDownloading) { 207 // The callback should be deleted, but not executed. 208 // TODO(scherkus): should this really be the behaviour? Seems strange... 209 StrictMock<media::MockCallback>* callback = 210 new StrictMock<media::MockCallback>(); 211 EXPECT_CALL(*callback, Destructor()); 212 213 InitializeDataSource(kHttpUrl, callback); 214 215 EXPECT_CALL(*url_loader_, cancel()); 216 DestroyDataSource(); 217} 218 219TEST_F(SimpleDataSourceTest, AsyncRead) { 220 InitializeDataSource(kFileUrl, media::NewExpectedCallback()); 221 RequestSucceeded(true); 222 AsyncRead(); 223 DestroyDataSource(); 224} 225 226// NOTE: This test will need to be reworked a little once 227// http://code.google.com/p/chromium/issues/detail?id=72578 228// is fixed. 229TEST_F(SimpleDataSourceTest, HasSingleOrigin) { 230 // Make sure no redirect case works as expected. 231 InitializeDataSource(kHttpUrl, media::NewExpectedCallback()); 232 RequestSucceeded(false); 233 EXPECT_TRUE(data_source_->HasSingleOrigin()); 234 DestroyDataSource(); 235 236 // Test redirect to the same domain. 237 InitializeDataSource(kHttpUrl, media::NewExpectedCallback()); 238 Redirect(kHttpRedirectToSameDomainUrl1); 239 RequestSucceeded(false); 240 EXPECT_TRUE(data_source_->HasSingleOrigin()); 241 DestroyDataSource(); 242 243 // Test redirect twice to the same domain. 244 InitializeDataSource(kHttpUrl, media::NewExpectedCallback()); 245 Redirect(kHttpRedirectToSameDomainUrl1); 246 Redirect(kHttpRedirectToSameDomainUrl2); 247 RequestSucceeded(false); 248 EXPECT_TRUE(data_source_->HasSingleOrigin()); 249 DestroyDataSource(); 250 251 // Test redirect to a different domain. 252 InitializeDataSource(kHttpUrl, media::NewExpectedCallback()); 253 Redirect(kHttpRedirectToDifferentDomainUrl1); 254 RequestSucceeded(false); 255 EXPECT_FALSE(data_source_->HasSingleOrigin()); 256 DestroyDataSource(); 257 258 // Test redirect to the same domain and then to a different domain. 259 InitializeDataSource(kHttpUrl, media::NewExpectedCallback()); 260 Redirect(kHttpRedirectToSameDomainUrl1); 261 Redirect(kHttpRedirectToDifferentDomainUrl1); 262 RequestSucceeded(false); 263 EXPECT_FALSE(data_source_->HasSingleOrigin()); 264 DestroyDataSource(); 265} 266 267} // namespace webkit_glue 268