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

Side by Side Diff: ui/app_list/search/mixer_unittest.cc

Issue 1136363003: Remove AppListMixer field trial. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@applist-mixer-priority-finch-test
Patch Set: Rebase. Created 4 years, 5 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 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "ui/app_list/search/mixer.h" 5 #include "ui/app_list/search/mixer.h"
6 6
7 #include <stddef.h> 7 #include <stddef.h>
8 8
9 #include <set> 9 #include <set>
10 #include <string> 10 #include <string>
11 11
12 #include "base/macros.h" 12 #include "base/macros.h"
13 #include "base/memory/ptr_util.h" 13 #include "base/memory/ptr_util.h"
14 #include "base/memory/scoped_vector.h" 14 #include "base/memory/scoped_vector.h"
15 #include "base/metrics/field_trial.h"
16 #include "base/strings/string16.h" 15 #include "base/strings/string16.h"
17 #include "base/strings/stringprintf.h" 16 #include "base/strings/stringprintf.h"
18 #include "base/strings/utf_string_conversions.h" 17 #include "base/strings/utf_string_conversions.h"
19 #include "base/test/mock_entropy_provider.h"
20 #include "testing/gtest/include/gtest/gtest.h" 18 #include "testing/gtest/include/gtest/gtest.h"
21 #include "ui/app_list/app_list_model.h" 19 #include "ui/app_list/app_list_model.h"
22 #include "ui/app_list/search/history_types.h" 20 #include "ui/app_list/search/history_types.h"
23 #include "ui/app_list/search_provider.h" 21 #include "ui/app_list/search_provider.h"
24 #include "ui/app_list/search_result.h" 22 #include "ui/app_list/search_result.h"
25 23
26 namespace app_list { 24 namespace app_list {
27 namespace test { 25 namespace test {
28 26
29 // Maximum number of results to show in each mixer group. 27 // Maximum number of results to show in each mixer group.
30 const size_t kMaxAppsGroupResults = 4; 28 const size_t kMaxAppsGroupResults = 4;
31 // Ignored unless AppListMixer field trial is "Blended".
32 const size_t kMaxOmniboxResults = 4; 29 const size_t kMaxOmniboxResults = 4;
33 const size_t kMaxWebstoreResults = 2; 30 const size_t kMaxWebstoreResults = 2;
34 31
35 class TestSearchResult : public SearchResult { 32 class TestSearchResult : public SearchResult {
36 public: 33 public:
37 TestSearchResult(const std::string& id, double relevance) 34 TestSearchResult(const std::string& id, double relevance)
38 : instance_id_(instantiation_count++) { 35 : instance_id_(instantiation_count++) {
39 set_id(id); 36 set_id(id);
40 set_title(base::UTF8ToUTF16(id)); 37 set_title(base::UTF8ToUTF16(id));
41 set_relevance(relevance); 38 set_relevance(relevance);
(...skipping 66 matching lines...) Expand 10 before | Expand all | Expand 10 after
108 std::string prefix_; 105 std::string prefix_;
109 size_t count_; 106 size_t count_;
110 bool bad_relevance_range_; 107 bool bad_relevance_range_;
111 SearchResult::DisplayType display_type_; 108 SearchResult::DisplayType display_type_;
112 // Indices of results that will have the |voice_result| flag set. 109 // Indices of results that will have the |voice_result| flag set.
113 std::set<size_t> voice_result_indices; 110 std::set<size_t> voice_result_indices;
114 111
115 DISALLOW_COPY_AND_ASSIGN(TestSearchProvider); 112 DISALLOW_COPY_AND_ASSIGN(TestSearchProvider);
116 }; 113 };
117 114
118 // Test is parameterized with bool. True enables the "Blended" field trial. 115 class MixerTest : public testing::Test {
119 class MixerTest : public testing::Test,
120 public testing::WithParamInterface<bool> {
121 public: 116 public:
122 MixerTest() 117 MixerTest() : is_voice_query_(false) {}
123 : is_voice_query_(false),
124 field_trial_list_(new base::MockEntropyProvider()) {}
125 ~MixerTest() override {} 118 ~MixerTest() override {}
126 119
127 // testing::Test overrides: 120 // testing::Test overrides:
128 void SetUp() override { 121 void SetUp() override {
129 // If the parameter is true, enable the field trial.
130 const char* field_trial_name = GetParam() ? "Blended" : "Control";
131 base::FieldTrialList::CreateFieldTrial("AppListMixer", field_trial_name);
132
133 results_.reset(new AppListModel::SearchResults); 122 results_.reset(new AppListModel::SearchResults);
134 123
135 providers_.push_back(new TestSearchProvider("app")); 124 providers_.push_back(new TestSearchProvider("app"));
136 providers_.push_back(new TestSearchProvider("omnibox")); 125 providers_.push_back(new TestSearchProvider("omnibox"));
137 providers_.push_back(new TestSearchProvider("webstore")); 126 providers_.push_back(new TestSearchProvider("webstore"));
138 127
139 is_voice_query_ = false; 128 is_voice_query_ = false;
140 129
141 mixer_.reset(new Mixer(results_.get())); 130 mixer_.reset(new Mixer(results_.get()));
142 131
143 size_t apps_group_id = mixer_->AddGroup(kMaxAppsGroupResults, 3.0, 1.0); 132 size_t apps_group_id = mixer_->AddGroup(kMaxAppsGroupResults, 1.0);
144 size_t omnibox_group_id = 133 size_t omnibox_group_id = mixer_->AddGroup(kMaxOmniboxResults, 1.0);
145 mixer_->AddOmniboxGroup(kMaxOmniboxResults, 2.0, 1.0); 134 size_t webstore_group_id = mixer_->AddGroup(kMaxWebstoreResults, 0.5);
146 size_t webstore_group_id = mixer_->AddGroup(kMaxWebstoreResults, 1.0, 0.5);
147 135
148 mixer_->AddProviderToGroup(apps_group_id, providers_[0]); 136 mixer_->AddProviderToGroup(apps_group_id, providers_[0]);
149 mixer_->AddProviderToGroup(omnibox_group_id, providers_[1]); 137 mixer_->AddProviderToGroup(omnibox_group_id, providers_[1]);
150 mixer_->AddProviderToGroup(webstore_group_id, providers_[2]); 138 mixer_->AddProviderToGroup(webstore_group_id, providers_[2]);
151 } 139 }
152 140
153 void RunQuery() { 141 void RunQuery() {
154 const base::string16 query; 142 const base::string16 query;
155 143
156 for (size_t i = 0; i < providers_.size(); ++i) { 144 for (size_t i = 0; i < providers_.size(); ++i) {
(...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after
189 177
190 private: 178 private:
191 std::unique_ptr<Mixer> mixer_; 179 std::unique_ptr<Mixer> mixer_;
192 std::unique_ptr<AppListModel::SearchResults> results_; 180 std::unique_ptr<AppListModel::SearchResults> results_;
193 KnownResults known_results_; 181 KnownResults known_results_;
194 182
195 bool is_voice_query_; 183 bool is_voice_query_;
196 184
197 ScopedVector<TestSearchProvider> providers_; 185 ScopedVector<TestSearchProvider> providers_;
198 186
199 base::FieldTrialList field_trial_list_;
200
201 DISALLOW_COPY_AND_ASSIGN(MixerTest); 187 DISALLOW_COPY_AND_ASSIGN(MixerTest);
202 }; 188 };
203 189
204 TEST_P(MixerTest, Basic) { 190 TEST_F(MixerTest, Basic) {
205 // Note: Some cases in |expected_blended| have vastly more results than 191 // Note: Some cases in |expected| have vastly more results than others, due to
206 // others, due to the "at least 6" mechanism. If it gets at least 6 results 192 // the "at least 6" mechanism. If it gets at least 6 results from all
207 // from all providers, it stops at 6. If not, it fetches potentially many more 193 // providers, it stops at 6. If not, it fetches potentially many more results
208 // results from all providers. Not ideal, but currently by design. 194 // from all providers. Not ideal, but currently by design.
209 struct TestCase { 195 struct TestCase {
210 const size_t app_results; 196 const size_t app_results;
211 const size_t omnibox_results; 197 const size_t omnibox_results;
212 const size_t webstore_results; 198 const size_t webstore_results;
213 const char* expected_default; // Expected results with trial off. 199 const char* expected;
214 const char* expected_blended; // Expected results with trial on.
215 } kTestCases[] = { 200 } kTestCases[] = {
216 {0, 0, 0, "", ""}, 201 {0, 0, 0, ""},
217 {10, 0, 0, "app0,app1,app2,app3", 202 {10, 0, 0, "app0,app1,app2,app3,app4,app5,app6,app7,app8,app9"},
218 "app0,app1,app2,app3,app4,app5,app6,app7,app8,app9"}, 203 {0, 0, 10,
219 {0, 0, 10, "webstore0,webstore1",
220 "webstore0,webstore1,webstore2,webstore3,webstore4,webstore5,webstore6," 204 "webstore0,webstore1,webstore2,webstore3,webstore4,webstore5,webstore6,"
221 "webstore7,webstore8,webstore9"}, 205 "webstore7,webstore8,webstore9"},
222 {4, 6, 0, "app0,app1,app2,app3,omnibox0,omnibox1", 206 {4, 6, 0, "app0,omnibox0,app1,omnibox1,app2,omnibox2,app3,omnibox3"},
223 "app0,omnibox0,app1,omnibox1,app2,omnibox2,app3,omnibox3"}, 207 {4, 6, 2,
224 {4, 6, 2, "app0,app1,app2,app3,omnibox0,webstore0",
225 "app0,omnibox0,app1,omnibox1,app2,omnibox2,app3,omnibox3,webstore0," 208 "app0,omnibox0,app1,omnibox1,app2,omnibox2,app3,omnibox3,webstore0,"
226 "webstore1"}, 209 "webstore1"},
227 {10, 10, 10, "app0,app1,app2,app3,omnibox0,webstore0", 210 {10, 10, 10,
228 "app0,omnibox0,app1,omnibox1,app2,omnibox2,app3,omnibox3,webstore0," 211 "app0,omnibox0,app1,omnibox1,app2,omnibox2,app3,omnibox3,webstore0,"
229 "webstore1"}, 212 "webstore1"},
230 {0, 10, 0, "omnibox0,omnibox1,omnibox2,omnibox3,omnibox4,omnibox5", 213 {0, 10, 0,
231 "omnibox0,omnibox1,omnibox2,omnibox3,omnibox4,omnibox5,omnibox6," 214 "omnibox0,omnibox1,omnibox2,omnibox3,omnibox4,omnibox5,omnibox6,"
232 "omnibox7,omnibox8,omnibox9"}, 215 "omnibox7,omnibox8,omnibox9"},
233 {0, 10, 1, "omnibox0,omnibox1,omnibox2,omnibox3,omnibox4,webstore0", 216 {0, 10, 1,
234 "omnibox0,omnibox1,omnibox2,omnibox3,webstore0,omnibox4,omnibox5," 217 "omnibox0,omnibox1,omnibox2,omnibox3,webstore0,omnibox4,omnibox5,"
235 "omnibox6,omnibox7,omnibox8,omnibox9"}, 218 "omnibox6,omnibox7,omnibox8,omnibox9"},
236 {0, 10, 2, "omnibox0,omnibox1,omnibox2,omnibox3,webstore0,webstore1", 219 {0, 10, 2, "omnibox0,omnibox1,omnibox2,omnibox3,webstore0,webstore1"},
237 "omnibox0,omnibox1,omnibox2,omnibox3,webstore0,webstore1"}, 220 {1, 10, 0,
238 {1, 10, 0, "app0,omnibox0,omnibox1,omnibox2,omnibox3,omnibox4",
239 "app0,omnibox0,omnibox1,omnibox2,omnibox3,omnibox4,omnibox5,omnibox6," 221 "app0,omnibox0,omnibox1,omnibox2,omnibox3,omnibox4,omnibox5,omnibox6,"
240 "omnibox7,omnibox8,omnibox9"}, 222 "omnibox7,omnibox8,omnibox9"},
241 {2, 10, 0, "app0,app1,omnibox0,omnibox1,omnibox2,omnibox3", 223 {2, 10, 0, "app0,omnibox0,app1,omnibox1,omnibox2,omnibox3"},
242 "app0,omnibox0,app1,omnibox1,omnibox2,omnibox3"}, 224 {2, 10, 1, "app0,omnibox0,app1,omnibox1,omnibox2,omnibox3,webstore0"},
243 {2, 10, 1, "app0,app1,omnibox0,omnibox1,omnibox2,webstore0", 225 {2, 10, 2,
244 "app0,omnibox0,app1,omnibox1,omnibox2,omnibox3,webstore0"},
245 {2, 10, 2, "app0,app1,omnibox0,omnibox1,webstore0,webstore1",
246 "app0,omnibox0,app1,omnibox1,omnibox2,omnibox3,webstore0,webstore1"}, 226 "app0,omnibox0,app1,omnibox1,omnibox2,omnibox3,webstore0,webstore1"},
247 {2, 0, 2, "app0,app1,webstore0,webstore1", 227 {2, 0, 2, "app0,app1,webstore0,webstore1"},
248 "app0,app1,webstore0,webstore1"}, 228 {0, 0, 0, ""},
249 {0, 0, 0, "", ""},
250 }; 229 };
251 230
252 for (size_t i = 0; i < arraysize(kTestCases); ++i) { 231 for (size_t i = 0; i < arraysize(kTestCases); ++i) {
253 app_provider()->set_count(kTestCases[i].app_results); 232 app_provider()->set_count(kTestCases[i].app_results);
254 omnibox_provider()->set_count(kTestCases[i].omnibox_results); 233 omnibox_provider()->set_count(kTestCases[i].omnibox_results);
255 webstore_provider()->set_count(kTestCases[i].webstore_results); 234 webstore_provider()->set_count(kTestCases[i].webstore_results);
256 RunQuery(); 235 RunQuery();
257 236
258 const char* expected = GetParam() ? kTestCases[i].expected_blended 237 EXPECT_EQ(kTestCases[i].expected, GetResults()) << "Case " << i;
259 : kTestCases[i].expected_default;
260 EXPECT_EQ(expected, GetResults()) << "Case " << i;
261 } 238 }
262 } 239 }
263 240
264 TEST_P(MixerTest, RemoveDuplicates) { 241 TEST_F(MixerTest, RemoveDuplicates) {
265 const std::string dup = "dup"; 242 const std::string dup = "dup";
266 243
267 // This gives "dup0,dup1,dup2". 244 // This gives "dup0,dup1,dup2".
268 app_provider()->set_prefix(dup); 245 app_provider()->set_prefix(dup);
269 app_provider()->set_count(3); 246 app_provider()->set_count(3);
270 247
271 // This gives "dup0,dup1". 248 // This gives "dup0,dup1".
272 omnibox_provider()->set_prefix(dup); 249 omnibox_provider()->set_prefix(dup);
273 omnibox_provider()->set_count(2); 250 omnibox_provider()->set_count(2);
274 251
275 // This gives "dup0". 252 // This gives "dup0".
276 webstore_provider()->set_prefix(dup); 253 webstore_provider()->set_prefix(dup);
277 webstore_provider()->set_count(1); 254 webstore_provider()->set_count(1);
278 255
279 RunQuery(); 256 RunQuery();
280 257
281 // Only three results with unique id are kept. 258 // Only three results with unique id are kept.
282 EXPECT_EQ("dup0,dup1,dup2", GetResults()); 259 EXPECT_EQ("dup0,dup1,dup2", GetResults());
283 } 260 }
284 261
285 // Tests that "known results" have priority over others. 262 // Tests that "known results" have priority over others.
286 TEST_P(MixerTest, KnownResultsPriority) { 263 TEST_F(MixerTest, KnownResultsPriority) {
287 // This gives omnibox 0 -- 5. 264 // This gives omnibox 0 -- 5.
288 omnibox_provider()->set_count(6); 265 omnibox_provider()->set_count(6);
289 266
290 // omnibox 1 -- 4 are "known results". 267 // omnibox 1 -- 4 are "known results".
291 AddKnownResult("omnibox1", PREFIX_SECONDARY); 268 AddKnownResult("omnibox1", PREFIX_SECONDARY);
292 AddKnownResult("omnibox2", PERFECT_SECONDARY); 269 AddKnownResult("omnibox2", PERFECT_SECONDARY);
293 AddKnownResult("omnibox3", PREFIX_PRIMARY); 270 AddKnownResult("omnibox3", PREFIX_PRIMARY);
294 AddKnownResult("omnibox4", PERFECT_PRIMARY); 271 AddKnownResult("omnibox4", PERFECT_PRIMARY);
295 272
296 RunQuery(); 273 RunQuery();
297 274
298 // omnibox 1 -- 4 should be prioritised over the others. They should be 275 // omnibox 1 -- 4 should be prioritised over the others. They should be
299 // ordered 4, 3, 2, 1 (in order of match quality). 276 // ordered 4, 3, 2, 1 (in order of match quality).
300 EXPECT_EQ("omnibox4,omnibox3,omnibox2,omnibox1,omnibox0,omnibox5", 277 EXPECT_EQ("omnibox4,omnibox3,omnibox2,omnibox1,omnibox0,omnibox5",
301 GetResults()); 278 GetResults());
302 } 279 }
303 280
304 // Tests that "known results" are not considered for recommendation results. 281 // Tests that "known results" are not considered for recommendation results.
305 TEST_P(MixerTest, KnownResultsIgnoredForRecommendations) { 282 TEST_F(MixerTest, KnownResultsIgnoredForRecommendations) {
306 // This gives omnibox 0 -- 5. 283 // This gives omnibox 0 -- 5.
307 omnibox_provider()->set_count(6); 284 omnibox_provider()->set_count(6);
308 omnibox_provider()->set_display_type(SearchResult::DISPLAY_RECOMMENDATION); 285 omnibox_provider()->set_display_type(SearchResult::DISPLAY_RECOMMENDATION);
309 286
310 // omnibox 1 -- 4 are "known results". 287 // omnibox 1 -- 4 are "known results".
311 AddKnownResult("omnibox1", PREFIX_SECONDARY); 288 AddKnownResult("omnibox1", PREFIX_SECONDARY);
312 AddKnownResult("omnibox2", PERFECT_SECONDARY); 289 AddKnownResult("omnibox2", PERFECT_SECONDARY);
313 AddKnownResult("omnibox3", PREFIX_PRIMARY); 290 AddKnownResult("omnibox3", PREFIX_PRIMARY);
314 AddKnownResult("omnibox4", PERFECT_PRIMARY); 291 AddKnownResult("omnibox4", PERFECT_PRIMARY);
315 292
316 RunQuery(); 293 RunQuery();
317 294
318 // omnibox 1 -- 4 should be unaffected despite being known results. 295 // omnibox 1 -- 4 should be unaffected despite being known results.
319 EXPECT_EQ("omnibox0,omnibox1,omnibox2,omnibox3,omnibox4,omnibox5", 296 EXPECT_EQ("omnibox0,omnibox1,omnibox2,omnibox3,omnibox4,omnibox5",
320 GetResults()); 297 GetResults());
321 } 298 }
322 299
323 TEST_P(MixerTest, VoiceQuery) { 300 TEST_F(MixerTest, VoiceQuery) {
324 omnibox_provider()->set_count(3); 301 omnibox_provider()->set_count(3);
325 RunQuery(); 302 RunQuery();
326 EXPECT_EQ("omnibox0,omnibox1,omnibox2", GetResults()); 303 EXPECT_EQ("omnibox0,omnibox1,omnibox2", GetResults());
327 304
328 // Set "omnibox1" as a voice result. Do not expect any changes (as this is not 305 // Set "omnibox1" as a voice result. Do not expect any changes (as this is not
329 // a voice query). 306 // a voice query).
330 omnibox_provider()->set_as_voice_result(1); 307 omnibox_provider()->set_as_voice_result(1);
331 RunQuery(); 308 RunQuery();
332 EXPECT_EQ("omnibox0,omnibox1,omnibox2", GetResults()); 309 EXPECT_EQ("omnibox0,omnibox1,omnibox2", GetResults());
333 310
334 // Perform a voice query. Expect voice result first. 311 // Perform a voice query. Expect voice result first.
335 set_is_voice_query(true); 312 set_is_voice_query(true);
336 RunQuery(); 313 RunQuery();
337 EXPECT_EQ("omnibox1,omnibox0,omnibox2", GetResults()); 314 EXPECT_EQ("omnibox1,omnibox0,omnibox2", GetResults());
338 315
339 // All voice results should appear before non-voice results. 316 // All voice results should appear before non-voice results.
340 omnibox_provider()->set_as_voice_result(2); 317 omnibox_provider()->set_as_voice_result(2);
341 RunQuery(); 318 RunQuery();
342 EXPECT_EQ("omnibox1,omnibox2,omnibox0", GetResults()); 319 EXPECT_EQ("omnibox1,omnibox2,omnibox0", GetResults());
343 } 320 }
344 321
345 TEST_P(MixerTest, Publish) { 322 TEST_F(MixerTest, Publish) {
346 std::unique_ptr<SearchResult> result1(new TestSearchResult("app1", 0)); 323 std::unique_ptr<SearchResult> result1(new TestSearchResult("app1", 0));
347 std::unique_ptr<SearchResult> result2(new TestSearchResult("app2", 0)); 324 std::unique_ptr<SearchResult> result2(new TestSearchResult("app2", 0));
348 std::unique_ptr<SearchResult> result3(new TestSearchResult("app3", 0)); 325 std::unique_ptr<SearchResult> result3(new TestSearchResult("app3", 0));
349 std::unique_ptr<SearchResult> result3_copy = result3->Duplicate(); 326 std::unique_ptr<SearchResult> result3_copy = result3->Duplicate();
350 std::unique_ptr<SearchResult> result4(new TestSearchResult("app4", 0)); 327 std::unique_ptr<SearchResult> result4(new TestSearchResult("app4", 0));
351 std::unique_ptr<SearchResult> result5(new TestSearchResult("app5", 0)); 328 std::unique_ptr<SearchResult> result5(new TestSearchResult("app5", 0));
352 329
353 AppListModel::SearchResults ui_results; 330 AppListModel::SearchResults ui_results;
354 331
355 // Publish the first three results to |ui_results|. 332 // Publish the first three results to |ui_results|.
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after
423 400
424 // The reordered results should use the original objects. 401 // The reordered results should use the original objects.
425 EXPECT_EQ(old_ui_result_ids[0], 402 EXPECT_EQ(old_ui_result_ids[0],
426 TestSearchResult::GetInstanceId(ui_results.GetItemAt(3))); 403 TestSearchResult::GetInstanceId(ui_results.GetItemAt(3)));
427 EXPECT_EQ(old_ui_result_ids[1], 404 EXPECT_EQ(old_ui_result_ids[1],
428 TestSearchResult::GetInstanceId(ui_results.GetItemAt(0))); 405 TestSearchResult::GetInstanceId(ui_results.GetItemAt(0)));
429 EXPECT_EQ(old_ui_result_ids[2], 406 EXPECT_EQ(old_ui_result_ids[2],
430 TestSearchResult::GetInstanceId(ui_results.GetItemAt(2))); 407 TestSearchResult::GetInstanceId(ui_results.GetItemAt(2)));
431 } 408 }
432 409
433 INSTANTIATE_TEST_CASE_P(MixerTestInstance, MixerTest, testing::Bool());
434
435 } // namespace test 410 } // namespace test
436 } // namespace app_list 411 } // namespace app_list
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698