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.
9 #include "base/format_macros.h"
10 #include "base/message_loop/message_loop.h"
11 #include "base/strings/stringprintf.h"
12 #include "media/base/media_log.h"
13 #include "media/base/seekable_buffer.h"
14 #include "media/blink/buffered_resource_loader.h"
15 #include "media/blink/mock_webframeclient.h"
16 #include "media/blink/mock_weburlloader.h"
17 #include "net/base/net_errors.h"
18 #include "net/http/http_request_headers.h"
19 #include "net/http/http_util.h"
20 #include "third_party/WebKit/public/platform/WebString.h"
21 #include "third_party/WebKit/public/platform/WebURLError.h"
22 #include "third_party/WebKit/public/platform/WebURLRequest.h"
23 #include "third_party/WebKit/public/platform/WebURLResponse.h"
24 #include "third_party/WebKit/public/web/WebLocalFrame.h"
25 #include "third_party/WebKit/public/web/WebView.h"
28 using ::testing::InSequence
;
29 using ::testing::Return
;
30 using ::testing::Truly
;
31 using ::testing::NiceMock
;
33 using blink::WebLocalFrame
;
34 using blink::WebString
;
35 using blink::WebURLError
;
36 using blink::WebURLResponse
;
41 static const char* kHttpUrl
= "http://test";
42 static const char kHttpRedirectToSameDomainUrl1
[] = "http://test/ing";
43 static const char kHttpRedirectToSameDomainUrl2
[] = "http://test/ing2";
44 static const char kHttpRedirectToDifferentDomainUrl1
[] = "http://test2";
46 static const int kDataSize
= 1024;
47 static const int kHttpOK
= 200;
48 static const int kHttpPartialContent
= 206;
56 // Predicate that tests that request disallows compressed data.
57 static bool CorrectAcceptEncoding(const blink::WebURLRequest
&request
) {
58 std::string value
= request
.httpHeaderField(
59 WebString::fromUTF8(net::HttpRequestHeaders::kAcceptEncoding
)).utf8();
60 return (value
.find("identity;q=1") != std::string::npos
) &&
61 (value
.find("*;q=0") != std::string::npos
);
64 class BufferedResourceLoaderTest
: public testing::Test
{
66 BufferedResourceLoaderTest()
67 : view_(WebView::create(NULL
)), frame_(WebLocalFrame::create(&client_
)) {
68 view_
->setMainFrame(frame_
);
70 for (int i
= 0; i
< kDataSize
; ++i
) {
75 virtual ~BufferedResourceLoaderTest() {
80 void Initialize(const char* url
, int first_position
, int last_position
) {
82 first_position_
= first_position
;
83 last_position_
= last_position
;
85 loader_
.reset(new BufferedResourceLoader(
86 gurl_
, BufferedResourceLoader::kUnspecified
,
87 first_position_
, last_position_
,
88 BufferedResourceLoader::kCapacityDefer
, 0, 0,
91 // |test_loader_| will be used when Start() is called.
92 url_loader_
= new NiceMock
<MockWebURLLoader
>();
93 loader_
->test_loader_
= scoped_ptr
<blink::WebURLLoader
>(url_loader_
);
96 void SetLoaderBuffer(int forward_capacity
, int backward_capacity
) {
97 loader_
->buffer_
.set_forward_capacity(forward_capacity
);
98 loader_
->buffer_
.set_backward_capacity(backward_capacity
);
99 loader_
->buffer_
.Clear();
104 EXPECT_CALL(*url_loader_
, loadAsynchronously(Truly(CorrectAcceptEncoding
),
107 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoading
));
109 base::Bind(&BufferedResourceLoaderTest::StartCallback
,
110 base::Unretained(this)),
111 base::Bind(&BufferedResourceLoaderTest::LoadingCallback
,
112 base::Unretained(this)),
113 base::Bind(&BufferedResourceLoaderTest::ProgressCallback
,
114 base::Unretained(this)),
118 void FullResponse(int64 instance_size
) {
119 FullResponse(instance_size
, BufferedResourceLoader::kOk
);
122 void FullResponse(int64 instance_size
,
123 BufferedResourceLoader::Status status
) {
124 EXPECT_CALL(*this, StartCallback(status
));
126 WebURLResponse
response(gurl_
);
127 response
.setHTTPHeaderField(WebString::fromUTF8("Content-Length"),
128 WebString::fromUTF8(base::StringPrintf("%"
129 PRId64
, instance_size
)));
130 response
.setExpectedContentLength(instance_size
);
131 response
.setHTTPStatusCode(kHttpOK
);
132 loader_
->didReceiveResponse(url_loader_
, response
);
134 if (status
== BufferedResourceLoader::kOk
) {
135 EXPECT_EQ(instance_size
, loader_
->content_length());
136 EXPECT_EQ(instance_size
, loader_
->instance_size());
139 EXPECT_FALSE(loader_
->range_supported());
142 void PartialResponse(int64 first_position
, int64 last_position
,
143 int64 instance_size
) {
144 PartialResponse(first_position
, last_position
, instance_size
, false, true);
147 void PartialResponse(int64 first_position
, int64 last_position
,
148 int64 instance_size
, bool chunked
, bool accept_ranges
) {
149 EXPECT_CALL(*this, StartCallback(BufferedResourceLoader::kOk
));
151 WebURLResponse
response(gurl_
);
152 response
.setHTTPHeaderField(WebString::fromUTF8("Content-Range"),
153 WebString::fromUTF8(base::StringPrintf("bytes "
154 "%" PRId64
"-%" PRId64
"/%" PRId64
,
159 // HTTP 1.1 doesn't permit Content-Length with Transfer-Encoding: chunked.
160 int64 content_length
= -1;
162 response
.setHTTPHeaderField(WebString::fromUTF8("Transfer-Encoding"),
163 WebString::fromUTF8("chunked"));
165 content_length
= last_position
- first_position
+ 1;
167 response
.setExpectedContentLength(content_length
);
169 // A server isn't required to return Accept-Ranges even though it might.
171 response
.setHTTPHeaderField(WebString::fromUTF8("Accept-Ranges"),
172 WebString::fromUTF8("bytes"));
175 response
.setHTTPStatusCode(kHttpPartialContent
);
176 loader_
->didReceiveResponse(url_loader_
, response
);
178 // XXX: what's the difference between these two? For example in the chunked
179 // range request case, Content-Length is unspecified (because it's chunked)
180 // but Content-Range: a-b/c can be returned, where c == Content-Length
182 // Can we eliminate one?
183 EXPECT_EQ(content_length
, loader_
->content_length());
184 EXPECT_EQ(instance_size
, loader_
->instance_size());
186 // A valid partial response should always result in this being true.
187 EXPECT_TRUE(loader_
->range_supported());
190 void Redirect(const char* url
) {
191 GURL
redirectUrl(url
);
192 blink::WebURLRequest
newRequest(redirectUrl
);
193 blink::WebURLResponse
redirectResponse(gurl_
);
195 loader_
->willSendRequest(url_loader_
, newRequest
, redirectResponse
);
197 base::MessageLoop::current()->RunUntilIdle();
200 void StopWhenLoad() {
202 EXPECT_CALL(*url_loader_
, cancel());
207 // Helper method to write to |loader_| from |data_|.
208 void WriteLoader(int position
, int size
) {
209 EXPECT_CALL(*this, ProgressCallback(position
+ size
- 1));
210 loader_
->didReceiveData(url_loader_
,
211 reinterpret_cast<char*>(data_
+ position
),
216 void WriteData(int size
) {
217 EXPECT_CALL(*this, ProgressCallback(_
));
219 scoped_ptr
<char[]> data(new char[size
]);
220 loader_
->didReceiveData(url_loader_
, data
.get(), size
, size
);
223 void WriteUntilThreshold() {
224 int buffered
= loader_
->buffer_
.forward_bytes();
225 int capacity
= loader_
->buffer_
.forward_capacity();
226 CHECK_LT(buffered
, capacity
);
228 EXPECT_CALL(*this, LoadingCallback(
229 BufferedResourceLoader::kLoadingDeferred
));
230 WriteData(capacity
- buffered
);
233 // Helper method to read from |loader_|.
234 void ReadLoader(int64 position
, int size
, uint8
* buffer
) {
235 loader_
->Read(position
, size
, buffer
,
236 base::Bind(&BufferedResourceLoaderTest::ReadCallback
,
237 base::Unretained(this)));
240 // Verifies that data in buffer[0...size] is equal to data_[pos...pos+size].
241 void VerifyBuffer(uint8
* buffer
, int pos
, int size
) {
242 EXPECT_EQ(0, memcmp(buffer
, data_
+ pos
, size
));
245 void ConfirmLoaderOffsets(int64 expected_offset
,
246 int expected_first_offset
,
247 int expected_last_offset
) {
248 EXPECT_EQ(loader_
->offset_
, expected_offset
);
249 EXPECT_EQ(loader_
->first_offset_
, expected_first_offset
);
250 EXPECT_EQ(loader_
->last_offset_
, expected_last_offset
);
253 void ConfirmBufferState(int backward_bytes
,
254 int backward_capacity
,
256 int forward_capacity
) {
257 EXPECT_EQ(backward_bytes
, loader_
->buffer_
.backward_bytes());
258 EXPECT_EQ(backward_capacity
, loader_
->buffer_
.backward_capacity());
259 EXPECT_EQ(forward_bytes
, loader_
->buffer_
.forward_bytes());
260 EXPECT_EQ(forward_capacity
, loader_
->buffer_
.forward_capacity());
263 void ConfirmLoaderBufferBackwardCapacity(int expected_backward_capacity
) {
264 EXPECT_EQ(loader_
->buffer_
.backward_capacity(),
265 expected_backward_capacity
);
268 void ConfirmLoaderBufferForwardCapacity(int expected_forward_capacity
) {
269 EXPECT_EQ(loader_
->buffer_
.forward_capacity(), expected_forward_capacity
);
272 // Makes sure the |loader_| buffer window is in a reasonable range.
273 void CheckBufferWindowBounds() {
274 // Corresponds to value defined in buffered_resource_loader.cc.
275 static const int kMinBufferCapacity
= 2 * 1024 * 1024;
276 EXPECT_GE(loader_
->buffer_
.forward_capacity(), kMinBufferCapacity
);
277 EXPECT_GE(loader_
->buffer_
.backward_capacity(), kMinBufferCapacity
);
279 // Corresponds to value defined in buffered_resource_loader.cc.
280 static const int kMaxBufferCapacity
= 20 * 1024 * 1024;
281 EXPECT_LE(loader_
->buffer_
.forward_capacity(), kMaxBufferCapacity
);
282 EXPECT_LE(loader_
->buffer_
.backward_capacity(), kMaxBufferCapacity
);
285 bool HasActiveLoader() { return loader_
->active_loader_
; }
287 MOCK_METHOD1(StartCallback
, void(BufferedResourceLoader::Status
));
288 MOCK_METHOD2(ReadCallback
, void(BufferedResourceLoader::Status
, int));
289 MOCK_METHOD1(LoadingCallback
, void(BufferedResourceLoader::LoadingState
));
290 MOCK_METHOD1(ProgressCallback
, void(int64
));
294 int64 first_position_
;
295 int64 last_position_
;
297 scoped_ptr
<BufferedResourceLoader
> loader_
;
298 NiceMock
<MockWebURLLoader
>* url_loader_
;
300 MockWebFrameClient client_
;
302 WebLocalFrame
* frame_
;
304 base::MessageLoop message_loop_
;
306 uint8 data_
[kDataSize
];
309 DISALLOW_COPY_AND_ASSIGN(BufferedResourceLoaderTest
);
312 TEST_F(BufferedResourceLoaderTest
, StartStop
) {
313 Initialize(kHttpUrl
, -1, -1);
318 // Tests that a bad HTTP response is recived, e.g. file not found.
319 TEST_F(BufferedResourceLoaderTest
, BadHttpResponse
) {
320 Initialize(kHttpUrl
, -1, -1);
323 EXPECT_CALL(*this, StartCallback(BufferedResourceLoader::kFailed
));
325 WebURLResponse
response(gurl_
);
326 response
.setHTTPStatusCode(404);
327 response
.setHTTPStatusText("Not Found\n");
328 loader_
->didReceiveResponse(url_loader_
, response
);
332 // Tests that partial content is requested but not fulfilled.
333 TEST_F(BufferedResourceLoaderTest
, NotPartialResponse
) {
334 Initialize(kHttpUrl
, 100, -1);
336 FullResponse(1024, BufferedResourceLoader::kFailed
);
340 // Tests that a 200 response is received.
341 TEST_F(BufferedResourceLoaderTest
, FullResponse
) {
342 Initialize(kHttpUrl
, -1, -1);
348 // Tests that a partial content response is received.
349 TEST_F(BufferedResourceLoaderTest
, PartialResponse
) {
350 Initialize(kHttpUrl
, 100, 200);
352 PartialResponse(100, 200, 1024);
356 TEST_F(BufferedResourceLoaderTest
, PartialResponse_Chunked
) {
357 Initialize(kHttpUrl
, 100, 200);
359 PartialResponse(100, 200, 1024, true, true);
363 TEST_F(BufferedResourceLoaderTest
, PartialResponse_NoAcceptRanges
) {
364 Initialize(kHttpUrl
, 100, 200);
366 PartialResponse(100, 200, 1024, false, false);
370 TEST_F(BufferedResourceLoaderTest
, PartialResponse_ChunkedNoAcceptRanges
) {
371 Initialize(kHttpUrl
, 100, 200);
373 PartialResponse(100, 200, 1024, true, false);
377 // Tests that an invalid partial response is received.
378 TEST_F(BufferedResourceLoaderTest
, InvalidPartialResponse
) {
379 Initialize(kHttpUrl
, 0, 10);
382 EXPECT_CALL(*this, StartCallback(BufferedResourceLoader::kFailed
));
384 WebURLResponse
response(gurl_
);
385 response
.setHTTPHeaderField(WebString::fromUTF8("Content-Range"),
386 WebString::fromUTF8(base::StringPrintf("bytes "
387 "%d-%d/%d", 1, 10, 1024)));
388 response
.setExpectedContentLength(10);
389 response
.setHTTPStatusCode(kHttpPartialContent
);
390 loader_
->didReceiveResponse(url_loader_
, response
);
394 // Tests the logic of sliding window for data buffering and reading.
395 TEST_F(BufferedResourceLoaderTest
, BufferAndRead
) {
396 Initialize(kHttpUrl
, 10, 29);
397 loader_
->UpdateDeferStrategy(BufferedResourceLoader::kCapacityDefer
);
399 PartialResponse(10, 29, 30);
404 // Writes 10 bytes and read them back.
406 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 10));
407 ReadLoader(10, 10, buffer
);
408 VerifyBuffer(buffer
, 10, 10);
410 // Writes 10 bytes and read 2 times.
412 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 5));
413 ReadLoader(20, 5, buffer
);
414 VerifyBuffer(buffer
, 20, 5);
415 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 5));
416 ReadLoader(25, 5, buffer
);
417 VerifyBuffer(buffer
, 25, 5);
419 // Read backward within buffer.
420 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 10));
421 ReadLoader(10, 10, buffer
);
422 VerifyBuffer(buffer
, 10, 10);
424 // Read backward outside buffer.
425 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kCacheMiss
, 0));
426 ReadLoader(9, 10, buffer
);
428 // Response has completed.
429 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoadingFinished
));
430 loader_
->didFinishLoading(url_loader_
, 0, -1);
432 // Try to read 10 from position 25 will just return with 5 bytes.
433 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 5));
434 ReadLoader(25, 10, buffer
);
435 VerifyBuffer(buffer
, 25, 5);
437 // Try to read outside buffered range after request has completed.
438 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kCacheMiss
, 0));
439 ReadLoader(5, 10, buffer
);
441 // Try to read beyond the instance size.
442 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 0));
443 ReadLoader(30, 10, buffer
);
446 // Tests the logic of expanding the data buffer for large reads.
447 TEST_F(BufferedResourceLoaderTest
, ReadExtendBuffer
) {
448 Initialize(kHttpUrl
, 10, 0x014FFFFFF);
449 SetLoaderBuffer(10, 20);
451 PartialResponse(10, 0x014FFFFFF, 0x015000000);
456 // Write more than forward capacity and read it back. Ensure forward capacity
457 // gets reset after reading.
458 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoadingDeferred
));
461 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 20));
462 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoading
));
463 ReadLoader(10, 20, buffer
);
465 VerifyBuffer(buffer
, 10, 20);
466 ConfirmLoaderBufferForwardCapacity(10);
468 // Make and outstanding read request larger than forward capacity. Ensure
469 // forward capacity gets extended.
470 ReadLoader(30, 20, buffer
);
471 ConfirmLoaderBufferForwardCapacity(20);
473 // Fulfill outstanding request. Ensure forward capacity gets reset.
474 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 20));
477 VerifyBuffer(buffer
, 30, 20);
478 ConfirmLoaderBufferForwardCapacity(10);
480 // Try to read further ahead than kForwardWaitThreshold allows. Ensure
481 // forward capacity is not changed.
482 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kCacheMiss
, 0));
483 ReadLoader(0x00300000, 1, buffer
);
485 ConfirmLoaderBufferForwardCapacity(10);
487 // Try to read more than maximum forward capacity. Ensure forward capacity is
489 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kFailed
, 0));
490 ReadLoader(30, 0x01400001, buffer
);
492 ConfirmLoaderBufferForwardCapacity(10);
497 TEST_F(BufferedResourceLoaderTest
, ReadOutsideBuffer
) {
498 Initialize(kHttpUrl
, 10, 0x00FFFFFF);
500 PartialResponse(10, 0x00FFFFFF, 0x01000000);
505 // Read very far ahead will get a cache miss.
506 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kCacheMiss
, 0));
507 ReadLoader(0x00FFFFFF, 1, buffer
);
509 // The following call will not call ReadCallback() because it is waiting for
511 ReadLoader(10, 10, buffer
);
513 // Writing to loader will fulfill the read request.
514 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 10));
516 VerifyBuffer(buffer
, 10, 10);
518 // The following call cannot be fulfilled now.
519 ReadLoader(25, 10, buffer
);
521 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoadingFinished
));
522 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 5));
523 loader_
->didFinishLoading(url_loader_
, 0, -1);
526 TEST_F(BufferedResourceLoaderTest
, RequestFailedWhenRead
) {
527 Initialize(kHttpUrl
, 10, 29);
529 PartialResponse(10, 29, 30);
534 // We should convert any error we receive to BufferedResourceLoader::kFailed.
535 ReadLoader(10, 10, buffer
);
536 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoadingFailed
));
537 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kFailed
, 0));
539 error
.reason
= net::ERR_TIMED_OUT
;
540 error
.isCancellation
= false;
541 loader_
->didFail(url_loader_
, error
);
544 TEST_F(BufferedResourceLoaderTest
, RequestFailedWithNoPendingReads
) {
545 Initialize(kHttpUrl
, 10, 29);
547 PartialResponse(10, 29, 30);
552 // Write enough data so that a read would technically complete had the request
556 // Fail without a pending read.
558 error
.reason
= net::ERR_TIMED_OUT
;
559 error
.isCancellation
= false;
560 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoadingFailed
));
561 loader_
->didFail(url_loader_
, error
);
563 // Now we should immediately fail any read even if we have data buffered.
564 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kFailed
, 0));
565 ReadLoader(10, 10, buffer
);
568 TEST_F(BufferedResourceLoaderTest
, RequestCancelledWhenRead
) {
569 Initialize(kHttpUrl
, 10, 29);
571 PartialResponse(10, 29, 30);
576 // We should convert any error we receive to BufferedResourceLoader::kFailed.
577 ReadLoader(10, 10, buffer
);
578 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoadingFailed
));
579 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kFailed
, 0));
582 error
.isCancellation
= true;
583 loader_
->didFail(url_loader_
, error
);
586 // Tests the data buffering logic of NeverDefer strategy.
587 TEST_F(BufferedResourceLoaderTest
, NeverDeferStrategy
) {
588 Initialize(kHttpUrl
, 10, 99);
589 SetLoaderBuffer(10, 20);
590 loader_
->UpdateDeferStrategy(BufferedResourceLoader::kNeverDefer
);
592 PartialResponse(10, 99, 100);
596 // Read past the buffer size; should not defer regardless.
600 // Should move past window.
601 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kCacheMiss
, 0));
602 ReadLoader(10, 10, buffer
);
607 // Tests the data buffering logic of ReadThenDefer strategy.
608 TEST_F(BufferedResourceLoaderTest
, ReadThenDeferStrategy
) {
609 Initialize(kHttpUrl
, 10, 99);
610 SetLoaderBuffer(10, 20);
611 loader_
->UpdateDeferStrategy(BufferedResourceLoader::kReadThenDefer
);
613 PartialResponse(10, 99, 100);
617 // Make an outstanding read request.
618 ReadLoader(10, 10, buffer
);
620 // Receive almost enough data to cover, shouldn't defer.
623 // As soon as we have received enough data to fulfill the read, defer.
624 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoadingDeferred
));
625 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 10));
628 VerifyBuffer(buffer
, 10, 10);
630 // Read again which should disable deferring since there should be nothing
631 // left in our internal buffer.
632 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoading
));
633 ReadLoader(20, 10, buffer
);
635 // Over-fulfill requested bytes, then deferring should be enabled again.
636 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoadingDeferred
));
637 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 10));
640 VerifyBuffer(buffer
, 20, 10);
642 // Read far ahead, which should disable deferring. In this case we still have
643 // bytes in our internal buffer.
644 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoading
));
645 ReadLoader(80, 10, buffer
);
647 // Fulfill requested bytes, then deferring should be enabled again.
648 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoadingDeferred
));
649 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 10));
652 VerifyBuffer(buffer
, 80, 10);
657 // Tests the data buffering logic of kCapacityDefer strategy.
658 TEST_F(BufferedResourceLoaderTest
, ThresholdDeferStrategy
) {
659 Initialize(kHttpUrl
, 10, 99);
660 SetLoaderBuffer(10, 20);
662 PartialResponse(10, 99, 100);
667 // Write half of capacity: keep not deferring.
670 // Write rest of space until capacity: start deferring.
671 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoadingDeferred
));
674 // Read a byte from the buffer: stop deferring.
675 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 1));
676 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoading
));
677 ReadLoader(10, 1, buffer
);
679 // Write a byte to hit capacity: start deferring.
680 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoadingDeferred
));
686 TEST_F(BufferedResourceLoaderTest
, Tricky_ReadForwardsPastBuffered
) {
687 Initialize(kHttpUrl
, 10, 99);
688 SetLoaderBuffer(10, 10);
690 PartialResponse(10, 99, 100);
696 WriteUntilThreshold();
697 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 1));
698 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoading
));
699 ReadLoader(10, 1, buffer
);
700 ConfirmBufferState(1, 10, 9, 10);
701 ConfirmLoaderOffsets(11, 0, 0);
703 // *** TRICKY BUSINESS, PT. I ***
704 // Read past buffered: stop deferring.
706 // In order for the read to complete we must:
707 // 1) Stop deferring to receive more data.
710 // offset=11 [xxxxxxxxx_]
711 // ^ ^^^ requested 4 bytes @ offset 20
713 // offset=24 [__________]
715 ReadLoader(20, 4, buffer
);
717 // Write a little, make sure we didn't start deferring.
720 // Write the rest, read should complete.
721 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 4));
725 ConfirmBufferState(4, 10, 0, 10);
726 ConfirmLoaderOffsets(24, 0, 0);
731 TEST_F(BufferedResourceLoaderTest
, Tricky_ReadBackwardsPastBuffered
) {
732 Initialize(kHttpUrl
, 10, 99);
733 SetLoaderBuffer(10, 10);
735 PartialResponse(10, 99, 100);
741 WriteUntilThreshold();
742 ConfirmBufferState(0, 10, 10, 10);
743 ConfirmLoaderOffsets(10, 0, 0);
745 // *** TRICKY BUSINESS, PT. II ***
746 // Read backwards a little too much: cache miss.
749 // offset=10 [__________|xxxxxxxxxx]
750 // ^ ^^^ requested 10 bytes @ offset 9
752 // offset=10 [__________|xxxxxxxxxx] !!! cache miss !!!
754 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kCacheMiss
, 0));
755 ReadLoader(9, 4, buffer
);
758 ConfirmBufferState(0, 10, 10, 10);
759 ConfirmLoaderOffsets(10, 0, 0);
764 TEST_F(BufferedResourceLoaderTest
, Tricky_SmallReadWithinThreshold
) {
765 Initialize(kHttpUrl
, 10, 99);
766 SetLoaderBuffer(10, 10);
768 PartialResponse(10, 99, 100);
774 WriteUntilThreshold();
775 ConfirmBufferState(0, 10, 10, 10);
776 ConfirmLoaderOffsets(10, 0, 0);
778 // *** TRICKY BUSINESS, PT. III ***
779 // Read past forward capacity but within capacity: stop deferring.
781 // In order for the read to complete we must:
782 // 1) Adjust offset forward to create capacity.
783 // 2) Stop deferring to receive more data.
786 // offset=10 [xxxxxxxxxx]
787 // ^^^^ requested 4 bytes @ offset 24
789 // offset=20 [__________]
790 // ^^^^ requested 4 bytes @ offset 24
792 // offset=28 [__________]
794 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoading
));
795 ReadLoader(24, 4, buffer
);
796 ConfirmLoaderOffsets(20, 4, 8);
798 // Write a little, make sure we didn't start deferring.
801 // Write the rest, read should complete.
802 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 4));
806 ConfirmBufferState(8, 10, 0, 10);
807 ConfirmLoaderOffsets(28, 0, 0);
812 TEST_F(BufferedResourceLoaderTest
, Tricky_LargeReadWithinThreshold
) {
813 Initialize(kHttpUrl
, 10, 99);
814 SetLoaderBuffer(10, 10);
816 PartialResponse(10, 99, 100);
822 WriteUntilThreshold();
823 ConfirmBufferState(0, 10, 10, 10);
824 ConfirmLoaderOffsets(10, 0, 0);
826 // *** TRICKY BUSINESS, PT. IV ***
827 // Read a large amount past forward capacity but within
828 // capacity: stop deferring.
830 // In order for the read to complete we must:
831 // 1) Adjust offset forward to create capacity.
832 // 2) Expand capacity to make sure we don't defer as data arrives.
833 // 3) Stop deferring to receive more data.
836 // offset=10 [xxxxxxxxxx]
837 // ^^^^^^^^^^^^ requested 12 bytes @ offset 24
839 // offset=20 [__________]
840 // ^^^^^^ ^^^^^^ requested 12 bytes @ offset 24
842 // offset=20 [________________]
843 // ^^^^^^^^^^^^ requested 12 bytes @ offset 24
845 // offset=36 [__________]
847 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoading
));
848 ReadLoader(24, 12, buffer
);
849 ConfirmLoaderOffsets(20, 4, 16);
850 ConfirmBufferState(10, 10, 0, 16);
852 // Write a little, make sure we didn't start deferring.
855 // Write the rest, read should complete and capacity should go back to normal.
856 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 12));
858 ConfirmLoaderBufferForwardCapacity(10);
861 ConfirmBufferState(6, 10, 0, 10);
862 ConfirmLoaderOffsets(36, 0, 0);
867 TEST_F(BufferedResourceLoaderTest
, Tricky_LargeReadBackwards
) {
868 Initialize(kHttpUrl
, 10, 99);
869 SetLoaderBuffer(10, 10);
871 PartialResponse(10, 99, 100);
877 WriteUntilThreshold();
878 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 10));
879 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoading
));
880 ReadLoader(10, 10, buffer
);
881 WriteUntilThreshold();
882 ConfirmBufferState(10, 10, 10, 10);
883 ConfirmLoaderOffsets(20, 0, 0);
885 // *** TRICKY BUSINESS, PT. V ***
886 // Read a large amount that involves backwards data: stop deferring.
888 // In order for the read to complete we must:
889 // 1) Adjust offset *backwards* to create capacity.
890 // 2) Expand capacity to make sure we don't defer as data arrives.
891 // 3) Stop deferring to receive more data.
894 // offset=20 [xxxxxxxxxx|xxxxxxxxxx]
895 // ^^^^ ^^^^^^^^^^ ^^^^ requested 18 bytes @ offset 16
897 // offset=16 [____xxxxxx|xxxxxxxxxx]xxxx
898 // ^^^^^^^^^^ ^^^^^^^^ requested 18 bytes @ offset 16
900 // offset=16 [____xxxxxx|xxxxxxxxxxxxxx____]
901 // ^^^^^^^^^^^^^^^^^^ requested 18 bytes @ offset 16
903 // offset=34 [xxxxxxxxxx|__________]
905 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoading
));
906 ReadLoader(16, 18, buffer
);
907 ConfirmLoaderOffsets(16, 0, 18);
908 ConfirmBufferState(6, 10, 14, 18);
910 // Write a little, make sure we didn't start deferring.
913 // Write the rest, read should complete and capacity should go back to normal.
914 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 18));
916 ConfirmLoaderBufferForwardCapacity(10);
919 ConfirmBufferState(4, 10, 0, 10);
920 ConfirmLoaderOffsets(34, 0, 0);
925 TEST_F(BufferedResourceLoaderTest
, Tricky_ReadPastThreshold
) {
926 const int kSize
= 5 * 1024 * 1024;
927 const int kThreshold
= 2 * 1024 * 1024;
929 Initialize(kHttpUrl
, 10, kSize
);
930 SetLoaderBuffer(10, 10);
932 PartialResponse(10, kSize
- 1, kSize
);
938 WriteUntilThreshold();
939 ConfirmBufferState(0, 10, 10, 10);
940 ConfirmLoaderOffsets(10, 0, 0);
942 // *** TRICKY BUSINESS, PT. VI ***
943 // Read past the forward wait threshold: cache miss.
946 // offset=10 [xxxxxxxxxx] ...
947 // ^^^^ requested 10 bytes @ threshold
949 // offset=10 [xxxxxxxxxx] !!! cache miss !!!
951 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kCacheMiss
, 0));
952 ReadLoader(kThreshold
+ 20, 10, buffer
);
955 ConfirmBufferState(0, 10, 10, 10);
956 ConfirmLoaderOffsets(10, 0, 0);
961 TEST_F(BufferedResourceLoaderTest
, HasSingleOrigin
) {
962 // Make sure no redirect case works as expected.
963 Initialize(kHttpUrl
, -1, -1);
966 EXPECT_TRUE(loader_
->HasSingleOrigin());
969 // Test redirect to the same domain.
970 Initialize(kHttpUrl
, -1, -1);
972 Redirect(kHttpRedirectToSameDomainUrl1
);
974 EXPECT_TRUE(loader_
->HasSingleOrigin());
977 // Test redirect twice to the same domain.
978 Initialize(kHttpUrl
, -1, -1);
980 Redirect(kHttpRedirectToSameDomainUrl1
);
981 Redirect(kHttpRedirectToSameDomainUrl2
);
983 EXPECT_TRUE(loader_
->HasSingleOrigin());
986 // Test redirect to a different domain.
987 Initialize(kHttpUrl
, -1, -1);
989 Redirect(kHttpRedirectToDifferentDomainUrl1
);
991 EXPECT_FALSE(loader_
->HasSingleOrigin());
994 // Test redirect to the same domain and then to a different domain.
995 Initialize(kHttpUrl
, -1, -1);
997 Redirect(kHttpRedirectToSameDomainUrl1
);
998 Redirect(kHttpRedirectToDifferentDomainUrl1
);
1000 EXPECT_FALSE(loader_
->HasSingleOrigin());
1004 TEST_F(BufferedResourceLoaderTest
, BufferWindow_Default
) {
1005 Initialize(kHttpUrl
, -1, -1);
1008 // Test ensures that default construction of a BufferedResourceLoader has sane
1011 // Please do not change these values in order to make a test pass! Instead,
1012 // start a conversation on what the default buffer window capacities should
1014 ConfirmLoaderBufferBackwardCapacity(2 * 1024 * 1024);
1015 ConfirmLoaderBufferForwardCapacity(2 * 1024 * 1024);
1020 TEST_F(BufferedResourceLoaderTest
, BufferWindow_Bitrate_Unknown
) {
1021 Initialize(kHttpUrl
, -1, -1);
1023 loader_
->SetBitrate(0);
1024 CheckBufferWindowBounds();
1028 TEST_F(BufferedResourceLoaderTest
, BufferWindow_Bitrate_BelowLowerBound
) {
1029 Initialize(kHttpUrl
, -1, -1);
1031 loader_
->SetBitrate(1024 * 8); // 1 Kbps.
1032 CheckBufferWindowBounds();
1036 TEST_F(BufferedResourceLoaderTest
, BufferWindow_Bitrate_WithinBounds
) {
1037 Initialize(kHttpUrl
, -1, -1);
1039 loader_
->SetBitrate(2 * 1024 * 1024 * 8); // 2 Mbps.
1040 CheckBufferWindowBounds();
1044 TEST_F(BufferedResourceLoaderTest
, BufferWindow_Bitrate_AboveUpperBound
) {
1045 Initialize(kHttpUrl
, -1, -1);
1047 loader_
->SetBitrate(100 * 1024 * 1024 * 8); // 100 Mbps.
1048 CheckBufferWindowBounds();
1052 TEST_F(BufferedResourceLoaderTest
, BufferWindow_PlaybackRate_Negative
) {
1053 Initialize(kHttpUrl
, -1, -1);
1055 loader_
->SetPlaybackRate(-10);
1056 CheckBufferWindowBounds();
1060 TEST_F(BufferedResourceLoaderTest
, BufferWindow_PlaybackRate_Zero
) {
1061 Initialize(kHttpUrl
, -1, -1);
1063 loader_
->SetPlaybackRate(0);
1064 CheckBufferWindowBounds();
1068 TEST_F(BufferedResourceLoaderTest
, BufferWindow_PlaybackRate_BelowLowerBound
) {
1069 Initialize(kHttpUrl
, -1, -1);
1071 loader_
->SetPlaybackRate(0.1f
);
1072 CheckBufferWindowBounds();
1076 TEST_F(BufferedResourceLoaderTest
, BufferWindow_PlaybackRate_WithinBounds
) {
1077 Initialize(kHttpUrl
, -1, -1);
1079 loader_
->SetPlaybackRate(10);
1080 CheckBufferWindowBounds();
1084 TEST_F(BufferedResourceLoaderTest
, BufferWindow_PlaybackRate_AboveUpperBound
) {
1085 Initialize(kHttpUrl
, -1, -1);
1087 loader_
->SetPlaybackRate(100);
1088 CheckBufferWindowBounds();
1092 static void ExpectContentRange(
1093 const std::string
& str
, bool expect_success
,
1094 int64 expected_first
, int64 expected_last
, int64 expected_size
) {
1095 int64 first
, last
, size
;
1096 ASSERT_EQ(expect_success
, BufferedResourceLoader::ParseContentRange(
1097 str
, &first
, &last
, &size
)) << str
;
1098 if (!expect_success
)
1100 EXPECT_EQ(first
, expected_first
);
1101 EXPECT_EQ(last
, expected_last
);
1102 EXPECT_EQ(size
, expected_size
);
1105 static void ExpectContentRangeFailure(const std::string
& str
) {
1106 ExpectContentRange(str
, false, 0, 0, 0);
1109 static void ExpectContentRangeSuccess(
1110 const std::string
& str
,
1111 int64 expected_first
, int64 expected_last
, int64 expected_size
) {
1112 ExpectContentRange(str
, true, expected_first
, expected_last
, expected_size
);
1115 TEST(BufferedResourceLoaderStandaloneTest
, ParseContentRange
) {
1116 ExpectContentRangeFailure("cytes 0-499/500");
1117 ExpectContentRangeFailure("bytes 0499/500");
1118 ExpectContentRangeFailure("bytes 0-499500");
1119 ExpectContentRangeFailure("bytes 0-499/500-blorg");
1120 ExpectContentRangeFailure("bytes 0-499/500-1");
1121 ExpectContentRangeFailure("bytes 0-499/400");
1122 ExpectContentRangeFailure("bytes 0-/400");
1123 ExpectContentRangeFailure("bytes -300/400");
1124 ExpectContentRangeFailure("bytes 20-10/400");
1126 ExpectContentRangeSuccess("bytes 0-499/500", 0, 499, 500);
1127 ExpectContentRangeSuccess("bytes 0-0/500", 0, 0, 500);
1128 ExpectContentRangeSuccess("bytes 10-11/50", 10, 11, 50);
1129 ExpectContentRangeSuccess("bytes 10-11/*", 10, 11,
1130 kPositionNotSpecified
);
1133 // Tests the data buffering logic of ReadThenDefer strategy.
1134 TEST_F(BufferedResourceLoaderTest
, CancelAfterDeferral
) {
1135 Initialize(kHttpUrl
, 10, 99);
1136 SetLoaderBuffer(10, 20);
1137 loader_
->UpdateDeferStrategy(BufferedResourceLoader::kReadThenDefer
);
1138 loader_
->CancelUponDeferral();
1140 PartialResponse(10, 99, 100);
1144 // Make an outstanding read request.
1145 ReadLoader(10, 10, buffer
);
1147 // Receive almost enough data to cover, shouldn't defer.
1149 EXPECT_TRUE(HasActiveLoader());
1151 // As soon as we have received enough data to fulfill the read, defer.
1152 EXPECT_CALL(*this, LoadingCallback(BufferedResourceLoader::kLoadingDeferred
));
1153 EXPECT_CALL(*this, ReadCallback(BufferedResourceLoader::kOk
, 10));
1155 VerifyBuffer(buffer
, 10, 10);
1156 EXPECT_FALSE(HasActiveLoader());
1159 } // namespace media