Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1182)

Side by Side Diff: webkit/glue/media/buffered_data_source_unittest.cc

Issue 8570010: Moving media-related files from webkit/glue/ to webkit/media/. (Closed) Base URL: svn://chrome-svn/chrome/trunk/src
Patch Set: minor fixes Created 9 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « webkit/glue/media/buffered_data_source.cc ('k') | webkit/glue/media/buffered_resource_loader.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
(Empty)
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 <algorithm>
6
7 #include "base/bind.h"
8 #include "base/test/test_timeouts.h"
9 #include "media/base/media_log.h"
10 #include "media/base/mock_callback.h"
11 #include "media/base/mock_filter_host.h"
12 #include "media/base/mock_filters.h"
13 #include "net/base/net_errors.h"
14 #include "third_party/WebKit/Source/WebKit/chromium/public/WebString.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
17 #include "webkit/glue/media/buffered_data_source.h"
18 #include "webkit/mocks/mock_webframeclient.h"
19 #include "webkit/mocks/mock_weburlloader.h"
20
21 using ::testing::_;
22 using ::testing::Assign;
23 using ::testing::AtLeast;
24 using ::testing::DeleteArg;
25 using ::testing::DoAll;
26 using ::testing::InSequence;
27 using ::testing::Invoke;
28 using ::testing::InvokeWithoutArgs;
29 using ::testing::NotNull;
30 using ::testing::Return;
31 using ::testing::ReturnRef;
32 using ::testing::SetArgumentPointee;
33 using ::testing::StrictMock;
34 using ::testing::NiceMock;
35 using ::testing::WithArgs;
36
37 using WebKit::WebFrame;
38 using WebKit::WebString;
39 using WebKit::WebURLError;
40 using WebKit::WebURLResponse;
41 using WebKit::WebView;
42
43 namespace webkit_glue {
44
45 static const char* kHttpUrl = "http://test";
46 static const char* kFileUrl = "file://test";
47 static const int kDataSize = 1024;
48 static const int kMaxCacheMissesBeforeFailTest = 20;
49
50 enum NetworkState {
51 NONE,
52 LOADED,
53 LOADING
54 };
55
56 // A mock BufferedDataSource to inject mock BufferedResourceLoader through
57 // CreateResourceLoader() method.
58 class MockBufferedDataSource : public BufferedDataSource {
59 public:
60 MockBufferedDataSource(MessageLoop* message_loop, WebFrame* frame)
61 : BufferedDataSource(message_loop, frame, new media::MediaLog()) {
62 }
63
64 virtual base::TimeDelta GetTimeoutMilliseconds() {
65 return base::TimeDelta::FromMilliseconds(
66 TestTimeouts::tiny_timeout_ms());
67 }
68
69 MOCK_METHOD2(CreateResourceLoader,
70 BufferedResourceLoader*(int64 first_position,
71 int64 last_position));
72
73 private:
74 DISALLOW_COPY_AND_ASSIGN(MockBufferedDataSource);
75 };
76
77 class MockBufferedResourceLoader : public BufferedResourceLoader {
78 public:
79 MockBufferedResourceLoader()
80 : BufferedResourceLoader(GURL(), 0, 0, kThresholdDefer,
81 0, 0, new media::MediaLog()) {
82 }
83
84 MOCK_METHOD3(Start, void(net::OldCompletionCallback* read_callback,
85 const base::Closure& network_callback,
86 WebFrame* frame));
87 MOCK_METHOD0(Stop, void());
88 MOCK_METHOD4(Read, void(int64 position, int read_size, uint8* buffer,
89 net::OldCompletionCallback* callback));
90 MOCK_METHOD0(content_length, int64());
91 MOCK_METHOD0(instance_size, int64());
92 MOCK_METHOD0(range_supported, bool());
93 MOCK_METHOD0(network_activity, bool());
94 MOCK_METHOD0(url, const GURL&());
95 MOCK_METHOD0(GetBufferedFirstBytePosition, int64());
96 MOCK_METHOD0(GetBufferedLastBytePosition, int64());
97
98 protected:
99 ~MockBufferedResourceLoader() {}
100
101 DISALLOW_COPY_AND_ASSIGN(MockBufferedResourceLoader);
102 };
103
104 class BufferedDataSourceTest : public testing::Test {
105 public:
106 BufferedDataSourceTest()
107 : view_(WebView::create(NULL)) {
108 view_->initializeMainFrame(&client_);
109 message_loop_ = MessageLoop::current();
110
111 for (size_t i = 0; i < sizeof(data_); ++i) {
112 data_[i] = i;
113 }
114 }
115
116 virtual ~BufferedDataSourceTest() {
117 view_->close();
118 }
119
120 void ExpectCreateAndStartResourceLoader(int start_error) {
121 EXPECT_CALL(*data_source_, CreateResourceLoader(_, _))
122 .WillOnce(Return(loader_.get()));
123
124 EXPECT_CALL(*loader_, Start(NotNull(), _, NotNull()))
125 .WillOnce(
126 DoAll(Assign(&error_, start_error),
127 Invoke(this,
128 &BufferedDataSourceTest::InvokeStartCallback)));
129 }
130
131 void InitializeDataSource(const char* url, int error,
132 bool partial_response, int64 instance_size,
133 NetworkState networkState) {
134 // Saves the url first.
135 gurl_ = GURL(url);
136
137 data_source_ = new MockBufferedDataSource(MessageLoop::current(),
138 view_->mainFrame());
139 data_source_->set_host(&host_);
140
141 scoped_refptr<NiceMock<MockBufferedResourceLoader> > first_loader(
142 new NiceMock<MockBufferedResourceLoader>());
143
144 // Creates the mock loader to be injected.
145 loader_ = first_loader;
146
147 bool initialized_ok = (error == net::OK);
148 bool loaded = networkState == LOADED;
149 {
150 InSequence s;
151 ExpectCreateAndStartResourceLoader(error);
152
153 // In the case of an invalid partial response we expect a second loader
154 // to be created.
155 if (partial_response && (error == net::ERR_INVALID_RESPONSE)) {
156 // Verify that the initial loader is stopped.
157 EXPECT_CALL(*loader_, url())
158 .WillRepeatedly(ReturnRef(gurl_));
159 EXPECT_CALL(*loader_, Stop());
160
161 // Replace loader_ with a new instance.
162 loader_ = new NiceMock<MockBufferedResourceLoader>();
163
164 // Create and start. Make sure Start() is called on the new loader.
165 ExpectCreateAndStartResourceLoader(net::OK);
166
167 // Update initialization variable since we know the second loader will
168 // return OK.
169 initialized_ok = true;
170 }
171 }
172
173 // Attach a static function that deletes the memory referred by the
174 // "callback" parameter.
175 ON_CALL(*loader_, Read(_, _, _ , _))
176 .WillByDefault(DeleteArg<3>());
177
178 ON_CALL(*loader_, instance_size())
179 .WillByDefault(Return(instance_size));
180
181 // range_supported() return true if we expect to get a partial response.
182 ON_CALL(*loader_, range_supported())
183 .WillByDefault(Return(partial_response));
184
185 ON_CALL(*loader_, url())
186 .WillByDefault(ReturnRef(gurl_));
187 media::PipelineStatus expected_init_status = media::PIPELINE_OK;
188 if (initialized_ok) {
189 // Expected loaded or not.
190 EXPECT_CALL(host_, SetLoaded(loaded));
191
192 // TODO(hclam): The condition for streaming needs to be adjusted.
193 if (instance_size != -1 && (loaded || partial_response)) {
194 EXPECT_CALL(host_, SetTotalBytes(instance_size));
195 if (loaded)
196 EXPECT_CALL(host_, SetBufferedBytes(instance_size));
197 else
198 EXPECT_CALL(host_, SetBufferedBytes(0));
199 } else {
200 EXPECT_CALL(host_, SetStreaming(true));
201 }
202 } else {
203 expected_init_status = media::PIPELINE_ERROR_NETWORK;
204 EXPECT_CALL(*loader_, Stop());
205 }
206
207 // Actual initialization of the data source.
208 data_source_->Initialize(url,
209 media::NewExpectedStatusCB(expected_init_status));
210 message_loop_->RunAllPending();
211
212 if (initialized_ok) {
213 // Verify the size of the data source.
214 int64 size;
215 if (instance_size != -1 && (loaded || partial_response)) {
216 EXPECT_TRUE(data_source_->GetSize(&size));
217 EXPECT_EQ(instance_size, size);
218 } else {
219 EXPECT_TRUE(data_source_->IsStreaming());
220 }
221 }
222 }
223
224 void StopDataSource() {
225 if (loader_) {
226 InSequence s;
227 EXPECT_CALL(*loader_, Stop());
228 }
229
230 data_source_->Stop(media::NewExpectedClosure());
231 message_loop_->RunAllPending();
232 }
233
234 void InvokeStartCallback(
235 net::OldCompletionCallback* callback,
236 const base::Closure& network_callback,
237 WebFrame* frame) {
238 callback->RunWithParams(Tuple1<int>(error_));
239 delete callback;
240 // TODO(hclam): Save network_callback.
241 }
242
243 void InvokeReadCallback(int64 position, int size, uint8* buffer,
244 net::OldCompletionCallback* callback) {
245 if (error_ > 0)
246 memcpy(buffer, data_ + static_cast<int>(position), error_);
247 callback->RunWithParams(Tuple1<int>(error_));
248 delete callback;
249 }
250
251 void ReadDataSourceHit(int64 position, int size, int read_size) {
252 EXPECT_TRUE(loader_);
253
254 InSequence s;
255 // Expect the read is delegated to the resource loader.
256 EXPECT_CALL(*loader_, Read(position, size, NotNull(), NotNull()))
257 .WillOnce(DoAll(Assign(&error_, read_size),
258 Invoke(this,
259 &BufferedDataSourceTest::InvokeReadCallback)));
260
261 // The read has succeeded, so read callback will be called.
262 EXPECT_CALL(*this, ReadCallback(read_size));
263
264 data_source_->Read(
265 position, size, buffer_,
266 base::Bind(&BufferedDataSourceTest::ReadCallback,
267 base::Unretained(this)));
268 message_loop_->RunAllPending();
269
270 // Make sure data is correct.
271 EXPECT_EQ(0,
272 memcmp(buffer_, data_ + static_cast<int>(position), read_size));
273 }
274
275 void ReadDataSourceHang(int64 position, int size) {
276 EXPECT_TRUE(loader_);
277
278 // Expect a call to read, but the call never returns.
279 EXPECT_CALL(*loader_, Read(position, size, NotNull(), NotNull()));
280 data_source_->Read(
281 position, size, buffer_,
282 base::Bind(&BufferedDataSourceTest::ReadCallback,
283 base::Unretained(this)));
284 message_loop_->RunAllPending();
285
286 // Now expect the read to return after aborting the data source.
287 EXPECT_CALL(*this, ReadCallback(_));
288 EXPECT_CALL(*loader_, Stop());
289 data_source_->Abort();
290 message_loop_->RunAllPending();
291
292 // The loader has now been stopped. Set this to null so that when the
293 // DataSource is stopped, it does not expect a call to stop the loader.
294 loader_ = NULL;
295 }
296
297 void ReadDataSourceMiss(int64 position, int size, int start_error) {
298 EXPECT_TRUE(loader_);
299
300 // 1. Reply with a cache miss for the read.
301 {
302 InSequence s;
303 EXPECT_CALL(*loader_, Read(position, size, NotNull(), NotNull()))
304 .WillOnce(DoAll(Assign(&error_, net::ERR_CACHE_MISS),
305 Invoke(this,
306 &BufferedDataSourceTest::InvokeReadCallback)));
307 EXPECT_CALL(*loader_, Stop());
308 }
309
310 // 2. Then the current loader will be stop and destroyed.
311 NiceMock<MockBufferedResourceLoader> *new_loader =
312 new NiceMock<MockBufferedResourceLoader>();
313 EXPECT_CALL(*data_source_, CreateResourceLoader(position, -1))
314 .WillOnce(Return(new_loader));
315
316 // 3. Then the new loader will be started.
317 EXPECT_CALL(*new_loader, Start(NotNull(), _, NotNull()))
318 .WillOnce(DoAll(Assign(&error_, start_error),
319 Invoke(this,
320 &BufferedDataSourceTest::InvokeStartCallback)));
321
322 if (start_error == net::OK) {
323 EXPECT_CALL(*new_loader, range_supported())
324 .WillRepeatedly(Return(loader_->range_supported()));
325
326 // 4a. Then again a read request is made to the new loader.
327 EXPECT_CALL(*new_loader, Read(position, size, NotNull(), NotNull()))
328 .WillOnce(DoAll(Assign(&error_, size),
329 Invoke(this,
330 &BufferedDataSourceTest::InvokeReadCallback)));
331
332 EXPECT_CALL(*this, ReadCallback(size));
333 } else {
334 // 4b. The read callback is called with an error because Start() on the
335 // new loader returned an error.
336 EXPECT_CALL(*this, ReadCallback(media::DataSource::kReadError));
337 }
338
339 data_source_->Read(
340 position, size, buffer_,
341 base::Bind(&BufferedDataSourceTest::ReadCallback,
342 base::Unretained(this)));
343 message_loop_->RunAllPending();
344
345 // Make sure data is correct.
346 if (start_error == net::OK)
347 EXPECT_EQ(0, memcmp(buffer_, data_ + static_cast<int>(position), size));
348
349 loader_ = new_loader;
350 }
351
352 void ReadDataSourceFailed(int64 position, int size, int error) {
353 EXPECT_TRUE(loader_);
354
355 // 1. Expect the read is delegated to the resource loader.
356 EXPECT_CALL(*loader_, Read(position, size, NotNull(), NotNull()))
357 .WillOnce(DoAll(Assign(&error_, error),
358 Invoke(this,
359 &BufferedDataSourceTest::InvokeReadCallback)));
360
361 // 2. Host will then receive an error.
362 EXPECT_CALL(*loader_, Stop());
363
364 // 3. The read has failed, so read callback will be called.
365 EXPECT_CALL(*this, ReadCallback(media::DataSource::kReadError));
366
367 data_source_->Read(
368 position, size, buffer_,
369 base::Bind(&BufferedDataSourceTest::ReadCallback,
370 base::Unretained(this)));
371
372 message_loop_->RunAllPending();
373 }
374
375 BufferedResourceLoader* InvokeCacheMissCreateResourceLoader(int64 start,
376 int64 end) {
377 NiceMock<MockBufferedResourceLoader>* new_loader =
378 new NiceMock<MockBufferedResourceLoader>();
379
380 EXPECT_CALL(*new_loader, Start(NotNull(), _, NotNull()))
381 .WillOnce(DoAll(Assign(&error_, net::OK),
382 Invoke(this,
383 &BufferedDataSourceTest::InvokeStartCallback)));
384
385 EXPECT_CALL(*new_loader, range_supported())
386 .WillRepeatedly(Return(loader_->range_supported()));
387
388 int error = net::ERR_FAILED;
389 if (cache_miss_count_ < kMaxCacheMissesBeforeFailTest) {
390 cache_miss_count_++;
391 error = net::ERR_CACHE_MISS;
392 }
393
394 EXPECT_CALL(*new_loader, Read(start, _, NotNull(), NotNull()))
395 .WillOnce(DoAll(Assign(&error_, error),
396 Invoke(this,
397 &BufferedDataSourceTest::InvokeReadCallback)));
398
399 loader_ = new_loader;
400 return new_loader;
401 }
402
403 void ReadDataSourceAlwaysCacheMiss(int64 position, int size) {
404 cache_miss_count_ = 0;
405
406 EXPECT_CALL(*data_source_, CreateResourceLoader(position, -1))
407 .WillRepeatedly(Invoke(
408 this,
409 &BufferedDataSourceTest::InvokeCacheMissCreateResourceLoader));
410
411 EXPECT_CALL(*loader_, Read(position, size, NotNull(), NotNull()))
412 .WillOnce(DoAll(Assign(&error_, net::ERR_CACHE_MISS),
413 Invoke(this,
414 &BufferedDataSourceTest::InvokeReadCallback)));
415
416 EXPECT_CALL(*this, ReadCallback(media::DataSource::kReadError));
417
418 data_source_->Read(
419 position, size, buffer_,
420 base::Bind(&BufferedDataSourceTest::ReadCallback,
421 base::Unretained(this)));
422
423 message_loop_->RunAllPending();
424
425 EXPECT_LT(cache_miss_count_, kMaxCacheMissesBeforeFailTest);
426 }
427
428 MOCK_METHOD1(ReadCallback, void(size_t size));
429
430 scoped_refptr<NiceMock<MockBufferedResourceLoader> > loader_;
431 scoped_refptr<MockBufferedDataSource> data_source_;
432
433 MockWebFrameClient client_;
434 WebView* view_;
435
436 StrictMock<media::MockFilterHost> host_;
437 GURL gurl_;
438 MessageLoop* message_loop_;
439
440 int error_;
441 uint8 buffer_[1024];
442 uint8 data_[1024];
443
444 int cache_miss_count_;
445
446 private:
447 DISALLOW_COPY_AND_ASSIGN(BufferedDataSourceTest);
448 };
449
450 TEST_F(BufferedDataSourceTest, InitializationSuccess) {
451 InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING);
452 StopDataSource();
453 }
454
455 TEST_F(BufferedDataSourceTest, InitiailizationFailed) {
456 InitializeDataSource(kHttpUrl, net::ERR_FILE_NOT_FOUND, false, 0, NONE);
457 StopDataSource();
458 }
459
460 TEST_F(BufferedDataSourceTest, MissingContentLength) {
461 InitializeDataSource(kHttpUrl, net::OK, true, -1, LOADING);
462 StopDataSource();
463 }
464
465 TEST_F(BufferedDataSourceTest, RangeRequestNotSupported) {
466 InitializeDataSource(kHttpUrl, net::OK, false, 1024, LOADING);
467 StopDataSource();
468 }
469
470 // Test the case where we get a 206 response, but no Content-Range header.
471 TEST_F(BufferedDataSourceTest, MissingContentRange) {
472 InitializeDataSource(kHttpUrl, net::ERR_INVALID_RESPONSE, true, 1024,
473 LOADING);
474 StopDataSource();
475 }
476
477 TEST_F(BufferedDataSourceTest,
478 MissingContentLengthAndRangeRequestNotSupported) {
479 InitializeDataSource(kHttpUrl, net::OK, false, -1, LOADING);
480 StopDataSource();
481 }
482
483 TEST_F(BufferedDataSourceTest, ReadCacheHit) {
484 InitializeDataSource(kHttpUrl, net::OK, true, 25, LOADING);
485
486 // Performs read with cache hit.
487 ReadDataSourceHit(10, 10, 10);
488
489 // Performs read with cache hit but partially filled.
490 ReadDataSourceHit(20, 10, 5);
491
492 StopDataSource();
493 }
494
495 TEST_F(BufferedDataSourceTest, ReadCacheMiss) {
496 InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING);
497 ReadDataSourceMiss(1000, 10, net::OK);
498 ReadDataSourceMiss(20, 10, net::OK);
499 StopDataSource();
500 }
501
502 // Test the case where the initial response from the server indicates that
503 // Range requests are supported, but a later request prove otherwise.
504 TEST_F(BufferedDataSourceTest, ServerLiesAboutRangeSupport) {
505 InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING);
506 ReadDataSourceHit(10, 10, 10);
507 ReadDataSourceMiss(1000, 10, net::ERR_INVALID_RESPONSE);
508 StopDataSource();
509 }
510
511 TEST_F(BufferedDataSourceTest, ReadHang) {
512 InitializeDataSource(kHttpUrl, net::OK, true, 25, LOADING);
513 ReadDataSourceHang(10, 10);
514 StopDataSource();
515 }
516
517 TEST_F(BufferedDataSourceTest, ReadFailed) {
518 InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING);
519 ReadDataSourceHit(10, 10, 10);
520 ReadDataSourceFailed(10, 10, net::ERR_CONNECTION_RESET);
521 StopDataSource();
522 }
523
524 // Helper that sets |*value| to true. Useful for binding into a Closure.
525 static void SetTrue(bool* value) {
526 *value = true;
527 }
528
529 // This test makes sure that Stop() does not require a task to run on
530 // |message_loop_| before it calls its callback. This prevents accidental
531 // introduction of a pipeline teardown deadlock. The pipeline owner blocks
532 // the render message loop while waiting for Stop() to complete. Since this
533 // object runs on the render message loop, Stop() will not complete if it
534 // requires a task to run on the the message loop that is being blocked.
535 TEST_F(BufferedDataSourceTest, StopDoesNotUseMessageLoopForCallback) {
536 InitializeDataSource(kFileUrl, net::OK, true, 1024, LOADED);
537
538 // Stop() the data source, using a callback that lets us verify that it was
539 // called before Stop() returns. This is to make sure that the callback does
540 // not require |message_loop_| to execute tasks before being called.
541 bool stop_done_called = false;
542 data_source_->Stop(base::Bind(&SetTrue, &stop_done_called));
543
544 // Verify that the callback was called inside the Stop() call.
545 EXPECT_TRUE(stop_done_called);
546
547 message_loop_->RunAllPending();
548 }
549
550 TEST_F(BufferedDataSourceTest, AbortDuringPendingRead) {
551 InitializeDataSource(kFileUrl, net::OK, true, 1024, LOADED);
552
553 // Setup a way to verify that Read() is not called on the loader.
554 // We are doing this to make sure that the ReadTask() is still on
555 // the message loop queue when Abort() is called.
556 bool read_called = false;
557 ON_CALL(*loader_, Read(_, _, _ , _))
558 .WillByDefault(DoAll(Assign(&read_called, true),
559 DeleteArg<3>()));
560
561 // Initiate a Read() on the data source, but don't allow the
562 // message loop to run.
563 data_source_->Read(
564 0, 10, buffer_,
565 base::Bind(&BufferedDataSourceTest::ReadCallback,
566 base::Unretained(static_cast<BufferedDataSourceTest*>(this))));
567
568 // Call Abort() with the read pending.
569 EXPECT_CALL(*this, ReadCallback(-1));
570 EXPECT_CALL(*loader_, Stop());
571 data_source_->Abort();
572
573 // Verify that Read()'s after the Abort() issue callback with an error.
574 EXPECT_CALL(*this, ReadCallback(-1));
575 data_source_->Read(
576 0, 10, buffer_,
577 base::Bind(&BufferedDataSourceTest::ReadCallback,
578 base::Unretained(static_cast<BufferedDataSourceTest*>(this))));
579
580 // Stop() the data source like normal.
581 data_source_->Stop(media::NewExpectedClosure());
582
583 // Allow cleanup task to run.
584 message_loop_->RunAllPending();
585
586 // Verify that Read() was not called on the loader.
587 EXPECT_FALSE(read_called);
588 }
589
590 // Test that we only allow a limited number of cache misses for a
591 // single Read() request.
592 TEST_F(BufferedDataSourceTest, BoundedCacheMisses) {
593 InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING);
594
595 ReadDataSourceAlwaysCacheMiss(0, 10);
596
597 StopDataSource();
598 }
599
600 // TODO(scherkus): de-dupe from buffered_resource_loader_unittest.cc
601 ACTION_P(RequestCanceled, loader) {
602 WebURLError error;
603 error.reason = net::ERR_ABORTED;
604 error.domain = WebString::fromUTF8(net::kErrorDomain);
605 loader->didFail(NULL, error);
606 }
607
608 // A more realistic BufferedDataSource that uses BufferedResourceLoader instead
609 // of a mocked version but injects a MockWebURLLoader.
610 //
611 // TODO(scherkus): re-write these tests to use this class then drop the "2"
612 // suffix.
613 class MockBufferedDataSource2 : public BufferedDataSource {
614 public:
615 MockBufferedDataSource2(MessageLoop* message_loop, WebFrame* frame)
616 : BufferedDataSource(message_loop, frame, new media::MediaLog()),
617 url_loader_(NULL) {
618 }
619
620 virtual base::TimeDelta GetTimeoutMilliseconds() {
621 return base::TimeDelta::FromMilliseconds(
622 TestTimeouts::tiny_timeout_ms());
623 }
624
625 virtual BufferedResourceLoader* CreateResourceLoader(int64 first_position,
626 int64 last_position) {
627 loader_ = BufferedDataSource::CreateResourceLoader(first_position,
628 last_position);
629
630 url_loader_ = new NiceMock<MockWebURLLoader>();
631 ON_CALL(*url_loader_, cancel())
632 .WillByDefault(RequestCanceled(loader_));
633
634 loader_->SetURLLoaderForTest(url_loader_);
635 return loader_;
636 }
637
638 const scoped_refptr<BufferedResourceLoader>& loader() { return loader_; }
639 NiceMock<MockWebURLLoader>* url_loader() { return url_loader_; }
640
641 private:
642 scoped_refptr<BufferedResourceLoader> loader_;
643 NiceMock<MockWebURLLoader>* url_loader_;
644
645 DISALLOW_COPY_AND_ASSIGN(MockBufferedDataSource2);
646 };
647
648 class BufferedDataSourceTest2 : public testing::Test {
649 public:
650 BufferedDataSourceTest2()
651 : view_(WebView::create(NULL)),
652 message_loop_(MessageLoop::current()) {
653 view_->initializeMainFrame(&client_);
654 }
655
656 virtual ~BufferedDataSourceTest2() {
657 view_->close();
658 }
659
660 void InitializeDataSource(const char* url) {
661 gurl_ = GURL(url);
662
663 data_source_ = new MockBufferedDataSource2(message_loop_,
664 view_->mainFrame());
665 data_source_->set_host(&host_);
666 data_source_->Initialize(url,
667 media::NewExpectedStatusCB(media::PIPELINE_OK));
668 message_loop_->RunAllPending();
669
670 // Simulate 206 response for a 5,000,000 byte length file.
671 WebURLResponse response(gurl_);
672 response.setHTTPHeaderField(WebString::fromUTF8("Accept-Ranges"),
673 WebString::fromUTF8("bytes"));
674 response.setHTTPHeaderField(WebString::fromUTF8("Content-Range"),
675 WebString::fromUTF8("bytes 0-4999999/5000000"));
676 response.setHTTPHeaderField(WebString::fromUTF8("Content-Length"),
677 WebString::fromUTF8("5000000"));
678 response.setExpectedContentLength(5000000);
679 response.setHTTPStatusCode(206);
680
681 // We should receive corresponding information about the media resource.
682 EXPECT_CALL(host_, SetLoaded(false));
683 EXPECT_CALL(host_, SetTotalBytes(5000000));
684 EXPECT_CALL(host_, SetBufferedBytes(0));
685
686 data_source_->loader()->didReceiveResponse(data_source_->url_loader(),
687 response);
688
689 message_loop_->RunAllPending();
690 }
691
692 void StopDataSource() {
693 data_source_->Stop(media::NewExpectedClosure());
694 message_loop_->RunAllPending();
695 }
696
697 MOCK_METHOD1(ReadCallback, void(size_t size));
698 media::DataSource::ReadCallback NewReadCallback(size_t size) {
699 EXPECT_CALL(*this, ReadCallback(size));
700 return base::Bind(&BufferedDataSourceTest2::ReadCallback,
701 base::Unretained(this));
702 }
703
704 // Accessors for private variables on |data_source_|.
705 media::Preload preload() { return data_source_->preload_; }
706 BufferedResourceLoader::DeferStrategy defer_strategy() {
707 return data_source_->loader()->defer_strategy_;
708 }
709 int data_source_bitrate() { return data_source_->bitrate_; }
710 int data_source_playback_rate() { return data_source_->playback_rate_; }
711 int loader_bitrate() { return data_source_->loader()->bitrate_; }
712 int loader_playback_rate() { return data_source_->loader()->playback_rate_; }
713
714 scoped_refptr<MockBufferedDataSource2> data_source_;
715
716 GURL gurl_;
717 MockWebFrameClient client_;
718 WebView* view_;
719
720 StrictMock<media::MockFilterHost> host_;
721 MessageLoop* message_loop_;
722
723 private:
724 DISALLOW_COPY_AND_ASSIGN(BufferedDataSourceTest2);
725 };
726
727 TEST_F(BufferedDataSourceTest2, Default) {
728 InitializeDataSource("http://localhost/foo.webm");
729
730 // Ensure we have sane values for default loading scenario.
731 EXPECT_EQ(media::AUTO, preload());
732 EXPECT_EQ(BufferedResourceLoader::kThresholdDefer, defer_strategy());
733
734 EXPECT_EQ(0, data_source_bitrate());
735 EXPECT_EQ(0.0f, data_source_playback_rate());
736 EXPECT_EQ(0, loader_bitrate());
737 EXPECT_EQ(0.0f, loader_playback_rate());
738
739 StopDataSource();
740 }
741
742 TEST_F(BufferedDataSourceTest2, SetBitrate) {
743 InitializeDataSource("http://localhost/foo.webm");
744
745 data_source_->SetBitrate(1234);
746 message_loop_->RunAllPending();
747 EXPECT_EQ(1234, data_source_bitrate());
748 EXPECT_EQ(1234, loader_bitrate());
749
750 // Read so far ahead to cause the loader to get recreated.
751 BufferedResourceLoader* old_loader = data_source_->loader();
752
753 uint8 buffer[1024];
754 data_source_->Read(4000000, 1024, buffer,
755 NewReadCallback(media::DataSource::kReadError));
756 message_loop_->RunAllPending();
757
758 // Verify loader changed but still has same bitrate.
759 EXPECT_NE(old_loader, data_source_->loader().get());
760 EXPECT_EQ(1234, loader_bitrate());
761
762 StopDataSource();
763 }
764
765 TEST_F(BufferedDataSourceTest2, SetPlaybackRate) {
766 InitializeDataSource("http://localhost/foo.webm");
767
768 data_source_->SetPlaybackRate(2.0f);
769 message_loop_->RunAllPending();
770 EXPECT_EQ(2.0f, data_source_playback_rate());
771 EXPECT_EQ(2.0f, loader_playback_rate());
772
773 // Read so far ahead to cause the loader to get recreated.
774 BufferedResourceLoader* old_loader = data_source_->loader();
775
776 uint8 buffer[1024];
777 data_source_->Read(4000000, 1024, buffer,
778 NewReadCallback(media::DataSource::kReadError));
779 message_loop_->RunAllPending();
780
781 // Verify loader changed but still has same bitrate.
782 EXPECT_NE(old_loader, data_source_->loader().get());
783 EXPECT_EQ(2.0f, loader_playback_rate());
784
785 StopDataSource();
786 }
787
788 } // namespace webkit_glue
OLDNEW
« no previous file with comments | « webkit/glue/media/buffered_data_source.cc ('k') | webkit/glue/media/buffered_resource_loader.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698