xref: /aosp_15_r20/external/cronet/base/moving_window_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2023 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "base/moving_window.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include "base/time/time.h"
8*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker namespace base {
11*6777b538SAndroid Build Coastguard Worker 
12*6777b538SAndroid Build Coastguard Worker namespace {
13*6777b538SAndroid Build Coastguard Worker 
14*6777b538SAndroid Build Coastguard Worker constexpr int kTestValues[] = {
15*6777b538SAndroid Build Coastguard Worker     33, 1, 2, 7, 5, 2, 4, 45, 1000, 1, 100, 2, 200, 2,  2, 2, 300, 4, 1,
16*6777b538SAndroid Build Coastguard Worker     2,  3, 4, 5, 6, 7, 8, 9,  10,   9, 8,   7, 6,   5,  4, 3, 2,   1, 1,
17*6777b538SAndroid Build Coastguard Worker     2,  1, 4, 2, 1, 8, 1, 2,  1,    4, 1,   2, 1,   16, 1, 2, 1};
18*6777b538SAndroid Build Coastguard Worker 
19*6777b538SAndroid Build Coastguard Worker }  // namespace
20*6777b538SAndroid Build Coastguard Worker 
21*6777b538SAndroid Build Coastguard Worker class MovingMaxTest : public testing::TestWithParam<unsigned int> {};
22*6777b538SAndroid Build Coastguard Worker 
23*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(All,
24*6777b538SAndroid Build Coastguard Worker                          MovingMaxTest,
25*6777b538SAndroid Build Coastguard Worker                          testing::ValuesIn({1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u,
26*6777b538SAndroid Build Coastguard Worker                                             10u, 17u, 20u, 100u}));
27*6777b538SAndroid Build Coastguard Worker 
TEST_P(MovingMaxTest,BlanketTest)28*6777b538SAndroid Build Coastguard Worker TEST_P(MovingMaxTest, BlanketTest) {
29*6777b538SAndroid Build Coastguard Worker   const size_t window_size = GetParam();
30*6777b538SAndroid Build Coastguard Worker   MovingMax<int> window(window_size);
31*6777b538SAndroid Build Coastguard Worker   for (size_t i = 0; i < std::size(kTestValues); ++i) {
32*6777b538SAndroid Build Coastguard Worker     window.AddSample(kTestValues[i]);
33*6777b538SAndroid Build Coastguard Worker     int slow_max = kTestValues[i];
34*6777b538SAndroid Build Coastguard Worker     for (size_t j = 1; j < window_size && j <= i; ++j) {
35*6777b538SAndroid Build Coastguard Worker       slow_max = std::max(slow_max, kTestValues[i - j]);
36*6777b538SAndroid Build Coastguard Worker     }
37*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(window.Max(), slow_max);
38*6777b538SAndroid Build Coastguard Worker   }
39*6777b538SAndroid Build Coastguard Worker }
40*6777b538SAndroid Build Coastguard Worker 
TEST(MovingMax,SingleElementWindow)41*6777b538SAndroid Build Coastguard Worker TEST(MovingMax, SingleElementWindow) {
42*6777b538SAndroid Build Coastguard Worker   MovingMax<int> window(1u);
43*6777b538SAndroid Build Coastguard Worker   window.AddSample(100);
44*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Max(), 100);
45*6777b538SAndroid Build Coastguard Worker   window.AddSample(1000);
46*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Max(), 1000);
47*6777b538SAndroid Build Coastguard Worker   window.AddSample(1);
48*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Max(), 1);
49*6777b538SAndroid Build Coastguard Worker   window.AddSample(3);
50*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Max(), 3);
51*6777b538SAndroid Build Coastguard Worker   window.AddSample(4);
52*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Max(), 4);
53*6777b538SAndroid Build Coastguard Worker }
54*6777b538SAndroid Build Coastguard Worker 
TEST(MovingMax,VeryLargeWindow)55*6777b538SAndroid Build Coastguard Worker TEST(MovingMax, VeryLargeWindow) {
56*6777b538SAndroid Build Coastguard Worker   MovingMax<int> window(100u);
57*6777b538SAndroid Build Coastguard Worker   window.AddSample(100);
58*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Max(), 100);
59*6777b538SAndroid Build Coastguard Worker   window.AddSample(1000);
60*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Max(), 1000);
61*6777b538SAndroid Build Coastguard Worker   window.AddSample(1);
62*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Max(), 1000);
63*6777b538SAndroid Build Coastguard Worker   window.AddSample(3);
64*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Max(), 1000);
65*6777b538SAndroid Build Coastguard Worker   window.AddSample(4);
66*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Max(), 1000);
67*6777b538SAndroid Build Coastguard Worker }
68*6777b538SAndroid Build Coastguard Worker 
TEST(MovingMax,Counts)69*6777b538SAndroid Build Coastguard Worker TEST(MovingMax, Counts) {
70*6777b538SAndroid Build Coastguard Worker   MovingMax<int> window(3u);
71*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Count(), 0u);
72*6777b538SAndroid Build Coastguard Worker   window.AddSample(100);
73*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Count(), 1u);
74*6777b538SAndroid Build Coastguard Worker   window.AddSample(1000);
75*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Count(), 2u);
76*6777b538SAndroid Build Coastguard Worker   window.AddSample(1);
77*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Count(), 3u);
78*6777b538SAndroid Build Coastguard Worker   window.AddSample(3);
79*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Count(), 4u);
80*6777b538SAndroid Build Coastguard Worker   window.AddSample(4);
81*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Count(), 5u);
82*6777b538SAndroid Build Coastguard Worker }
83*6777b538SAndroid Build Coastguard Worker 
TEST(MovingAverage,Unrounded)84*6777b538SAndroid Build Coastguard Worker TEST(MovingAverage, Unrounded) {
85*6777b538SAndroid Build Coastguard Worker   MovingAverage<int, int64_t> window(4u);
86*6777b538SAndroid Build Coastguard Worker   window.AddSample(1);
87*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Mean<double>(), 1.0);
88*6777b538SAndroid Build Coastguard Worker   window.AddSample(2);
89*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Mean<double>(), 1.5);
90*6777b538SAndroid Build Coastguard Worker   window.AddSample(3);
91*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Mean<double>(), 2.0);
92*6777b538SAndroid Build Coastguard Worker   window.AddSample(4);
93*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Mean<double>(), 2.5);
94*6777b538SAndroid Build Coastguard Worker   window.AddSample(101);
95*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Mean<double>(), 27.5);
96*6777b538SAndroid Build Coastguard Worker }
97*6777b538SAndroid Build Coastguard Worker 
98*6777b538SAndroid Build Coastguard Worker class MovingMinTest : public testing::TestWithParam<unsigned int> {};
99*6777b538SAndroid Build Coastguard Worker 
100*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(All,
101*6777b538SAndroid Build Coastguard Worker                          MovingMinTest,
102*6777b538SAndroid Build Coastguard Worker                          testing::ValuesIn({1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u,
103*6777b538SAndroid Build Coastguard Worker                                             10u, 17u, 20u, 100u}));
104*6777b538SAndroid Build Coastguard Worker 
TEST_P(MovingMinTest,BlanketTest)105*6777b538SAndroid Build Coastguard Worker TEST_P(MovingMinTest, BlanketTest) {
106*6777b538SAndroid Build Coastguard Worker   const size_t window_size = GetParam();
107*6777b538SAndroid Build Coastguard Worker   MovingMin<int> window(window_size);
108*6777b538SAndroid Build Coastguard Worker   for (int repeats = 0; repeats < 2; ++repeats) {
109*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < std::size(kTestValues); ++i) {
110*6777b538SAndroid Build Coastguard Worker       window.AddSample(kTestValues[i]);
111*6777b538SAndroid Build Coastguard Worker       int slow_min = kTestValues[i];
112*6777b538SAndroid Build Coastguard Worker       for (size_t j = 1; j < window_size && j <= i; ++j) {
113*6777b538SAndroid Build Coastguard Worker         slow_min = std::min(slow_min, kTestValues[i - j]);
114*6777b538SAndroid Build Coastguard Worker       }
115*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(window.Min(), slow_min);
116*6777b538SAndroid Build Coastguard Worker     }
117*6777b538SAndroid Build Coastguard Worker     window.Reset();
118*6777b538SAndroid Build Coastguard Worker   }
119*6777b538SAndroid Build Coastguard Worker }
120*6777b538SAndroid Build Coastguard Worker 
121*6777b538SAndroid Build Coastguard Worker class MovingAverageTest : public testing::TestWithParam<unsigned int> {};
122*6777b538SAndroid Build Coastguard Worker 
123*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(All,
124*6777b538SAndroid Build Coastguard Worker                          MovingAverageTest,
125*6777b538SAndroid Build Coastguard Worker                          testing::ValuesIn({1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u,
126*6777b538SAndroid Build Coastguard Worker                                             10u, 17u, 20u, 100u}));
127*6777b538SAndroid Build Coastguard Worker 
TEST_P(MovingAverageTest,BlanketTest)128*6777b538SAndroid Build Coastguard Worker TEST_P(MovingAverageTest, BlanketTest) {
129*6777b538SAndroid Build Coastguard Worker   const size_t window_size = GetParam();
130*6777b538SAndroid Build Coastguard Worker   MovingAverage<int, int64_t> window(window_size);
131*6777b538SAndroid Build Coastguard Worker   for (int repeats = 0; repeats < 2; ++repeats) {
132*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < std::size(kTestValues); ++i) {
133*6777b538SAndroid Build Coastguard Worker       window.AddSample(kTestValues[i]);
134*6777b538SAndroid Build Coastguard Worker       int slow_mean = 0;
135*6777b538SAndroid Build Coastguard Worker       for (size_t j = 0; j < window_size && j <= i; ++j) {
136*6777b538SAndroid Build Coastguard Worker         slow_mean += kTestValues[i - j];
137*6777b538SAndroid Build Coastguard Worker       }
138*6777b538SAndroid Build Coastguard Worker       slow_mean /= std::min(window_size, i + 1);
139*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(window.Mean(), slow_mean);
140*6777b538SAndroid Build Coastguard Worker     }
141*6777b538SAndroid Build Coastguard Worker     window.Reset();
142*6777b538SAndroid Build Coastguard Worker   }
143*6777b538SAndroid Build Coastguard Worker }
144*6777b538SAndroid Build Coastguard Worker 
145*6777b538SAndroid Build Coastguard Worker class MovingDeviationTest : public testing::TestWithParam<unsigned int> {};
146*6777b538SAndroid Build Coastguard Worker 
147*6777b538SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(All,
148*6777b538SAndroid Build Coastguard Worker                          MovingDeviationTest,
149*6777b538SAndroid Build Coastguard Worker                          testing::ValuesIn({1u, 2u, 3u, 4u, 5u, 6u, 7u, 8u, 9u,
150*6777b538SAndroid Build Coastguard Worker                                             10u, 17u, 20u, 100u}));
151*6777b538SAndroid Build Coastguard Worker 
TEST_P(MovingDeviationTest,BlanketTest)152*6777b538SAndroid Build Coastguard Worker TEST_P(MovingDeviationTest, BlanketTest) {
153*6777b538SAndroid Build Coastguard Worker   const size_t window_size = GetParam();
154*6777b538SAndroid Build Coastguard Worker   MovingAverageDeviation<double> window(window_size);
155*6777b538SAndroid Build Coastguard Worker   for (int repeats = 0; repeats < 2; ++repeats) {
156*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < std::size(kTestValues); ++i) {
157*6777b538SAndroid Build Coastguard Worker       window.AddSample(kTestValues[i]);
158*6777b538SAndroid Build Coastguard Worker       double slow_deviation = 0;
159*6777b538SAndroid Build Coastguard Worker       double mean = window.Mean();
160*6777b538SAndroid Build Coastguard Worker       for (size_t j = 0; j < window_size && j <= i; ++j) {
161*6777b538SAndroid Build Coastguard Worker         slow_deviation +=
162*6777b538SAndroid Build Coastguard Worker             (kTestValues[i - j] - mean) * (kTestValues[i - j] - mean);
163*6777b538SAndroid Build Coastguard Worker       }
164*6777b538SAndroid Build Coastguard Worker       slow_deviation /= std::min(window_size, i + 1);
165*6777b538SAndroid Build Coastguard Worker       slow_deviation = sqrt(slow_deviation);
166*6777b538SAndroid Build Coastguard Worker       double fast_deviation = window.Deviation();
167*6777b538SAndroid Build Coastguard Worker       EXPECT_TRUE(std::abs(fast_deviation - slow_deviation) < 1e-9);
168*6777b538SAndroid Build Coastguard Worker     }
169*6777b538SAndroid Build Coastguard Worker     window.Reset();
170*6777b538SAndroid Build Coastguard Worker   }
171*6777b538SAndroid Build Coastguard Worker }
172*6777b538SAndroid Build Coastguard Worker 
TEST(MovingWindowTest,Iteration)173*6777b538SAndroid Build Coastguard Worker TEST(MovingWindowTest, Iteration) {
174*6777b538SAndroid Build Coastguard Worker   const size_t kWindowSize = 10;
175*6777b538SAndroid Build Coastguard Worker   MovingWindow<int, base::MovingWindowFeatures::Iteration> window(kWindowSize);
176*6777b538SAndroid Build Coastguard Worker   for (int repeats = 0; repeats < 2; ++repeats) {
177*6777b538SAndroid Build Coastguard Worker     for (size_t i = 0; i < std::size(kTestValues); ++i) {
178*6777b538SAndroid Build Coastguard Worker       window.AddSample(kTestValues[i]);
179*6777b538SAndroid Build Coastguard Worker       size_t j = 0;
180*6777b538SAndroid Build Coastguard Worker       const size_t in_window = std::min(i + 1, kWindowSize);
181*6777b538SAndroid Build Coastguard Worker       for (int value : window) {
182*6777b538SAndroid Build Coastguard Worker         ASSERT_LT(j, in_window);
183*6777b538SAndroid Build Coastguard Worker         EXPECT_EQ(value, kTestValues[i + j + 1 - in_window]);
184*6777b538SAndroid Build Coastguard Worker         ++j;
185*6777b538SAndroid Build Coastguard Worker       }
186*6777b538SAndroid Build Coastguard Worker       EXPECT_EQ(j, in_window);
187*6777b538SAndroid Build Coastguard Worker     }
188*6777b538SAndroid Build Coastguard Worker     window.Reset();
189*6777b538SAndroid Build Coastguard Worker   }
190*6777b538SAndroid Build Coastguard Worker }
191*6777b538SAndroid Build Coastguard Worker 
TEST(MovingMeanDeviation,WorksWithTimeDelta)192*6777b538SAndroid Build Coastguard Worker TEST(MovingMeanDeviation, WorksWithTimeDelta) {
193*6777b538SAndroid Build Coastguard Worker   MovingAverageDeviation<base::TimeDelta> window(2);
194*6777b538SAndroid Build Coastguard Worker   window.AddSample(base::Milliseconds(400));
195*6777b538SAndroid Build Coastguard Worker   window.AddSample(base::Milliseconds(200));
196*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Mean(), base::Milliseconds(300));
197*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Deviation(), base::Milliseconds(100));
198*6777b538SAndroid Build Coastguard Worker   window.AddSample(base::Seconds(40));
199*6777b538SAndroid Build Coastguard Worker   window.AddSample(base::Seconds(20));
200*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Mean(), base::Seconds(30));
201*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(window.Deviation(), base::Seconds(10));
202*6777b538SAndroid Build Coastguard Worker }
203*6777b538SAndroid Build Coastguard Worker 
204*6777b538SAndroid Build Coastguard Worker }  // namespace base
205