1 // Copyright (c) 2012 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/stringprintf.h"
11 #include "media/base/media_log.h"
12 #include "net/base/net_errors.h"
13 #include "net/http/http_request_headers.h"
14 #include "net/http/http_util.h"
15 #include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
16 #include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
17 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebString.h"
18 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLError.h"
19 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLRequest.h"
20 #include "third_party/WebKit/Source/WebKit/chromium/public/platform/WebURLResponse.h"
21 #include "webkit/media/buffered_resource_loader.h"
22 #include "webkit/mocks/mock_webframeclient.h"
23 #include "webkit/mocks/mock_weburlloader.h"
25 using ::testing::InSequence
;
26 using ::testing::Return
;
27 using ::testing::Truly
;
28 using ::testing::NiceMock
;
30 using WebKit::WebString
;
31 using WebKit::WebURLError
;
32 using WebKit::WebURLResponse
;
33 using WebKit::WebView
;
35 using webkit_glue::MockWebFrameClient
;
36 using webkit_glue::MockWebURLLoader
;
38 namespace webkit_media
{
40 static const char* kHttpUrl
= "http://test";
41 static const char kHttpRedirectToSameDomainUrl1
[] = "http://test/ing";
42 static const char kHttpRedirectToSameDomainUrl2
[] = "http://test/ing2";
43 static const char kHttpRedirectToDifferentDomainUrl1
[] = "http://test2";
44 static const char kHttpRedirectToDifferentDomainUrl2
[] = "http://test2/ing";
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 WebKit::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
)) {
68 view_
->initializeMainFrame(&client_
);
70 for (int i
= 0; i
< kDataSize
; ++i
) {
75 virtual ~BufferedResourceLoaderTest() {
79 void Initialize(const char* url
, int first_position
, int last_position
) {
81 first_position_
= first_position
;
82 last_position_
= last_position
;
84 url_loader_
= new NiceMock
<MockWebURLLoader
>();
85 loader_
.reset(new BufferedResourceLoader(
86 gurl_
, first_position_
, last_position_
,
87 BufferedResourceLoader::kThresholdDefer
, 0, 0,
88 new media::MediaLog()));
89 loader_
->SetURLLoaderForTest(scoped_ptr
<WebKit::WebURLLoader
>(url_loader_
));
92 void SetLoaderBuffer(size_t forward_capacity
, size_t backward_capacity
) {
93 loader_
->buffer_
.reset(
94 new media::SeekableBuffer(backward_capacity
, forward_capacity
));
99 EXPECT_CALL(*url_loader_
, loadAsynchronously(Truly(CorrectAcceptEncoding
),
102 base::Bind(&BufferedResourceLoaderTest::StartCallback
,
103 base::Unretained(this)),
104 base::Bind(&BufferedResourceLoaderTest::NetworkCallback
,
105 base::Unretained(this)),
109 void FullResponse(int64 instance_size
) {
110 FullResponse(instance_size
, net::OK
);
113 void FullResponse(int64 instance_size
, int status
) {
114 EXPECT_CALL(*this, StartCallback(status
));
116 WebURLResponse
response(gurl_
);
117 response
.setHTTPHeaderField(WebString::fromUTF8("Content-Length"),
118 WebString::fromUTF8(base::StringPrintf("%"
119 PRId64
, instance_size
)));
120 response
.setExpectedContentLength(instance_size
);
121 response
.setHTTPStatusCode(kHttpOK
);
122 loader_
->didReceiveResponse(url_loader_
, response
);
124 if (status
== net::OK
) {
125 EXPECT_EQ(instance_size
, loader_
->content_length());
126 EXPECT_EQ(instance_size
, loader_
->instance_size());
129 EXPECT_FALSE(loader_
->range_supported());
132 void PartialResponse(int64 first_position
, int64 last_position
,
133 int64 instance_size
) {
134 PartialResponse(first_position
, last_position
, instance_size
, false, true);
137 void PartialResponse(int64 first_position
, int64 last_position
,
138 int64 instance_size
, bool chunked
, bool accept_ranges
) {
139 EXPECT_CALL(*this, StartCallback(net::OK
));
141 WebURLResponse
response(gurl_
);
142 response
.setHTTPHeaderField(WebString::fromUTF8("Content-Range"),
143 WebString::fromUTF8(base::StringPrintf("bytes "
144 "%" PRId64
"-%" PRId64
"/%" PRId64
,
149 // HTTP 1.1 doesn't permit Content-Length with Transfer-Encoding: chunked.
150 int64 content_length
= -1;
152 response
.setHTTPHeaderField(WebString::fromUTF8("Transfer-Encoding"),
153 WebString::fromUTF8("chunked"));
155 content_length
= last_position
- first_position
+ 1;
157 response
.setExpectedContentLength(content_length
);
159 // A server isn't required to return Accept-Ranges even though it might.
161 response
.setHTTPHeaderField(WebString::fromUTF8("Accept-Ranges"),
162 WebString::fromUTF8("bytes"));
165 response
.setHTTPStatusCode(kHttpPartialContent
);
166 loader_
->didReceiveResponse(url_loader_
, response
);
168 // XXX: what's the difference between these two? For example in the chunked
169 // range request case, Content-Length is unspecified (because it's chunked)
170 // but Content-Range: a-b/c can be returned, where c == Content-Length
172 // Can we eliminate one?
173 EXPECT_EQ(content_length
, loader_
->content_length());
174 EXPECT_EQ(instance_size
, loader_
->instance_size());
176 // A valid partial response should always result in this being true.
177 EXPECT_TRUE(loader_
->range_supported());
180 void Redirect(const char* url
) {
181 GURL
redirectUrl(url
);
182 WebKit::WebURLRequest
newRequest(redirectUrl
);
183 WebKit::WebURLResponse
redirectResponse(gurl_
);
185 loader_
->willSendRequest(url_loader_
, newRequest
, redirectResponse
);
187 MessageLoop::current()->RunAllPending();
190 void StopWhenLoad() {
192 EXPECT_CALL(*url_loader_
, cancel());
197 // Helper method to write to |loader_| from |data_|.
198 void WriteLoader(int position
, int size
) {
199 EXPECT_CALL(*this, NetworkCallback())
200 .RetiresOnSaturation();
201 loader_
->didReceiveData(url_loader_
,
202 reinterpret_cast<char*>(data_
+ position
),
207 void WriteData(int size
) {
208 EXPECT_CALL(*this, NetworkCallback())
209 .RetiresOnSaturation();
211 scoped_array
<char> data(new char[size
]);
212 loader_
->didReceiveData(url_loader_
, data
.get(), size
, size
);
215 void WriteUntilThreshold() {
216 size_t buffered
= loader_
->buffer_
->forward_bytes();
217 size_t capacity
= loader_
->buffer_
->forward_capacity();
218 CHECK_LT(buffered
, capacity
);
220 EXPECT_CALL(*this, NetworkCallback());
221 WriteData(capacity
- buffered
);
222 ConfirmLoaderDeferredState(true);
225 // Helper method to read from |loader_|.
226 void ReadLoader(int64 position
, int size
, uint8
* buffer
) {
227 loader_
->Read(position
, size
, buffer
,
228 base::Bind(&BufferedResourceLoaderTest::ReadCallback
,
229 base::Unretained(this)));
232 // Verifies that data in buffer[0...size] is equal to data_[pos...pos+size].
233 void VerifyBuffer(uint8
* buffer
, int pos
, int size
) {
234 EXPECT_EQ(0, memcmp(buffer
, data_
+ pos
, size
));
237 void ConfirmLoaderOffsets(int64 expected_offset
,
238 int expected_first_offset
,
239 int expected_last_offset
) {
240 EXPECT_EQ(loader_
->offset_
, expected_offset
);
241 EXPECT_EQ(loader_
->first_offset_
, expected_first_offset
);
242 EXPECT_EQ(loader_
->last_offset_
, expected_last_offset
);
245 void ConfirmBufferState(size_t backward_bytes
,
246 size_t backward_capacity
,
247 size_t forward_bytes
,
248 size_t forward_capacity
) {
249 EXPECT_EQ(backward_bytes
, loader_
->buffer_
->backward_bytes());
250 EXPECT_EQ(backward_capacity
, loader_
->buffer_
->backward_capacity());
251 EXPECT_EQ(forward_bytes
, loader_
->buffer_
->forward_bytes());
252 EXPECT_EQ(forward_capacity
, loader_
->buffer_
->forward_capacity());
255 void ConfirmLoaderBufferBackwardCapacity(size_t expected_backward_capacity
) {
256 EXPECT_EQ(loader_
->buffer_
->backward_capacity(),
257 expected_backward_capacity
);
260 void ConfirmLoaderBufferForwardCapacity(size_t expected_forward_capacity
) {
261 EXPECT_EQ(loader_
->buffer_
->forward_capacity(), expected_forward_capacity
);
264 void ConfirmLoaderDeferredState(bool expectedVal
) {
265 EXPECT_EQ(loader_
->active_loader_
->deferred(), expectedVal
);
268 // Makes sure the |loader_| buffer window is in a reasonable range.
269 void CheckBufferWindowBounds() {
270 // Corresponds to value defined in buffered_resource_loader.cc.
271 static const size_t kMinBufferCapacity
= 2 * 1024 * 1024;
272 EXPECT_GE(loader_
->buffer_
->forward_capacity(), kMinBufferCapacity
);
273 EXPECT_GE(loader_
->buffer_
->backward_capacity(), kMinBufferCapacity
);
275 // Corresponds to value defined in buffered_resource_loader.cc.
276 static const size_t kMaxBufferCapacity
= 20 * 1024 * 1024;
277 EXPECT_LE(loader_
->buffer_
->forward_capacity(), kMaxBufferCapacity
);
278 EXPECT_LE(loader_
->buffer_
->backward_capacity(), kMaxBufferCapacity
);
281 MOCK_METHOD1(StartCallback
, void(int error
));
282 MOCK_METHOD1(ReadCallback
, void(int error
));
283 MOCK_METHOD0(NetworkCallback
, void());
285 // Accessors for private variables on |loader_|.
286 size_t forward_bytes() { return loader_
->buffer_
->forward_bytes(); }
287 size_t forward_capacity() { return loader_
->buffer_
->forward_capacity(); }
291 int64 first_position_
;
292 int64 last_position_
;
294 scoped_ptr
<BufferedResourceLoader
> loader_
;
295 NiceMock
<MockWebURLLoader
>* url_loader_
;
297 MockWebFrameClient client_
;
300 uint8 data_
[kDataSize
];
303 DISALLOW_COPY_AND_ASSIGN(BufferedResourceLoaderTest
);
306 TEST_F(BufferedResourceLoaderTest
, StartStop
) {
307 Initialize(kHttpUrl
, -1, -1);
312 // Tests that a bad HTTP response is recived, e.g. file not found.
313 TEST_F(BufferedResourceLoaderTest
, BadHttpResponse
) {
314 Initialize(kHttpUrl
, -1, -1);
317 EXPECT_CALL(*this, StartCallback(net::ERR_FAILED
));
319 WebURLResponse
response(gurl_
);
320 response
.setHTTPStatusCode(404);
321 response
.setHTTPStatusText("Not Found\n");
322 loader_
->didReceiveResponse(url_loader_
, response
);
326 // Tests that partial content is requested but not fulfilled.
327 TEST_F(BufferedResourceLoaderTest
, NotPartialResponse
) {
328 Initialize(kHttpUrl
, 100, -1);
330 FullResponse(1024, net::ERR_INVALID_RESPONSE
);
334 // Tests that a 200 response is received.
335 TEST_F(BufferedResourceLoaderTest
, FullResponse
) {
336 Initialize(kHttpUrl
, -1, -1);
342 // Tests that a partial content response is received.
343 TEST_F(BufferedResourceLoaderTest
, PartialResponse
) {
344 Initialize(kHttpUrl
, 100, 200);
346 PartialResponse(100, 200, 1024);
350 TEST_F(BufferedResourceLoaderTest
, PartialResponse_Chunked
) {
351 Initialize(kHttpUrl
, 100, 200);
353 PartialResponse(100, 200, 1024, true, true);
357 TEST_F(BufferedResourceLoaderTest
, PartialResponse_NoAcceptRanges
) {
358 Initialize(kHttpUrl
, 100, 200);
360 PartialResponse(100, 200, 1024, false, false);
364 TEST_F(BufferedResourceLoaderTest
, PartialResponse_ChunkedNoAcceptRanges
) {
365 Initialize(kHttpUrl
, 100, 200);
367 PartialResponse(100, 200, 1024, true, false);
371 // Tests that an invalid partial response is received.
372 TEST_F(BufferedResourceLoaderTest
, InvalidPartialResponse
) {
373 Initialize(kHttpUrl
, 0, 10);
376 EXPECT_CALL(*this, StartCallback(net::ERR_INVALID_RESPONSE
));
378 WebURLResponse
response(gurl_
);
379 response
.setHTTPHeaderField(WebString::fromUTF8("Content-Range"),
380 WebString::fromUTF8(base::StringPrintf("bytes "
381 "%d-%d/%d", 1, 10, 1024)));
382 response
.setExpectedContentLength(10);
383 response
.setHTTPStatusCode(kHttpPartialContent
);
384 loader_
->didReceiveResponse(url_loader_
, response
);
388 // Tests the logic of sliding window for data buffering and reading.
389 TEST_F(BufferedResourceLoaderTest
, BufferAndRead
) {
390 Initialize(kHttpUrl
, 10, 29);
391 loader_
->UpdateDeferStrategy(BufferedResourceLoader::kThresholdDefer
);
393 PartialResponse(10, 29, 30);
398 // Writes 10 bytes and read them back.
400 EXPECT_CALL(*this, ReadCallback(10));
401 ReadLoader(10, 10, buffer
);
402 VerifyBuffer(buffer
, 10, 10);
404 // Writes 10 bytes and read 2 times.
406 EXPECT_CALL(*this, ReadCallback(5));
407 ReadLoader(20, 5, buffer
);
408 VerifyBuffer(buffer
, 20, 5);
409 EXPECT_CALL(*this, ReadCallback(5));
410 ReadLoader(25, 5, buffer
);
411 VerifyBuffer(buffer
, 25, 5);
413 // Read backward within buffer.
414 EXPECT_CALL(*this, ReadCallback(10));
415 ReadLoader(10, 10, buffer
);
416 VerifyBuffer(buffer
, 10, 10);
418 // Read backward outside buffer.
419 EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS
));
420 ReadLoader(9, 10, buffer
);
422 // Response has completed.
423 EXPECT_CALL(*this, NetworkCallback());
424 loader_
->didFinishLoading(url_loader_
, 0);
426 // Try to read 10 from position 25 will just return with 5 bytes.
427 EXPECT_CALL(*this, ReadCallback(5));
428 ReadLoader(25, 10, buffer
);
429 VerifyBuffer(buffer
, 25, 5);
431 // Try to read outside buffered range after request has completed.
432 EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS
));
433 ReadLoader(5, 10, buffer
);
435 // Try to read beyond the instance size.
436 EXPECT_CALL(*this, ReadCallback(0));
437 ReadLoader(30, 10, buffer
);
440 // Tests the logic of expanding the data buffer for large reads.
441 TEST_F(BufferedResourceLoaderTest
, ReadExtendBuffer
) {
442 Initialize(kHttpUrl
, 10, 0x014FFFFFF);
443 SetLoaderBuffer(10, 20);
445 PartialResponse(10, 0x014FFFFFF, 0x01500000);
447 // Don't test for network callbacks (covered by *Strategy tests).
448 EXPECT_CALL(*this, NetworkCallback())
449 .WillRepeatedly(Return());
454 // Write more than forward capacity and read it back. Ensure forward capacity
457 EXPECT_CALL(*this, ReadCallback(20));
458 ReadLoader(10, 20, buffer
);
460 VerifyBuffer(buffer
, 10, 20);
461 ConfirmLoaderBufferForwardCapacity(10);
463 // Make and outstanding read request larger than forward capacity. Ensure
464 // forward capacity gets extended.
465 ReadLoader(30, 20, buffer
);
467 ConfirmLoaderBufferForwardCapacity(20);
469 // Fulfill outstanding request. Ensure forward capacity gets reset.
470 EXPECT_CALL(*this, ReadCallback(20));
473 VerifyBuffer(buffer
, 30, 20);
474 ConfirmLoaderBufferForwardCapacity(10);
476 // Try to read further ahead than kForwardWaitThreshold allows. Ensure
477 // forward capacity is not changed.
478 EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS
));
479 ReadLoader(0x00300000, 1, buffer
);
481 ConfirmLoaderBufferForwardCapacity(10);
483 // Try to read more than maximum forward capacity. Ensure forward capacity is
485 EXPECT_CALL(*this, ReadCallback(net::ERR_FAILED
));
486 ReadLoader(30, 0x01400001, buffer
);
488 ConfirmLoaderBufferForwardCapacity(10);
493 TEST_F(BufferedResourceLoaderTest
, ReadOutsideBuffer
) {
494 Initialize(kHttpUrl
, 10, 0x00FFFFFF);
496 PartialResponse(10, 0x00FFFFFF, 0x01000000);
501 // Read very far ahead will get a cache miss.
502 EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS
));
503 ReadLoader(0x00FFFFFF, 1, buffer
);
505 // The following call will not call ReadCallback() because it is waiting for
507 ReadLoader(10, 10, buffer
);
509 // Writing to loader will fulfill the read request.
510 EXPECT_CALL(*this, ReadCallback(10));
512 VerifyBuffer(buffer
, 10, 10);
514 // The following call cannot be fulfilled now.
515 ReadLoader(25, 10, buffer
);
517 EXPECT_CALL(*this, NetworkCallback());
518 EXPECT_CALL(*this, ReadCallback(5));
519 loader_
->didFinishLoading(url_loader_
, 0);
522 TEST_F(BufferedResourceLoaderTest
, RequestFailedWhenRead
) {
523 Initialize(kHttpUrl
, 10, 29);
525 PartialResponse(10, 29, 30);
530 ReadLoader(10, 10, buffer
);
531 EXPECT_CALL(*this, NetworkCallback());
532 EXPECT_CALL(*this, ReadCallback(net::ERR_FAILED
));
534 error
.reason
= net::ERR_FAILED
;
535 loader_
->didFail(url_loader_
, error
);
538 // Tests the data buffering logic of NeverDefer strategy.
539 TEST_F(BufferedResourceLoaderTest
, NeverDeferStrategy
) {
540 Initialize(kHttpUrl
, 10, 99);
541 SetLoaderBuffer(10, 20);
542 loader_
->UpdateDeferStrategy(BufferedResourceLoader::kNeverDefer
);
544 PartialResponse(10, 99, 100);
548 // Read past the buffer size; should not defer regardless.
551 ConfirmLoaderDeferredState(false);
553 // Should move past window.
554 EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS
));
555 ReadLoader(10, 10, buffer
);
560 // Tests the data buffering logic of ReadThenDefer strategy.
561 TEST_F(BufferedResourceLoaderTest
, ReadThenDeferStrategy
) {
562 Initialize(kHttpUrl
, 10, 99);
563 SetLoaderBuffer(10, 20);
564 loader_
->UpdateDeferStrategy(BufferedResourceLoader::kReadThenDefer
);
566 PartialResponse(10, 99, 100);
570 // Make an outstanding read request.
571 ReadLoader(10, 10, buffer
);
573 // Receive almost enough data to cover, shouldn't defer.
575 ConfirmLoaderDeferredState(false);
577 // As soon as we have received enough data to fulfill the read, defer.
578 EXPECT_CALL(*this, NetworkCallback());
579 EXPECT_CALL(*this, ReadCallback(10));
582 ConfirmLoaderDeferredState(true);
583 VerifyBuffer(buffer
, 10, 10);
585 // Read again which should disable deferring since there should be nothing
586 // left in our internal buffer.
587 EXPECT_CALL(*this, NetworkCallback());
588 ReadLoader(20, 10, buffer
);
590 ConfirmLoaderDeferredState(false);
592 // Over-fulfill requested bytes, then deferring should be enabled again.
593 EXPECT_CALL(*this, NetworkCallback());
594 EXPECT_CALL(*this, ReadCallback(10));
597 ConfirmLoaderDeferredState(true);
598 VerifyBuffer(buffer
, 20, 10);
600 // Read far ahead, which should disable deferring. In this case we still have
601 // bytes in our internal buffer.
602 EXPECT_CALL(*this, NetworkCallback());
603 ReadLoader(80, 10, buffer
);
605 ConfirmLoaderDeferredState(false);
607 // Fulfill requested bytes, then deferring should be enabled again.
608 EXPECT_CALL(*this, NetworkCallback());
609 EXPECT_CALL(*this, ReadCallback(10));
612 ConfirmLoaderDeferredState(true);
613 VerifyBuffer(buffer
, 80, 10);
618 // Tests the data buffering logic of ThresholdDefer strategy.
619 TEST_F(BufferedResourceLoaderTest
, ThresholdDeferStrategy
) {
620 Initialize(kHttpUrl
, 10, 99);
621 SetLoaderBuffer(10, 20);
623 PartialResponse(10, 99, 100);
628 // Initial expectation: we're not deferring.
629 ConfirmLoaderDeferredState(false);
631 // Write half of threshold: keep not deferring.
633 ConfirmLoaderDeferredState(false);
635 // Write rest of space until threshold: start deferring.
636 EXPECT_CALL(*this, NetworkCallback());
638 ConfirmLoaderDeferredState(true);
640 // Read a little from the buffer: keep deferring.
641 EXPECT_CALL(*this, ReadCallback(2));
642 ReadLoader(10, 2, buffer
);
643 ConfirmLoaderDeferredState(true);
645 // Read a little more and go under threshold: stop deferring.
646 EXPECT_CALL(*this, ReadCallback(4));
647 EXPECT_CALL(*this, NetworkCallback());
648 ReadLoader(12, 4, buffer
);
649 ConfirmLoaderDeferredState(false);
651 // Write rest of space until threshold: start deferring.
652 EXPECT_CALL(*this, NetworkCallback());
654 ConfirmLoaderDeferredState(true);
656 // Read a little from the buffer: keep deferring.
657 EXPECT_CALL(*this, ReadCallback(4));
658 ReadLoader(16, 4, buffer
);
659 ConfirmLoaderDeferredState(true);
664 TEST_F(BufferedResourceLoaderTest
, Tricky_ReadForwardsPastBuffered
) {
665 Initialize(kHttpUrl
, 10, 99);
666 SetLoaderBuffer(10, 10);
668 PartialResponse(10, 99, 100);
674 WriteUntilThreshold();
675 EXPECT_CALL(*this, ReadCallback(4));
676 ReadLoader(10, 4, buffer
);
677 ConfirmBufferState(4, 10, 6, 10);
678 ConfirmLoaderOffsets(14, 0, 0);
679 ConfirmLoaderDeferredState(true);
681 // *** TRICKY BUSINESS, PT. I ***
682 // Read past buffered: stop deferring.
684 // In order for the read to complete we must:
685 // 1) Stop deferring to receive more data.
688 // offset=14 [xxxxxx____]
689 // ^^^^ requested 4 bytes @ offset 20
691 // offset=24 [__________]
693 EXPECT_CALL(*this, NetworkCallback());
694 ReadLoader(20, 4, buffer
);
695 ConfirmLoaderDeferredState(false);
697 // Write a little, make sure we didn't start deferring.
699 ConfirmLoaderDeferredState(false);
701 // Write the rest, read should complete.
702 EXPECT_CALL(*this, ReadCallback(4));
704 ConfirmLoaderDeferredState(false);
707 ConfirmBufferState(4, 10, 0, 10);
708 ConfirmLoaderOffsets(24, 0, 0);
709 ConfirmLoaderDeferredState(false);
714 TEST_F(BufferedResourceLoaderTest
, Tricky_ReadBackwardsPastBuffered
) {
715 Initialize(kHttpUrl
, 10, 99);
716 SetLoaderBuffer(10, 10);
718 PartialResponse(10, 99, 100);
724 WriteUntilThreshold();
725 ConfirmBufferState(0, 10, 10, 10);
726 ConfirmLoaderOffsets(10, 0, 0);
727 ConfirmLoaderDeferredState(true);
729 // *** TRICKY BUSINESS, PT. II ***
730 // Read backwards a little too much: cache miss.
733 // offset=10 [__________|xxxxxxxxxx]
734 // ^ ^^^ requested 10 bytes @ offset 9
736 // offset=10 [__________|xxxxxxxxxx] !!! cache miss !!!
738 EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS
));
739 ReadLoader(9, 4, buffer
);
742 ConfirmBufferState(0, 10, 10, 10);
743 ConfirmLoaderOffsets(10, 0, 0);
744 ConfirmLoaderDeferredState(true);
749 TEST_F(BufferedResourceLoaderTest
, Tricky_SmallReadWithinThreshold
) {
750 Initialize(kHttpUrl
, 10, 99);
751 SetLoaderBuffer(10, 10);
753 PartialResponse(10, 99, 100);
759 WriteUntilThreshold();
760 ConfirmBufferState(0, 10, 10, 10);
761 ConfirmLoaderOffsets(10, 0, 0);
762 ConfirmLoaderDeferredState(true);
764 // *** TRICKY BUSINESS, PT. III ***
765 // Read past forward capacity but within threshold: stop deferring.
767 // In order for the read to complete we must:
768 // 1) Adjust offset forward to create capacity.
769 // 2) Stop deferring to receive more data.
772 // offset=10 [xxxxxxxxxx]
773 // ^^^^ requested 4 bytes @ offset 24
775 // offset=20 [__________]
776 // ^^^^ requested 4 bytes @ offset 24
778 // offset=28 [__________]
780 EXPECT_CALL(*this, NetworkCallback());
781 ReadLoader(24, 4, buffer
);
782 ConfirmLoaderOffsets(20, 4, 8);
783 ConfirmLoaderDeferredState(false);
785 // Write a little, make sure we didn't start deferring.
787 ConfirmLoaderDeferredState(false);
789 // Write the rest, read should complete.
790 EXPECT_CALL(*this, ReadCallback(4));
792 ConfirmLoaderDeferredState(false);
795 ConfirmBufferState(8, 10, 0, 10);
796 ConfirmLoaderOffsets(28, 0, 0);
797 ConfirmLoaderDeferredState(false);
802 TEST_F(BufferedResourceLoaderTest
, Tricky_LargeReadWithinThreshold
) {
803 Initialize(kHttpUrl
, 10, 99);
804 SetLoaderBuffer(10, 10);
806 PartialResponse(10, 99, 100);
812 WriteUntilThreshold();
813 ConfirmBufferState(0, 10, 10, 10);
814 ConfirmLoaderOffsets(10, 0, 0);
815 ConfirmLoaderDeferredState(true);
817 // *** TRICKY BUSINESS, PT. IV ***
818 // Read a large amount past forward capacity but within
819 // threshold: stop deferring.
821 // In order for the read to complete we must:
822 // 1) Adjust offset forward to create capacity.
823 // 2) Expand capacity to make sure we don't defer as data arrives.
824 // 3) Stop deferring to receive more data.
827 // offset=10 [xxxxxxxxxx]
828 // ^^^^^^^^^^^^ requested 12 bytes @ offset 24
830 // offset=20 [__________]
831 // ^^^^^^ ^^^^^^ requested 12 bytes @ offset 24
833 // offset=20 [________________]
834 // ^^^^^^^^^^^^ requested 12 bytes @ offset 24
836 // offset=36 [__________]
838 EXPECT_CALL(*this, NetworkCallback());
839 ReadLoader(24, 12, buffer
);
840 ConfirmLoaderOffsets(20, 4, 16);
841 ConfirmBufferState(10, 10, 0, 16);
842 ConfirmLoaderDeferredState(false);
844 // Write a little, make sure we didn't start deferring.
846 ConfirmLoaderDeferredState(false);
848 // Write the rest, read should complete and capacity should go back to normal.
849 EXPECT_CALL(*this, ReadCallback(12));
851 ConfirmLoaderBufferForwardCapacity(10);
852 ConfirmLoaderDeferredState(false);
855 ConfirmBufferState(6, 10, 0, 10);
856 ConfirmLoaderOffsets(36, 0, 0);
857 ConfirmLoaderDeferredState(false);
862 TEST_F(BufferedResourceLoaderTest
, Tricky_LargeReadBackwards
) {
863 Initialize(kHttpUrl
, 10, 99);
864 SetLoaderBuffer(10, 10);
866 PartialResponse(10, 99, 100);
872 WriteUntilThreshold();
873 EXPECT_CALL(*this, ReadCallback(10));
874 EXPECT_CALL(*this, NetworkCallback());
875 ReadLoader(10, 10, buffer
);
876 WriteUntilThreshold();
877 ConfirmBufferState(10, 10, 10, 10);
878 ConfirmLoaderOffsets(20, 0, 0);
879 ConfirmLoaderDeferredState(true);
881 // *** TRICKY BUSINESS, PT. V ***
882 // Read a large amount that involves backwards data: stop deferring.
884 // In order for the read to complete we must:
885 // 1) Adjust offset *backwards* to create capacity.
886 // 2) Expand capacity to make sure we don't defer as data arrives.
887 // 3) Stop deferring to receive more data.
890 // offset=20 [xxxxxxxxxx|xxxxxxxxxx]
891 // ^^^^ ^^^^^^^^^^ ^^^^ requested 18 bytes @ offset 16
893 // offset=16 [____xxxxxx|xxxxxxxxxx]xxxx
894 // ^^^^^^^^^^ ^^^^^^^^ requested 18 bytes @ offset 16
896 // offset=16 [____xxxxxx|xxxxxxxxxxxxxx____]
897 // ^^^^^^^^^^^^^^^^^^ requested 18 bytes @ offset 16
899 // offset=34 [xxxxxxxxxx|__________]
901 EXPECT_CALL(*this, NetworkCallback());
902 ReadLoader(16, 18, buffer
);
903 ConfirmLoaderOffsets(16, 0, 18);
904 ConfirmBufferState(6, 10, 14, 18);
905 ConfirmLoaderDeferredState(false);
907 // Write a little, make sure we didn't start deferring.
909 ConfirmLoaderDeferredState(false);
911 // Write the rest, read should complete and capacity should go back to normal.
912 EXPECT_CALL(*this, ReadCallback(18));
914 ConfirmLoaderBufferForwardCapacity(10);
915 ConfirmLoaderDeferredState(false);
918 ConfirmBufferState(4, 10, 0, 10);
919 ConfirmLoaderOffsets(34, 0, 0);
920 ConfirmLoaderDeferredState(false);
925 TEST_F(BufferedResourceLoaderTest
, Tricky_ReadPastThreshold
) {
926 const size_t kSize
= 5 * 1024 * 1024;
927 const size_t 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);
941 ConfirmLoaderDeferredState(true);
943 // *** TRICKY BUSINESS, PT. VI ***
944 // Read past the forward wait threshold: cache miss.
947 // offset=10 [xxxxxxxxxx] ...
948 // ^^^^ requested 10 bytes @ threshold
950 // offset=10 [xxxxxxxxxx] !!! cache miss !!!
952 EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS
));
953 ReadLoader(kThreshold
+ 20, 10, buffer
);
956 ConfirmBufferState(0, 10, 10, 10);
957 ConfirmLoaderOffsets(10, 0, 0);
958 ConfirmLoaderDeferredState(true);
963 // NOTE: This test will need to be reworked a little once
964 // http://code.google.com/p/chromium/issues/detail?id=72578
966 TEST_F(BufferedResourceLoaderTest
, HasSingleOrigin
) {
967 // Make sure no redirect case works as expected.
968 Initialize(kHttpUrl
, -1, -1);
971 EXPECT_TRUE(loader_
->HasSingleOrigin());
974 // Test redirect to the same domain.
975 Initialize(kHttpUrl
, -1, -1);
977 Redirect(kHttpRedirectToSameDomainUrl1
);
979 EXPECT_TRUE(loader_
->HasSingleOrigin());
982 // Test redirect twice to the same domain.
983 Initialize(kHttpUrl
, -1, -1);
985 Redirect(kHttpRedirectToSameDomainUrl1
);
986 Redirect(kHttpRedirectToSameDomainUrl2
);
988 EXPECT_TRUE(loader_
->HasSingleOrigin());
991 // Test redirect to a different domain.
992 Initialize(kHttpUrl
, -1, -1);
994 Redirect(kHttpRedirectToDifferentDomainUrl1
);
995 EXPECT_FALSE(loader_
->HasSingleOrigin());
998 // Test redirect to the same domain and then to a different domain.
999 Initialize(kHttpUrl
, -1, -1);
1001 Redirect(kHttpRedirectToSameDomainUrl1
);
1002 Redirect(kHttpRedirectToDifferentDomainUrl1
);
1003 EXPECT_FALSE(loader_
->HasSingleOrigin());
1007 TEST_F(BufferedResourceLoaderTest
, BufferWindow_Default
) {
1008 Initialize(kHttpUrl
, -1, -1);
1011 // Test ensures that default construction of a BufferedResourceLoader has sane
1014 // Please do not change these values in order to make a test pass! Instead,
1015 // start a conversation on what the default buffer window capacities should
1017 ConfirmLoaderBufferBackwardCapacity(2 * 1024 * 1024);
1018 ConfirmLoaderBufferForwardCapacity(2 * 1024 * 1024);
1023 TEST_F(BufferedResourceLoaderTest
, BufferWindow_Bitrate_Unknown
) {
1024 Initialize(kHttpUrl
, -1, -1);
1026 loader_
->SetBitrate(0);
1027 CheckBufferWindowBounds();
1031 TEST_F(BufferedResourceLoaderTest
, BufferWindow_Bitrate_BelowLowerBound
) {
1032 Initialize(kHttpUrl
, -1, -1);
1034 loader_
->SetBitrate(1024 * 8); // 1 Kbps.
1035 CheckBufferWindowBounds();
1039 TEST_F(BufferedResourceLoaderTest
, BufferWindow_Bitrate_WithinBounds
) {
1040 Initialize(kHttpUrl
, -1, -1);
1042 loader_
->SetBitrate(2 * 1024 * 1024 * 8); // 2 Mbps.
1043 CheckBufferWindowBounds();
1047 TEST_F(BufferedResourceLoaderTest
, BufferWindow_Bitrate_AboveUpperBound
) {
1048 Initialize(kHttpUrl
, -1, -1);
1050 loader_
->SetBitrate(100 * 1024 * 1024 * 8); // 100 Mbps.
1051 CheckBufferWindowBounds();
1055 TEST_F(BufferedResourceLoaderTest
, BufferWindow_PlaybackRate_Negative
) {
1056 Initialize(kHttpUrl
, -1, -1);
1058 loader_
->SetPlaybackRate(-10);
1059 CheckBufferWindowBounds();
1063 TEST_F(BufferedResourceLoaderTest
, BufferWindow_PlaybackRate_Zero
) {
1064 Initialize(kHttpUrl
, -1, -1);
1066 loader_
->SetPlaybackRate(0);
1067 CheckBufferWindowBounds();
1071 TEST_F(BufferedResourceLoaderTest
, BufferWindow_PlaybackRate_BelowLowerBound
) {
1072 Initialize(kHttpUrl
, -1, -1);
1074 loader_
->SetPlaybackRate(0.1f
);
1075 CheckBufferWindowBounds();
1079 TEST_F(BufferedResourceLoaderTest
, BufferWindow_PlaybackRate_WithinBounds
) {
1080 Initialize(kHttpUrl
, -1, -1);
1082 loader_
->SetPlaybackRate(10);
1083 CheckBufferWindowBounds();
1087 TEST_F(BufferedResourceLoaderTest
, BufferWindow_PlaybackRate_AboveUpperBound
) {
1088 Initialize(kHttpUrl
, -1, -1);
1090 loader_
->SetPlaybackRate(100);
1091 CheckBufferWindowBounds();
1095 } // namespace webkit_media