172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// Copyright (c) 2011 The Chromium Authors. All rights reserved.
2c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// Use of this source code is governed by a BSD-style license that can be
3c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch// found in the LICENSE file.
4c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include <algorithm>
6c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "base/test/test_timeouts.h"
872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "media/base/mock_callback.h"
9c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "media/base/mock_filter_host.h"
10c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "media/base/mock_filters.h"
11c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "net/base/net_errors.h"
1272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLError.h"
1372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen#include "third_party/WebKit/Source/WebKit/chromium/public/WebURLResponse.h"
14c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch#include "webkit/glue/media/buffered_data_source.h"
1521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen#include "webkit/mocks/mock_webframe.h"
16c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
17c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing ::testing::_;
18c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing ::testing::Assign;
1921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenusing ::testing::AtLeast;
20c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing ::testing::DeleteArg;
21c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing ::testing::DoAll;
22c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing ::testing::InSequence;
23c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing ::testing::Invoke;
24c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing ::testing::InvokeWithoutArgs;
25c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing ::testing::NotNull;
26c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing ::testing::Return;
27513209b27ff55e2841eac0e4120199c23acce758Ben Murdochusing ::testing::ReturnRef;
28c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing ::testing::SetArgumentPointee;
29c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing ::testing::StrictMock;
30731df977c0511bca2206b5f333555b1205ff1f43Iain Merrickusing ::testing::NiceMock;
31c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochusing ::testing::WithArgs;
32c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
33dc0f95d653279beabeb9817299e2902918ba123eKristian Monsennamespace webkit_glue {
34c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
35dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const char* kHttpUrl = "http://test";
36dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const char* kFileUrl = "file://test";
37dc0f95d653279beabeb9817299e2902918ba123eKristian Monsenstatic const int kDataSize = 1024;
38c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
39c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochenum NetworkState {
40c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  NONE,
41c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LOADED,
42c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  LOADING
43c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
44c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
4521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// A mock BufferedDataSource to inject mock BufferedResourceLoader through
4621d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen// CreateResourceLoader() method.
4721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsenclass MockBufferedDataSource : public BufferedDataSource {
48c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
49dc0f95d653279beabeb9817299e2902918ba123eKristian Monsen  MockBufferedDataSource(MessageLoop* message_loop, WebFrame* frame)
5021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      : BufferedDataSource(message_loop, frame) {
51c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
52c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  virtual base::TimeDelta GetTimeoutMilliseconds() {
5421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    return base::TimeDelta::FromMilliseconds(
5521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                            TestTimeouts::tiny_timeout_ms());
56c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
57c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
5821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MOCK_METHOD2(CreateResourceLoader,
5921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen               BufferedResourceLoader*(int64 first_position,
6021d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                       int64 last_position));
61c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
62c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
6321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  DISALLOW_COPY_AND_ASSIGN(MockBufferedDataSource);
64c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
65c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
66c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass MockBufferedResourceLoader : public BufferedResourceLoader {
67c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
6821d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MockBufferedResourceLoader() : BufferedResourceLoader(GURL(), 0, 0) {
69c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
70c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
7121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  MOCK_METHOD3(Start, void(net::CompletionCallback* read_callback,
7221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                           NetworkEventCallback* network_callback,
7321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                           WebFrame* frame));
74c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MOCK_METHOD0(Stop, void());
75c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MOCK_METHOD4(Read, void(int64 position, int read_size, uint8* buffer,
76c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          net::CompletionCallback* callback));
77c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MOCK_METHOD0(content_length, int64());
78c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MOCK_METHOD0(instance_size, int64());
79ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  MOCK_METHOD0(range_supported, bool());
80c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MOCK_METHOD0(network_activity, bool());
81513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  MOCK_METHOD0(url, const GURL&());
82c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MOCK_METHOD0(GetBufferedFirstBytePosition, int64());
83c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MOCK_METHOD0(GetBufferedLastBytePosition, int64());
84c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
85c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch protected:
86c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ~MockBufferedResourceLoader() {}
87c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
88c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(MockBufferedResourceLoader);
89c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
90c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
91c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdochclass BufferedDataSourceTest : public testing::Test {
92c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch public:
93c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  BufferedDataSourceTest() {
94c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_loop_ = MessageLoop::current();
95c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
96c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Prepare test data.
97c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    for (size_t i = 0; i < sizeof(data_); ++i) {
98c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      data_[i] = i;
99c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
100c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
101c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
102c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  virtual ~BufferedDataSourceTest() {
103c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
104c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
105731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  void ExpectCreateAndStartResourceLoader(int start_error) {
106731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    EXPECT_CALL(*data_source_, CreateResourceLoader(_, _))
107731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        .WillOnce(Return(loader_.get()));
108731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
10921d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    EXPECT_CALL(*loader_, Start(NotNull(), NotNull(), NotNull()))
110731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        .WillOnce(
111731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick            DoAll(Assign(&error_, start_error),
112731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                  Invoke(this,
113731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                         &BufferedDataSourceTest::InvokeStartCallback)));
114731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  }
115731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
116c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void InitializeDataSource(const char* url, int error,
117c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            bool partial_response, int64 instance_size,
118c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                            NetworkState networkState) {
119c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Saves the url first.
120c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    gurl_ = GURL(url);
121c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    frame_.reset(new NiceMock<MockWebFrame>());
123c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
12421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    data_source_ = new MockBufferedDataSource(MessageLoop::current(),
12521d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen                                              frame_.get());
126c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data_source_->set_host(&host_);
127c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
128513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    scoped_refptr<NiceMock<MockBufferedResourceLoader> > first_loader(
129513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        new NiceMock<MockBufferedResourceLoader>());
130731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
131c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Creates the mock loader to be injected.
132731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    loader_ = first_loader;
133c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
134731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    bool initialized_ok = (error == net::OK);
135c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    bool loaded = networkState == LOADED;
136c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    {
137c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      InSequence s;
138731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      ExpectCreateAndStartResourceLoader(error);
139731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
140731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // In the case of an invalid partial response we expect a second loader
141731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      // to be created.
142731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      if (partial_response && (error == net::ERR_INVALID_RESPONSE)) {
143731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        // Verify that the initial loader is stopped.
144513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        EXPECT_CALL(*loader_, url())
145513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch            .WillRepeatedly(ReturnRef(gurl_));
146731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        EXPECT_CALL(*loader_, Stop());
147731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
148731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        // Replace loader_ with a new instance.
149731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        loader_ = new NiceMock<MockBufferedResourceLoader>();
150731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
15121d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen        // Create and start. Make sure Start() is called on the new loader.
152731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        ExpectCreateAndStartResourceLoader(net::OK);
153731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
154731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        // Update initialization variable since we know the second loader will
155731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        // return OK.
156731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        initialized_ok = true;
157731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick      }
158c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
159c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
160513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // Attach a static function that deletes the memory referred by the
161513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // "callback" parameter.
162513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    ON_CALL(*loader_, Read(_, _, _ , _))
163513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        .WillByDefault(DeleteArg<3>());
164513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
165513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    ON_CALL(*loader_, instance_size())
166513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        .WillByDefault(Return(instance_size));
167ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
168ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    // range_supported() return true if we expect to get a partial response.
169ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    ON_CALL(*loader_, range_supported())
170513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        .WillByDefault(Return(partial_response));
171ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
172513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    ON_CALL(*loader_, url())
173513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        .WillByDefault(ReturnRef(gurl_));
174ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    media::PipelineStatus expected_init_status = media::PIPELINE_OK;
175731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (initialized_ok) {
176c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Expected loaded or not.
177c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_CALL(host_, SetLoaded(loaded));
178c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
179c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // TODO(hclam): The condition for streaming needs to be adjusted.
180c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (instance_size != -1 && (loaded || partial_response)) {
181c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        EXPECT_CALL(host_, SetTotalBytes(instance_size));
182c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        if (loaded)
183c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          EXPECT_CALL(host_, SetBufferedBytes(instance_size));
184c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        else
185c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          EXPECT_CALL(host_, SetBufferedBytes(0));
186c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
187c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        EXPECT_CALL(host_, SetStreaming(true));
188c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
189c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    } else {
190ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      expected_init_status = media::PIPELINE_ERROR_NETWORK;
191c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_CALL(*loader_, Stop());
192c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
193c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
194c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Actual initialization of the data source.
195ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    data_source_->Initialize(url,
196ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        media::NewExpectedStatusCallback(expected_init_status));
197c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_loop_->RunAllPending();
198c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
199731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    if (initialized_ok) {
200c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      // Verify the size of the data source.
201c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      int64 size;
202c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      if (instance_size != -1 && (loaded || partial_response)) {
203c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        EXPECT_TRUE(data_source_->GetSize(&size));
204c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        EXPECT_EQ(instance_size, size);
205c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      } else {
206c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        EXPECT_TRUE(data_source_->IsStreaming());
207c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      }
208c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
209c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
210c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
211c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void StopDataSource() {
212c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (loader_) {
213c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      InSequence s;
214c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_CALL(*loader_, Stop());
215c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
216c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
21772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen    data_source_->Stop(media::NewExpectedCallback());
218c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_loop_->RunAllPending();
219c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
220c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
221c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void InvokeStartCallback(
222c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      net::CompletionCallback* callback,
22321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      BufferedResourceLoader::NetworkEventCallback* network_callback,
22421d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen      WebFrame* frame) {
225c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    callback->RunWithParams(Tuple1<int>(error_));
226c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete callback;
227c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // TODO(hclam): Save this callback.
228c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete network_callback;
229c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
230c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
231c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void InvokeReadCallback(int64 position, int size, uint8* buffer,
232c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          net::CompletionCallback* callback) {
233c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    if (error_ > 0)
234c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      memcpy(buffer, data_ + static_cast<int>(position), error_);
235c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    callback->RunWithParams(Tuple1<int>(error_));
236c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    delete callback;
237c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
238c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
239c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ReadDataSourceHit(int64 position, int size, int read_size) {
240c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(loader_);
241c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
242c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    InSequence s;
243c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Expect the read is delegated to the resource loader.
244c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(*loader_, Read(position, size, NotNull(), NotNull()))
245c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        .WillOnce(DoAll(Assign(&error_, read_size),
246c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        Invoke(this,
247c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               &BufferedDataSourceTest::InvokeReadCallback)));
248c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
249c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // The read has succeeded, so read callback will be called.
250c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(*this, ReadCallback(read_size));
251c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
252c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data_source_->Read(
253c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        position, size, buffer_,
254c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewCallback(this, &BufferedDataSourceTest::ReadCallback));
255c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_loop_->RunAllPending();
256c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
257c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Make sure data is correct.
258c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(0,
259c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch              memcmp(buffer_, data_ + static_cast<int>(position), read_size));
260c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
261c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
262513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  void ReadDataSourceHang(int64 position, int size) {
263513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    EXPECT_TRUE(loader_);
264513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
265513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // Expect a call to read, but the call never returns.
266513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    EXPECT_CALL(*loader_, Read(position, size, NotNull(), NotNull()));
267513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    data_source_->Read(
268513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        position, size, buffer_,
269513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch        NewCallback(this, &BufferedDataSourceTest::ReadCallback));
270513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    message_loop_->RunAllPending();
271513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
272513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // Now expect the read to return after aborting the data source.
273513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    EXPECT_CALL(*this, ReadCallback(_));
274513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    EXPECT_CALL(*loader_, Stop());
275513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    data_source_->Abort();
276513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    message_loop_->RunAllPending();
277513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
278513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // The loader has now been stopped. Set this to null so that when the
279513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    // DataSource is stopped, it does not expect a call to stop the loader.
280513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch    loader_ = NULL;
281513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  }
282513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
283ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  void ReadDataSourceMiss(int64 position, int size, int start_error) {
284c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(loader_);
285c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
286c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 1. Reply with a cache miss for the read.
287c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    {
288c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      InSequence s;
289c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_CALL(*loader_, Read(position, size, NotNull(), NotNull()))
290c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          .WillOnce(DoAll(Assign(&error_, net::ERR_CACHE_MISS),
291c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                          Invoke(this,
292c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                 &BufferedDataSourceTest::InvokeReadCallback)));
293c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_CALL(*loader_, Stop());
294c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
295c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
296c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 2. Then the current loader will be stop and destroyed.
297731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    NiceMock<MockBufferedResourceLoader> *new_loader =
298731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        new NiceMock<MockBufferedResourceLoader>();
299c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(*data_source_, CreateResourceLoader(position, -1))
300c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        .WillOnce(Return(new_loader));
301c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
302c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 3. Then the new loader will be started.
30321d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    EXPECT_CALL(*new_loader, Start(NotNull(), NotNull(), NotNull()))
304ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        .WillOnce(DoAll(Assign(&error_, start_error),
305c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        Invoke(this,
306c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               &BufferedDataSourceTest::InvokeStartCallback)));
307c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
308ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (start_error == net::OK) {
309ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      EXPECT_CALL(*new_loader, range_supported())
310ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          .WillRepeatedly(Return(loader_->range_supported()));
311c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
312ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // 4a. Then again a read request is made to the new loader.
313ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      EXPECT_CALL(*new_loader, Read(position, size, NotNull(), NotNull()))
314ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen          .WillOnce(DoAll(Assign(&error_, size),
315ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                          Invoke(this,
316ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen                                 &BufferedDataSourceTest::InvokeReadCallback)));
317ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
318ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      EXPECT_CALL(*this, ReadCallback(size));
319ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    } else {
320ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // 4b. The read callback is called with an error because Start() on the
321ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      // new loader returned an error.
322ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      EXPECT_CALL(*this, ReadCallback(media::DataSource::kReadError));
323ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    }
324c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
325c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data_source_->Read(
326c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        position, size, buffer_,
327c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewCallback(this, &BufferedDataSourceTest::ReadCallback));
328c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_loop_->RunAllPending();
329c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
330c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Make sure data is correct.
331ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    if (start_error == net::OK)
332ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen      EXPECT_EQ(0, memcmp(buffer_, data_ + static_cast<int>(position), size));
333c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
334c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    loader_ = new_loader;
335c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
336c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
337c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ReadDataSourceFailed(int64 position, int size, int error) {
338c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_TRUE(loader_);
339c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
340c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 1. Expect the read is delegated to the resource loader.
341c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(*loader_, Read(position, size, NotNull(), NotNull()))
342c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        .WillOnce(DoAll(Assign(&error_, error),
343c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        Invoke(this,
344c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               &BufferedDataSourceTest::InvokeReadCallback)));
345c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
346c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 2. Host will then receive an error.
347c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(*loader_, Stop());
348c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
349c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 3. The read has failed, so read callback will be called.
350c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(*this, ReadCallback(media::DataSource::kReadError));
351c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
352c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data_source_->Read(
353c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        position, size, buffer_,
354c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewCallback(this, &BufferedDataSourceTest::ReadCallback));
355c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
356c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_loop_->RunAllPending();
357c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
358c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
359c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  void ReadDataSourceTimesOut(int64 position, int size) {
360c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 1. Drop the request and let it times out.
361c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    {
362c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      InSequence s;
363c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_CALL(*loader_, Read(position, size, NotNull(), NotNull()))
364c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch          .WillOnce(DeleteArg<3>());
365c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch      EXPECT_CALL(*loader_, Stop());
366c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    }
367c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
368c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 2. Then the current loader will be stop and destroyed.
369731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick    NiceMock<MockBufferedResourceLoader> *new_loader =
370731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick        new NiceMock<MockBufferedResourceLoader>();
371c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(*data_source_, CreateResourceLoader(position, -1))
372c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        .WillOnce(Return(new_loader));
373c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
374c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 3. Then the new loader will be started and respond to queries about
375c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //    whether this is a partial response using the value of the previous
376c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    //    loader.
37721d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen    EXPECT_CALL(*new_loader, Start(NotNull(), NotNull(), NotNull()))
378c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        .WillOnce(DoAll(Assign(&error_, net::OK),
379c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        Invoke(this,
380c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               &BufferedDataSourceTest::InvokeStartCallback)));
381ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen    EXPECT_CALL(*new_loader, range_supported())
382ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen        .WillRepeatedly(Return(loader_->range_supported()));
383c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
384c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // 4. Then again a read request is made to the new loader.
385c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(*new_loader, Read(position, size, NotNull(), NotNull()))
386c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        .WillOnce(DoAll(Assign(&error_, size),
387c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        Invoke(this,
388c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                               &BufferedDataSourceTest::InvokeReadCallback),
389c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                        InvokeWithoutArgs(message_loop_,
390c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch                                          &MessageLoop::Quit)));
391c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
392c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_CALL(*this, ReadCallback(size));
393c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
394c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    data_source_->Read(
395c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        position, size, buffer_,
396c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch        NewCallback(this, &BufferedDataSourceTest::ReadCallback));
397c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
398c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // This blocks the current thread until the watch task is executed and
399c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // triggers a read callback to quit this message loop.
400c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    message_loop_->Run();
401c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
402c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    // Make sure data is correct.
403c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    EXPECT_EQ(0, memcmp(buffer_, data_ + static_cast<int>(position), size));
404c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
405c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch    loader_ = new_loader;
406c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  }
407c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
408c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MOCK_METHOD1(ReadCallback, void(size_t size));
409c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
410731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  scoped_refptr<NiceMock<MockBufferedResourceLoader> > loader_;
411c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  scoped_refptr<MockBufferedDataSource> data_source_;
41221d179b334e59e9a3bfcaed4c4430bef1bc5759dKristian Monsen  scoped_ptr<NiceMock<MockWebFrame> > frame_;
413c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
414c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StrictMock<media::MockFilterHost> host_;
415c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  GURL gurl_;
416c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  MessageLoop* message_loop_;
417c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
418c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  int error_;
419c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  uint8 buffer_[1024];
420c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  uint8 data_[1024];
421c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
422c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch private:
423c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  DISALLOW_COPY_AND_ASSIGN(BufferedDataSourceTest);
424c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch};
425c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
426c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BufferedDataSourceTest, InitializationSuccess) {
427c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING);
428c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StopDataSource();
429c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
430c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
431c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BufferedDataSourceTest, InitiailizationFailed) {
432c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitializeDataSource(kHttpUrl, net::ERR_FILE_NOT_FOUND, false, 0, NONE);
433c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StopDataSource();
434c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
435c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
436c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BufferedDataSourceTest, MissingContentLength) {
437c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitializeDataSource(kHttpUrl, net::OK, true, -1, LOADING);
438c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StopDataSource();
439c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
440c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
441c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BufferedDataSourceTest, RangeRequestNotSupported) {
442c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitializeDataSource(kHttpUrl, net::OK, false, 1024, LOADING);
443c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StopDataSource();
444c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
445c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
446731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick// Test the case where we get a 206 response, but no Content-Range header.
447731df977c0511bca2206b5f333555b1205ff1f43Iain MerrickTEST_F(BufferedDataSourceTest, MissingContentRange) {
448731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  InitializeDataSource(kHttpUrl, net::ERR_INVALID_RESPONSE, true, 1024,
449731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick                       LOADING);
450731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick  StopDataSource();
451731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick}
452731df977c0511bca2206b5f333555b1205ff1f43Iain Merrick
453c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BufferedDataSourceTest,
454c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch       MissingContentLengthAndRangeRequestNotSupported) {
455c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitializeDataSource(kHttpUrl, net::OK, false, -1, LOADING);
456c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StopDataSource();
457c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
458c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
459c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BufferedDataSourceTest, ReadCacheHit) {
460c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitializeDataSource(kHttpUrl, net::OK, true, 25, LOADING);
461c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
462c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Performs read with cache hit.
463c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ReadDataSourceHit(10, 10, 10);
464c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
465c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  // Performs read with cache hit but partially filled.
466c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ReadDataSourceHit(20, 10, 5);
467c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
468c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StopDataSource();
469c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
470c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
471c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BufferedDataSourceTest, ReadCacheMiss) {
472c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING);
473ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ReadDataSourceMiss(1000, 10, net::OK);
474ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ReadDataSourceMiss(20, 10, net::OK);
475ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  StopDataSource();
476ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen}
477ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen
478ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Test the case where the initial response from the server indicates that
479ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen// Range requests are supported, but a later request prove otherwise.
480ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian MonsenTEST_F(BufferedDataSourceTest, ServerLiesAboutRangeSupport) {
481ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING);
482ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ReadDataSourceHit(10, 10, 10);
483ddb351dbec246cf1fab5ec20d2d5520909041de1Kristian Monsen  ReadDataSourceMiss(1000, 10, net::ERR_INVALID_RESPONSE);
484c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StopDataSource();
485c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
486c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
487513209b27ff55e2841eac0e4120199c23acce758Ben MurdochTEST_F(BufferedDataSourceTest, ReadHang) {
488513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  InitializeDataSource(kHttpUrl, net::OK, true, 25, LOADING);
489513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  ReadDataSourceHang(10, 10);
490513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch  StopDataSource();
491513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch}
492513209b27ff55e2841eac0e4120199c23acce758Ben Murdoch
493c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BufferedDataSourceTest, ReadFailed) {
494c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING);
495c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ReadDataSourceHit(10, 10, 10);
496c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ReadDataSourceFailed(10, 10, net::ERR_CONNECTION_RESET);
497c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StopDataSource();
498c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
499c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
500c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BufferedDataSourceTest, ReadTimesOut) {
501c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitializeDataSource(kHttpUrl, net::OK, true, 1024, LOADING);
502c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ReadDataSourceTimesOut(20, 10);
503c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StopDataSource();
504c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
505c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
506c407dc5cd9bdc5668497f21b26b09d988ab439deBen MurdochTEST_F(BufferedDataSourceTest, FileHasLoadedState) {
507c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  InitializeDataSource(kFileUrl, net::OK, true, 1024, LOADED);
508c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  ReadDataSourceTimesOut(20, 10);
509c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch  StopDataSource();
510c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}
511c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch
51272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// This test makes sure that Stop() does not require a task to run on
51372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// |message_loop_| before it calls its callback. This prevents accidental
51472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// introduction of a pipeline teardown deadlock. The pipeline owner blocks
51572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// the render message loop while waiting for Stop() to complete. Since this
51672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// object runs on the render message loop, Stop() will not complete if it
51772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen// requires a task to run on the the message loop that is being blocked.
51872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(BufferedDataSourceTest, StopDoesNotUseMessageLoopForCallback) {
51972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  InitializeDataSource(kFileUrl, net::OK, true, 1024, LOADED);
52072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
52172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Create a callback that lets us verify that it was called before
52272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Stop() returns. This is to make sure that the callback does not
52372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // require |message_loop_| to execute tasks before being called.
52472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  media::MockCallback* stop_callback = media::NewExpectedCallback();
52572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool stop_done_called = false;
52672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ON_CALL(*stop_callback, RunWithParams(_))
52772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillByDefault(Assign(&stop_done_called, true));
52872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
52972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Stop() the data source like normal.
53072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  data_source_->Stop(stop_callback);
53172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
53272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Verify that the callback was called inside the Stop() call.
53372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_TRUE(stop_done_called);
53472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
53572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  message_loop_->RunAllPending();
53672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
53772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
53872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian MonsenTEST_F(BufferedDataSourceTest, AbortDuringPendingRead) {
53972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  InitializeDataSource(kFileUrl, net::OK, true, 1024, LOADED);
54072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
54172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Setup a way to verify that Read() is not called on the loader.
54272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // We are doing this to make sure that the ReadTask() is still on
54372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // the message loop queue when Abort() is called.
54472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  bool read_called = false;
54572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  ON_CALL(*loader_, Read(_, _, _ , _))
54672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      .WillByDefault(DoAll(Assign(&read_called, true),
54772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                           DeleteArg<3>()));
54872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
54972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Initiate a Read() on the data source, but don't allow the
55072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // message loop to run.
55172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  data_source_->Read(
55272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      0, 10, buffer_,
55372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NewCallback(static_cast<BufferedDataSourceTest*>(this),
55472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                  &BufferedDataSourceTest::ReadCallback));
55572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
55672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Call Abort() with the read pending.
55772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*this, ReadCallback(-1));
55872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*loader_, Stop());
55972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  data_source_->Abort();
56072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
56172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Verify that Read()'s after the Abort() issue callback with an error.
56272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_CALL(*this, ReadCallback(-1));
56372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  data_source_->Read(
56472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      0, 10, buffer_,
56572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen      NewCallback(static_cast<BufferedDataSourceTest*>(this),
56672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen                  &BufferedDataSourceTest::ReadCallback));
56772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
56872a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Stop() the data source like normal.
56972a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  data_source_->Stop(media::NewExpectedCallback());
57072a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
57172a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Allow cleanup task to run.
57272a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  message_loop_->RunAllPending();
57372a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
57472a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  // Verify that Read() was not called on the loader.
57572a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen  EXPECT_FALSE(read_called);
57672a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen}
57772a454cd3513ac24fbdd0e0cb9ad70b86a99b801Kristian Monsen
578c407dc5cd9bdc5668497f21b26b09d988ab439deBen Murdoch}  // namespace webkit_glue
579