xref: /aosp_15_r20/external/pigweed/pw_allocator/benchmarks/measurements_test.cc (revision 61c4878ac05f98d0ceed94b57d316916de578985)
1 // Copyright 2024 The Pigweed Authors
2 //
3 // Licensed under the Apache License, Version 2.0 (the "License"); you may not
4 // use this file except in compliance with the License. You may obtain a copy of
5 // the License at
6 //
7 //     https://www.apache.org/licenses/LICENSE-2.0
8 //
9 // Unless required by applicable law or agreed to in writing, software
10 // distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
11 // WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
12 // License for the specific language governing permissions and limitations under
13 // the License.
14 
15 #include "pw_allocator/benchmarks/measurements.h"
16 
17 #include "pw_metric/metric.h"
18 #include "pw_unit_test/framework.h"
19 
20 namespace {
21 
22 using pw::allocator::Measurement;
23 using pw::allocator::Measurements;
24 using pw::allocator::internal::BenchmarkSample;
25 
26 constexpr pw::metric::Token kName = PW_TOKENIZE_STRING("test");
27 
TEST(MeasurementTest,Construct_Default)28 TEST(MeasurementTest, Construct_Default) {
29   Measurement<size_t> measurement(kName, 0);
30 
31   EXPECT_EQ(measurement.nanoseconds(), 0.f);
32   EXPECT_FLOAT_EQ(measurement.fragmentation(), 0.f);
33   EXPECT_FLOAT_EQ(measurement.largest(), 0.f);
34   EXPECT_EQ(measurement.failures(), 0u);
35 }
36 
TEST(MeasurementTest,Update_Once)37 TEST(MeasurementTest, Update_Once) {
38   BenchmarkSample data = {
39       .nanoseconds = 1000,
40       .fragmentation = 0.1f,
41       .largest = 4096,
42       .failed = false,
43   };
44 
45   Measurement<size_t> measurement(kName, 0);
46   measurement.Update(data);
47 
48   EXPECT_FLOAT_EQ(measurement.nanoseconds(), 1000.f);
49   EXPECT_FLOAT_EQ(measurement.fragmentation(), 0.1f);
50   EXPECT_FLOAT_EQ(measurement.largest(), 4096.f);
51   EXPECT_EQ(measurement.failures(), 0u);
52 }
53 
TEST(MeasurementTest,Update_TwiceSame)54 TEST(MeasurementTest, Update_TwiceSame) {
55   BenchmarkSample data = {
56       .nanoseconds = 1000,
57       .fragmentation = 0.1f,
58       .largest = 4096,
59       .failed = true,
60   };
61 
62   Measurement<size_t> measurement(kName, 0);
63   measurement.Update(data);
64   measurement.Update(data);
65 
66   EXPECT_FLOAT_EQ(measurement.nanoseconds(), 1000.f);
67   EXPECT_FLOAT_EQ(measurement.fragmentation(), 0.1f);
68   EXPECT_FLOAT_EQ(measurement.largest(), 4096.f);
69   EXPECT_EQ(measurement.failures(), 2u);
70 }
71 
TEST(MeasurementTest,Update_TwiceDifferent)72 TEST(MeasurementTest, Update_TwiceDifferent) {
73   BenchmarkSample data = {
74       .nanoseconds = 1000,
75       .fragmentation = 0.1f,
76       .largest = 4096,
77       .failed = true,
78   };
79 
80   Measurement<size_t> measurement(kName, 0);
81   measurement.Update(data);
82 
83   data.nanoseconds = 2000;
84   data.fragmentation = 0.04f;
85   data.largest = 2048;
86   data.failed = false;
87   measurement.Update(data);
88 
89   EXPECT_FLOAT_EQ(measurement.nanoseconds(), 1500.f);
90   EXPECT_FLOAT_EQ(measurement.fragmentation(), 0.07f);
91   EXPECT_FLOAT_EQ(measurement.largest(), 3072.f);
92   EXPECT_EQ(measurement.failures(), 1u);
93 }
94 
TEST(MeasurementTest,Update_ManyVarious)95 TEST(MeasurementTest, Update_ManyVarious) {
96   BenchmarkSample data;
97   data.largest = 8192;
98   Measurement<size_t> measurement(kName, 0);
99   for (size_t i = 0; i < 10; ++i) {
100     data.nanoseconds += 100.f;
101     data.fragmentation += 0.02f;
102     data.largest -= 512;
103     data.failed = !data.failed;
104     measurement.Update(data);
105   }
106 
107   // sum([1..10]) is 55, for averages that are 5.5 times each increment.
108   EXPECT_FLOAT_EQ(measurement.nanoseconds(), 5.5f * 100);
109   EXPECT_FLOAT_EQ(measurement.fragmentation(), 5.5f * 0.02f);
110   EXPECT_FLOAT_EQ(measurement.largest(), 8192 - (5.5f * 512));
111   EXPECT_EQ(measurement.failures(), 5u);
112 }
113 
114 class TestMeasurements : public Measurements {
115  public:
TestMeasurements()116   TestMeasurements() : Measurements(kName) {}
~TestMeasurements()117   ~TestMeasurements() { Measurements::Clear(); }
118   using Measurements::AddByCount;
119   using Measurements::AddByFragmentation;
120   using Measurements::AddBySize;
121   using Measurements::GetByCount;
122   using Measurements::GetByFragmentation;
123   using Measurements::GetBySize;
124 };
125 
TEST(MeasurementsTest,ByCount)126 TEST(MeasurementsTest, ByCount) {
127   Measurement<size_t> at_least_0(kName, 0);
128   Measurement<size_t> at_least_10(kName, 10);
129   Measurement<size_t> at_least_100(kName, 100);
130 
131   TestMeasurements by_count;
132   by_count.AddByCount(at_least_0);
133   by_count.AddByCount(at_least_10);
134   by_count.AddByCount(at_least_100);
135 
136   EXPECT_EQ(&(by_count.GetByCount(0)), &at_least_0);
137   EXPECT_EQ(&(by_count.GetByCount(9)), &at_least_0);
138   EXPECT_EQ(&(by_count.GetByCount(10)), &at_least_10);
139   EXPECT_EQ(&(by_count.GetByCount(99)), &at_least_10);
140   EXPECT_EQ(&(by_count.GetByCount(100)), &at_least_100);
141   EXPECT_EQ(&(by_count.GetByCount(size_t(-1))), &at_least_100);
142 }
143 
TEST(MeasurementsTest,ByFragmentation)144 TEST(MeasurementsTest, ByFragmentation) {
145   Measurement<float> bottom_third(kName, 0.0f);
146   Measurement<float> middle_third(kName, 0.33f);
147   Measurement<float> top_third(kName, 0.66f);
148 
149   TestMeasurements by_fragmentation;
150   by_fragmentation.AddByFragmentation(bottom_third);
151   by_fragmentation.AddByFragmentation(middle_third);
152   by_fragmentation.AddByFragmentation(top_third);
153 
154   EXPECT_EQ(&(by_fragmentation.GetByFragmentation(0)), &bottom_third);
155   EXPECT_EQ(&(by_fragmentation.GetByFragmentation(0.3299)), &bottom_third);
156   EXPECT_EQ(&(by_fragmentation.GetByFragmentation(0.33f)), &middle_third);
157   EXPECT_EQ(&(by_fragmentation.GetByFragmentation(0.6599f)), &middle_third);
158   EXPECT_EQ(&(by_fragmentation.GetByFragmentation(0.66f)), &top_third);
159   EXPECT_EQ(&(by_fragmentation.GetByFragmentation(1.0f)), &top_third);
160 }
161 
TEST(MeasurementsTest,BySize)162 TEST(MeasurementsTest, BySize) {
163   Measurement<size_t> at_least_0(kName, 0);
164   Measurement<size_t> at_least_16(kName, 0x10);
165   Measurement<size_t> at_least_256(kName, 0x100);
166 
167   TestMeasurements by_size;
168   by_size.AddBySize(at_least_0);
169   by_size.AddBySize(at_least_16);
170   by_size.AddBySize(at_least_256);
171 
172   EXPECT_EQ(&(by_size.GetBySize(0)), &at_least_0);
173   EXPECT_EQ(&(by_size.GetBySize(0xf)), &at_least_0);
174   EXPECT_EQ(&(by_size.GetBySize(0x10)), &at_least_16);
175   EXPECT_EQ(&(by_size.GetBySize(0xff)), &at_least_16);
176   EXPECT_EQ(&(by_size.GetBySize(0x100)), &at_least_256);
177   EXPECT_EQ(&(by_size.GetBySize(size_t(-1))), &at_least_256);
178 }
179 
180 }  // namespace
181