1 /*
2  * Copyright (C) 2023 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 package com.android.modules.expresslog;
17 
18 import static org.junit.Assert.assertEquals;
19 import static org.junit.Assert.assertTrue;
20 
21 import androidx.test.filters.SmallTest;
22 
23 import org.junit.Test;
24 import org.junit.runner.RunWith;
25 import org.junit.runners.JUnit4;
26 
27 @RunWith(JUnit4.class)
28 @SmallTest
29 public class ScaledRangeOptionsTest {
30     private static final String TAG = ScaledRangeOptionsTest.class.getSimpleName();
31 
32     @Test
testGetBinsCount()33     public void testGetBinsCount() {
34         Histogram.ScaledRangeOptions options1 = new Histogram.ScaledRangeOptions(1, 100, 100, 2);
35         assertEquals(3, options1.getBinsCount());
36 
37         Histogram.ScaledRangeOptions options10 = new Histogram.ScaledRangeOptions(10, 100, 100, 2);
38         assertEquals(12, options10.getBinsCount());
39     }
40 
41     @Test(expected = IllegalArgumentException.class)
testConstructZeroBinsCount()42     public void testConstructZeroBinsCount() {
43         new Histogram.ScaledRangeOptions(0, 100, 100, 2);
44     }
45 
46     @Test(expected = IllegalArgumentException.class)
testConstructNegativeBinsCount()47     public void testConstructNegativeBinsCount() {
48         new Histogram.ScaledRangeOptions(-1, 100, 100, 2);
49     }
50 
51     @Test(expected = IllegalArgumentException.class)
testConstructNegativeFirstBinWidth()52     public void testConstructNegativeFirstBinWidth() {
53         new Histogram.ScaledRangeOptions(10, 100, -100, 2);
54     }
55 
56     @Test(expected = IllegalArgumentException.class)
testConstructTooSmallFirstBinWidth()57     public void testConstructTooSmallFirstBinWidth() {
58         new Histogram.ScaledRangeOptions(10, 100, 0.5f, 2);
59     }
60 
61     @Test(expected = IllegalArgumentException.class)
testConstructNegativeScaleFactor()62     public void testConstructNegativeScaleFactor() {
63         new Histogram.ScaledRangeOptions(10, 100, 100, -2);
64     }
65 
66     @Test(expected = IllegalArgumentException.class)
testConstructTooSmallScaleFactor()67     public void testConstructTooSmallScaleFactor() {
68         new Histogram.ScaledRangeOptions(10, 100, 100, 0.5f);
69     }
70 
71     @Test(expected = IllegalArgumentException.class)
testConstructTooBigScaleFactor()72     public void testConstructTooBigScaleFactor() {
73         new Histogram.ScaledRangeOptions(10, 100, 100, 500.f);
74     }
75 
76     @Test(expected = IllegalArgumentException.class)
testConstructTooBigBinRange()77     public void testConstructTooBigBinRange() {
78         new Histogram.ScaledRangeOptions(100, 100, 100, 10.f);
79     }
80 
81     @Test
testBinIndexForRangeEqual1()82     public void testBinIndexForRangeEqual1() {
83         Histogram.ScaledRangeOptions options = new Histogram.ScaledRangeOptions(10, 1, 1, 1);
84         assertEquals(12, options.getBinsCount());
85 
86         assertEquals(11, options.getBinForSample(11));
87 
88         for (int i = 0, bins = options.getBinsCount(); i < bins; i++) {
89             assertEquals(i, options.getBinForSample(i));
90         }
91     }
92 
93     @Test
testBinIndexForRangeEqual2()94     public void testBinIndexForRangeEqual2() {
95         // this should produce bin otpions similar to linear histogram with bin width 2
96         Histogram.ScaledRangeOptions options = new Histogram.ScaledRangeOptions(10, 1, 2, 1);
97         assertEquals(12, options.getBinsCount());
98 
99         for (int i = 0, bins = options.getBinsCount(); i < bins; i++) {
100             assertEquals(i, options.getBinForSample(i * 2));
101             assertEquals(i, options.getBinForSample(i * 2 - 1));
102         }
103     }
104 
105     @Test
testBinIndexForRangeEqual5()106     public void testBinIndexForRangeEqual5() {
107         Histogram.ScaledRangeOptions options = new Histogram.ScaledRangeOptions(2, 0, 5, 1);
108         assertEquals(4, options.getBinsCount());
109         for (int i = 0; i < 2; i++) {
110             for (int sample = 0; sample < 5; sample++) {
111                 assertEquals(i + 1, options.getBinForSample(i * 5 + sample));
112             }
113         }
114     }
115 
116     @Test
testBinIndexForRangeEqual10()117     public void testBinIndexForRangeEqual10() {
118         Histogram.ScaledRangeOptions options = new Histogram.ScaledRangeOptions(10, 1, 10, 1);
119         assertEquals(0, options.getBinForSample(0));
120         assertEquals(options.getBinsCount() - 2, options.getBinForSample(100));
121         assertEquals(options.getBinsCount() - 1, options.getBinForSample(101));
122 
123         final float binSize = (101 - 1) / 10f;
124         for (int i = 1, bins = options.getBinsCount() - 1; i < bins; i++) {
125             assertEquals(i, options.getBinForSample(i * binSize));
126         }
127     }
128 
129     @Test
testBinIndexForScaleFactor2()130     public void testBinIndexForScaleFactor2() {
131         final int binsCount = 10;
132         final int minValue = 10;
133         final int firstBinWidth = 5;
134         final int scaledFactor = 2;
135 
136         Histogram.ScaledRangeOptions options = new Histogram.ScaledRangeOptions(
137                 binsCount, minValue, firstBinWidth, scaledFactor);
138         assertEquals(binsCount + 2, options.getBinsCount());
139         long[] binCounts = new long[10];
140 
141         // precalculate max valid value - start value for the overflow bin
142         int lastBinStartValue = minValue; //firstBinMin value
143         int lastBinWidth = firstBinWidth;
144         for (int binIdx = 2; binIdx <= binsCount + 1; binIdx++) {
145             lastBinStartValue = lastBinStartValue + lastBinWidth;
146             lastBinWidth *= scaledFactor;
147         }
148 
149         // underflow bin
150         for (int i = 1; i < minValue; i++) {
151             assertEquals(0, options.getBinForSample(i));
152         }
153 
154         for (int i = 10; i < lastBinStartValue; i++) {
155             assertTrue(options.getBinForSample(i) > 0);
156             assertTrue(options.getBinForSample(i) <= binsCount);
157             binCounts[options.getBinForSample(i) - 1]++;
158         }
159 
160         // overflow bin
161         assertEquals(binsCount + 1, options.getBinForSample(lastBinStartValue));
162 
163         for (int i = 1; i < binsCount; i++) {
164             assertEquals(binCounts[i], binCounts[i - 1] * 2L);
165         }
166     }
167 }
168