1dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Use of this source code is governed by a BSD-style license that can be
321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// found in the LICENSE file.
421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include <algorithm>
621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/format_macros.h"
821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/stringprintf.h"
921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/base/net_errors.h"
1021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "net/http/http_util.h"
1172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrame.h"
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebFrameClient.h"
1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h"
1472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h"
1572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebView.h"
1621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "webkit/glue/media/buffered_resource_loader.h"
1721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "webkit/mocks/mock_webframe.h"
1821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "webkit/mocks/mock_weburlloader.h"
1921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
2021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing ::testing::_;
2121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing ::testing::Assign;
2221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing ::testing::AtLeast;
2321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing ::testing::DeleteArg;
2421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing ::testing::DoAll;
2521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing ::testing::InSequence;
2621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing ::testing::Invoke;
2721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing ::testing::InvokeWithoutArgs;
2821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing ::testing::NotNull;
2921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing ::testing::Return;
3021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing ::testing::ReturnRef;
3121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing ::testing::SetArgumentPointee;
3221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing ::testing::StrictMock;
3321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing ::testing::NiceMock;
3421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing ::testing::WithArgs;
3521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
3621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing WebKit::WebURLError;
3721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing WebKit::WebFrameClient;
3821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing WebKit::WebURLResponse;
3921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing WebKit::WebView;
4021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
41dc0f95d653279beabeb9817299e2902918ba123eKristian Monsennamespace webkit_glue {
4221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
43dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const char* kHttpUrl = "http://test";
44dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const char kHttpRedirectToSameDomainUrl1[] = "http://test/ing";
45dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const char kHttpRedirectToSameDomainUrl2[] = "http://test/ing2";
46dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const char kHttpRedirectToDifferentDomainUrl1[] = "http://test2";
47dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const char kHttpRedirectToDifferentDomainUrl2[] = "http://test2/ing";
4872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const int kDataSize = 1024;
50dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const int kHttpOK = 200;
51dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const int kHttpPartialContent = 206;
5221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenenum NetworkState {
5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  NONE,
5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  LOADED,
5621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  LOADING
5721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen};
5821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Submit a request completed event to the resource loader due to request
6021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// being canceled. Pretending the event is from external.
6121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenACTION_P(RequestCanceled, loader) {
6221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  WebURLError error;
6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  error.reason = net::ERR_ABORTED;
6421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  error.domain = WebString::fromUTF8(net::kErrorDomain);
6521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  loader->didFail(NULL, error);
6621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
6721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenclass BufferedResourceLoaderTest : public testing::Test {
6921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen public:
7021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  BufferedResourceLoaderTest() {
7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    for (int i = 0; i < kDataSize; ++i)
7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      data_[i] = i;
7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
7421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual ~BufferedResourceLoaderTest() {
7621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
7721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
7821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void Initialize(const char* url, int first_position, int last_position) {
7921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    gurl_ = GURL(url);
8021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    first_position_ = first_position;
8121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    last_position_ = last_position;
8221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
8321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    frame_.reset(new NiceMock<MockWebFrame>());
8421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
8572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    url_loader_ = new NiceMock<MockWebURLLoader>();
8621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    loader_ = new BufferedResourceLoader(gurl_,
8721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                         first_position_, last_position_);
8821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    loader_->SetURLLoaderForTest(url_loader_);
8921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
9021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
9121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void SetLoaderBuffer(size_t forward_capacity, size_t backward_capacity) {
9221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    loader_->buffer_.reset(
9321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        new media::SeekableBuffer(backward_capacity, forward_capacity));
9421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
9521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
9621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void Start() {
9721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    InSequence s;
9821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    EXPECT_CALL(*url_loader_, loadAsynchronously(_, loader_.get()));
9921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    loader_->Start(
10021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        NewCallback(this, &BufferedResourceLoaderTest::StartCallback),
10121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        NewCallback(this, &BufferedResourceLoaderTest::NetworkCallback),
10221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        frame_.get());
10321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
10421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
10521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void FullResponse(int64 instance_size) {
106ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    FullResponse(instance_size, net::OK);
107ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
108ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
109ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void FullResponse(int64 instance_size, int status) {
110ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_CALL(*this, StartCallback(status));
111ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (status != net::OK) {
112ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      EXPECT_CALL(*url_loader_, cancel())
113ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          .WillOnce(RequestCanceled(loader_));
114ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
11521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
11621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    WebURLResponse response(gurl_);
11721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    response.setHTTPHeaderField(WebString::fromUTF8("Content-Length"),
11821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                WebString::fromUTF8(base::StringPrintf("%"
11921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                    PRId64, instance_size)));
12021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    response.setExpectedContentLength(instance_size);
12121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    response.setHTTPStatusCode(kHttpOK);
12221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    loader_->didReceiveResponse(url_loader_, response);
123ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
124ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (status == net::OK) {
125ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      EXPECT_EQ(instance_size, loader_->content_length());
126ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      EXPECT_EQ(instance_size, loader_->instance_size());
127ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
128ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
129ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_FALSE(loader_->range_supported());
13021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
13121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
13221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void PartialResponse(int64 first_position, int64 last_position,
13321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                       int64 instance_size) {
134ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    PartialResponse(first_position, last_position, instance_size, false, true);
135ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  }
136ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
137ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void PartialResponse(int64 first_position, int64 last_position,
138ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                       int64 instance_size, bool chunked, bool accept_ranges) {
13921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    EXPECT_CALL(*this, StartCallback(net::OK));
14021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
14121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    WebURLResponse response(gurl_);
14221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    response.setHTTPHeaderField(WebString::fromUTF8("Content-Range"),
14321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                WebString::fromUTF8(base::StringPrintf("bytes "
14421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                            "%" PRId64 "-%" PRId64 "/%" PRId64,
14521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                            first_position,
14621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                            last_position,
14721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                            instance_size)));
148ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
149ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // HTTP 1.1 doesn't permit Content-Length with Transfer-Encoding: chunked.
150ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    int64 content_length = -1;
151ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (chunked) {
152ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      response.setHTTPHeaderField(WebString::fromUTF8("Transfer-Encoding"),
153ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  WebString::fromUTF8("chunked"));
154ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
155ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      content_length = last_position - first_position + 1;
156ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
15721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    response.setExpectedContentLength(content_length);
158ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
159ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // A server isn't required to return Accept-Ranges even though it might.
160ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (accept_ranges) {
161ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      response.setHTTPHeaderField(WebString::fromUTF8("Accept-Ranges"),
162ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                  WebString::fromUTF8("bytes"));
163ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
164ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
16521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    response.setHTTPStatusCode(kHttpPartialContent);
16621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    loader_->didReceiveResponse(url_loader_, response);
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // XXX: what's the difference between these two? For example in the chunked
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // range request case, Content-Length is unspecified (because it's chunked)
170ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // but Content-Range: a-b/c can be returned, where c == Content-Length
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    //
172ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // Can we eliminate one?
17321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    EXPECT_EQ(content_length, loader_->content_length());
17421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    EXPECT_EQ(instance_size, loader_->instance_size());
175ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
176ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // A valid partial response should always result in this being true.
177ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_TRUE(loader_->range_supported());
17821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
17921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
18072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  void Redirect(const char* url) {
18172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    GURL redirectUrl(url);
18272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    WebKit::WebURLRequest newRequest(redirectUrl);
18372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    WebKit::WebURLResponse redirectResponse(gurl_);
18472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
18572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    loader_->willSendRequest(url_loader_, newRequest, redirectResponse);
18672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
18772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    MessageLoop::current()->RunAllPending();
18872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  }
18972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
19021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void StopWhenLoad() {
19121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    InSequence s;
19221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    EXPECT_CALL(*url_loader_, cancel())
19321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        .WillOnce(RequestCanceled(loader_));
19421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    loader_->Stop();
19572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    loader_ = NULL;
19621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
19721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
19821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Helper method to write to |loader_| from |data_|.
19921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void WriteLoader(int position, int size) {
20021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    EXPECT_CALL(*this, NetworkCallback())
20121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        .RetiresOnSaturation();
20221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    loader_->didReceiveData(url_loader_,
203ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            reinterpret_cast<char*>(data_ + position),
204ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            size,
205ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                            size);
20621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
20721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
20821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Helper method to read from |loader_|.
20921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void ReadLoader(int64 position, int size, uint8* buffer) {
21021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    loader_->Read(position, size, buffer,
21121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                  NewCallback(this, &BufferedResourceLoaderTest::ReadCallback));
21221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
21321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
21421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Verifis that data in buffer[0...size] is equal to data_[pos...pos+size].
21521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  void VerifyBuffer(uint8* buffer, int pos, int size) {
21621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    EXPECT_EQ(0, memcmp(buffer, data_ + pos, size));
21721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
21821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
219ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void ConfirmLoaderDeferredState(bool expectedVal) {
220ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_EQ(loader_->deferred_, expectedVal);
22121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  }
22221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
22321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MOCK_METHOD1(StartCallback, void(int error));
22421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MOCK_METHOD1(ReadCallback, void(int error));
22521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MOCK_METHOD0(NetworkCallback, void());
22621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
22721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen protected:
22821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  GURL gurl_;
22921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  int64 first_position_;
23021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  int64 last_position_;
23121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
23221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  scoped_refptr<BufferedResourceLoader> loader_;
23321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  NiceMock<MockWebURLLoader>* url_loader_;
23421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  scoped_ptr<NiceMock<MockWebFrame> > frame_;
23521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
23621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  uint8 data_[kDataSize];
23721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
23821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen private:
23921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DISALLOW_COPY_AND_ASSIGN(BufferedResourceLoaderTest);
24021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen};
24121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
24221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(BufferedResourceLoaderTest, StartStop) {
24321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Initialize(kHttpUrl, -1, -1);
24421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Start();
24521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  StopWhenLoad();
24621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
24721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
24821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Tests that a bad HTTP response is recived, e.g. file not found.
24921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(BufferedResourceLoaderTest, BadHttpResponse) {
25021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Initialize(kHttpUrl, -1, -1);
25121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Start();
25221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
25321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, StartCallback(net::ERR_FAILED));
25421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*url_loader_, cancel())
25521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      .WillOnce(RequestCanceled(loader_));
25621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
25721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  WebURLResponse response(gurl_);
25821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  response.setHTTPStatusCode(404);
25921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  response.setHTTPStatusText("Not Found\n");
26021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  loader_->didReceiveResponse(url_loader_, response);
26121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
26221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
26321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Tests that partial content is requested but not fulfilled.
26421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(BufferedResourceLoaderTest, NotPartialResponse) {
26521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Initialize(kHttpUrl, 100, -1);
26621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Start();
267ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  FullResponse(1024, net::ERR_INVALID_RESPONSE);
26821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
26921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
27021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Tests that a 200 response is received.
27121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(BufferedResourceLoaderTest, FullResponse) {
27221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Initialize(kHttpUrl, -1, -1);
27321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Start();
27421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  FullResponse(1024);
27521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  StopWhenLoad();
27621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
27721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
27821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Tests that a partial content response is received.
27921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(BufferedResourceLoaderTest, PartialResponse) {
28021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Initialize(kHttpUrl, 100, 200);
28121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Start();
28221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  PartialResponse(100, 200, 1024);
28321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  StopWhenLoad();
28421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
28521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
286ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(BufferedResourceLoaderTest, PartialResponse_Chunked) {
287ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Initialize(kHttpUrl, 100, 200);
288ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Start();
289ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PartialResponse(100, 200, 1024, true, true);
290ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  StopWhenLoad();
291ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
292ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
293ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(BufferedResourceLoaderTest, PartialResponse_NoAcceptRanges) {
294ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Initialize(kHttpUrl, 100, 200);
295ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Start();
296ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PartialResponse(100, 200, 1024, false, false);
297ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  StopWhenLoad();
298ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
299ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
300ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(BufferedResourceLoaderTest, PartialResponse_ChunkedNoAcceptRanges) {
301ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Initialize(kHttpUrl, 100, 200);
302ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  Start();
303ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  PartialResponse(100, 200, 1024, true, false);
304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  StopWhenLoad();
305ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
306ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
30721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Tests that an invalid partial response is received.
30821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(BufferedResourceLoaderTest, InvalidPartialResponse) {
30921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Initialize(kHttpUrl, 0, 10);
31021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Start();
31121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
31221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, StartCallback(net::ERR_INVALID_RESPONSE));
31321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*url_loader_, cancel())
31421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      .WillOnce(RequestCanceled(loader_));
31521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
31621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  WebURLResponse response(gurl_);
31721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  response.setHTTPHeaderField(WebString::fromUTF8("Content-Range"),
31821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                              WebString::fromUTF8(base::StringPrintf("bytes "
31921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                  "%d-%d/%d", 1, 10, 1024)));
32021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  response.setExpectedContentLength(10);
32121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  response.setHTTPStatusCode(kHttpPartialContent);
32221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  loader_->didReceiveResponse(url_loader_, response);
32321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
32421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
32521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// Tests the logic of sliding window for data buffering and reading.
32621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(BufferedResourceLoaderTest, BufferAndRead) {
32721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Initialize(kHttpUrl, 10, 29);
328ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  loader_->UpdateDeferStrategy(BufferedResourceLoader::kThresholdDefer);
32921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Start();
33021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  PartialResponse(10, 29, 30);
33121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
33221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  uint8 buffer[10];
33321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InSequence s;
33421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
33521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Writes 10 bytes and read them back.
33621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  WriteLoader(10, 10);
33721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, ReadCallback(10));
33821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ReadLoader(10, 10, buffer);
33921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  VerifyBuffer(buffer, 10, 10);
34021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
34121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Writes 10 bytes and read 2 times.
34221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  WriteLoader(20, 10);
34321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, ReadCallback(5));
34421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ReadLoader(20, 5, buffer);
34521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  VerifyBuffer(buffer, 20, 5);
34621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, ReadCallback(5));
34721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ReadLoader(25, 5, buffer);
34821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  VerifyBuffer(buffer, 25, 5);
34921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
35021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Read backward within buffer.
35121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, ReadCallback(10));
35221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ReadLoader(10, 10, buffer);
35321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  VerifyBuffer(buffer, 10, 10);
35421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
35521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Read backward outside buffer.
35621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS));
35721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ReadLoader(9, 10, buffer);
35821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
35921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Response has completed.
36021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, NetworkCallback());
36121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  loader_->didFinishLoading(url_loader_, 0);
36221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
36321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Try to read 10 from position 25 will just return with 5 bytes.
36421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, ReadCallback(5));
36521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ReadLoader(25, 10, buffer);
36621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  VerifyBuffer(buffer, 25, 5);
36721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
36821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Try to read outside buffered range after request has completed.
36921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS));
37021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ReadLoader(5, 10, buffer);
37121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
37221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Try to read beyond the instance size.
37321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, ReadCallback(0));
37421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ReadLoader(30, 10, buffer);
37521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
37621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
37721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(BufferedResourceLoaderTest, ReadOutsideBuffer) {
37821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Initialize(kHttpUrl, 10, 0x00FFFFFF);
379ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  loader_->UpdateDeferStrategy(BufferedResourceLoader::kThresholdDefer);
38021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Start();
38121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  PartialResponse(10, 0x00FFFFFF, 0x01000000);
38221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
38321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  uint8 buffer[10];
38421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InSequence s;
38521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
38621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Read very far aheard will get a cache miss.
38721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS));
38821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ReadLoader(0x00FFFFFF, 1, buffer);
38921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
39021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // The following call will not call ReadCallback() because it is waiting for
39121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // data to arrive.
39221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ReadLoader(10, 10, buffer);
39321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
39421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // Writing to loader will fulfill the read request.
39521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, ReadCallback(10));
39621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  WriteLoader(10, 20);
39721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  VerifyBuffer(buffer, 10, 10);
39821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
39921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  // The following call cannot be fulfilled now.
40021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ReadLoader(25, 10, buffer);
40121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
40221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, ReadCallback(5));
40321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, NetworkCallback());
40421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  loader_->didFinishLoading(url_loader_, 0);
40521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
40621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
40721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian MonsenTEST_F(BufferedResourceLoaderTest, RequestFailedWhenRead) {
40821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Initialize(kHttpUrl, 10, 29);
40921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Start();
41021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  PartialResponse(10, 29, 30);
41121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
41221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  uint8 buffer[10];
41321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  InSequence s;
41421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
41521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ReadLoader(10, 10, buffer);
41621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, ReadCallback(net::ERR_FAILED));
41721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, NetworkCallback());
41821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  WebURLError error;
41921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  error.reason = net::ERR_FAILED;
42021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  loader_->didFail(url_loader_, error);
42121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
42221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
423ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Tests the data buffering logic of NeverDefer strategy.
424ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(BufferedResourceLoaderTest, NeverDeferStrategy) {
42521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Initialize(kHttpUrl, 10, 99);
42621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  SetLoaderBuffer(10, 20);
427ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  loader_->UpdateDeferStrategy(BufferedResourceLoader::kNeverDefer);
42821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Start();
42921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  PartialResponse(10, 99, 100);
43021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
43121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  uint8 buffer[10];
43221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
433ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Read past the buffer size; should not defer regardless.
43421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  WriteLoader(10, 10);
43521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  WriteLoader(20, 50);
436ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ConfirmLoaderDeferredState(false);
43721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
438ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Should move past window.
43921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, ReadCallback(net::ERR_CACHE_MISS));
44021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  ReadLoader(10, 10, buffer);
441ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
44221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  StopWhenLoad();
44321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
44421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
445ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Tests the data buffering logic of ReadThenDefer strategy.
446ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(BufferedResourceLoaderTest, ReadThenDeferStrategy) {
44721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Initialize(kHttpUrl, 10, 99);
44821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  SetLoaderBuffer(10, 20);
449ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  loader_->UpdateDeferStrategy(BufferedResourceLoader::kReadThenDefer);
45021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Start();
45121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  PartialResponse(10, 99, 100);
45221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
45321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  uint8 buffer[10];
45421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
455ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Make an outstanding read request.
456ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We should disable deferring after the read request, so expect
457ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // a network event.
45821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, NetworkCallback());
459ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ReadLoader(10, 10, buffer);
46021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
461ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Receive almost enough data to cover, shouldn't defer.
462ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WriteLoader(10, 9);
463ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ConfirmLoaderDeferredState(false);
46421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
465ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // As soon as we have received enough data to fulfill the read, defer.
46621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, NetworkCallback());
467ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(*this, ReadCallback(10));
468ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WriteLoader(19, 1);
46921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
470ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ConfirmLoaderDeferredState(true);
471ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  VerifyBuffer(buffer, 10, 10);
47221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
47321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  StopWhenLoad();
47421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
47521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Tests the data buffering logic of ThresholdDefer strategy.
477ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(BufferedResourceLoaderTest, ThresholdDeferStrategy) {
47821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Initialize(kHttpUrl, 10, 99);
47921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  SetLoaderBuffer(10, 20);
480ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  loader_->UpdateDeferStrategy(BufferedResourceLoader::kThresholdDefer);
48121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  Start();
48221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  PartialResponse(10, 99, 100);
48321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
48421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  uint8 buffer[10];
48521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
486ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WriteLoader(10, 5);
487ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Haven't reached threshold, don't defer.
488ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ConfirmLoaderDeferredState(false);
489ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
490ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // We're at the threshold now, let's defer.
49121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  EXPECT_CALL(*this, NetworkCallback());
492ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  WriteLoader(15, 5);
493ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ConfirmLoaderDeferredState(true);
49421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
495ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  // Now we've read over half of the buffer, disable deferring.
496ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(*this, ReadCallback(6));
497ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  EXPECT_CALL(*this, NetworkCallback());
498ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ReadLoader(10, 6, buffer);
499ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
500ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ConfirmLoaderDeferredState(false);
501ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  VerifyBuffer(buffer, 10, 6);
50221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
50321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  StopWhenLoad();
50421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}
50572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
50672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// NOTE: This test will need to be reworked a little once
50772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// http://code.google.com/p/chromium/issues/detail?id=72578
50872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// is fixed.
50972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(BufferedResourceLoaderTest, HasSingleOrigin) {
51072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Make sure no redirect case works as expected.
51172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Initialize(kHttpUrl, -1, -1);
51272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Start();
51372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FullResponse(1024);
51472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_TRUE(loader_->HasSingleOrigin());
51572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  StopWhenLoad();
51672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
51772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Test redirect to the same domain.
51872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Initialize(kHttpUrl, -1, -1);
51972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Start();
52072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Redirect(kHttpRedirectToSameDomainUrl1);
52172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FullResponse(1024);
52272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_TRUE(loader_->HasSingleOrigin());
52372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  StopWhenLoad();
52472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
52572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Test redirect twice to the same domain.
52672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Initialize(kHttpUrl, -1, -1);
52772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Start();
52872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Redirect(kHttpRedirectToSameDomainUrl1);
52972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Redirect(kHttpRedirectToSameDomainUrl2);
53072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  FullResponse(1024);
53172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_TRUE(loader_->HasSingleOrigin());
53272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  StopWhenLoad();
53372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
53472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Test redirect to a different domain.
53572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Initialize(kHttpUrl, -1, -1);
53672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Start();
53772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Redirect(kHttpRedirectToDifferentDomainUrl1);
53872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_FALSE(loader_->HasSingleOrigin());
53972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  StopWhenLoad();
54072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
541dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  // Test redirect to the same domain and then to a different domain.
54272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Initialize(kHttpUrl, -1, -1);
54372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Start();
54472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  Redirect(kHttpRedirectToSameDomainUrl1);
545dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  Redirect(kHttpRedirectToDifferentDomainUrl1);
54672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_FALSE(loader_->HasSingleOrigin());
54772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  StopWhenLoad();
54872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
54972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
55021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// TODO(hclam): add unit test for defer loading.
55121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen
55221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen}  // namespace webkit_glue
553