Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1319)

Unified Diff: components/ntp_snippets/remote/ntp_snippets_fetcher_unittest.cc

Issue 2548343002: NTPSnippets: Set MaxRetriesOn5xx only for interactive requests. (Closed)
Patch Set: Rebased. Created 4 years ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
« no previous file with comments | « components/ntp_snippets/remote/ntp_snippets_fetcher.cc ('k') | no next file » | no next file with comments »
Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
Index: components/ntp_snippets/remote/ntp_snippets_fetcher_unittest.cc
diff --git a/components/ntp_snippets/remote/ntp_snippets_fetcher_unittest.cc b/components/ntp_snippets/remote/ntp_snippets_fetcher_unittest.cc
index dde8e3816d420453d28df2ee7f2a88daba772e53..bf1810cd67ae3f8a9832f9b23bc39fb31f727402 100644
--- a/components/ntp_snippets/remote/ntp_snippets_fetcher_unittest.cc
+++ b/components/ntp_snippets/remote/ntp_snippets_fetcher_unittest.cc
@@ -4,6 +4,7 @@
#include "components/ntp_snippets/remote/ntp_snippets_fetcher.h"
+#include <deque>
#include <map>
#include <utility>
@@ -16,6 +17,7 @@
#include "base/time/time.h"
#include "base/values.h"
#include "components/ntp_snippets/category_factory.h"
+#include "components/ntp_snippets/features.h"
#include "components/ntp_snippets/ntp_snippets_constants.h"
#include "components/ntp_snippets/remote/ntp_snippet.h"
#include "components/ntp_snippets/user_classifier.h"
@@ -160,6 +162,78 @@ class MockSnippetsAvailableCallback {
NTPSnippetsFetcher::OptionalFetchedCategories* fetched_categories));
};
+// DelegateCallingTestURLFetcherFactory can be used to temporarily inject
+// TestURLFetcher instances into a scope.
+// Client code can access the last created fetcher to verify expected
+// properties. When the factory gets destroyed, all available delegates of still
+// valid fetchers will be called.
+// This ensures once-bound callbacks (like SnippetsAvailableCallback) will be
+// called at some point and are not leaked.
+class DelegateCallingTestURLFetcherFactory
+ : public net::TestURLFetcherFactory,
+ public net::TestURLFetcherDelegateForTests {
+ public:
+ DelegateCallingTestURLFetcherFactory() {
+ SetDelegateForTests(this);
+ set_remove_fetcher_on_delete(true);
+ }
+
+ ~DelegateCallingTestURLFetcherFactory() override {
+ while (!fetchers_.empty()) {
+ DropAndCallDelegate(fetchers_.front());
+ }
+ }
+
+ std::unique_ptr<net::URLFetcher> CreateURLFetcher(
+ int id,
+ const GURL& url,
+ net::URLFetcher::RequestType request_type,
+ net::URLFetcherDelegate* d) override {
+ if (GetFetcherByID(id)) {
+ LOG(WARNING) << "The ID " << id << " was already assigned to a fetcher."
+ << "Its delegate will thereforde be called right now.";
+ DropAndCallDelegate(id);
+ }
+ fetchers_.push_back(id);
+ return TestURLFetcherFactory::CreateURLFetcher(id, url, request_type, d);
+ }
+
+ // Returns the raw pointer of the last created URL fetcher.
+ // If it was destroyed or no fetcher was created, it will return a nulltpr.
+ net::TestURLFetcher* GetLastCreatedFetcher() {
+ if (fetchers_.empty()) {
+ return nullptr;
+ }
+ return GetFetcherByID(fetchers_.front());
+ }
+
+ private:
+ // The fetcher can either be destroyed because the delegate was called during
+ // execution or because we called it on destruction.
+ void DropAndCallDelegate(int fetcher_id) {
+ auto found_id_iter =
+ std::find(fetchers_.begin(), fetchers_.end(), fetcher_id);
+ if (found_id_iter == fetchers_.end()) {
+ return;
+ }
+ fetchers_.erase(found_id_iter);
+ net::TestURLFetcher* fetcher = GetFetcherByID(fetcher_id);
+ if (!fetcher || !fetcher->delegate()) {
+ return;
Marc Treib 2016/12/12 10:17:16 When would |fetcher| be null here? Add a comment t
fhorschig 2016/12/12 11:05:10 Removed. It cannot be 0. If it is, crashing is an
+ }
+ fetcher->delegate()->OnURLFetchComplete(fetcher);
+ }
+
+ // net::TestURLFetcherDelegateForTests overrides:
+ void OnRequestStart(int fetcher_id) override {}
+ void OnChunkUpload(int fetcher_id) override {}
+ void OnRequestEnd(int fetcher_id) override {
+ DropAndCallDelegate(fetcher_id);
+ }
+
+ std::deque<int> fetchers_; // std::queue doesn't support std::find.
+};
+
// Factory for FakeURLFetcher objects that always generate errors.
class FailingFakeURLFetcherFactory : public net::URLFetcherFactory {
public:
@@ -211,6 +285,11 @@ class NTPSnippetsFetcherTest : public testing::Test {
bool IsSendingTopLanguagesEnabled() const override { return true; }
};
+ struct ExpectationForVariationParam {
Marc Treib 2016/12/12 10:17:16 nit: Move this into the test that uses it.
fhorschig 2016/12/12 11:05:10 Done.
+ std::string param_value;
+ int expected_value;
+ };
+
NTPSnippetsFetcherTest()
: NTPSnippetsFetcherTest(GURL(kTestChromeReaderUrl),
std::map<std::string, std::string>()) {}
@@ -292,6 +371,15 @@ class NTPSnippetsFetcherTest : public testing::Test {
ntp_snippets::kStudyName, params);
}
+ void SetVariationParametersForFeatures(
+ const std::map<std::string, std::string>& params,
+ const std::set<std::string>& features) {
+ params_manager_.reset();
+ params_manager_ =
+ base::MakeUnique<variations::testing::VariationParamsManager>(
+ ntp_snippets::kStudyName, params, features);
+ }
+
void SetFakeResponse(const std::string& response_data,
net::HttpStatusCode response_code,
net::URLRequestStatus::Status status) {
@@ -912,13 +1000,15 @@ TEST_F(NTPSnippetsFetcherTest, ShouldFetchSuccessfullyEmptyList) {
}
TEST_F(NTPSnippetsFetcherTest, ShouldRestrictToHosts) {
- net::TestURLFetcherFactory test_url_fetcher_factory;
+ DelegateCallingTestURLFetcherFactory fetcher_factory;
NTPSnippetsFetcher::Params params = test_params();
params.hosts = {"www.somehost1.com", "www.somehost2.com"};
params.count_to_fetch = 17;
+
snippets_fetcher().FetchSnippets(
params, ToSnippetsAvailableCallback(&mock_callback()));
- net::TestURLFetcher* fetcher = test_url_fetcher_factory.GetFetcherByID(0);
+
+ net::TestURLFetcher* fetcher = fetcher_factory.GetLastCreatedFetcher();
ASSERT_THAT(fetcher, NotNull());
std::unique_ptr<base::Value> value =
base::JSONReader::Read(fetcher->upload_data());
@@ -941,19 +1031,43 @@ TEST_F(NTPSnippetsFetcherTest, ShouldRestrictToHosts) {
ASSERT_TRUE(content_selectors->GetDictionary(1, &content_selector));
EXPECT_TRUE(content_selector->GetString("value", &content_selector_value));
EXPECT_THAT(content_selector_value, Eq("www.somehost2.com"));
- // Call the delegate callback manually as the TestURLFetcher deletes any
- // call to the delegate that usually happens on |Start|.
- // Without the call to the delegate, it leaks the request that owns itself.
- ASSERT_THAT(fetcher->delegate(), NotNull());
- EXPECT_CALL(mock_callback(),
- Run(NTPSnippetsFetcher::FetchResult::URL_REQUEST_STATUS_ERROR,
- /*snippets=*/Not(HasValue())))
- .Times(1);
- // An 4XX response needs the least configuration to successfully invoke the
- // callback properly as the results are not important in this test.
- fetcher->set_response_code(net::HTTP_NOT_FOUND);
- fetcher->set_status(net::URLRequestStatus(net::URLRequestStatus::FAILED, -2));
- fetcher->delegate()->OnURLFetchComplete(fetcher);
+}
+
+TEST_F(NTPSnippetsFetcherTest, RetryOnInteractiveRequests) {
+ DelegateCallingTestURLFetcherFactory fetcher_factory;
+ NTPSnippetsFetcher::Params params = test_params();
+ params.interactive_request = true;
+
+ snippets_fetcher().FetchSnippets(
+ params, ToSnippetsAvailableCallback(&mock_callback()));
+
+ net::TestURLFetcher* fetcher = fetcher_factory.GetLastCreatedFetcher();
+ ASSERT_THAT(fetcher, NotNull());
+ EXPECT_THAT(fetcher->GetMaxRetriesOn5xx(), Eq(2));
+}
+
+TEST_F(NTPSnippetsFetcherTest, RetriesConfigurableOnNonInteractiveRequests) {
+ NTPSnippetsFetcher::Params params = test_params();
+ params.interactive_request = false;
+ const std::vector<ExpectationForVariationParam> retry_config_expectation = {
+ {"", 0}, // Keep 2 retries if no variation is set.
Marc Treib 2016/12/12 10:17:16 Comment is out of date. One alternative is adding
fhorschig 2016/12/12 11:05:10 Good idea.
tschumann 2016/12/12 11:55:48 This is fine by me, but we're getting close into t
fhorschig 2016/12/12 12:16:45 Looks like a valid concern even though this very e
+ {"0", 0},
+ {"-1", 0}, // Allow no negative retry count.
+ {"3", 3}};
+
+ for (const auto& retry_config : retry_config_expectation) {
+ DelegateCallingTestURLFetcherFactory fetcher_factory;
+ SetVariationParametersForFeatures(
+ {{"background_5xx_retries_count", retry_config.param_value}},
+ {ntp_snippets::kArticleSuggestionsFeature.name});
+
+ snippets_fetcher().FetchSnippets(
+ params, ToSnippetsAvailableCallback(&mock_callback()));
+
+ net::TestURLFetcher* fetcher = fetcher_factory.GetLastCreatedFetcher();
+ ASSERT_THAT(fetcher, NotNull());
+ EXPECT_THAT(fetcher->GetMaxRetriesOn5xx(), Eq(retry_config.expected_value));
+ }
}
TEST_F(NTPSnippetsFetcherTest, ShouldReportUrlStatusError) {
« no previous file with comments | « components/ntp_snippets/remote/ntp_snippets_fetcher.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698