Migrate FeedbackUploader to SimpleURLLoader.
This is a copy of https://crrev.com/c/1067424 but with tests fixed.
Bug: 844932
Change-Id: I77239bf76a673b33d56b8b7fe584a78ec319bc24
Reviewed-on: https://chromium-review.googlesource.com/1114253
Commit-Queue: Robbie McElrath <[email protected]>
Reviewed-by: Matt Menke <[email protected]>
Reviewed-by: Ahmed Fakhry <[email protected]>
Reviewed-by: Trent Apted <[email protected]>
Cr-Commit-Position: refs/heads/master@{#573467}
diff --git a/components/feedback/BUILD.gn b/components/feedback/BUILD.gn
index a3fa1d10..9278c2fb 100644
--- a/components/feedback/BUILD.gn
+++ b/components/feedback/BUILD.gn
@@ -16,8 +16,6 @@
"feedback_switches.h",
"feedback_uploader.cc",
"feedback_uploader.h",
- "feedback_uploader_delegate.cc",
- "feedback_uploader_delegate.h",
"feedback_uploader_factory.cc",
"feedback_uploader_factory.h",
"feedback_util.cc",
@@ -40,6 +38,7 @@
"//content/public/browser",
"//content/public/common",
"//net",
+ "//services/network/public/cpp",
"//third_party/re2",
"//third_party/zlib/google:zip",
]
@@ -65,6 +64,8 @@
"//components/variations/net",
"//content/test:test_support",
"//net:test_support",
+ "//services/network:test_support",
+ "//services/network/public/cpp",
"//testing/gmock",
"//testing/gtest",
]
diff --git a/components/feedback/DEPS b/components/feedback/DEPS
index 2d72d20..5d02e2060 100644
--- a/components/feedback/DEPS
+++ b/components/feedback/DEPS
@@ -11,6 +11,9 @@
"+net/base",
"+net/traffic_annotation",
"+net/url_request",
+ "+net/http",
+ "+services/network/public/cpp",
+ "+services/network/test",
"+third_party/re2",
"+third_party/zlib/google",
]
diff --git a/components/feedback/feedback_data_unittest.cc b/components/feedback/feedback_data_unittest.cc
index 06fb1ff..d5e7baf 100644
--- a/components/feedback/feedback_data_unittest.cc
+++ b/components/feedback/feedback_data_unittest.cc
@@ -14,6 +14,9 @@
#include "components/prefs/testing_pref_service.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
+#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace feedback {
@@ -26,18 +29,21 @@
class MockUploader : public FeedbackUploader {
public:
- MockUploader(content::BrowserContext* context,
- const base::Closure& on_report_sent)
- : FeedbackUploader(context,
+ MockUploader(
+ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+ content::BrowserContext* context,
+ base::OnceClosure on_report_sent)
+ : FeedbackUploader(url_loader_factory,
+ context,
FeedbackUploaderFactory::CreateUploaderTaskRunner()),
- on_report_sent_(on_report_sent) {}
+ on_report_sent_(std::move(on_report_sent)) {}
~MockUploader() override {}
// feedback::FeedbackUploader:
- void StartDispatchingReport() override { on_report_sent_.Run(); }
+ void StartDispatchingReport() override { std::move(on_report_sent_).Run(); }
private:
- base::Closure on_report_sent_;
+ base::OnceClosure on_report_sent_;
DISALLOW_COPY_AND_ASSIGN(MockUploader);
};
@@ -51,9 +57,13 @@
class FeedbackDataTest : public testing::Test {
protected:
FeedbackDataTest()
- : uploader_(&context_,
- base::Bind(&FeedbackDataTest::set_send_report_callback,
- base::Unretained(this))),
+ : test_shared_loader_factory_(
+ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
+ &test_url_loader_factory_)),
+ uploader_(test_shared_loader_factory_,
+ &context_,
+ base::BindOnce(&FeedbackDataTest::set_send_report_callback,
+ base::Unretained(this))),
data_(base::MakeRefCounted<FeedbackData>(&uploader_)) {}
~FeedbackDataTest() override = default;
@@ -79,6 +89,8 @@
base::Closure quit_closure_;
std::unique_ptr<base::RunLoop> run_loop_;
content::TestBrowserThreadBundle test_browser_thread_bundle_;
+ network::TestURLLoaderFactory test_url_loader_factory_;
+ scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
content::TestBrowserContext context_;
MockUploader uploader_;
scoped_refptr<FeedbackData> data_;
diff --git a/components/feedback/feedback_uploader.cc b/components/feedback/feedback_uploader.cc
index 6b70f3a..77bae900 100644
--- a/components/feedback/feedback_uploader.cc
+++ b/components/feedback/feedback_uploader.cc
@@ -9,12 +9,14 @@
#include "components/data_use_measurement/core/data_use_user_data.h"
#include "components/feedback/feedback_report.h"
#include "components/feedback/feedback_switches.h"
-#include "components/feedback/feedback_uploader_delegate.h"
#include "components/variations/net/variations_http_headers.h"
#include "content/public/browser/browser_context.h"
#include "content/public/browser/storage_partition.h"
#include "net/base/load_flags.h"
#include "net/url_request/url_fetcher.h"
+#include "services/network/public/cpp/resource_request.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/cpp/simple_url_loader.h"
namespace feedback {
@@ -28,6 +30,11 @@
constexpr char kProtoBufMimeType[] = "application/x-protobuf";
+constexpr int kHttpPostSuccessNoContent = 204;
+constexpr int kHttpPostFailNoConnection = -1;
+constexpr int kHttpPostFailClientError = 400;
+constexpr int kHttpPostFailServerError = 500;
+
// The minimum time to wait before uploading reports are retried. Exponential
// backoff delay is applied on successive failures.
// This value can be overriden by tests by calling
@@ -53,9 +60,11 @@
} // namespace
FeedbackUploader::FeedbackUploader(
+ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
content::BrowserContext* context,
scoped_refptr<base::SingleThreadTaskRunner> task_runner)
- : context_(context),
+ : url_loader_factory_(std::move(url_loader_factory)),
+ context_(context),
feedback_reports_path_(GetPathFromContext(context)),
task_runner_(task_runner),
feedback_post_url_(GetFeedbackPostGURL()),
@@ -116,7 +125,7 @@
}
void FeedbackUploader::AppendExtraHeadersToUploadRequest(
- net::URLFetcher* fetcher) {}
+ network::ResourceRequest* resource_request) {}
void FeedbackUploader::DispatchReport() {
net::NetworkTrafficAnnotationTag traffic_annotation =
@@ -148,39 +157,80 @@
"by direct user request."
policy_exception_justification: "Not implemented."
})");
- // Note: FeedbackUploaderDelegate deletes itself and the fetcher.
- net::URLFetcher* fetcher =
- net::URLFetcher::Create(
- feedback_post_url_, net::URLFetcher::POST,
- new FeedbackUploaderDelegate(
- base::Bind(&FeedbackUploader::OnReportUploadSuccess, AsWeakPtr()),
- base::Bind(&FeedbackUploader::OnReportUploadFailure,
- AsWeakPtr())),
- traffic_annotation)
- .release();
- data_use_measurement::DataUseUserData::AttachToFetcher(
- fetcher, data_use_measurement::DataUseUserData::FEEDBACK_UPLOADER);
+ auto resource_request = std::make_unique<network::ResourceRequest>();
+ resource_request->url = feedback_post_url_;
+ resource_request->load_flags =
+ net::LOAD_DO_NOT_SAVE_COOKIES | net::LOAD_DO_NOT_SEND_COOKIES;
+ resource_request->method = "POST";
+
// Tell feedback server about the variation state of this install.
- net::HttpRequestHeaders headers;
// Note: It's OK to pass SignedIn::kNo if it's unknown, as it does not affect
// transmission of experiments coming from the variations server.
- variations::AppendVariationHeaders(fetcher->GetOriginalURL(),
- context_->IsOffTheRecord()
- ? variations::InIncognito::kYes
- : variations::InIncognito::kNo,
- variations::SignedIn::kNo, &headers);
- fetcher->SetExtraRequestHeaders(headers.ToString());
+ variations::AppendVariationHeaders(
+ feedback_post_url_,
+ context_->IsOffTheRecord() ? variations::InIncognito::kYes
+ : variations::InIncognito::kNo,
+ variations::SignedIn::kNo, &resource_request->headers);
- fetcher->SetUploadData(kProtoBufMimeType, report_being_dispatched_->data());
- fetcher->SetRequestContext(
- content::BrowserContext::GetDefaultStoragePartition(context_)
- ->GetURLRequestContext());
+ AppendExtraHeadersToUploadRequest(resource_request.get());
- AppendExtraHeadersToUploadRequest(fetcher);
+ std::unique_ptr<network::SimpleURLLoader> simple_url_loader =
+ network::SimpleURLLoader::Create(std::move(resource_request),
+ traffic_annotation);
+ network::SimpleURLLoader* simple_url_loader_ptr = simple_url_loader.get();
+ simple_url_loader->AttachStringForUpload(report_being_dispatched_->data(),
+ kProtoBufMimeType);
+ auto it = uploads_in_progress_.insert(uploads_in_progress_.begin(),
+ std::move(simple_url_loader));
+ // TODO(https://crbug.com/808498): Re-add data use measurement once
+ // SimpleURLLoader supports it.
+ // ID=data_use_measurement::DataUseUserData::FEEDBACK_UPLOADER
+ simple_url_loader_ptr->DownloadToStringOfUnboundedSizeUntilCrashAndDie(
+ url_loader_factory_.get(),
+ base::BindOnce(&FeedbackUploader::OnDispatchComplete,
+ base::Unretained(this), std::move(it)));
+}
- fetcher->SetLoadFlags(net::LOAD_DO_NOT_SAVE_COOKIES |
- net::LOAD_DO_NOT_SEND_COOKIES);
- fetcher->Start();
+void FeedbackUploader::OnDispatchComplete(
+ UrlLoaderList::iterator it,
+ std::unique_ptr<std::string> response_body) {
+ std::stringstream error_stream;
+ network::SimpleURLLoader* simple_url_loader = it->get();
+ int response_code = kHttpPostFailNoConnection;
+ if (simple_url_loader->ResponseInfo() &&
+ simple_url_loader->ResponseInfo()->headers) {
+ response_code = simple_url_loader->ResponseInfo()->headers->response_code();
+ }
+ if (response_code == kHttpPostSuccessNoContent) {
+ error_stream << "Success";
+ OnReportUploadSuccess();
+ } else {
+ bool should_retry = true;
+ // Process the error for debug output
+ if (response_code == kHttpPostFailNoConnection) {
+ error_stream << "No connection to server.";
+ } else if ((response_code >= kHttpPostFailClientError) &&
+ (response_code < kHttpPostFailServerError)) {
+ // Client errors mean that the server failed to parse the proto that was
+ // sent, or that some requirements weren't met by the server side
+ // validation, and hence we should NOT retry sending this corrupt report
+ // and give up.
+ should_retry = false;
+
+ error_stream << "Client error: HTTP response code " << response_code;
+ } else if (response_code >= kHttpPostFailServerError) {
+ error_stream << "Server error: HTTP response code " << response_code;
+ } else {
+ error_stream << "Unknown error: HTTP response code " << response_code;
+ }
+
+ OnReportUploadFailure(should_retry);
+ }
+
+ LOG(WARNING) << "FEEDBACK: Submission to feedback server ("
+ << simple_url_loader->GetFinalURL()
+ << ") status: " << error_stream.str();
+ uploads_in_progress_.erase(it);
}
void FeedbackUploader::UpdateUploadTimer() {
diff --git a/components/feedback/feedback_uploader.h b/components/feedback/feedback_uploader.h
index 1c500fe..816fa25 100644
--- a/components/feedback/feedback_uploader.h
+++ b/components/feedback/feedback_uploader.h
@@ -5,6 +5,7 @@
#ifndef COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_H_
#define COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_H_
+#include <list>
#include <queue>
#include <vector>
@@ -22,9 +23,11 @@
class BrowserContext;
} // namespace content
-namespace net {
-class URLFetcher;
-} // namespace net
+namespace network {
+struct ResourceRequest;
+class SimpleURLLoader;
+class SharedURLLoaderFactory;
+} // namespace network
namespace feedback {
@@ -36,8 +39,10 @@
class FeedbackUploader : public KeyedService,
public base::SupportsWeakPtr<FeedbackUploader> {
public:
- FeedbackUploader(content::BrowserContext* context,
- scoped_refptr<base::SingleThreadTaskRunner> task_runner);
+ FeedbackUploader(
+ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+ content::BrowserContext* context,
+ scoped_refptr<base::SingleThreadTaskRunner> task_runner);
~FeedbackUploader() override;
static void SetMinimumRetryDelayForTesting(base::TimeDelta delay);
@@ -84,6 +89,9 @@
private:
friend class FeedbackUploaderTest;
+ // This is a std::list so that iterators remain valid during modifications.
+ using UrlLoaderList = std::list<std::unique_ptr<network::SimpleURLLoader>>;
+
struct ReportsUploadTimeComparator {
bool operator()(const scoped_refptr<FeedbackReport>& a,
const scoped_refptr<FeedbackReport>& b) const;
@@ -91,19 +99,26 @@
// Called from DispatchReport() to give implementers a chance to add extra
// headers to the upload request before it's sent.
- virtual void AppendExtraHeadersToUploadRequest(net::URLFetcher* fetcher);
+ virtual void AppendExtraHeadersToUploadRequest(
+ network::ResourceRequest* resource_request);
// Uploads the |report_being_dispatched_| to be uploaded. It must
// call either OnReportUploadSuccess() or OnReportUploadFailure() so that
// dispatching reports can progress.
void DispatchReport();
+ void OnDispatchComplete(UrlLoaderList::iterator it,
+ std::unique_ptr<std::string> response_body);
+
// Update our timer for uploading the next report.
void UpdateUploadTimer();
void QueueReportWithDelay(std::unique_ptr<std::string> data,
base::TimeDelta delay);
+ // URLLoaderFactory used for network requests.
+ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory_;
+
// Browser context this uploader was created for.
content::BrowserContext* context_;
@@ -132,6 +147,8 @@
// at-a-time should be dispatched.
bool is_dispatching_;
+ UrlLoaderList uploads_in_progress_;
+
DISALLOW_COPY_AND_ASSIGN(FeedbackUploader);
};
diff --git a/components/feedback/feedback_uploader_delegate.cc b/components/feedback/feedback_uploader_delegate.cc
deleted file mode 100644
index fd7e475a..0000000
--- a/components/feedback/feedback_uploader_delegate.cc
+++ /dev/null
@@ -1,71 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "components/feedback/feedback_uploader_delegate.h"
-
-#include <memory>
-#include <sstream>
-
-#include "base/logging.h"
-#include "components/feedback/feedback_report.h"
-#include "net/url_request/url_fetcher.h"
-
-namespace feedback {
-
-namespace {
-
-constexpr int kHttpPostSuccessNoContent = 204;
-constexpr int kHttpPostFailNoConnection = -1;
-constexpr int kHttpPostFailClientError = 400;
-constexpr int kHttpPostFailServerError = 500;
-
-} // namespace
-
-FeedbackUploaderDelegate::FeedbackUploaderDelegate(
- const base::Closure& success_callback,
- const ReportFailureCallback& error_callback)
- : success_callback_(success_callback), error_callback_(error_callback) {}
-
-FeedbackUploaderDelegate::~FeedbackUploaderDelegate() {}
-
-void FeedbackUploaderDelegate::OnURLFetchComplete(
- const net::URLFetcher* source) {
- std::unique_ptr<const net::URLFetcher> source_scoper(source);
-
- std::stringstream error_stream;
- int response_code = source->GetResponseCode();
- if (response_code == kHttpPostSuccessNoContent) {
- error_stream << "Success";
- success_callback_.Run();
- } else {
- bool should_retry = true;
- // Process the error for debug output
- if (response_code == kHttpPostFailNoConnection) {
- error_stream << "No connection to server.";
- } else if ((response_code >= kHttpPostFailClientError) &&
- (response_code < kHttpPostFailServerError)) {
- // Client errors mean that the server failed to parse the proto that was
- // sent, or that some requirements weren't met by the server side
- // validation, and hence we should NOT retry sending this corrupt report
- // and give up.
- should_retry = false;
-
- error_stream << "Client error: HTTP response code " << response_code;
- } else if (response_code >= kHttpPostFailServerError) {
- error_stream << "Server error: HTTP response code " << response_code;
- } else {
- error_stream << "Unknown error: HTTP response code " << response_code;
- }
-
- error_callback_.Run(should_retry);
- }
-
- LOG(WARNING) << "FEEDBACK: Submission to feedback server ("
- << source->GetURL() << ") status: " << error_stream.str();
-
- // This instance won't be used for anything else, delete us.
- delete this;
-}
-
-} // namespace feedback
diff --git a/components/feedback/feedback_uploader_delegate.h b/components/feedback/feedback_uploader_delegate.h
deleted file mode 100644
index 817b53f..0000000
--- a/components/feedback/feedback_uploader_delegate.h
+++ /dev/null
@@ -1,43 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_DELEGATE_H_
-#define COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_DELEGATE_H_
-
-#include "base/callback.h"
-#include "base/macros.h"
-#include "base/memory/ref_counted.h"
-#include "components/feedback/feedback_uploader.h"
-#include "net/url_request/url_fetcher_delegate.h"
-
-namespace feedback {
-
-// Type of the callback that gets invoked when uploading a feedback report
-// fails. |should_retry| is set to true when it's OK to retry sending the
-// report; e.g. when the failure is not a client error and retries is likely to
-// fail again.
-using ReportFailureCallback = base::Callback<void(bool should_retry)>;
-
-// FeedbackUploaderDelegate is a simple HTTP uploader for a feedback report.
-// When finished, it runs the appropriate callback passed in via the
-// constructor, and then deletes itself.
-class FeedbackUploaderDelegate : public net::URLFetcherDelegate {
- public:
- FeedbackUploaderDelegate(const base::Closure& success_callback,
- const ReportFailureCallback& error_callback);
- ~FeedbackUploaderDelegate() override;
-
- private:
- // Overridden from net::URLFetcherDelegate.
- void OnURLFetchComplete(const net::URLFetcher* source) override;
-
- base::Closure success_callback_;
- ReportFailureCallback error_callback_;
-
- DISALLOW_COPY_AND_ASSIGN(FeedbackUploaderDelegate);
-};
-
-} // namespace feedback
-
-#endif // COMPONENTS_FEEDBACK_FEEDBACK_UPLOADER_DELEGATE_H_
diff --git a/components/feedback/feedback_uploader_dispatch_unittest.cc b/components/feedback/feedback_uploader_dispatch_unittest.cc
index 300d3d70..351a07c 100644
--- a/components/feedback/feedback_uploader_dispatch_unittest.cc
+++ b/components/feedback/feedback_uploader_dispatch_unittest.cc
@@ -11,13 +11,16 @@
#include "base/run_loop.h"
#include "base/task_scheduler/post_task.h"
#include "base/task_scheduler/task_traits.h"
+#include "base/test/bind_test_util.h"
#include "components/feedback/feedback_uploader_factory.h"
#include "components/variations/variations_associated_data.h"
#include "components/variations/variations_http_header_provider.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
-#include "net/url_request/test_url_fetcher_factory.h"
-#include "net/url_request/url_fetcher_delegate.h"
+#include "net/http/http_util.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
+#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace feedback {
@@ -27,9 +30,8 @@
constexpr base::TimeDelta kTestRetryDelay =
base::TimeDelta::FromMilliseconds(1);
-constexpr int kHttpPostSuccessNoContent = 204;
-constexpr int kHttpPostFailClientError = 400;
-constexpr int kHttpPostFailServerError = 500;
+constexpr char kFeedbackPostUrl[] =
+ "https://www.google.com/tools/feedback/chrome/__submit";
void QueueReport(FeedbackUploader* uploader, const std::string& report_data) {
uploader->QueueReport(std::make_unique<std::string>(report_data));
@@ -40,7 +42,10 @@
class FeedbackUploaderDispatchTest : public ::testing::Test {
protected:
FeedbackUploaderDispatchTest()
- : browser_thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP) {}
+ : browser_thread_bundle_(content::TestBrowserThreadBundle::IO_MAINLOOP),
+ shared_url_loader_factory_(
+ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
+ &test_url_loader_factory_)) {}
~FeedbackUploaderDispatchTest() override {
// Clean up registered ids.
@@ -58,11 +63,21 @@
base::FieldTrialList::CreateFieldTrial(trial_name, group_name)->group();
}
+ scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory() {
+ return shared_url_loader_factory_;
+ }
+
+ network::TestURLLoaderFactory* test_url_loader_factory() {
+ return &test_url_loader_factory_;
+ }
+
content::BrowserContext* context() { return &context_; }
private:
content::TestBrowserThreadBundle browser_thread_bundle_;
content::TestBrowserContext context_;
+ network::TestURLLoaderFactory test_url_loader_factory_;
+ scoped_refptr<network::SharedURLLoaderFactory> shared_url_loader_factory_;
DISALLOW_COPY_AND_ASSIGN(FeedbackUploaderDispatchTest);
};
@@ -76,54 +91,89 @@
CreateFieldTrialWithId("Test", "Group1", 123);
FeedbackUploader uploader(
- context(), FeedbackUploaderFactory::CreateUploaderTaskRunner());
+ shared_url_loader_factory(), context(),
+ FeedbackUploaderFactory::CreateUploaderTaskRunner());
- net::TestURLFetcherFactory factory;
- QueueReport(&uploader, "test");
-
- net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
net::HttpRequestHeaders headers;
- fetcher->GetExtraRequestHeaders(&headers);
+ test_url_loader_factory()->SetInterceptor(
+ base::BindLambdaForTesting([&](const network::ResourceRequest& request) {
+ headers = request.headers;
+ }));
+
+ QueueReport(&uploader, "test");
+ base::RunLoop().RunUntilIdle();
+
std::string value;
EXPECT_TRUE(headers.GetHeader("X-Client-Data", &value));
EXPECT_FALSE(value.empty());
- // The fetcher's delegate is responsible for freeing the fetcher (and itself).
- fetcher->delegate()->OnURLFetchComplete(fetcher);
variations::VariationsHttpHeaderProvider::GetInstance()->ResetForTesting();
}
-TEST_F(FeedbackUploaderDispatchTest, TestVariousServerResponses) {
+TEST_F(FeedbackUploaderDispatchTest, 204Response) {
FeedbackUploader::SetMinimumRetryDelayForTesting(kTestRetryDelay);
FeedbackUploader uploader(
- context(), FeedbackUploaderFactory::CreateUploaderTaskRunner());
+ shared_url_loader_factory(), context(),
+ FeedbackUploaderFactory::CreateUploaderTaskRunner());
EXPECT_EQ(kTestRetryDelay, uploader.retry_delay());
// Successful reports should not introduce any retries, and should not
// increase the backoff delay.
- net::TestURLFetcherFactory factory;
- factory.set_remove_fetcher_on_delete(true);
+ network::ResourceResponseHead head;
+ std::string headers("HTTP/1.1 204 No Content\n\n");
+ head.headers = base::MakeRefCounted<net::HttpResponseHeaders>(
+ net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size()));
+ network::URLLoaderCompletionStatus status;
+ test_url_loader_factory()->AddResponse(GURL(kFeedbackPostUrl), head, "",
+ status);
QueueReport(&uploader, "Successful report");
- net::TestURLFetcher* fetcher = factory.GetFetcherByID(0);
- fetcher->set_response_code(kHttpPostSuccessNoContent);
- fetcher->delegate()->OnURLFetchComplete(fetcher);
+ base::RunLoop().RunUntilIdle();
+
EXPECT_EQ(kTestRetryDelay, uploader.retry_delay());
EXPECT_TRUE(uploader.QueueEmpty());
+}
+TEST_F(FeedbackUploaderDispatchTest, 400Response) {
+ FeedbackUploader::SetMinimumRetryDelayForTesting(kTestRetryDelay);
+ FeedbackUploader uploader(
+ shared_url_loader_factory(), context(),
+ FeedbackUploaderFactory::CreateUploaderTaskRunner());
+
+ EXPECT_EQ(kTestRetryDelay, uploader.retry_delay());
// Failed reports due to client errors are not retried. No backoff delay
// should be doubled.
+ network::ResourceResponseHead head;
+ std::string headers("HTTP/1.1 400 Bad Request\n\n");
+ head.headers = base::MakeRefCounted<net::HttpResponseHeaders>(
+ net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size()));
+ network::URLLoaderCompletionStatus status;
+ test_url_loader_factory()->AddResponse(GURL(kFeedbackPostUrl), head, "",
+ status);
QueueReport(&uploader, "Client error failed report");
- fetcher = factory.GetFetcherByID(0);
- fetcher->set_response_code(kHttpPostFailClientError);
- fetcher->delegate()->OnURLFetchComplete(fetcher);
+ base::RunLoop().RunUntilIdle();
+
EXPECT_EQ(kTestRetryDelay, uploader.retry_delay());
EXPECT_TRUE(uploader.QueueEmpty());
+}
+TEST_F(FeedbackUploaderDispatchTest, 500Response) {
+ FeedbackUploader::SetMinimumRetryDelayForTesting(kTestRetryDelay);
+ FeedbackUploader uploader(
+ shared_url_loader_factory(), context(),
+ FeedbackUploaderFactory::CreateUploaderTaskRunner());
+
+ EXPECT_EQ(kTestRetryDelay, uploader.retry_delay());
// Failed reports due to server errors are retried.
+ network::ResourceResponseHead head;
+ std::string headers("HTTP/1.1 500 Server Error\n\n");
+ head.headers = base::MakeRefCounted<net::HttpResponseHeaders>(
+ net::HttpUtil::AssembleRawHeaders(headers.c_str(), headers.size()));
+ network::URLLoaderCompletionStatus status;
+ test_url_loader_factory()->AddResponse(GURL(kFeedbackPostUrl), head, "",
+ status);
QueueReport(&uploader, "Server error failed report");
- fetcher = factory.GetFetcherByID(0);
- fetcher->set_response_code(kHttpPostFailServerError);
- fetcher->delegate()->OnURLFetchComplete(fetcher);
+ base::RunLoop().RunUntilIdle();
+
EXPECT_EQ(kTestRetryDelay * 2, uploader.retry_delay());
EXPECT_FALSE(uploader.QueueEmpty());
}
diff --git a/components/feedback/feedback_uploader_factory.cc b/components/feedback/feedback_uploader_factory.cc
index 5445e1d..f446d03 100644
--- a/components/feedback/feedback_uploader_factory.cc
+++ b/components/feedback/feedback_uploader_factory.cc
@@ -10,6 +10,8 @@
#include "base/task_scheduler/task_traits.h"
#include "components/feedback/feedback_uploader.h"
#include "components/keyed_service/content/browser_context_dependency_manager.h"
+#include "content/public/browser/browser_context.h"
+#include "content/public/browser/storage_partition.h"
namespace feedback {
@@ -51,7 +53,10 @@
KeyedService* FeedbackUploaderFactory::BuildServiceInstanceFor(
content::BrowserContext* context) const {
- return new FeedbackUploader(context, task_runner_);
+ return new FeedbackUploader(
+ content::BrowserContext::GetDefaultStoragePartition(context)
+ ->GetURLLoaderFactoryForBrowserProcess(),
+ context, task_runner_);
}
content::BrowserContext* FeedbackUploaderFactory::GetBrowserContextToUse(
diff --git a/components/feedback/feedback_uploader_unittest.cc b/components/feedback/feedback_uploader_unittest.cc
index 6c93fa02..356229e 100644
--- a/components/feedback/feedback_uploader_unittest.cc
+++ b/components/feedback/feedback_uploader_unittest.cc
@@ -18,6 +18,9 @@
#include "components/feedback/feedback_uploader_factory.h"
#include "content/public/test/test_browser_context.h"
#include "content/public/test/test_browser_thread_bundle.h"
+#include "services/network/public/cpp/shared_url_loader_factory.h"
+#include "services/network/public/cpp/weak_wrapper_shared_url_loader_factory.h"
+#include "services/network/test/test_url_loader_factory.h"
#include "testing/gtest/include/gtest/gtest.h"
namespace feedback {
@@ -35,8 +38,11 @@
class MockFeedbackUploader : public FeedbackUploader {
public:
- MockFeedbackUploader(content::BrowserContext* context)
- : FeedbackUploader(context,
+ MockFeedbackUploader(
+ scoped_refptr<network::SharedURLLoaderFactory> url_loader_factory,
+ content::BrowserContext* context)
+ : FeedbackUploader(url_loader_factory,
+ context,
FeedbackUploaderFactory::CreateUploaderTaskRunner()) {}
~MockFeedbackUploader() override {}
@@ -112,13 +118,17 @@
public:
FeedbackUploaderTest() {
FeedbackUploader::SetMinimumRetryDelayForTesting(kRetryDelayForTest);
+ test_shared_loader_factory_ =
+ base::MakeRefCounted<network::WeakWrapperSharedURLLoaderFactory>(
+ &test_url_loader_factory_);
RecreateUploader();
}
~FeedbackUploaderTest() override = default;
void RecreateUploader() {
- uploader_ = std::make_unique<MockFeedbackUploader>(&context_);
+ uploader_ = std::make_unique<MockFeedbackUploader>(
+ test_shared_loader_factory_, &context_);
}
void QueueReport(const std::string& data) {
@@ -128,6 +138,8 @@
MockFeedbackUploader* uploader() const { return uploader_.get(); }
private:
+ network::TestURLLoaderFactory test_url_loader_factory_;
+ scoped_refptr<network::SharedURLLoaderFactory> test_shared_loader_factory_;
content::TestBrowserThreadBundle test_browser_thread_bundle_;
content::TestBrowserContext context_;
std::unique_ptr<MockFeedbackUploader> uploader_;