• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2022 The Android Open Source Project
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  *      http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 
18 #include <android-base/file.h>
19 #include <android-base/test_utils.h>
20 #include <androidfw/Util.h>
21 
22 #include "TestHelpers.h"
23 
24 #include <androidfw/ResourceTimer.h>
25 
26 namespace android {
27 
28 namespace {
29 
30 // Create a reading in us.  This is a convenience function to avoid multiplying by 1000
31 // everywhere.
US(int us)32 unsigned int US(int us) {
33   return us * 1000;
34 }
35 
36 }
37 
TEST(ResourceTimerTest,TimerBasic)38 TEST(ResourceTimerTest, TimerBasic) {
39   ResourceTimer::Timer timer;
40   ASSERT_THAT(timer.count, 0);
41   ASSERT_THAT(timer.total, 0);
42 
43   for (int i = 1; i <= 100; i++) {
44     timer.record(US(i));
45   }
46   ASSERT_THAT(timer.count, 100);
47   ASSERT_THAT(timer.total, US((101 * 100)/2));
48   ASSERT_THAT(timer.mintime, US(1));
49   ASSERT_THAT(timer.maxtime, US(100));
50   ASSERT_THAT(timer.pvalues.p50.floor, 0);
51   ASSERT_THAT(timer.pvalues.p50.nominal, 0);
52   ASSERT_THAT(timer.largest[0], US(100));
53   ASSERT_THAT(timer.largest[1], US(99));
54   ASSERT_THAT(timer.largest[2], US(98));
55   ASSERT_THAT(timer.largest[3], US(97));
56   ASSERT_THAT(timer.largest[4], US(96));
57   timer.compute();
58   ASSERT_THAT(timer.pvalues.p50.floor, US(49));
59   ASSERT_THAT(timer.pvalues.p50.nominal, US(50));
60   ASSERT_THAT(timer.pvalues.p90.floor, US(89));
61   ASSERT_THAT(timer.pvalues.p90.nominal, US(90));
62   ASSERT_THAT(timer.pvalues.p95.floor, US(94));
63   ASSERT_THAT(timer.pvalues.p95.nominal, US(95));
64   ASSERT_THAT(timer.pvalues.p99.floor, US(98));
65   ASSERT_THAT(timer.pvalues.p99.nominal, US(99));
66 
67   // Test reset functionality.  All values should be zero after the reset.  Computing pvalues
68   // after the result should also yield zeros.
69   timer.reset();
70   ASSERT_THAT(timer.count, 0);
71   ASSERT_THAT(timer.total, 0);
72   ASSERT_THAT(timer.mintime, US(0));
73   ASSERT_THAT(timer.maxtime, US(0));
74   ASSERT_THAT(timer.pvalues.p50.floor, US(0));
75   ASSERT_THAT(timer.pvalues.p50.nominal, US(0));
76   ASSERT_THAT(timer.largest[0], US(0));
77   ASSERT_THAT(timer.largest[1], US(0));
78   ASSERT_THAT(timer.largest[2], US(0));
79   ASSERT_THAT(timer.largest[3], US(0));
80   ASSERT_THAT(timer.largest[4], US(0));
81   timer.compute();
82   ASSERT_THAT(timer.pvalues.p50.floor, US(0));
83   ASSERT_THAT(timer.pvalues.p50.nominal, US(0));
84   ASSERT_THAT(timer.pvalues.p90.floor, US(0));
85   ASSERT_THAT(timer.pvalues.p90.nominal, US(0));
86   ASSERT_THAT(timer.pvalues.p95.floor, US(0));
87   ASSERT_THAT(timer.pvalues.p95.nominal, US(0));
88   ASSERT_THAT(timer.pvalues.p99.floor, US(0));
89   ASSERT_THAT(timer.pvalues.p99.nominal, US(0));
90 
91   // Test again, adding elements in reverse.
92   for (int i = 100; i >= 1; i--) {
93     timer.record(US(i));
94   }
95   ASSERT_THAT(timer.count, 100);
96   ASSERT_THAT(timer.total, US((101 * 100)/2));
97   ASSERT_THAT(timer.mintime, US(1));
98   ASSERT_THAT(timer.maxtime, US(100));
99   ASSERT_THAT(timer.pvalues.p50.floor, 0);
100   ASSERT_THAT(timer.pvalues.p50.nominal, 0);
101   timer.compute();
102   ASSERT_THAT(timer.pvalues.p50.floor, US(49));
103   ASSERT_THAT(timer.pvalues.p50.nominal, US(50));
104   ASSERT_THAT(timer.pvalues.p90.floor, US(89));
105   ASSERT_THAT(timer.pvalues.p90.nominal, US(90));
106   ASSERT_THAT(timer.pvalues.p95.floor, US(94));
107   ASSERT_THAT(timer.pvalues.p95.nominal, US(95));
108   ASSERT_THAT(timer.pvalues.p99.floor, US(98));
109   ASSERT_THAT(timer.pvalues.p99.nominal, US(99));
110   ASSERT_THAT(timer.largest[0], US(100));
111   ASSERT_THAT(timer.largest[1], US(99));
112   ASSERT_THAT(timer.largest[2], US(98));
113   ASSERT_THAT(timer.largest[3], US(97));
114   ASSERT_THAT(timer.largest[4], US(96));
115 }
116 
TEST(ResourceTimerTest,TimerLimit)117 TEST(ResourceTimerTest, TimerLimit) {
118   ResourceTimer::Timer timer;
119 
120   // Event truncation means that a time of 1050us will be stored in the 1000us
121   // bucket.  Since there is a single event, all p-values lie in the same range.
122   timer.record(US(1050));
123   timer.compute();
124   ASSERT_THAT(timer.pvalues.p50.floor, US(900));
125   ASSERT_THAT(timer.pvalues.p50.nominal, US(1000));
126   ASSERT_THAT(timer.pvalues.p90.floor, US(900));
127   ASSERT_THAT(timer.pvalues.p90.nominal, US(1000));
128   ASSERT_THAT(timer.pvalues.p95.floor, US(900));
129   ASSERT_THAT(timer.pvalues.p95.nominal, US(1000));
130   ASSERT_THAT(timer.pvalues.p99.floor, US(900));
131   ASSERT_THAT(timer.pvalues.p99.nominal, US(1000));
132 }
133 
TEST(ResourceTimerTest,TimerCopy)134 TEST(ResourceTimerTest, TimerCopy) {
135   ResourceTimer::Timer source;
136   for (int i = 1; i <= 100; i++) {
137     source.record(US(i));
138   }
139   ResourceTimer::Timer timer;
140   ResourceTimer::Timer::copy(timer, source, true);
141   ASSERT_THAT(source.count, 0);
142   ASSERT_THAT(source.total, 0);
143   // compute() is not normally be called on a reset timer, but it should work and it should return
144   // all zeros.
145   source.compute();
146   ASSERT_THAT(source.pvalues.p50.floor, US(0));
147   ASSERT_THAT(source.pvalues.p50.nominal, US(0));
148   ASSERT_THAT(source.pvalues.p90.floor, US(0));
149   ASSERT_THAT(source.pvalues.p90.nominal, US(0));
150   ASSERT_THAT(source.pvalues.p95.floor, US(0));
151   ASSERT_THAT(source.pvalues.p95.nominal, US(0));
152   ASSERT_THAT(source.pvalues.p99.floor, US(0));
153   ASSERT_THAT(source.pvalues.p99.nominal, US(0));
154   ASSERT_THAT(source.largest[0], US(0));
155   ASSERT_THAT(source.largest[1], US(0));
156   ASSERT_THAT(source.largest[2], US(0));
157   ASSERT_THAT(source.largest[3], US(0));
158   ASSERT_THAT(source.largest[4], US(0));
159 
160   timer.compute();
161   ASSERT_THAT(timer.pvalues.p50.floor, US(49));
162   ASSERT_THAT(timer.pvalues.p50.nominal, US(50));
163   ASSERT_THAT(timer.pvalues.p90.floor, US(89));
164   ASSERT_THAT(timer.pvalues.p90.nominal, US(90));
165   ASSERT_THAT(timer.pvalues.p95.floor, US(94));
166   ASSERT_THAT(timer.pvalues.p95.nominal, US(95));
167   ASSERT_THAT(timer.pvalues.p99.floor, US(98));
168   ASSERT_THAT(timer.pvalues.p99.nominal, US(99));
169   ASSERT_THAT(timer.largest[0], US(100));
170   ASSERT_THAT(timer.largest[1], US(99));
171   ASSERT_THAT(timer.largest[2], US(98));
172   ASSERT_THAT(timer.largest[3], US(97));
173   ASSERT_THAT(timer.largest[4], US(96));
174 
175   // Call compute a second time.  The values must be the same.
176   timer.compute();
177   ASSERT_THAT(timer.pvalues.p50.floor, US(49));
178   ASSERT_THAT(timer.pvalues.p50.nominal, US(50));
179   ASSERT_THAT(timer.pvalues.p90.floor, US(89));
180   ASSERT_THAT(timer.pvalues.p90.nominal, US(90));
181   ASSERT_THAT(timer.pvalues.p95.floor, US(94));
182   ASSERT_THAT(timer.pvalues.p95.nominal, US(95));
183   ASSERT_THAT(timer.pvalues.p99.floor, US(98));
184   ASSERT_THAT(timer.pvalues.p99.nominal, US(99));
185   ASSERT_THAT(timer.largest[0], US(100));
186   ASSERT_THAT(timer.largest[1], US(99));
187   ASSERT_THAT(timer.largest[2], US(98));
188   ASSERT_THAT(timer.largest[3], US(97));
189   ASSERT_THAT(timer.largest[4], US(96));
190 
191   // Modify the source.  If timer and source share histogram arrays, this will introduce an
192   // error.
193   for (int i = 1; i <= 100; i++) {
194     source.record(US(i));
195   }
196   // Call compute a third time.  The values must be the same.
197   timer.compute();
198   ASSERT_THAT(timer.pvalues.p50.floor, US(49));
199   ASSERT_THAT(timer.pvalues.p50.nominal, US(50));
200   ASSERT_THAT(timer.pvalues.p90.floor, US(89));
201   ASSERT_THAT(timer.pvalues.p90.nominal, US(90));
202   ASSERT_THAT(timer.pvalues.p95.floor, US(94));
203   ASSERT_THAT(timer.pvalues.p95.nominal, US(95));
204   ASSERT_THAT(timer.pvalues.p99.floor, US(98));
205   ASSERT_THAT(timer.pvalues.p99.nominal, US(99));
206   ASSERT_THAT(timer.largest[0], US(100));
207   ASSERT_THAT(timer.largest[1], US(99));
208   ASSERT_THAT(timer.largest[2], US(98));
209   ASSERT_THAT(timer.largest[3], US(97));
210   ASSERT_THAT(timer.largest[4], US(96));
211 }
212 
213 // Verify that if too many oversize entries are reported, the percentile values cannot be computed
214 // and are set to zero.
TEST(ResourceTimerTest,TimerOversize)215 TEST(ResourceTimerTest, TimerOversize) {
216   static const int oversize = US(2 * 1000 * 1000);
217 
218   ResourceTimer::Timer timer;
219   for (int i = 1; i <= 100; i++) {
220     timer.record(US(i));
221   }
222 
223   // Insert enough oversize values to invalidate the p90, p95, and p99 percentiles.  The p50 is
224   // still computable.
225   for (int i = 1; i <= 50; i++) {
226     timer.record(oversize);
227   }
228   ASSERT_THAT(timer.largest[0], oversize);
229   ASSERT_THAT(timer.largest[1], oversize);
230   ASSERT_THAT(timer.largest[2], oversize);
231   ASSERT_THAT(timer.largest[3], oversize);
232   ASSERT_THAT(timer.largest[4], oversize);
233   timer.compute();
234   ASSERT_THAT(timer.pvalues.p50.floor, US(74));
235   ASSERT_THAT(timer.pvalues.p50.nominal, US(75));
236   ASSERT_THAT(timer.pvalues.p90.floor, 0);
237   ASSERT_THAT(timer.pvalues.p90.nominal, 0);
238   ASSERT_THAT(timer.pvalues.p95.floor, 0);
239   ASSERT_THAT(timer.pvalues.p95.nominal, 0);
240   ASSERT_THAT(timer.pvalues.p99.floor, 0);
241   ASSERT_THAT(timer.pvalues.p99.nominal, 0);
242 }
243 
244 
245 }  // namespace android
246