1 // Copyright 2013 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/bind.h"
6 #include "base/message_loop/message_loop.h"
7 #include "media/base/media_log.h"
8 #include "media/base/mock_filters.h"
9 #include "media/base/test_helpers.h"
10 #include "media/blink/buffered_data_source.h"
11 #include "media/blink/mock_webframeclient.h"
12 #include "media/blink/mock_weburlloader.h"
13 #include "media/blink/test_response_generator.h"
14 #include "third_party/WebKit/public/platform/WebURLResponse.h"
15 #include "third_party/WebKit/public/web/WebLocalFrame.h"
16 #include "third_party/WebKit/public/web/WebView.h"
17
18 using ::testing::_;
19 using ::testing::Assign;
20 using ::testing::Invoke;
21 using ::testing::InSequence;
22 using ::testing::NiceMock;
23 using ::testing::StrictMock;
24
25 using blink::WebLocalFrame;
26 using blink::WebString;
27 using blink::WebURLLoader;
28 using blink::WebURLResponse;
29 using blink::WebView;
30
31 namespace media {
32
33 class MockBufferedDataSourceHost : public BufferedDataSourceHost {
34 public:
MockBufferedDataSourceHost()35 MockBufferedDataSourceHost() {}
~MockBufferedDataSourceHost()36 virtual ~MockBufferedDataSourceHost() {}
37
38 MOCK_METHOD1(SetTotalBytes, void(int64 total_bytes));
39 MOCK_METHOD2(AddBufferedByteRange, void(int64 start, int64 end));
40
41 private:
42 DISALLOW_COPY_AND_ASSIGN(MockBufferedDataSourceHost);
43 };
44
45 // Overrides CreateResourceLoader() to permit injecting a MockWebURLLoader.
46 // Also keeps track of whether said MockWebURLLoader is actively loading.
47 class MockBufferedDataSource : public BufferedDataSource {
48 public:
MockBufferedDataSource(const GURL & url,const scoped_refptr<base::SingleThreadTaskRunner> & task_runner,WebLocalFrame * frame,BufferedDataSourceHost * host)49 MockBufferedDataSource(
50 const GURL& url,
51 const scoped_refptr<base::SingleThreadTaskRunner>& task_runner,
52 WebLocalFrame* frame,
53 BufferedDataSourceHost* host)
54 : BufferedDataSource(url,
55 BufferedResourceLoader::kUnspecified,
56 task_runner,
57 frame,
58 new media::MediaLog(),
59 host,
60 base::Bind(&MockBufferedDataSource::set_downloading,
61 base::Unretained(this))),
62 downloading_(false),
63 loading_(false) {}
~MockBufferedDataSource()64 virtual ~MockBufferedDataSource() {}
65
66 MOCK_METHOD2(CreateResourceLoader, BufferedResourceLoader*(int64, int64));
CreateMockResourceLoader(int64 first_byte_position,int64 last_byte_position)67 BufferedResourceLoader* CreateMockResourceLoader(int64 first_byte_position,
68 int64 last_byte_position) {
69 CHECK(!loading_) << "Previous resource load wasn't cancelled";
70
71 BufferedResourceLoader* loader =
72 BufferedDataSource::CreateResourceLoader(first_byte_position,
73 last_byte_position);
74
75 // Keep track of active loading state via loadAsynchronously() and cancel().
76 NiceMock<MockWebURLLoader>* url_loader = new NiceMock<MockWebURLLoader>();
77 ON_CALL(*url_loader, loadAsynchronously(_, _))
78 .WillByDefault(Assign(&loading_, true));
79 ON_CALL(*url_loader, cancel())
80 .WillByDefault(Assign(&loading_, false));
81
82 // |test_loader_| will be used when Start() is called.
83 loader->test_loader_ = scoped_ptr<WebURLLoader>(url_loader);
84 return loader;
85 }
86
loading()87 bool loading() { return loading_; }
set_loading(bool loading)88 void set_loading(bool loading) { loading_ = loading; }
downloading()89 bool downloading() { return downloading_; }
set_downloading(bool downloading)90 void set_downloading(bool downloading) { downloading_ = downloading; }
91
92 private:
93 // Whether the resource is downloading or deferred.
94 bool downloading_;
95
96 // Whether the resource load has starting loading but yet to been cancelled.
97 bool loading_;
98
99 DISALLOW_COPY_AND_ASSIGN(MockBufferedDataSource);
100 };
101
102 static const int64 kFileSize = 5000000;
103 static const int64 kFarReadPosition = 4000000;
104 static const int kDataSize = 1024;
105
106 static const char kHttpUrl[] = "http://localhost/foo.webm";
107 static const char kFileUrl[] = "file:///tmp/bar.webm";
108
109 class BufferedDataSourceTest : public testing::Test {
110 public:
BufferedDataSourceTest()111 BufferedDataSourceTest()
112 : view_(WebView::create(NULL)),
113 frame_(WebLocalFrame::create(&client_)),
114 preload_(BufferedDataSource::AUTO) {
115 view_->setMainFrame(frame_);
116 }
117
~BufferedDataSourceTest()118 virtual ~BufferedDataSourceTest() {
119 view_->close();
120 frame_->close();
121 }
122
123 MOCK_METHOD1(OnInitialize, void(bool));
124
Initialize(const char * url,bool expected)125 void Initialize(const char* url, bool expected) {
126 GURL gurl(url);
127 data_source_.reset(
128 new MockBufferedDataSource(gurl,
129 message_loop_.message_loop_proxy(),
130 view_->mainFrame()->toWebLocalFrame(),
131 &host_));
132 data_source_->SetPreload(preload_);
133
134 response_generator_.reset(new TestResponseGenerator(gurl, kFileSize));
135 ExpectCreateResourceLoader();
136 EXPECT_CALL(*this, OnInitialize(expected));
137 data_source_->Initialize(base::Bind(&BufferedDataSourceTest::OnInitialize,
138 base::Unretained(this)));
139 message_loop_.RunUntilIdle();
140
141 bool is_http = gurl.SchemeIsHTTPOrHTTPS();
142 EXPECT_EQ(data_source_->downloading(), is_http);
143 }
144
145 // Helper to initialize tests with a valid 200 response.
InitializeWith200Response()146 void InitializeWith200Response() {
147 Initialize(kHttpUrl, true);
148
149 EXPECT_CALL(host_, SetTotalBytes(response_generator_->content_length()));
150 Respond(response_generator_->Generate200());
151 }
152
153 // Helper to initialize tests with a valid 206 response.
InitializeWith206Response()154 void InitializeWith206Response() {
155 Initialize(kHttpUrl, true);
156
157 EXPECT_CALL(host_, SetTotalBytes(response_generator_->content_length()));
158 Respond(response_generator_->Generate206(0));
159 }
160
161 // Helper to initialize tests with a valid file:// response.
InitializeWithFileResponse()162 void InitializeWithFileResponse() {
163 Initialize(kFileUrl, true);
164
165 EXPECT_CALL(host_, SetTotalBytes(kFileSize));
166 EXPECT_CALL(host_, AddBufferedByteRange(0, kFileSize));
167 Respond(response_generator_->GenerateFileResponse(0));
168 }
169
170 // Stops any active loaders and shuts down the data source.
171 //
172 // This typically happens when the page is closed and for our purposes is
173 // appropriate to do when tearing down a test.
Stop()174 void Stop() {
175 if (data_source_->loading()) {
176 loader()->didFail(url_loader(), response_generator_->GenerateError());
177 message_loop_.RunUntilIdle();
178 }
179
180 data_source_->Stop();
181 message_loop_.RunUntilIdle();
182 }
183
ExpectCreateResourceLoader()184 void ExpectCreateResourceLoader() {
185 EXPECT_CALL(*data_source_, CreateResourceLoader(_, _))
186 .WillOnce(Invoke(data_source_.get(),
187 &MockBufferedDataSource::CreateMockResourceLoader));
188 message_loop_.RunUntilIdle();
189 }
190
Respond(const WebURLResponse & response)191 void Respond(const WebURLResponse& response) {
192 loader()->didReceiveResponse(url_loader(), response);
193 message_loop_.RunUntilIdle();
194 }
195
ReceiveData(int size)196 void ReceiveData(int size) {
197 scoped_ptr<char[]> data(new char[size]);
198 memset(data.get(), 0xA5, size); // Arbitrary non-zero value.
199
200 loader()->didReceiveData(url_loader(), data.get(), size, size);
201 message_loop_.RunUntilIdle();
202 }
203
FinishLoading()204 void FinishLoading() {
205 data_source_->set_loading(false);
206 loader()->didFinishLoading(url_loader(), 0, -1);
207 message_loop_.RunUntilIdle();
208 }
209
210 MOCK_METHOD1(ReadCallback, void(int size));
211
ReadAt(int64 position)212 void ReadAt(int64 position) {
213 data_source_->Read(position, kDataSize, buffer_,
214 base::Bind(&BufferedDataSourceTest::ReadCallback,
215 base::Unretained(this)));
216 message_loop_.RunUntilIdle();
217 }
218
219 // Accessors for private variables on |data_source_|.
loader()220 BufferedResourceLoader* loader() {
221 return data_source_->loader_.get();
222 }
url_loader()223 WebURLLoader* url_loader() {
224 return loader()->active_loader_->loader_.get();
225 }
226
preload()227 BufferedDataSource::Preload preload() { return data_source_->preload_; }
set_preload(BufferedDataSource::Preload preload)228 void set_preload(BufferedDataSource::Preload preload) { preload_ = preload; }
defer_strategy()229 BufferedResourceLoader::DeferStrategy defer_strategy() {
230 return loader()->defer_strategy_;
231 }
data_source_bitrate()232 int data_source_bitrate() { return data_source_->bitrate_; }
data_source_playback_rate()233 int data_source_playback_rate() { return data_source_->playback_rate_; }
loader_bitrate()234 int loader_bitrate() { return loader()->bitrate_; }
loader_playback_rate()235 int loader_playback_rate() { return loader()->playback_rate_; }
is_local_source()236 bool is_local_source() { return data_source_->assume_fully_buffered(); }
set_might_be_reused_from_cache_in_future(bool value)237 void set_might_be_reused_from_cache_in_future(bool value) {
238 loader()->might_be_reused_from_cache_in_future_ = value;
239 }
240
241 scoped_ptr<MockBufferedDataSource> data_source_;
242
243 scoped_ptr<TestResponseGenerator> response_generator_;
244 MockWebFrameClient client_;
245 WebView* view_;
246 WebLocalFrame* frame_;
247
248 StrictMock<MockBufferedDataSourceHost> host_;
249 base::MessageLoop message_loop_;
250
251 private:
252 // Used for calling BufferedDataSource::Read().
253 uint8 buffer_[kDataSize];
254
255 BufferedDataSource::Preload preload_;
256
257 DISALLOW_COPY_AND_ASSIGN(BufferedDataSourceTest);
258 };
259
TEST_F(BufferedDataSourceTest,Range_Supported)260 TEST_F(BufferedDataSourceTest, Range_Supported) {
261 InitializeWith206Response();
262
263 EXPECT_TRUE(data_source_->loading());
264 EXPECT_FALSE(data_source_->IsStreaming());
265 Stop();
266 }
267
TEST_F(BufferedDataSourceTest,Range_InstanceSizeUnknown)268 TEST_F(BufferedDataSourceTest, Range_InstanceSizeUnknown) {
269 Initialize(kHttpUrl, true);
270
271 Respond(response_generator_->Generate206(
272 0, TestResponseGenerator::kNoContentRangeInstanceSize));
273
274 EXPECT_TRUE(data_source_->loading());
275 EXPECT_TRUE(data_source_->IsStreaming());
276 Stop();
277 }
278
TEST_F(BufferedDataSourceTest,Range_NotFound)279 TEST_F(BufferedDataSourceTest, Range_NotFound) {
280 Initialize(kHttpUrl, false);
281 Respond(response_generator_->Generate404());
282
283 EXPECT_FALSE(data_source_->loading());
284 Stop();
285 }
286
TEST_F(BufferedDataSourceTest,Range_NotSupported)287 TEST_F(BufferedDataSourceTest, Range_NotSupported) {
288 InitializeWith200Response();
289
290 EXPECT_TRUE(data_source_->loading());
291 EXPECT_TRUE(data_source_->IsStreaming());
292 Stop();
293 }
294
295 // Special carve-out for Apache versions that choose to return a 200 for
296 // Range:0- ("because it's more efficient" than a 206)
TEST_F(BufferedDataSourceTest,Range_SupportedButReturned200)297 TEST_F(BufferedDataSourceTest, Range_SupportedButReturned200) {
298 Initialize(kHttpUrl, true);
299 EXPECT_CALL(host_, SetTotalBytes(response_generator_->content_length()));
300 WebURLResponse response = response_generator_->Generate200();
301 response.setHTTPHeaderField(WebString::fromUTF8("Accept-Ranges"),
302 WebString::fromUTF8("bytes"));
303 Respond(response);
304
305 EXPECT_TRUE(data_source_->loading());
306 EXPECT_FALSE(data_source_->IsStreaming());
307 Stop();
308 }
309
TEST_F(BufferedDataSourceTest,Range_MissingContentRange)310 TEST_F(BufferedDataSourceTest, Range_MissingContentRange) {
311 Initialize(kHttpUrl, false);
312 Respond(response_generator_->Generate206(
313 0, TestResponseGenerator::kNoContentRange));
314
315 EXPECT_FALSE(data_source_->loading());
316 Stop();
317 }
318
TEST_F(BufferedDataSourceTest,Range_MissingContentLength)319 TEST_F(BufferedDataSourceTest, Range_MissingContentLength) {
320 Initialize(kHttpUrl, true);
321
322 // It'll manage without a Content-Length response.
323 EXPECT_CALL(host_, SetTotalBytes(response_generator_->content_length()));
324 Respond(response_generator_->Generate206(
325 0, TestResponseGenerator::kNoContentLength));
326
327 EXPECT_TRUE(data_source_->loading());
328 EXPECT_FALSE(data_source_->IsStreaming());
329 Stop();
330 }
331
TEST_F(BufferedDataSourceTest,Range_WrongContentRange)332 TEST_F(BufferedDataSourceTest, Range_WrongContentRange) {
333 Initialize(kHttpUrl, false);
334
335 // Now it's done and will fail.
336 Respond(response_generator_->Generate206(1337));
337
338 EXPECT_FALSE(data_source_->loading());
339 Stop();
340 }
341
342 // Test the case where the initial response from the server indicates that
343 // Range requests are supported, but a later request prove otherwise.
TEST_F(BufferedDataSourceTest,Range_ServerLied)344 TEST_F(BufferedDataSourceTest, Range_ServerLied) {
345 InitializeWith206Response();
346
347 // Read causing a new request to be made -- we'll expect it to error.
348 ExpectCreateResourceLoader();
349 ReadAt(kFarReadPosition);
350
351 // Return a 200 in response to a range request.
352 EXPECT_CALL(*this, ReadCallback(media::DataSource::kReadError));
353 Respond(response_generator_->Generate200());
354
355 EXPECT_FALSE(data_source_->loading());
356 Stop();
357 }
358
TEST_F(BufferedDataSourceTest,Http_AbortWhileReading)359 TEST_F(BufferedDataSourceTest, Http_AbortWhileReading) {
360 InitializeWith206Response();
361
362 // Make sure there's a pending read -- we'll expect it to error.
363 ReadAt(0);
364
365 // Abort!!!
366 EXPECT_CALL(*this, ReadCallback(media::DataSource::kReadError));
367 data_source_->Abort();
368 message_loop_.RunUntilIdle();
369
370 EXPECT_FALSE(data_source_->loading());
371 Stop();
372 }
373
TEST_F(BufferedDataSourceTest,File_AbortWhileReading)374 TEST_F(BufferedDataSourceTest, File_AbortWhileReading) {
375 InitializeWithFileResponse();
376
377 // Make sure there's a pending read -- we'll expect it to error.
378 ReadAt(0);
379
380 // Abort!!!
381 EXPECT_CALL(*this, ReadCallback(media::DataSource::kReadError));
382 data_source_->Abort();
383 message_loop_.RunUntilIdle();
384
385 EXPECT_FALSE(data_source_->loading());
386 Stop();
387 }
388
TEST_F(BufferedDataSourceTest,Http_Retry)389 TEST_F(BufferedDataSourceTest, Http_Retry) {
390 InitializeWith206Response();
391
392 // Read to advance our position.
393 EXPECT_CALL(*this, ReadCallback(kDataSize));
394 EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize - 1));
395 ReadAt(0);
396 ReceiveData(kDataSize);
397
398 // Issue a pending read but terminate the connection to force a retry.
399 ReadAt(kDataSize);
400 ExpectCreateResourceLoader();
401 FinishLoading();
402 Respond(response_generator_->Generate206(kDataSize));
403
404 // Complete the read.
405 EXPECT_CALL(*this, ReadCallback(kDataSize));
406 EXPECT_CALL(host_, AddBufferedByteRange(kDataSize, (kDataSize * 2) - 1));
407 ReceiveData(kDataSize);
408
409 EXPECT_TRUE(data_source_->loading());
410 Stop();
411 }
412
TEST_F(BufferedDataSourceTest,File_Retry)413 TEST_F(BufferedDataSourceTest, File_Retry) {
414 InitializeWithFileResponse();
415
416 // Read to advance our position.
417 EXPECT_CALL(*this, ReadCallback(kDataSize));
418 ReadAt(0);
419 ReceiveData(kDataSize);
420
421 // Issue a pending read but terminate the connection to force a retry.
422 ReadAt(kDataSize);
423 ExpectCreateResourceLoader();
424 FinishLoading();
425 Respond(response_generator_->GenerateFileResponse(kDataSize));
426
427 // Complete the read.
428 EXPECT_CALL(*this, ReadCallback(kDataSize));
429 ReceiveData(kDataSize);
430
431 EXPECT_TRUE(data_source_->loading());
432 Stop();
433 }
434
TEST_F(BufferedDataSourceTest,Http_TooManyRetries)435 TEST_F(BufferedDataSourceTest, Http_TooManyRetries) {
436 InitializeWith206Response();
437
438 // Make sure there's a pending read -- we'll expect it to error.
439 ReadAt(0);
440
441 // It'll try three times.
442 ExpectCreateResourceLoader();
443 FinishLoading();
444 Respond(response_generator_->Generate206(0));
445
446 ExpectCreateResourceLoader();
447 FinishLoading();
448 Respond(response_generator_->Generate206(0));
449
450 ExpectCreateResourceLoader();
451 FinishLoading();
452 Respond(response_generator_->Generate206(0));
453
454 // It'll error after this.
455 EXPECT_CALL(*this, ReadCallback(media::DataSource::kReadError));
456 FinishLoading();
457
458 EXPECT_FALSE(data_source_->loading());
459 Stop();
460 }
461
TEST_F(BufferedDataSourceTest,File_TooManyRetries)462 TEST_F(BufferedDataSourceTest, File_TooManyRetries) {
463 InitializeWithFileResponse();
464
465 // Make sure there's a pending read -- we'll expect it to error.
466 ReadAt(0);
467
468 // It'll try three times.
469 ExpectCreateResourceLoader();
470 FinishLoading();
471 Respond(response_generator_->GenerateFileResponse(0));
472
473 ExpectCreateResourceLoader();
474 FinishLoading();
475 Respond(response_generator_->GenerateFileResponse(0));
476
477 ExpectCreateResourceLoader();
478 FinishLoading();
479 Respond(response_generator_->GenerateFileResponse(0));
480
481 // It'll error after this.
482 EXPECT_CALL(*this, ReadCallback(media::DataSource::kReadError));
483 FinishLoading();
484
485 EXPECT_FALSE(data_source_->loading());
486 Stop();
487 }
488
TEST_F(BufferedDataSourceTest,File_InstanceSizeUnknown)489 TEST_F(BufferedDataSourceTest, File_InstanceSizeUnknown) {
490 Initialize(kFileUrl, false);
491 EXPECT_FALSE(data_source_->downloading());
492
493 Respond(response_generator_->GenerateFileResponse(-1));
494
495 EXPECT_FALSE(data_source_->loading());
496 Stop();
497 }
498
TEST_F(BufferedDataSourceTest,File_Successful)499 TEST_F(BufferedDataSourceTest, File_Successful) {
500 InitializeWithFileResponse();
501
502 EXPECT_TRUE(data_source_->loading());
503 EXPECT_FALSE(data_source_->IsStreaming());
504 Stop();
505 }
506
TEST_F(BufferedDataSourceTest,StopDuringRead)507 TEST_F(BufferedDataSourceTest, StopDuringRead) {
508 InitializeWith206Response();
509
510 uint8 buffer[256];
511 data_source_->Read(0, arraysize(buffer), buffer, base::Bind(
512 &BufferedDataSourceTest::ReadCallback, base::Unretained(this)));
513
514 // The outstanding read should fail before the stop callback runs.
515 {
516 InSequence s;
517 EXPECT_CALL(*this, ReadCallback(media::DataSource::kReadError));
518 data_source_->Stop();
519 }
520 message_loop_.RunUntilIdle();
521 }
522
TEST_F(BufferedDataSourceTest,DefaultValues)523 TEST_F(BufferedDataSourceTest, DefaultValues) {
524 InitializeWith206Response();
525
526 // Ensure we have sane values for default loading scenario.
527 EXPECT_EQ(BufferedDataSource::AUTO, preload());
528 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
529
530 EXPECT_EQ(0, data_source_bitrate());
531 EXPECT_EQ(0.0f, data_source_playback_rate());
532 EXPECT_EQ(0, loader_bitrate());
533 EXPECT_EQ(0.0f, loader_playback_rate());
534
535 EXPECT_TRUE(data_source_->loading());
536 Stop();
537 }
538
TEST_F(BufferedDataSourceTest,SetBitrate)539 TEST_F(BufferedDataSourceTest, SetBitrate) {
540 InitializeWith206Response();
541
542 data_source_->SetBitrate(1234);
543 message_loop_.RunUntilIdle();
544 EXPECT_EQ(1234, data_source_bitrate());
545 EXPECT_EQ(1234, loader_bitrate());
546
547 // Read so far ahead to cause the loader to get recreated.
548 BufferedResourceLoader* old_loader = loader();
549 ExpectCreateResourceLoader();
550 ReadAt(kFarReadPosition);
551 Respond(response_generator_->Generate206(kFarReadPosition));
552
553 // Verify loader changed but still has same bitrate.
554 EXPECT_NE(old_loader, loader());
555 EXPECT_EQ(1234, loader_bitrate());
556
557 EXPECT_TRUE(data_source_->loading());
558 EXPECT_CALL(*this, ReadCallback(media::DataSource::kReadError));
559 Stop();
560 }
561
TEST_F(BufferedDataSourceTest,MediaPlaybackRateChanged)562 TEST_F(BufferedDataSourceTest, MediaPlaybackRateChanged) {
563 InitializeWith206Response();
564
565 data_source_->MediaPlaybackRateChanged(2.0f);
566 message_loop_.RunUntilIdle();
567 EXPECT_EQ(2.0f, data_source_playback_rate());
568 EXPECT_EQ(2.0f, loader_playback_rate());
569
570 // Read so far ahead to cause the loader to get recreated.
571 BufferedResourceLoader* old_loader = loader();
572 ExpectCreateResourceLoader();
573 ReadAt(kFarReadPosition);
574 Respond(response_generator_->Generate206(kFarReadPosition));
575
576 // Verify loader changed but still has same playback rate.
577 EXPECT_NE(old_loader, loader());
578
579 EXPECT_TRUE(data_source_->loading());
580 EXPECT_CALL(*this, ReadCallback(media::DataSource::kReadError));
581 Stop();
582 }
583
TEST_F(BufferedDataSourceTest,Http_Read)584 TEST_F(BufferedDataSourceTest, Http_Read) {
585 InitializeWith206Response();
586
587 ReadAt(0);
588
589 // Receive first half of the read.
590 EXPECT_CALL(host_, AddBufferedByteRange(0, (kDataSize / 2) - 1));
591 ReceiveData(kDataSize / 2);
592
593 // Receive last half of the read.
594 EXPECT_CALL(*this, ReadCallback(kDataSize));
595 EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize - 1));
596 ReceiveData(kDataSize / 2);
597
598 EXPECT_TRUE(data_source_->downloading());
599 Stop();
600 }
601
TEST_F(BufferedDataSourceTest,Http_Read_Seek)602 TEST_F(BufferedDataSourceTest, Http_Read_Seek) {
603 InitializeWith206Response();
604
605 // Read a bit from the beginning.
606 ReadAt(0);
607 EXPECT_CALL(*this, ReadCallback(kDataSize));
608 EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize - 1));
609 ReceiveData(kDataSize);
610
611 // Simulate a seek by reading a bit beyond kDataSize.
612 ReadAt(kDataSize * 2);
613
614 // We receive data leading up to but not including our read.
615 EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize * 2 - 1));
616 ReceiveData(kDataSize);
617
618 // We now receive the rest of the data for our read.
619 EXPECT_CALL(*this, ReadCallback(kDataSize));
620 EXPECT_CALL(host_, AddBufferedByteRange(0, kDataSize * 3 - 1));
621 ReceiveData(kDataSize);
622
623 EXPECT_TRUE(data_source_->downloading());
624 Stop();
625 }
626
TEST_F(BufferedDataSourceTest,File_Read)627 TEST_F(BufferedDataSourceTest, File_Read) {
628 InitializeWithFileResponse();
629
630 ReadAt(0);
631
632 // Receive first half of the read but no buffering update.
633 ReceiveData(kDataSize / 2);
634
635 // Receive last half of the read but no buffering update.
636 EXPECT_CALL(*this, ReadCallback(kDataSize));
637 ReceiveData(kDataSize / 2);
638
639 Stop();
640 }
641
TEST_F(BufferedDataSourceTest,Http_FinishLoading)642 TEST_F(BufferedDataSourceTest, Http_FinishLoading) {
643 InitializeWith206Response();
644
645 EXPECT_TRUE(data_source_->downloading());
646 FinishLoading();
647 EXPECT_FALSE(data_source_->downloading());
648
649 Stop();
650 }
651
TEST_F(BufferedDataSourceTest,File_FinishLoading)652 TEST_F(BufferedDataSourceTest, File_FinishLoading) {
653 InitializeWithFileResponse();
654
655 EXPECT_FALSE(data_source_->downloading());
656 FinishLoading();
657 EXPECT_FALSE(data_source_->downloading());
658
659 Stop();
660 }
661
TEST_F(BufferedDataSourceTest,LocalResource_DeferStrategy)662 TEST_F(BufferedDataSourceTest, LocalResource_DeferStrategy) {
663 InitializeWithFileResponse();
664
665 EXPECT_EQ(BufferedDataSource::AUTO, preload());
666 EXPECT_TRUE(is_local_source());
667 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
668
669 data_source_->MediaIsPlaying();
670 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
671
672 data_source_->MediaIsPaused();
673 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
674
675 Stop();
676 }
677
TEST_F(BufferedDataSourceTest,LocalResource_PreloadMetadata_DeferStrategy)678 TEST_F(BufferedDataSourceTest, LocalResource_PreloadMetadata_DeferStrategy) {
679 set_preload(BufferedDataSource::METADATA);
680 InitializeWithFileResponse();
681
682 EXPECT_EQ(BufferedDataSource::METADATA, preload());
683 EXPECT_TRUE(is_local_source());
684 EXPECT_EQ(BufferedResourceLoader::kReadThenDefer, defer_strategy());
685
686 data_source_->MediaIsPlaying();
687 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
688
689 data_source_->MediaIsPaused();
690 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
691
692 Stop();
693 }
694
TEST_F(BufferedDataSourceTest,ExternalResource_Reponse200_DeferStrategy)695 TEST_F(BufferedDataSourceTest, ExternalResource_Reponse200_DeferStrategy) {
696 InitializeWith200Response();
697
698 EXPECT_EQ(BufferedDataSource::AUTO, preload());
699 EXPECT_FALSE(is_local_source());
700 EXPECT_FALSE(loader()->range_supported());
701 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
702
703 data_source_->MediaIsPlaying();
704 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
705
706 data_source_->MediaIsPaused();
707 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
708
709 Stop();
710 }
711
TEST_F(BufferedDataSourceTest,ExternalResource_Response200_PreloadMetadata_DeferStrategy)712 TEST_F(BufferedDataSourceTest,
713 ExternalResource_Response200_PreloadMetadata_DeferStrategy) {
714 set_preload(BufferedDataSource::METADATA);
715 InitializeWith200Response();
716
717 EXPECT_EQ(BufferedDataSource::METADATA, preload());
718 EXPECT_FALSE(is_local_source());
719 EXPECT_FALSE(loader()->range_supported());
720 EXPECT_EQ(BufferedResourceLoader::kReadThenDefer, defer_strategy());
721
722 data_source_->MediaIsPlaying();
723 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
724
725 data_source_->MediaIsPaused();
726 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
727
728 Stop();
729 }
730
TEST_F(BufferedDataSourceTest,ExternalResource_Reponse206_DeferStrategy)731 TEST_F(BufferedDataSourceTest, ExternalResource_Reponse206_DeferStrategy) {
732 InitializeWith206Response();
733
734 EXPECT_EQ(BufferedDataSource::AUTO, preload());
735 EXPECT_FALSE(is_local_source());
736 EXPECT_TRUE(loader()->range_supported());
737 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
738
739 data_source_->MediaIsPlaying();
740 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
741 set_might_be_reused_from_cache_in_future(true);
742 data_source_->MediaIsPaused();
743 EXPECT_EQ(BufferedResourceLoader::kNeverDefer, defer_strategy());
744
745 data_source_->MediaIsPlaying();
746 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
747 set_might_be_reused_from_cache_in_future(false);
748 data_source_->MediaIsPaused();
749 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
750
751 Stop();
752 }
753
TEST_F(BufferedDataSourceTest,ExternalResource_Response206_PreloadMetadata_DeferStrategy)754 TEST_F(BufferedDataSourceTest,
755 ExternalResource_Response206_PreloadMetadata_DeferStrategy) {
756 set_preload(BufferedDataSource::METADATA);
757 InitializeWith206Response();
758
759 EXPECT_EQ(BufferedDataSource::METADATA, preload());
760 EXPECT_FALSE(is_local_source());
761 EXPECT_TRUE(loader()->range_supported());
762 EXPECT_EQ(BufferedResourceLoader::kReadThenDefer, defer_strategy());
763
764 data_source_->MediaIsPlaying();
765 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
766 set_might_be_reused_from_cache_in_future(true);
767 data_source_->MediaIsPaused();
768 EXPECT_EQ(BufferedResourceLoader::kNeverDefer, defer_strategy());
769
770 data_source_->MediaIsPlaying();
771 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
772 set_might_be_reused_from_cache_in_future(false);
773 data_source_->MediaIsPaused();
774 EXPECT_EQ(BufferedResourceLoader::kCapacityDefer, defer_strategy());
775
776 Stop();
777 }
778
779 } // namespace media
780