Index: net/url_request/report_sender_unittest.cc |
diff --git a/net/url_request/report_sender_unittest.cc b/net/url_request/report_sender_unittest.cc |
index 3865730ea088ae8b0a3b6665b5fbf5f82234b9fe..a4243cf7a552296a12cf40be85361e9a970fbfec 100644 |
--- a/net/url_request/report_sender_unittest.cc |
+++ b/net/url_request/report_sender_unittest.cc |
@@ -14,8 +14,11 @@ |
#include "net/base/upload_bytes_element_reader.h" |
#include "net/base/upload_data_stream.h" |
#include "net/base/upload_element_reader.h" |
+#include "net/http/http_response_headers.h" |
+#include "net/http/http_status_code.h" |
#include "net/test/url_request/url_request_failed_job.h" |
#include "net/test/url_request/url_request_mock_data_job.h" |
+#include "net/test/url_request/url_request_mock_http_job.h" |
#include "net/url_request/url_request_filter.h" |
#include "net/url_request/url_request_test_util.h" |
#include "testing/gtest/include/gtest/gtest.h" |
@@ -25,6 +28,7 @@ namespace { |
const char kDummyReport[] = "foo.test"; |
const char kSecondDummyReport[] = "foo2.test"; |
+const char kServerErrorHostname[] = "mock.server.error"; |
void MarkURLRequestDestroyed(bool* url_request_destroyed) { |
*url_request_destroyed = true; |
@@ -47,10 +51,24 @@ void CheckUploadData(const URLRequest& request, |
EXPECT_EQ(1u, expect_reports->erase(upload_data)); |
} |
-// Provides an error callback for report sending that sets |called| to |
-// true. |
-void ErrorCallback(bool* called, const GURL& report_uri, int net_error) { |
+// Error callback for a report with a net error. |
+void ErrorCallback(bool* called, |
+ const GURL& report_uri, |
+ int net_error, |
+ int http_response_code) { |
EXPECT_NE(OK, net_error); |
+ EXPECT_EQ(-1, http_response_code); |
+ *called = true; |
+} |
+ |
+// Error callback for a report with a non-200 HTTP response code and no net |
+// errors. |
+void ServerErrorResponseCallback(bool* called, |
+ const GURL& report_uri, |
+ int net_error, |
+ int http_response_code) { |
+ EXPECT_EQ(OK, net_error); |
+ EXPECT_EQ(HTTP_INTERNAL_SERVER_ERROR, http_response_code); |
*called = true; |
} |
@@ -58,6 +76,41 @@ void SuccessCallback(bool* called) { |
*called = true; |
} |
+// URLRequestJob that returns an HTTP 500 response. |
+class MockServerErrorJob : public URLRequestJob { |
+ public: |
+ MockServerErrorJob(URLRequest* request, NetworkDelegate* network_delegate) |
+ : URLRequestJob(request, network_delegate) {} |
+ ~MockServerErrorJob() override {} |
+ |
+ protected: |
+ void GetResponseInfo(HttpResponseInfo* info) override { |
+ info->headers = new HttpResponseHeaders( |
+ "HTTP/1.1 500 Internal Server Error\n" |
+ "Content-type: text/plain\n" |
+ "Content-Length: 0\n"); |
+ } |
+ void Start() override { NotifyHeadersComplete(); } |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(MockServerErrorJob); |
+}; |
+ |
+class MockServerErrorJobInterceptor : public URLRequestInterceptor { |
+ public: |
+ MockServerErrorJobInterceptor() {} |
+ ~MockServerErrorJobInterceptor() override {} |
+ |
+ URLRequestJob* MaybeInterceptRequest( |
+ URLRequest* request, |
+ NetworkDelegate* network_delegate) const override { |
+ return new MockServerErrorJob(request, network_delegate); |
+ } |
+ |
+ private: |
+ DISALLOW_COPY_AND_ASSIGN(MockServerErrorJobInterceptor); |
+}; |
+ |
// A network delegate that lets tests check that a report |
// was sent. It counts the number of requests and lets tests register a |
// callback to run when the request is destroyed. It also checks that |
@@ -152,6 +205,10 @@ class ReportSenderTest : public ::testing::Test { |
void SetUp() override { |
URLRequestFailedJob::AddUrlHandler(); |
URLRequestMockDataJob::AddUrlHandler(); |
+ URLRequestFilter::GetInstance()->AddHostnameInterceptor( |
+ "http", kServerErrorHostname, |
+ std::unique_ptr<URLRequestInterceptor>( |
+ new MockServerErrorJobInterceptor())); |
} |
void TearDown() override { URLRequestFilter::GetInstance()->ClearHandlers(); } |
@@ -165,7 +222,7 @@ class ReportSenderTest : public ::testing::Test { |
const GURL& url, |
size_t request_sequence_number, |
const base::Callback<void()>& success_callback, |
- const base::Callback<void(const GURL&, int)>& error_callback) { |
+ const base::Callback<void(const GURL&, int, int)>& error_callback) { |
base::RunLoop run_loop; |
network_delegate_.set_url_request_destroyed_callback( |
run_loop.QuitClosure()); |
@@ -191,8 +248,9 @@ class ReportSenderTest : public ::testing::Test { |
const std::string& report, |
const GURL& url, |
size_t request_sequence_number) { |
- SendReport(reporter, report, url, request_sequence_number, base::Closure(), |
- base::Callback<void(const GURL&, int)>()); |
+ SendReport(reporter, report, url, request_sequence_number, |
+ base::Callback<void()>(), |
+ base::Callback<void(const GURL&, int, int)>()); |
} |
TestReportSenderNetworkDelegate network_delegate_; |
@@ -231,10 +289,12 @@ TEST_F(ReportSenderTest, SendMultipleReportsSimultaneously) { |
EXPECT_EQ(0u, network_delegate_.num_requests()); |
- reporter.Send(url, "application/foobar", kDummyReport, base::Closure(), |
- base::Callback<void(const GURL&, int)>()); |
- reporter.Send(url, "application/foobar", kSecondDummyReport, base::Closure(), |
- base::Callback<void(const GURL&, int)>()); |
+ reporter.Send(url, "application/foobar", kDummyReport, |
+ base::Callback<void()>(), |
+ base::Callback<void(const GURL&, int, int)>()); |
+ reporter.Send(url, "application/foobar", kSecondDummyReport, |
+ base::Callback<void()>(), |
+ base::Callback<void(const GURL&, int, int)>()); |
run_loop.Run(); |
@@ -258,8 +318,9 @@ TEST_F(ReportSenderTest, PendingRequestGetsDeleted) { |
std::unique_ptr<ReportSender> reporter( |
new ReportSender(context(), ReportSender::DO_NOT_SEND_COOKIES)); |
- reporter->Send(url, "application/foobar", kDummyReport, base::Closure(), |
- base::Callback<void(const GURL&, int)>()); |
+ reporter->Send(url, "application/foobar", kDummyReport, |
+ base::Callback<void()>(), |
+ base::Callback<void(const GURL&, int, int)>()); |
reporter.reset(); |
EXPECT_EQ(1u, network_delegate_.num_requests()); |
@@ -279,7 +340,7 @@ TEST_F(ReportSenderTest, ErroredRequestGetsDeleted) { |
TEST_F(ReportSenderTest, ErroredRequestCallsErrorCallback) { |
bool error_callback_called = false; |
bool success_callback_called = false; |
- GURL url = URLRequestFailedJob::GetMockHttpsUrl(ERR_FAILED); |
+ const GURL url = URLRequestFailedJob::GetMockHttpsUrl(ERR_FAILED); |
ReportSender reporter(context(), ReportSender::DO_NOT_SEND_COOKIES); |
// SendReport will block until the URLRequest is destroyed. |
SendReport(&reporter, kDummyReport, url, 0, |
@@ -289,12 +350,28 @@ TEST_F(ReportSenderTest, ErroredRequestCallsErrorCallback) { |
EXPECT_FALSE(success_callback_called); |
} |
+// Test that the error callback, if provided, gets called when a request |
+// finishes successfully but results in a server error, and the success callback |
+// doesn't get called. |
+TEST_F(ReportSenderTest, BadResponseCodeCallsErrorCallback) { |
+ bool error_callback_called = false; |
+ bool success_callback_called = false; |
+ const GURL url(std::string("http://") + kServerErrorHostname); |
+ ReportSender reporter(context(), ReportSender::DO_NOT_SEND_COOKIES); |
+ // SendReport will block until the URLRequest is destroyed. |
+ SendReport(&reporter, kDummyReport, url, 0, |
+ base::Bind(SuccessCallback, &success_callback_called), |
+ base::Bind(ServerErrorResponseCallback, &error_callback_called)); |
+ EXPECT_TRUE(error_callback_called); |
+ EXPECT_FALSE(success_callback_called); |
+} |
+ |
// Test that the error callback does not get called and the success callback |
/// gets called when a request does not return an error. |
TEST_F(ReportSenderTest, SuccessfulRequestCallsSuccessCallback) { |
bool error_callback_called = false; |
bool success_callback_called = false; |
- GURL url = URLRequestMockDataJob::GetMockHttpsUrl("dummy data", 1); |
+ const GURL url = URLRequestMockDataJob::GetMockHttpsUrl("dummy data", 1); |
ReportSender reporter(context(), ReportSender::DO_NOT_SEND_COOKIES); |
SendReport(&reporter, kDummyReport, url, 0, |
base::Bind(SuccessCallback, &success_callback_called), |