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

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

Issue 2548343002: NTPSnippets: Set MaxRetriesOn5xx only for interactive requests. (Closed)
Patch Set: Document missing functionality inline. 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..88f85c43c202160b5298d6f8451a2a82cb48aa60 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,83 @@ class MockSnippetsAvailableCallback {
NTPSnippetsFetcher::OptionalFetchedCategories* fetched_categories));
};
+// TODO(fhorschig): Transfer this class' functionality to call delegates
+// automatically as option to TestURLFetcherFactory where it was just deleted.
+// This can be represented as a single member there and would reduce the amount
+// of fake implementations from three to two.
+
+// 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->delegate()) {
+ return;
+ }
+ 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:
@@ -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,50 @@ 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) {
+ struct ExpectationForVariationParam {
+ std::string param_value;
+ int expected_value;
+ std::string description;
+ };
+ const std::vector<ExpectationForVariationParam> retry_config_expectation = {
+ {"", 0, "Do not retry by default"},
+ {"0", 0, "Do not retry on param value 0"},
+ {"-1", 0, "Do not retry on negative param values."},
+ {"4", 4, "Retry as set in param value."}};
+
+ NTPSnippetsFetcher::Params params = test_params();
+ params.interactive_request = false;
+
+ 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))
+ << retry_config.description;
+ }
}
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