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

Side by Side Diff: components/ntp_snippets/remote/scheduling_remote_suggestions_provider_unittest.cc

Issue 2714863004: [Remote suggestions] Move the throttler into the Scheduler (Closed)
Patch Set: Ilya's comment Created 3 years, 9 months 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 unified diff | Download patch
OLDNEW
1 // Copyright 2016 The Chromium Authors. All rights reserved. 1 // Copyright 2016 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "components/ntp_snippets/remote/scheduling_remote_suggestions_provider. h" 5 #include "components/ntp_snippets/remote/scheduling_remote_suggestions_provider. h"
6 6
7 #include <memory> 7 #include <memory>
8 #include <set> 8 #include <set>
9 #include <string> 9 #include <string>
10 #include <utility> 10 #include <utility>
(...skipping 16 matching lines...) Expand all
27 #include "components/ntp_snippets/remote/test_utils.h" 27 #include "components/ntp_snippets/remote/test_utils.h"
28 #include "components/ntp_snippets/status.h" 28 #include "components/ntp_snippets/status.h"
29 #include "components/ntp_snippets/user_classifier.h" 29 #include "components/ntp_snippets/user_classifier.h"
30 #include "components/prefs/testing_pref_service.h" 30 #include "components/prefs/testing_pref_service.h"
31 #include "components/variations/variations_params_manager.h" 31 #include "components/variations/variations_params_manager.h"
32 #include "testing/gmock/include/gmock/gmock.h" 32 #include "testing/gmock/include/gmock/gmock.h"
33 #include "testing/gtest/include/gtest/gtest.h" 33 #include "testing/gtest/include/gtest/gtest.h"
34 34
35 using testing::ElementsAre; 35 using testing::ElementsAre;
36 using testing::Eq; 36 using testing::Eq;
37 using testing::Field;
37 using testing::InSequence; 38 using testing::InSequence;
38 using testing::Invoke; 39 using testing::Invoke;
39 using testing::IsEmpty; 40 using testing::IsEmpty;
40 using testing::Mock; 41 using testing::Mock;
41 using testing::MockFunction; 42 using testing::MockFunction;
42 using testing::Not; 43 using testing::Not;
43 using testing::Return; 44 using testing::Return;
44 using testing::SaveArg; 45 using testing::SaveArg;
45 using testing::SaveArgPointee; 46 using testing::SaveArgPointee;
46 using testing::SizeIs; 47 using testing::SizeIs;
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after
91 MOCK_METHOD1(GetCategoryStatus, CategoryStatus(Category)); 92 MOCK_METHOD1(GetCategoryStatus, CategoryStatus(Category));
92 MOCK_METHOD1(GetCategoryInfo, CategoryInfo(Category)); 93 MOCK_METHOD1(GetCategoryInfo, CategoryInfo(Category));
93 MOCK_METHOD3(ClearHistory, 94 MOCK_METHOD3(ClearHistory,
94 void(base::Time begin, 95 void(base::Time begin,
95 base::Time end, 96 base::Time end,
96 const base::Callback<bool(const GURL& url)>& filter)); 97 const base::Callback<bool(const GURL& url)>& filter));
97 MOCK_METHOD3(Fetch, 98 MOCK_METHOD3(Fetch,
98 void(const Category&, 99 void(const Category&,
99 const std::set<std::string>&, 100 const std::set<std::string>&,
100 const FetchDoneCallback&)); 101 const FetchDoneCallback&));
102 MOCK_METHOD0(ReloadSuggestions, void());
101 MOCK_METHOD1(ClearCachedSuggestions, void(Category)); 103 MOCK_METHOD1(ClearCachedSuggestions, void(Category));
102 MOCK_METHOD1(ClearDismissedSuggestionsForDebugging, void(Category)); 104 MOCK_METHOD1(ClearDismissedSuggestionsForDebugging, void(Category));
103 MOCK_METHOD1(DismissSuggestion, void(const ContentSuggestion::ID&)); 105 MOCK_METHOD1(DismissSuggestion, void(const ContentSuggestion::ID&));
104 MOCK_METHOD2(FetchSuggestionImage, 106 MOCK_METHOD2(FetchSuggestionImage,
105 void(const ContentSuggestion::ID&, const ImageFetchedCallback&)); 107 void(const ContentSuggestion::ID&, const ImageFetchedCallback&));
106 MOCK_METHOD2(GetDismissedSuggestionsForDebugging, 108 MOCK_METHOD2(GetDismissedSuggestionsForDebugging,
107 void(Category, const DismissedSuggestionsCallback&)); 109 void(Category, const DismissedSuggestionsCallback&));
108 MOCK_METHOD0(OnSignInStateChanged, void()); 110 MOCK_METHOD0(OnSignInStateChanged, void());
109 }; 111 };
110 112
111 } // namespace 113 } // namespace
112 114
113 class SchedulingRemoteSuggestionsProviderTest 115 class SchedulingRemoteSuggestionsProviderTest
114 : public ::testing::Test { 116 : public ::testing::Test {
115 public: 117 public:
116 SchedulingRemoteSuggestionsProviderTest() 118 SchedulingRemoteSuggestionsProviderTest()
117 : // For the test we enabled all trigger types. 119 : // For the test we enabled all trigger types.
118 default_variation_params_{{"scheduler_trigger_types", 120 default_variation_params_{{"scheduler_trigger_types",
119 "persistent_scheduler_wake_up,ntp_opened," 121 "persistent_scheduler_wake_up,ntp_opened,"
120 "browser_foregrounded,browser_cold_start"}}, 122 "browser_foregrounded,browser_cold_start"}},
121 params_manager_(ntp_snippets::kStudyName, 123 params_manager_(ntp_snippets::kStudyName,
122 default_variation_params_, 124 default_variation_params_,
123 {kArticleSuggestionsFeature.name}), 125 {kArticleSuggestionsFeature.name}),
124 underlying_provider_(nullptr), 126 underlying_provider_(nullptr),
125 scheduling_provider_(nullptr), 127 scheduling_provider_(nullptr),
126 user_classifier_(/*pref_service=*/nullptr) { 128 user_classifier_(/*pref_service=*/nullptr) {
127 SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs( 129 SchedulingRemoteSuggestionsProvider::RegisterProfilePrefs(
128 utils_.pref_service()->registry()); 130 utils_.pref_service()->registry());
131 RequestThrottler::RegisterProfilePrefs(utils_.pref_service()->registry());
129 ResetProvider(); 132 ResetProvider();
130 } 133 }
131 134
132 void ResetProvider() { 135 void ResetProvider() {
133 auto underlying_provider = 136 auto underlying_provider =
134 base::MakeUnique<StrictMock<MockRemoteSuggestionsProvider>>( 137 base::MakeUnique<StrictMock<MockRemoteSuggestionsProvider>>(
135 /*observer=*/nullptr); 138 /*observer=*/nullptr);
136 underlying_provider_ = underlying_provider.get(); 139 underlying_provider_ = underlying_provider.get();
137 140
138 auto test_clock = base::MakeUnique<base::SimpleTestClock>(); 141 auto test_clock = base::MakeUnique<base::SimpleTestClock>();
(...skipping 11 matching lines...) Expand all
150 const std::string& param_value) { 153 const std::string& param_value) {
151 std::map<std::string, std::string> params = default_variation_params_; 154 std::map<std::string, std::string> params = default_variation_params_;
152 params[param_name] = param_value; 155 params[param_name] = param_value;
153 156
154 params_manager_.ClearAllVariationParams(); 157 params_manager_.ClearAllVariationParams();
155 params_manager_.SetVariationParamsWithFeatureAssociations( 158 params_manager_.SetVariationParamsWithFeatureAssociations(
156 ntp_snippets::kStudyName, params, 159 ntp_snippets::kStudyName, params,
157 {ntp_snippets::kArticleSuggestionsFeature.name}); 160 {ntp_snippets::kArticleSuggestionsFeature.name});
158 } 161 }
159 162
163 // GMock cannot deal with move-only types. We need to pass the vector to the
164 // mock function as const ref using this wrapper callback.
165 void FetchDoneWrapper(
166 MockFunction<void(Status status_code,
167 const std::vector<ContentSuggestion>& suggestions)>*
168 fetch_done,
169 Status status_code,
170 std::vector<ContentSuggestion> suggestions) {
171 fetch_done->Call(status_code, suggestions);
172 }
173
160 protected: 174 protected:
161 std::map<std::string, std::string> default_variation_params_; 175 std::map<std::string, std::string> default_variation_params_;
162 variations::testing::VariationParamsManager params_manager_; 176 variations::testing::VariationParamsManager params_manager_;
163 StrictMock<MockPersistentScheduler> persistent_scheduler_; 177 StrictMock<MockPersistentScheduler> persistent_scheduler_;
164 StrictMock<MockRemoteSuggestionsProvider>* underlying_provider_; 178 StrictMock<MockRemoteSuggestionsProvider>* underlying_provider_;
165 std::unique_ptr<SchedulingRemoteSuggestionsProvider> scheduling_provider_; 179 std::unique_ptr<SchedulingRemoteSuggestionsProvider> scheduling_provider_;
166 base::SimpleTestClock* test_clock_; 180 base::SimpleTestClock* test_clock_;
167 181
168 void ActivateUnderlyingProvider() { 182 void ActivateUnderlyingProvider() {
169 scheduling_provider_->OnProviderActivated(); 183 scheduling_provider_->OnProviderActivated();
(...skipping 494 matching lines...) Expand 10 before | Expand all | Expand 10 after
664 EXPECT_CALL(persistent_scheduler_, Schedule(_, _)); 678 EXPECT_CALL(persistent_scheduler_, Schedule(_, _));
665 signal_fetch_done.Run(Status::Success()); 679 signal_fetch_done.Run(Status::Success());
666 680
667 // Clear the suggestions. 681 // Clear the suggestions.
668 scheduling_provider_->OnSuggestionsCleared(); 682 scheduling_provider_->OnSuggestionsCleared();
669 // Another trigger right after results in a fetch again. 683 // Another trigger right after results in a fetch again.
670 EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_)); 684 EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_));
671 scheduling_provider_->OnBrowserForegrounded(); 685 scheduling_provider_->OnBrowserForegrounded();
672 } 686 }
673 687
688 TEST_F(SchedulingRemoteSuggestionsProviderTest,
689 ShouldThrottleInteractiveRequests) {
690 // Change the quota for interactive requests ("active NTP user" is the default
691 // class in tests).
692 SetVariationParameter("interactive_quota_SuggestionFetcherActiveNTPUser",
693 "10");
694 ResetProvider();
695
696 Category category = Category::FromKnownCategory(KnownCategories::ARTICLES);
697 std::set<std::string> known_suggestions;
698
699 // Both Fetch(..) and ReloadSuggestions() consume the same quota. As long as
700 // the quota suffices, the call gets through.
701 EXPECT_CALL(*underlying_provider_, ReloadSuggestions()).Times(5);
702 for (int x = 0; x < 5; ++x) {
703 scheduling_provider_->ReloadSuggestions();
704 }
705
706 // Expect underlying provider being called and store the callback to inform
707 // scheduling provider.
708 FetchDoneCallback signal_fetch_done_from_underlying_provider;
709 EXPECT_CALL(*underlying_provider_, Fetch(_, _, _))
710 .Times(5)
711 .WillRepeatedly(SaveArg<2>(&signal_fetch_done_from_underlying_provider));
712 // Expect scheduling provider to pass the information through.
713 MockFunction<void(Status status_code,
714 const std::vector<ContentSuggestion>& suggestions)>
715 fetch_done_from_scheduling_provider;
716 EXPECT_CALL(fetch_done_from_scheduling_provider,
717 Call(Field(&Status::code, StatusCode::SUCCESS), _))
718 .Times(5);
719 // Scheduling is not activated, each successful fetch results in Unschedule().
720 EXPECT_CALL(persistent_scheduler_, Unschedule()).Times(5);
721 for (int x = 0; x < 5; ++x) {
722 scheduling_provider_->Fetch(
723 category, known_suggestions,
724 base::Bind(&SchedulingRemoteSuggestionsProviderTest::FetchDoneWrapper,
725 base::Unretained(this),
726 &fetch_done_from_scheduling_provider));
727 // Inform scheduling provider the fetc is successful (with no suggestions).
728 signal_fetch_done_from_underlying_provider.Run(
729 Status::Success(), std::vector<ContentSuggestion>{});
730 }
731
732 // When the quota expires, it is blocked by the scheduling provider, directly
733 // calling the callback.
734 EXPECT_CALL(fetch_done_from_scheduling_provider,
735 Call(Field(&Status::code, StatusCode::TEMPORARY_ERROR), _));
736 scheduling_provider_->ReloadSuggestions();
737 scheduling_provider_->Fetch(
738 category, known_suggestions,
739 base::Bind(&SchedulingRemoteSuggestionsProviderTest::FetchDoneWrapper,
740 base::Unretained(this), &fetch_done_from_scheduling_provider));
741 }
742
743 TEST_F(SchedulingRemoteSuggestionsProviderTest,
744 ShouldThrottleNonInteractiveRequests) {
745 // Change the quota for interactive requests ("active NTP user" is the default
746 // class in tests).
747 SetVariationParameter("quota_SuggestionFetcherActiveNTPUser", "5");
748 ResetProvider();
749
750 // One scheduling on start, 5 times after successful fetches.
751 EXPECT_CALL(persistent_scheduler_, Schedule(_, _)).Times(6);
752
753 // First enable the scheduler -- this will trigger the persistent scheduling.
754 ActivateUnderlyingProvider();
755
756 // As long as the quota suffices, the call gets through.
757 RemoteSuggestionsProvider::FetchStatusCallback signal_fetch_done;
758 EXPECT_CALL(*underlying_provider_, RefetchInTheBackground(_))
759 .Times(5)
760 .WillRepeatedly(SaveArg<0>(&signal_fetch_done));
761 for (int x = 0; x < 5; ++x) {
762 scheduling_provider_->OnPersistentSchedulerWakeUp();
763 signal_fetch_done.Run(Status::Success());
764 }
765
766 // For the 6th time, it is blocked by the scheduling provider.
767 scheduling_provider_->OnPersistentSchedulerWakeUp();
768 }
769
674 } // namespace ntp_snippets 770 } // namespace ntp_snippets
OLDNEW
« no previous file with comments | « components/ntp_snippets/remote/scheduling_remote_suggestions_provider.cc ('k') | tools/metrics/histograms/histograms.xml » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698