Commit c8b5fe12 authored by mmenke's avatar mmenke Committed by Commit bot

Add more ResourceLoaderTests.

In particular, check the cases of async URLRequest::Read successes.

Also add ResourceHandler re-entrancy checks to TestResourceHandler,
which the current API is designed to avoid.

Review-Url: https://codereview.chromium.org/2552463002
Cr-Commit-Position: refs/heads/master@{#437586}
parent 58293adb
...@@ -396,10 +396,16 @@ class ResourceLoaderTest : public testing::Test, ...@@ -396,10 +396,16 @@ class ResourceLoaderTest : public testing::Test,
test_url_request_context_.Init(); test_url_request_context_.Init();
} }
// URL with a response body of test_data(). // URL with a response body of test_data() where reads complete synchronously.
GURL test_direct_url() const { return net::URLRequestTestJob::test_url_1(); } GURL test_sync_url() const { return net::URLRequestTestJob::test_url_1(); }
// URL that redirects to test_direct_url(). The ResourceLoader is set up to // URL with a response body of test_data() where reads complete
// asynchronously.
GURL test_async_url() const {
return net::URLRequestTestJob::test_url_auto_advance_async_reads_1();
}
// URL that redirects to test_sync_url(). The ResourceLoader is set up to
// use this URL by default. // use this URL by default.
GURL test_redirect_url() const { GURL test_redirect_url() const {
return net::URLRequestTestJob::test_url_redirect_to_url_1(); return net::URLRequestTestJob::test_url_redirect_to_url_1();
...@@ -522,6 +528,11 @@ class ResourceLoaderTest : public testing::Test, ...@@ -522,6 +528,11 @@ class ResourceLoaderTest : public testing::Test,
void DidFinishLoading(ResourceLoader* loader) override { void DidFinishLoading(ResourceLoader* loader) override {
EXPECT_EQ(loader, loader_.get()); EXPECT_EQ(loader, loader_.get());
EXPECT_EQ(0, did_finish_loading_); EXPECT_EQ(0, did_finish_loading_);
// Shouldn't be in a recursive ResourceHandler call - this is normally where
// the ResourceLoader (And thus the ResourceHandler chain) is destroyed.
EXPECT_EQ(0, raw_ptr_resource_handler_->call_depth());
++did_finish_loading_; ++did_finish_loading_;
} }
std::unique_ptr<net::ClientCertStore> CreateClientCertStore( std::unique_ptr<net::ClientCertStore> CreateClientCertStore(
...@@ -562,7 +573,7 @@ class ClientCertResourceLoaderTest : public ResourceLoaderTest { ...@@ -562,7 +573,7 @@ class ClientCertResourceLoaderTest : public ResourceLoaderTest {
void SetUp() override { void SetUp() override {
ResourceLoaderTest::SetUp(); ResourceLoaderTest::SetUp();
// These tests don't expect any redirects. // These tests don't expect any redirects.
SetUpResourceLoaderForUrl(test_direct_url()); SetUpResourceLoaderForUrl(test_sync_url());
} }
}; };
...@@ -744,6 +755,22 @@ TEST_F(ResourceLoaderTest, SyncResourceHandler) { ...@@ -744,6 +755,22 @@ TEST_F(ResourceLoaderTest, SyncResourceHandler) {
EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body()); EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body());
} }
// Same as above, except reads complete asynchronously, and there's no redirect.
TEST_F(ResourceLoaderTest, SyncResourceHandlerAsyncReads) {
SetUpResourceLoaderForUrl(test_async_url());
loader_->StartRequest();
raw_ptr_resource_handler_->WaitUntilResponseComplete();
EXPECT_EQ(1, did_start_request_);
EXPECT_EQ(0, did_received_redirect_);
EXPECT_EQ(1, did_receive_response_);
EXPECT_EQ(1, did_finish_loading_);
EXPECT_EQ(0, raw_ptr_resource_handler_->on_request_redirected_called());
EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_completed_called());
EXPECT_EQ(net::OK, raw_ptr_resource_handler_->final_status().error());
EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body());
}
// Test the case the ResourceHandler defers everything. // Test the case the ResourceHandler defers everything.
TEST_F(ResourceLoaderTest, AsyncResourceHandler) { TEST_F(ResourceLoaderTest, AsyncResourceHandler) {
raw_ptr_resource_handler_->set_defer_on_will_start(true); raw_ptr_resource_handler_->set_defer_on_will_start(true);
...@@ -835,6 +862,85 @@ TEST_F(ResourceLoaderTest, AsyncResourceHandler) { ...@@ -835,6 +862,85 @@ TEST_F(ResourceLoaderTest, AsyncResourceHandler) {
EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body()); EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body());
} }
// Same as above, except reads complete asynchronously and there's no redirect.
TEST_F(ResourceLoaderTest, AsyncResourceHandlerAsyncReads) {
SetUpResourceLoaderForUrl(test_async_url());
raw_ptr_resource_handler_->set_defer_on_will_start(true);
raw_ptr_resource_handler_->set_defer_on_response_started(true);
raw_ptr_resource_handler_->set_defer_on_read_completed(true);
raw_ptr_resource_handler_->set_defer_on_read_eof(true);
raw_ptr_resource_handler_->set_defer_on_response_completed(true);
// Start and run until OnWillStart.
loader_->StartRequest();
raw_ptr_resource_handler_->WaitUntilDeferred();
EXPECT_EQ(1, raw_ptr_resource_handler_->on_will_start_called());
// Spinning the message loop should not advance the state further.
base::RunLoop().RunUntilIdle();
EXPECT_EQ(0, did_start_request_);
EXPECT_EQ(1, raw_ptr_resource_handler_->on_will_start_called());
EXPECT_EQ(0, raw_ptr_resource_handler_->on_request_redirected_called());
EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_completed_called());
// Resume and run until OnResponseStarted.
raw_ptr_resource_handler_->Resume();
raw_ptr_resource_handler_->WaitUntilDeferred();
EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_started_called());
// Spinning the message loop should not advance the state further.
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, did_receive_response_);
EXPECT_EQ(0, did_finish_loading_);
EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_started_called());
EXPECT_EQ(0, raw_ptr_resource_handler_->on_will_read_called());
EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_completed_called());
// Resume and run until OnReadCompleted.
raw_ptr_resource_handler_->Resume();
raw_ptr_resource_handler_->WaitUntilDeferred();
EXPECT_EQ(1, raw_ptr_resource_handler_->on_read_completed_called());
// Spinning the message loop should not advance the state further.
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, raw_ptr_resource_handler_->on_will_read_called());
EXPECT_EQ(1, raw_ptr_resource_handler_->on_read_completed_called());
EXPECT_EQ(0, raw_ptr_resource_handler_->on_read_eof());
EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_completed_called());
// Resume and run until the final 0-byte read, signalling EOF.
raw_ptr_resource_handler_->Resume();
raw_ptr_resource_handler_->WaitUntilDeferred();
EXPECT_EQ(1, raw_ptr_resource_handler_->on_read_eof());
// Spinning the message loop should not advance the state further.
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, raw_ptr_resource_handler_->on_read_eof());
EXPECT_EQ(0, raw_ptr_resource_handler_->on_response_completed_called());
EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body());
// Resume and run until OnResponseCompleted is called, which again defers the
// request.
raw_ptr_resource_handler_->Resume();
raw_ptr_resource_handler_->WaitUntilResponseComplete();
EXPECT_EQ(0, did_finish_loading_);
EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_completed_called());
EXPECT_EQ(net::OK, raw_ptr_resource_handler_->final_status().error());
EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body());
// Resume and run until all pending tasks. Note that OnResponseCompleted was
// invoked in the previous section, so can't use RunUntilCompleted().
raw_ptr_resource_handler_->Resume();
EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_completed_called());
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, did_finish_loading_);
EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_completed_called());
EXPECT_EQ(net::OK, raw_ptr_resource_handler_->final_status().error());
EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body());
}
TEST_F(ResourceLoaderTest, SyncCancelOnWillStart) { TEST_F(ResourceLoaderTest, SyncCancelOnWillStart) {
raw_ptr_resource_handler_->set_on_will_start_result(false); raw_ptr_resource_handler_->set_on_will_start_result(false);
...@@ -925,7 +1031,42 @@ TEST_F(ResourceLoaderTest, SyncCancelOnReadCompleted) { ...@@ -925,7 +1031,42 @@ TEST_F(ResourceLoaderTest, SyncCancelOnReadCompleted) {
} }
TEST_F(ResourceLoaderTest, SyncCancelOnReceivedEof) { TEST_F(ResourceLoaderTest, SyncCancelOnReceivedEof) {
raw_ptr_resource_handler_->set_on_on_read_eof_result(false); raw_ptr_resource_handler_->set_on_read_eof_result(false);
loader_->StartRequest();
raw_ptr_resource_handler_->WaitUntilResponseComplete();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, did_receive_response_);
EXPECT_EQ(1, did_finish_loading_);
EXPECT_EQ(1, raw_ptr_resource_handler_->on_read_eof());
EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_completed_called());
EXPECT_EQ(net::ERR_ABORTED,
raw_ptr_resource_handler_->final_status().error());
EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body());
}
TEST_F(ResourceLoaderTest, SyncCancelOnAsyncReadCompleted) {
SetUpResourceLoaderForUrl(test_async_url());
raw_ptr_resource_handler_->set_on_read_completed_result(false);
loader_->StartRequest();
raw_ptr_resource_handler_->WaitUntilResponseComplete();
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, did_receive_response_);
EXPECT_EQ(1, did_finish_loading_);
EXPECT_EQ(1, raw_ptr_resource_handler_->on_read_completed_called());
EXPECT_EQ(0, raw_ptr_resource_handler_->on_read_eof());
EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_completed_called());
EXPECT_EQ(net::ERR_ABORTED,
raw_ptr_resource_handler_->final_status().error());
EXPECT_LT(0u, raw_ptr_resource_handler_->body().size());
}
TEST_F(ResourceLoaderTest, SyncCancelOnAsyncReceivedEof) {
SetUpResourceLoaderForUrl(test_async_url());
raw_ptr_resource_handler_->set_on_read_eof_result(false);
loader_->StartRequest(); loader_->StartRequest();
raw_ptr_resource_handler_->WaitUntilResponseComplete(); raw_ptr_resource_handler_->WaitUntilResponseComplete();
...@@ -1028,6 +1169,41 @@ TEST_F(ResourceLoaderTest, AsyncCancelOnReceivedEof) { ...@@ -1028,6 +1169,41 @@ TEST_F(ResourceLoaderTest, AsyncCancelOnReceivedEof) {
EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body()); EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body());
} }
TEST_F(ResourceLoaderTest, AsyncCancelOnAsyncReadCompleted) {
SetUpResourceLoaderForUrl(test_async_url());
raw_ptr_resource_handler_->set_defer_on_read_completed(true);
loader_->StartRequest();
raw_ptr_resource_handler_->WaitUntilDeferred();
raw_ptr_resource_handler_->CancelWithError(net::ERR_FAILED);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, did_receive_response_);
EXPECT_EQ(1, did_finish_loading_);
EXPECT_EQ(1, raw_ptr_resource_handler_->on_read_completed_called());
EXPECT_EQ(0, raw_ptr_resource_handler_->on_read_eof());
EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_completed_called());
EXPECT_EQ(net::ERR_FAILED, raw_ptr_resource_handler_->final_status().error());
EXPECT_LT(0u, raw_ptr_resource_handler_->body().size());
}
TEST_F(ResourceLoaderTest, AsyncCancelOnAsyncReceivedEof) {
SetUpResourceLoaderForUrl(test_async_url());
raw_ptr_resource_handler_->set_defer_on_read_eof(true);
loader_->StartRequest();
raw_ptr_resource_handler_->WaitUntilDeferred();
raw_ptr_resource_handler_->CancelWithError(net::ERR_FAILED);
base::RunLoop().RunUntilIdle();
EXPECT_EQ(1, did_receive_response_);
EXPECT_EQ(1, did_finish_loading_);
EXPECT_EQ(1, raw_ptr_resource_handler_->on_read_eof());
EXPECT_EQ(1, raw_ptr_resource_handler_->on_response_completed_called());
EXPECT_EQ(net::ERR_FAILED, raw_ptr_resource_handler_->final_status().error());
EXPECT_EQ(test_data(), raw_ptr_resource_handler_->body());
}
TEST_F(ResourceLoaderTest, RequestFailsOnStart) { TEST_F(ResourceLoaderTest, RequestFailsOnStart) {
SetUpResourceLoaderForUrl( SetUpResourceLoaderForUrl(
net::URLRequestFailedJob::GetMockHttpUrlWithFailurePhase( net::URLRequestFailedJob::GetMockHttpUrlWithFailurePhase(
......
...@@ -11,6 +11,28 @@ ...@@ -11,6 +11,28 @@
namespace content { namespace content {
namespace {
class ScopedCallDepthTracker {
public:
explicit ScopedCallDepthTracker(int* call_depth) : call_depth_(call_depth) {
EXPECT_EQ(0, *call_depth_);
(*call_depth_)++;
}
~ScopedCallDepthTracker() {
EXPECT_EQ(1, *call_depth_);
(*call_depth_)--;
}
private:
int* const call_depth_;
DISALLOW_COPY_AND_ASSIGN(ScopedCallDepthTracker);
};
} // namespace
TestResourceHandler::TestResourceHandler(net::URLRequestStatus* request_status, TestResourceHandler::TestResourceHandler(net::URLRequestStatus* request_status,
std::string* body) std::string* body)
: ResourceHandler(nullptr), : ResourceHandler(nullptr),
...@@ -37,6 +59,8 @@ bool TestResourceHandler::OnRequestRedirected( ...@@ -37,6 +59,8 @@ bool TestResourceHandler::OnRequestRedirected(
EXPECT_EQ(1, on_will_start_called_); EXPECT_EQ(1, on_will_start_called_);
EXPECT_EQ(0, on_response_started_called_); EXPECT_EQ(0, on_response_started_called_);
EXPECT_EQ(0, on_response_completed_called_); EXPECT_EQ(0, on_response_completed_called_);
ScopedCallDepthTracker call_depth_tracker(&call_depth_);
++on_request_redirected_called_; ++on_request_redirected_called_;
if (!on_request_redirected_result_) { if (!on_request_redirected_result_) {
...@@ -57,6 +81,8 @@ bool TestResourceHandler::OnResponseStarted(ResourceResponse* response, ...@@ -57,6 +81,8 @@ bool TestResourceHandler::OnResponseStarted(ResourceResponse* response,
EXPECT_EQ(1, on_will_start_called_); EXPECT_EQ(1, on_will_start_called_);
EXPECT_EQ(0, on_response_started_called_); EXPECT_EQ(0, on_response_started_called_);
EXPECT_EQ(0, on_response_completed_called_); EXPECT_EQ(0, on_response_completed_called_);
ScopedCallDepthTracker call_depth_tracker(&call_depth_);
++on_response_started_called_; ++on_response_started_called_;
EXPECT_FALSE(resource_response_); EXPECT_FALSE(resource_response_);
...@@ -79,6 +105,8 @@ bool TestResourceHandler::OnWillStart(const GURL& url, bool* defer) { ...@@ -79,6 +105,8 @@ bool TestResourceHandler::OnWillStart(const GURL& url, bool* defer) {
EXPECT_EQ(0, on_response_started_called_); EXPECT_EQ(0, on_response_started_called_);
EXPECT_EQ(0, on_will_start_called_); EXPECT_EQ(0, on_will_start_called_);
EXPECT_EQ(0, on_response_completed_called_); EXPECT_EQ(0, on_response_completed_called_);
ScopedCallDepthTracker call_depth_tracker(&call_depth_);
++on_will_start_called_; ++on_will_start_called_;
start_url_ = url; start_url_ = url;
...@@ -100,6 +128,8 @@ bool TestResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf, ...@@ -100,6 +128,8 @@ bool TestResourceHandler::OnWillRead(scoped_refptr<net::IOBuffer>* buf,
EXPECT_FALSE(canceled_); EXPECT_FALSE(canceled_);
EXPECT_FALSE(expect_on_data_downloaded_); EXPECT_FALSE(expect_on_data_downloaded_);
EXPECT_EQ(0, on_response_completed_called_); EXPECT_EQ(0, on_response_completed_called_);
ScopedCallDepthTracker call_depth_tracker(&call_depth_);
++on_will_read_called_; ++on_will_read_called_;
*buf = buffer_; *buf = buffer_;
...@@ -117,6 +147,7 @@ bool TestResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { ...@@ -117,6 +147,7 @@ bool TestResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
EXPECT_EQ(1, on_response_started_called_); EXPECT_EQ(1, on_response_started_called_);
EXPECT_EQ(0, on_response_completed_called_); EXPECT_EQ(0, on_response_completed_called_);
EXPECT_EQ(0, on_read_eof_); EXPECT_EQ(0, on_read_eof_);
ScopedCallDepthTracker call_depth_tracker(&call_depth_);
++on_read_completed_called_; ++on_read_completed_called_;
if (bytes_read == 0) if (bytes_read == 0)
...@@ -127,8 +158,7 @@ bool TestResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { ...@@ -127,8 +158,7 @@ bool TestResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
body_ptr_->append(buffer_->data(), bytes_read); body_ptr_->append(buffer_->data(), bytes_read);
body_.append(buffer_->data(), bytes_read); body_.append(buffer_->data(), bytes_read);
if (!on_read_completed_result_ || if (!on_read_completed_result_ || (!on_read_eof_result_ && bytes_read == 0)) {
(!on_on_read_eof_result_ && bytes_read == 0)) {
canceled_ = true; canceled_ = true;
return false; return false;
} }
...@@ -147,6 +177,8 @@ bool TestResourceHandler::OnReadCompleted(int bytes_read, bool* defer) { ...@@ -147,6 +177,8 @@ bool TestResourceHandler::OnReadCompleted(int bytes_read, bool* defer) {
void TestResourceHandler::OnResponseCompleted( void TestResourceHandler::OnResponseCompleted(
const net::URLRequestStatus& status, const net::URLRequestStatus& status,
bool* defer) { bool* defer) {
ScopedCallDepthTracker call_depth_tracker(&call_depth_);
EXPECT_EQ(0, on_response_completed_called_); EXPECT_EQ(0, on_response_completed_called_);
if (status.is_success() && !expect_on_data_downloaded_ && expect_eof_read_) if (status.is_success() && !expect_on_data_downloaded_ && expect_eof_read_)
EXPECT_EQ(1, on_read_eof_); EXPECT_EQ(1, on_read_eof_);
...@@ -170,10 +202,12 @@ void TestResourceHandler::OnDataDownloaded(int bytes_downloaded) { ...@@ -170,10 +202,12 @@ void TestResourceHandler::OnDataDownloaded(int bytes_downloaded) {
} }
void TestResourceHandler::Resume() { void TestResourceHandler::Resume() {
ScopedCallDepthTracker call_depth_tracker(&call_depth_);
controller_->Resume(); controller_->Resume();
} }
void TestResourceHandler::CancelWithError(net::Error net_error) { void TestResourceHandler::CancelWithError(net::Error net_error) {
ScopedCallDepthTracker call_depth_tracker(&call_depth_);
canceled_ = true; canceled_ = true;
controller_->CancelWithError(net_error); controller_->CancelWithError(net_error);
} }
......
...@@ -83,8 +83,8 @@ class TestResourceHandler : public ResourceHandler { ...@@ -83,8 +83,8 @@ class TestResourceHandler : public ResourceHandler {
void set_on_read_completed_result(bool on_read_completed_result) { void set_on_read_completed_result(bool on_read_completed_result) {
on_read_completed_result_ = on_read_completed_result; on_read_completed_result_ = on_read_completed_result;
} }
void set_on_on_read_eof_result(bool on_on_read_eof_result) { void set_on_read_eof_result(bool on_read_eof_result) {
on_on_read_eof_result_ = on_on_read_eof_result; on_read_eof_result_ = on_read_eof_result;
} }
// Cause |defer| to be set to true when the specified method is invoked. The // Cause |defer| to be set to true when the specified method is invoked. The
...@@ -146,6 +146,9 @@ class TestResourceHandler : public ResourceHandler { ...@@ -146,6 +146,9 @@ class TestResourceHandler : public ResourceHandler {
const std::string& body() const { return body_; } const std::string& body() const { return body_; }
net::URLRequestStatus final_status() const { return final_status_; } net::URLRequestStatus final_status() const { return final_status_; }
// Returns the current number of |this|'s methods on the callstack.
int call_depth() const { return call_depth_; }
// Spins the message loop until the request is deferred. Using this is // Spins the message loop until the request is deferred. Using this is
// optional, but if used, must use it exclusively to wait for the request. If // optional, but if used, must use it exclusively to wait for the request. If
// the request was deferred and then resumed/canceled without calling this // the request was deferred and then resumed/canceled without calling this
...@@ -169,7 +172,7 @@ class TestResourceHandler : public ResourceHandler { ...@@ -169,7 +172,7 @@ class TestResourceHandler : public ResourceHandler {
bool on_response_started_result_ = true; bool on_response_started_result_ = true;
bool on_will_read_result_ = true; bool on_will_read_result_ = true;
bool on_read_completed_result_ = true; bool on_read_completed_result_ = true;
bool on_on_read_eof_result_ = true; bool on_read_eof_result_ = true;
bool defer_on_will_start_ = false; bool defer_on_will_start_ = false;
bool defer_on_request_redirected_ = false; bool defer_on_request_redirected_ = false;
...@@ -198,6 +201,9 @@ class TestResourceHandler : public ResourceHandler { ...@@ -198,6 +201,9 @@ class TestResourceHandler : public ResourceHandler {
net::URLRequestStatus::FromError(net::ERR_UNEXPECTED); net::URLRequestStatus::FromError(net::ERR_UNEXPECTED);
bool canceled_ = false; bool canceled_ = false;
// Tracks recursive calls, which aren't allowed.
int call_depth_ = 0;
std::unique_ptr<base::RunLoop> deferred_run_loop_; std::unique_ptr<base::RunLoop> deferred_run_loop_;
base::RunLoop response_complete_run_loop_; base::RunLoop response_complete_run_loop_;
......
...@@ -44,21 +44,31 @@ class TestJobProtocolHandler : public URLRequestJobFactory::ProtocolHandler { ...@@ -44,21 +44,31 @@ class TestJobProtocolHandler : public URLRequestJobFactory::ProtocolHandler {
GURL URLRequestTestJob::test_url_1() { GURL URLRequestTestJob::test_url_1() {
return GURL("test:url1"); return GURL("test:url1");
} }
GURL URLRequestTestJob::test_url_2() { GURL URLRequestTestJob::test_url_2() {
return GURL("test:url2"); return GURL("test:url2");
} }
GURL URLRequestTestJob::test_url_3() { GURL URLRequestTestJob::test_url_3() {
return GURL("test:url3"); return GURL("test:url3");
} }
GURL URLRequestTestJob::test_url_4() { GURL URLRequestTestJob::test_url_4() {
return GURL("test:url4"); return GURL("test:url4");
} }
GURL URLRequestTestJob::test_url_auto_advance_async_reads_1() {
return GURL("test:url_auto_advance_async_reads_1");
}
GURL URLRequestTestJob::test_url_error() { GURL URLRequestTestJob::test_url_error() {
return GURL("test:error"); return GURL("test:error");
} }
GURL URLRequestTestJob::test_url_redirect_to_url_1() { GURL URLRequestTestJob::test_url_redirect_to_url_1() {
return GURL("test:redirect_to_1"); return GURL("test:redirect_to_1");
} }
GURL URLRequestTestJob::test_url_redirect_to_url_2() { GURL URLRequestTestJob::test_url_redirect_to_url_2() {
return GURL("test:redirect_to_2"); return GURL("test:redirect_to_2");
} }
...@@ -133,15 +143,7 @@ URLRequestTestJob::CreateProtocolHandler() { ...@@ -133,15 +143,7 @@ URLRequestTestJob::CreateProtocolHandler() {
URLRequestTestJob::URLRequestTestJob(URLRequest* request, URLRequestTestJob::URLRequestTestJob(URLRequest* request,
NetworkDelegate* network_delegate) NetworkDelegate* network_delegate)
: URLRequestJob(request, network_delegate), : URLRequestTestJob(request, network_delegate, false) {}
auto_advance_(false),
stage_(WAITING),
priority_(DEFAULT_PRIORITY),
offset_(0),
async_buf_(NULL),
async_buf_size_(0),
response_headers_length_(0),
weak_factory_(this) {}
URLRequestTestJob::URLRequestTestJob(URLRequest* request, URLRequestTestJob::URLRequestTestJob(URLRequest* request,
NetworkDelegate* network_delegate, NetworkDelegate* network_delegate,
...@@ -154,6 +156,7 @@ URLRequestTestJob::URLRequestTestJob(URLRequest* request, ...@@ -154,6 +156,7 @@ URLRequestTestJob::URLRequestTestJob(URLRequest* request,
async_buf_(NULL), async_buf_(NULL),
async_buf_size_(0), async_buf_size_(0),
response_headers_length_(0), response_headers_length_(0),
async_reads_(false),
weak_factory_(this) {} weak_factory_(this) {}
URLRequestTestJob::URLRequestTestJob(URLRequest* request, URLRequestTestJob::URLRequestTestJob(URLRequest* request,
...@@ -167,12 +170,13 @@ URLRequestTestJob::URLRequestTestJob(URLRequest* request, ...@@ -167,12 +170,13 @@ URLRequestTestJob::URLRequestTestJob(URLRequest* request,
priority_(DEFAULT_PRIORITY), priority_(DEFAULT_PRIORITY),
response_data_(response_data), response_data_(response_data),
offset_(0), offset_(0),
async_buf_(NULL), async_buf_(nullptr),
async_buf_size_(0), async_buf_size_(0),
response_headers_(new net::HttpResponseHeaders( response_headers_(new net::HttpResponseHeaders(
net::HttpUtil::AssembleRawHeaders(response_headers.c_str(), net::HttpUtil::AssembleRawHeaders(response_headers.c_str(),
response_headers.size()))), response_headers.size()))),
response_headers_length_(response_headers.size()), response_headers_length_(response_headers.size()),
async_reads_(false),
weak_factory_(this) {} weak_factory_(this) {}
URLRequestTestJob::~URLRequestTestJob() { URLRequestTestJob::~URLRequestTestJob() {
...@@ -204,18 +208,22 @@ void URLRequestTestJob::Start() { ...@@ -204,18 +208,22 @@ void URLRequestTestJob::Start() {
void URLRequestTestJob::StartAsync() { void URLRequestTestJob::StartAsync() {
if (!response_headers_.get()) { if (!response_headers_.get()) {
SetResponseHeaders(test_headers()); SetResponseHeaders(test_headers());
if (request_->url().spec() == test_url_1().spec()) { if (request_->url() == test_url_1()) {
response_data_ = test_data_1(); response_data_ = test_data_1();
stage_ = DATA_AVAILABLE; // Simulate a synchronous response for this one. stage_ = DATA_AVAILABLE; // Simulate a synchronous response for this one.
} else if (request_->url().spec() == test_url_2().spec()) { } else if (request_->url() == test_url_2()) {
response_data_ = test_data_2(); response_data_ = test_data_2();
} else if (request_->url().spec() == test_url_3().spec()) { } else if (request_->url() == test_url_3()) {
response_data_ = test_data_3(); response_data_ = test_data_3();
} else if (request_->url().spec() == test_url_4().spec()) { } else if (request_->url() == test_url_4()) {
response_data_ = test_data_4(); response_data_ = test_data_4();
} else if (request_->url().spec() == test_url_redirect_to_url_1().spec()) { } else if (request_->url() == test_url_auto_advance_async_reads_1()) {
response_data_ = test_data_1();
stage_ = DATA_AVAILABLE; // Data is available immediately.
async_reads_ = true; // All reads complete asynchronously.
} else if (request_->url() == test_url_redirect_to_url_1()) {
SetResponseHeaders(test_redirect_to_url_1_headers()); SetResponseHeaders(test_redirect_to_url_1_headers());
} else if (request_->url().spec() == test_url_redirect_to_url_2().spec()) { } else if (request_->url() == test_url_redirect_to_url_2()) {
SetResponseHeaders(test_redirect_to_url_2_headers()); SetResponseHeaders(test_redirect_to_url_2_headers());
} else { } else {
AdvanceJob(); AdvanceJob();
...@@ -243,24 +251,33 @@ void URLRequestTestJob::SetResponseHeaders( ...@@ -243,24 +251,33 @@ void URLRequestTestJob::SetResponseHeaders(
response_headers_length_ = response_headers.size(); response_headers_length_ = response_headers.size();
} }
int URLRequestTestJob::CopyDataForRead(IOBuffer* buf, int buf_size) {
int bytes_read = 0;
if (offset_ < static_cast<int>(response_data_.length())) {
bytes_read = buf_size;
if (bytes_read + offset_ > static_cast<int>(response_data_.length()))
bytes_read = static_cast<int>(response_data_.length()) - offset_;
memcpy(buf->data(), &response_data_.c_str()[offset_], bytes_read);
offset_ += bytes_read;
}
return bytes_read;
}
int URLRequestTestJob::ReadRawData(IOBuffer* buf, int buf_size) { int URLRequestTestJob::ReadRawData(IOBuffer* buf, int buf_size) {
if (stage_ == WAITING) { if (stage_ == WAITING || async_reads_) {
async_buf_ = buf; async_buf_ = buf;
async_buf_size_ = buf_size; async_buf_size_ = buf_size;
if (stage_ != WAITING) {
stage_ = WAITING;
base::ThreadTaskRunnerHandle::Get()->PostTask(
FROM_HERE, base::Bind(&URLRequestTestJob::ProcessNextOperation,
weak_factory_.GetWeakPtr()));
}
return ERR_IO_PENDING; return ERR_IO_PENDING;
} }
if (offset_ >= static_cast<int>(response_data_.length())) return CopyDataForRead(buf, buf_size);
return 0; // done reading
int to_read = buf_size;
if (to_read + offset_ > static_cast<int>(response_data_.length()))
to_read = static_cast<int>(response_data_.length()) - offset_;
memcpy(buf->data(), &response_data_.c_str()[offset_], to_read);
offset_ += to_read;
return to_read;
} }
void URLRequestTestJob::GetResponseInfo(HttpResponseInfo* info) { void URLRequestTestJob::GetResponseInfo(HttpResponseInfo* info) {
...@@ -322,7 +339,7 @@ void URLRequestTestJob::ProcessNextOperation() { ...@@ -322,7 +339,7 @@ void URLRequestTestJob::ProcessNextOperation() {
stage_ = DATA_AVAILABLE; stage_ = DATA_AVAILABLE;
// OK if ReadRawData wasn't called yet. // OK if ReadRawData wasn't called yet.
if (async_buf_) { if (async_buf_) {
int result = ReadRawData(async_buf_, async_buf_size_); int result = CopyDataForRead(async_buf_, async_buf_size_);
if (result < 0) if (result < 0)
NOTREACHED() << "Reads should not fail in DATA_AVAILABLE."; NOTREACHED() << "Reads should not fail in DATA_AVAILABLE.";
if (NextReadAsync()) { if (NextReadAsync()) {
......
...@@ -63,13 +63,28 @@ class NET_EXPORT_PRIVATE URLRequestTestJob : public URLRequestJob { ...@@ -63,13 +63,28 @@ class NET_EXPORT_PRIVATE URLRequestTestJob : public URLRequestJob {
// The canned URLs this handler will respond to without having been // The canned URLs this handler will respond to without having been
// explicitly initialized with response headers and data. // explicitly initialized with response headers and data.
// FIXME(brettw): we should probably also have a redirect one
// URL that, by default, automatically advances through each state. Reads
// complete synchronously.
static GURL test_url_1(); static GURL test_url_1();
// URLs that, by default, must be manually advanced through each state.
static GURL test_url_2(); static GURL test_url_2();
static GURL test_url_3(); static GURL test_url_3();
static GURL test_url_4(); static GURL test_url_4();
// URL that, by default, automatically advances through each state. Reads
// complete asynchronously. Has same response body as test_url_1(), which is
// (test_data_1()).
static GURL test_url_auto_advance_async_reads_1();
// URL that fails with ERR_INVALID_URL.
static GURL test_url_error(); static GURL test_url_error();
// Redirects to test_url_1().
static GURL test_url_redirect_to_url_1(); static GURL test_url_redirect_to_url_1();
// Redirects to test_url_2().
static GURL test_url_redirect_to_url_2(); static GURL test_url_redirect_to_url_2();
// The data that corresponds to each of the URLs above // The data that corresponds to each of the URLs above
...@@ -151,6 +166,10 @@ class NET_EXPORT_PRIVATE URLRequestTestJob : public URLRequestJob { ...@@ -151,6 +166,10 @@ class NET_EXPORT_PRIVATE URLRequestTestJob : public URLRequestJob {
// Assigns |response_headers_| and |response_headers_length_|. // Assigns |response_headers_| and |response_headers_length_|.
void SetResponseHeaders(const std::string& response_headers); void SetResponseHeaders(const std::string& response_headers);
// Copies as much of the response body as will into |buf|, and returns number
// of bytes written.
int CopyDataForRead(IOBuffer* buf, int buf_size);
bool auto_advance_; bool auto_advance_;
Stage stage_; Stage stage_;
...@@ -178,6 +197,8 @@ class NET_EXPORT_PRIVATE URLRequestTestJob : public URLRequestJob { ...@@ -178,6 +197,8 @@ class NET_EXPORT_PRIVATE URLRequestTestJob : public URLRequestJob {
// Original size in bytes of the response headers before decoding. // Original size in bytes of the response headers before decoding.
int response_headers_length_; int response_headers_length_;
bool async_reads_;
base::WeakPtrFactory<URLRequestTestJob> weak_factory_; base::WeakPtrFactory<URLRequestTestJob> weak_factory_;
}; };
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment