1 // Copyright 2018 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 "content/browser/client_hints/client_hints.h"
6 
7 #include "base/strings/string_number_conversions.h"
8 #include "base/time/time.h"
9 #include "testing/gtest/include/gtest/gtest.h"
10 
11 namespace content {
12 
13 class ClientHintsTest : public testing::Test {
14  public:
ClientHintsTest()15   ClientHintsTest() {}
16 
~ClientHintsTest()17   ~ClientHintsTest() override {}
18 
19  private:
20   DISALLOW_COPY_AND_ASSIGN(ClientHintsTest);
21 };
22 
TEST_F(ClientHintsTest,RttRoundedOff)23 TEST_F(ClientHintsTest, RttRoundedOff) {
24   EXPECT_EQ(
25       0u, RoundRttForTesting("", base::TimeDelta::FromMilliseconds(1023)) % 50);
26   EXPECT_EQ(
27       0u, RoundRttForTesting("", base::TimeDelta::FromMilliseconds(6787)) % 50);
28   EXPECT_EQ(0u,
29             RoundRttForTesting("", base::TimeDelta::FromMilliseconds(12)) % 50);
30   EXPECT_EQ(0u, RoundRttForTesting("foo.com",
31                                    base::TimeDelta::FromMilliseconds(1023)) %
32                     50);
33   EXPECT_EQ(0u, RoundRttForTesting("foo.com",
34                                    base::TimeDelta::FromMilliseconds(1193)) %
35                     50);
36   EXPECT_EQ(
37       0u, RoundRttForTesting("foo.com", base::TimeDelta::FromMilliseconds(12)) %
38               50);
39 }
40 
TEST_F(ClientHintsTest,DownlinkRoundedOff)41 TEST_F(ClientHintsTest, DownlinkRoundedOff) {
42   EXPECT_GE(1,
43             static_cast<int>(RoundKbpsToMbpsForTesting("", 102) * 1000) % 50);
44   EXPECT_GE(1, static_cast<int>(RoundKbpsToMbpsForTesting("", 12) * 1000) % 50);
45   EXPECT_GE(1,
46             static_cast<int>(RoundKbpsToMbpsForTesting("", 2102) * 1000) % 50);
47 
48   EXPECT_GE(
49       1,
50       static_cast<int>(RoundKbpsToMbpsForTesting("foo.com", 102) * 1000) % 50);
51   EXPECT_GE(
52       1,
53       static_cast<int>(RoundKbpsToMbpsForTesting("foo.com", 12) * 1000) % 50);
54   EXPECT_GE(
55       1,
56       static_cast<int>(RoundKbpsToMbpsForTesting("foo.com", 2102) * 1000) % 50);
57   EXPECT_GE(
58       1, static_cast<int>(RoundKbpsToMbpsForTesting("foo.com", 12102) * 1000) %
59              50);
60 }
61 
62 // Verify that the value of RTT after adding noise is within approximately 10%
63 // of the original value. Note that the difference between the final value of
64 // RTT and the original value may be slightly more than 10% due to rounding off.
65 // To handle that, the maximum absolute difference allowed is set to a value
66 // slightly larger than 10% of the original metric value.
TEST_F(ClientHintsTest,FinalRttWithin10PercentValue)67 TEST_F(ClientHintsTest, FinalRttWithin10PercentValue) {
68   EXPECT_NEAR(98, RoundRttForTesting("", base::TimeDelta::FromMilliseconds(98)),
69               100);
70   EXPECT_NEAR(1023,
71               RoundRttForTesting("", base::TimeDelta::FromMilliseconds(1023)),
72               200);
73   EXPECT_NEAR(1193,
74               RoundRttForTesting("", base::TimeDelta::FromMilliseconds(1193)),
75               200);
76   EXPECT_NEAR(2750,
77               RoundRttForTesting("", base::TimeDelta::FromMilliseconds(2750)),
78               400);
79 }
80 
81 // Verify that the value of downlink after adding noise is within approximately
82 // 10% of the original value. Note that the difference between the final value
83 // of downlink and the original value may be slightly more than 10% due to
84 // rounding off. To handle that, the maximum absolute difference allowed is set
85 // to a value slightly larger than 10% of the original metric value.
TEST_F(ClientHintsTest,FinalDownlinkWithin10PercentValue)86 TEST_F(ClientHintsTest, FinalDownlinkWithin10PercentValue) {
87   EXPECT_NEAR(0.098, RoundKbpsToMbpsForTesting("", 98), 0.1);
88   EXPECT_NEAR(1.023, RoundKbpsToMbpsForTesting("", 1023), 0.2);
89   EXPECT_NEAR(1.193, RoundKbpsToMbpsForTesting("", 1193), 0.2);
90   EXPECT_NEAR(7.523, RoundKbpsToMbpsForTesting("", 7523), 0.9);
91   EXPECT_NEAR(9.999, RoundKbpsToMbpsForTesting("", 9999), 1.2);
92 }
93 
TEST_F(ClientHintsTest,RttMaxValue)94 TEST_F(ClientHintsTest, RttMaxValue) {
95   EXPECT_GE(3000u,
96             RoundRttForTesting("", base::TimeDelta::FromMilliseconds(1023)));
97   EXPECT_GE(3000u,
98             RoundRttForTesting("", base::TimeDelta::FromMilliseconds(2789)));
99   EXPECT_GE(3000u,
100             RoundRttForTesting("", base::TimeDelta::FromMilliseconds(6023)));
101   EXPECT_EQ(
102       0u, RoundRttForTesting("", base::TimeDelta::FromMilliseconds(1023)) % 50);
103   EXPECT_EQ(
104       0u, RoundRttForTesting("", base::TimeDelta::FromMilliseconds(2789)) % 50);
105   EXPECT_EQ(
106       0u, RoundRttForTesting("", base::TimeDelta::FromMilliseconds(6023)) % 50);
107 }
108 
TEST_F(ClientHintsTest,DownlinkMaxValue)109 TEST_F(ClientHintsTest, DownlinkMaxValue) {
110   EXPECT_GE(10.0, RoundKbpsToMbpsForTesting("", 102));
111   EXPECT_GE(10.0, RoundKbpsToMbpsForTesting("", 2102));
112   EXPECT_GE(10.0, RoundKbpsToMbpsForTesting("", 100102));
113   EXPECT_GE(1,
114             static_cast<int>(RoundKbpsToMbpsForTesting("", 102) * 1000) % 50);
115   EXPECT_GE(1,
116             static_cast<int>(RoundKbpsToMbpsForTesting("", 2102) * 1000) % 50);
117   EXPECT_GE(
118       1, static_cast<int>(RoundKbpsToMbpsForTesting("", 100102) * 1000) % 50);
119 }
120 
TEST_F(ClientHintsTest,RttRandomized)121 TEST_F(ClientHintsTest, RttRandomized) {
122   const int initial_value = RoundRttForTesting(
123       "example.com", base::TimeDelta::FromMilliseconds(1023));
124   bool network_quality_randomized_by_host = false;
125   // There is a 1/20 chance that the same random noise is selected for two
126   // different hosts. Run this test across 20 hosts to reduce the chances of
127   // test failing to (1/20)^20.
128   for (size_t i = 0; i < 20; ++i) {
129     int value = RoundRttForTesting(base::NumberToString(i),
130                                    base::TimeDelta::FromMilliseconds(1023));
131     // If |value| is different than |initial_value|, it implies that RTT is
132     // randomized by host. This verifies the behavior, and test can be ended.
133     if (value != initial_value)
134       network_quality_randomized_by_host = true;
135   }
136   EXPECT_TRUE(network_quality_randomized_by_host);
137 
138   // Calling RoundRttForTesting for same host should return the same result.
139   for (size_t i = 0; i < 20; ++i) {
140     int value = RoundRttForTesting("example.com",
141                                    base::TimeDelta::FromMilliseconds(1023));
142     EXPECT_EQ(initial_value, value);
143   }
144 }
145 
TEST_F(ClientHintsTest,DownlinkRandomized)146 TEST_F(ClientHintsTest, DownlinkRandomized) {
147   const int initial_value = RoundKbpsToMbpsForTesting("example.com", 1023);
148   bool network_quality_randomized_by_host = false;
149   // There is a 1/20 chance that the same random noise is selected for two
150   // different hosts. Run this test across 20 hosts to reduce the chances of
151   // test failing to (1/20)^20.
152   for (size_t i = 0; i < 20; ++i) {
153     int value = RoundKbpsToMbpsForTesting(base::NumberToString(i), 1023);
154     // If |value| is different than |initial_value|, it implies that downlink is
155     // randomized by host. This verifies the behavior, and test can be ended.
156     if (value != initial_value)
157       network_quality_randomized_by_host = true;
158   }
159   EXPECT_TRUE(network_quality_randomized_by_host);
160 
161   // Calling RoundMbps for same host should return the same result.
162   for (size_t i = 0; i < 20; ++i) {
163     int value = RoundKbpsToMbpsForTesting("example.com", 1023);
164     EXPECT_EQ(initial_value, value);
165   }
166 }
167 
168 }  // namespace content
169