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

Side by Side Diff: chrome/browser/metrics/perf/random_selector_unittest.cc

Issue 1334943003: metrics: Add RandomSelector, a class that randomly selects items with odds (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Moved to metrics/perf/ directory Created 5 years, 3 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
(Empty)
1 // Copyright 2015 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "chrome/browser/metrics/perf/random_selector.h"
6
7 #include <cmath>
8 #include <map>
9 #include <string>
10
11 #include <gtest/gtest.h>
Alexei Svitkine (slow) 2015/09/14 19:12:33 Can this include "testing/gtest/include/gtest/gtes
dhsharp 2015/09/15 00:00:21 Done.
12
13 namespace metrics {
14
15 // A small floating point number used to verify that the expected odds are equal
16 // to the odds set.
17 const double kEpsilon = 0.01;
18
19 // A class that overrides RandDoubleUpTo() to not be random. The number
20 // generator will emulate a uniform distribution of numbers between 0.0 and
21 // |max| when called with the same |max| parameter and a whole multiple of
22 // |random_period| times. This allows better testing of the RandomSelector
23 // class.
24 class RandomSelectorWithCustomRNG : public RandomSelector {
25 public:
26 explicit RandomSelectorWithCustomRNG(unsigned int random_period)
27 : random_period_(random_period), current_index_(0) {}
28
29 private:
30 // This function returns floats between 0.0 and |max| in an increasing
31 // fashion at regular intervals.
32 double RandDoubleUpTo(double max) override {
33 current_index_ = (current_index_ + 1) % random_period_;
34 return max * current_index_ / random_period_;
35 }
36
37 // Period (number of calls) over which the fake RNG repeats.
38 const unsigned int random_period_;
39
40 // Stores the current position we are at in the interval between 0.0 and
41 // |max|. See the function RandDoubleUpTo for details on how this is used.
42 int current_index_;
43
44 DISALLOW_COPY_AND_ASSIGN(RandomSelectorWithCustomRNG);
45 };
46
47 // Use the random_selector to generate some values. The number of values to
48 // generate is |iterations|.
49 void GenerateResults(size_t iterations,
50 RandomSelector* random_selector,
51 std::map<std::string, int>* results) {
52 for (size_t i = 0; i < iterations; ++i) {
53 const std::string& next_value = random_selector->GetNext();
54 (*results)[next_value]++;
55 }
56 }
57
58 // This function tests whether the results are close enough to the odds (within
59 // 1%).
60 void CheckResultsAgainstOdds(
61 const std::vector<RandomSelector::OddsAndValue>& odds,
62 const std::map<std::string, int>& results) {
63 EXPECT_EQ(odds.size(), results.size());
64
65 const double odds_sum = RandomSelector::SumOdds(odds);
66 int results_sum = 0;
67 for (const auto& item : results) {
68 results_sum += item.second;
69 }
70
71 for (const auto& odd : odds) {
72 const auto result = results.find(odd.value);
73 EXPECT_NE(result, results.end());
74 const double results_ratio = 1.0*result->second / results_sum;
75 const double odds_ratio = odd.weight / odds_sum;
76 const double abs_diff = std::abs(results_ratio - odds_ratio);
77 EXPECT_LT(abs_diff, kEpsilon);
78 }
79 }
80
81 TEST(RandomSelector, SimpleAccessors) {
82 using OddsAndValue = RandomSelector::OddsAndValue;
83 std::vector<OddsAndValue> odds;
84 odds.push_back(OddsAndValue(1, "a 1"));
85 odds.push_back(OddsAndValue(3, "b --help"));
86 odds.push_back(OddsAndValue(107, "c bar"));
87 EXPECT_EQ(111.0L, RandomSelector::SumOdds(odds));
88 RandomSelector random_selector;
89 random_selector.SetOdds(odds);
90 EXPECT_EQ(3UL, random_selector.GetNumValues());
91 }
92
93 // Ensure RandomSelector is able to generate results from given odds.
94 TEST(RandomSelector, GenerateTest) {
95 using OddsAndValue = RandomSelector::OddsAndValue;
96 const int kLargeNumber = 2000;
97 std::vector<RandomSelector::OddsAndValue> odds;
98 odds.push_back(OddsAndValue(1, "a 1"));
99 odds.push_back(OddsAndValue(2, "b --help"));
100 odds.push_back(OddsAndValue(3, "c bar"));
101 RandomSelectorWithCustomRNG random_selector(kLargeNumber);
102 random_selector.SetOdds(odds);
103 // Generate a lot of values.
104 std::map<std::string, int> results;
105 GenerateResults(kLargeNumber, &random_selector, &results);
106 // Ensure the values and odds are related.
107 CheckResultsAgainstOdds(odds, results);
108 }
109
110 } // namespace metrics
111
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698