• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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