1 /*
2  * Copyright (C) 2016 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.server.notification;
17 
18 
19 import android.test.AndroidTestCase;
20 import android.test.suitebuilder.annotation.SmallTest;
21 
22 public class RateEstimatorTest extends AndroidTestCase {
23     private long mTestStartTime;
24     private RateEstimator mEstimator;
25 
26     @Override
setUp()27     public void setUp() {
28         mTestStartTime = 1225731600000L;
29         mEstimator = new RateEstimator();
30     }
31 
32     @SmallTest
testRunningTimeBackwardDoesntExplodeUpdate()33     public void testRunningTimeBackwardDoesntExplodeUpdate() throws Exception {
34         assertUpdateTime(mTestStartTime);
35         assertUpdateTime(mTestStartTime - 1000L);
36     }
37 
38     @SmallTest
testRunningTimeBackwardDoesntExplodeGet()39     public void testRunningTimeBackwardDoesntExplodeGet() throws Exception {
40         assertUpdateTime(mTestStartTime);
41         final float rate = mEstimator.getRate(mTestStartTime - 1000L);
42         assertFalse(Float.isInfinite(rate));
43         assertFalse(Float.isNaN(rate));
44     }
45 
46     @SmallTest
testInstantaneousEventsDontExplodeUpdate()47     public void testInstantaneousEventsDontExplodeUpdate() throws Exception {
48         assertUpdateTime(mTestStartTime);
49         assertUpdateTime(mTestStartTime);
50     }
51 
52     @SmallTest
testInstantaneousEventsDontExplodeGet()53     public void testInstantaneousEventsDontExplodeGet() throws Exception {
54         assertUpdateTime(mTestStartTime);
55         assertUpdateTime(mTestStartTime);
56         final float rate = mEstimator.getRate(mTestStartTime);
57         assertFalse(Float.isInfinite(rate));
58         assertFalse(Float.isNaN(rate));
59     }
60 
61     @SmallTest
testInstantaneousBurstIsEstimatedUnderTwoPercent()62     public void testInstantaneousBurstIsEstimatedUnderTwoPercent() throws Exception {
63         assertUpdateTime(mTestStartTime);
64         long eventStart = mTestStartTime + 1000; // start event a long time after initialization
65         long nextEventTime = postEvents(eventStart, 0, 5); // five events at \inf
66         final float rate = mEstimator.getRate(nextEventTime);
67         assertLessThan("Rate", rate, 20f);
68     }
69 
70     @SmallTest
testCompactBurstIsEstimatedUnderTwoPercent()71     public void testCompactBurstIsEstimatedUnderTwoPercent() throws Exception {
72         assertUpdateTime(mTestStartTime);
73         long eventStart = mTestStartTime + 1000; // start event a long time after initialization
74         long nextEventTime = postEvents(eventStart, 1, 5); // five events at 1000Hz
75         final float rate = mEstimator.getRate(nextEventTime);
76         assertLessThan("Rate", rate, 20f);
77     }
78 
79     @SmallTest
testSustained1000HzBurstIsEstimatedOverNinetyPercent()80     public void testSustained1000HzBurstIsEstimatedOverNinetyPercent() throws Exception {
81         assertUpdateTime(mTestStartTime);
82         long eventStart = mTestStartTime + 1000; // start event a long time after initialization
83         long nextEventTime = postEvents(eventStart, 1, 100); // one hundred events at 1000Hz
84         final float rate = mEstimator.getRate(nextEventTime);
85         assertGreaterThan("Rate", rate, 900f);
86     }
87 
88     @SmallTest
testSustained100HzBurstIsEstimatedOverNinetyPercent()89     public void testSustained100HzBurstIsEstimatedOverNinetyPercent() throws Exception {
90         assertUpdateTime(mTestStartTime);
91         long eventStart = mTestStartTime + 1000; // start event a long time after initialization
92         long nextEventTime = postEvents(eventStart, 10, 100); // one hundred events at 100Hz
93         final float rate = mEstimator.getRate(nextEventTime);
94 
95         assertGreaterThan("Rate", rate, 90f);
96     }
97 
98     @SmallTest
testRecoverQuicklyAfterSustainedBurst()99     public void testRecoverQuicklyAfterSustainedBurst() throws Exception {
100         assertUpdateTime(mTestStartTime);
101         long eventStart = mTestStartTime + 1000; // start event a long time after initialization
102         long nextEventTime = postEvents(eventStart, 10, 1000); // one hundred events at 100Hz
103         final float rate = mEstimator.getRate(nextEventTime + 5000L); // two seconds later
104         assertLessThan("Rate", rate, 2f);
105     }
106 
107     @SmallTest
testEstimateShouldNotOvershoot()108     public void testEstimateShouldNotOvershoot() throws Exception {
109         assertUpdateTime(mTestStartTime);
110         long eventStart = mTestStartTime + 1000; // start event a long time after initialization
111         long nextEventTime = postEvents(eventStart, 1, 1000); // one thousand events at 1000Hz
112         final float rate = mEstimator.getRate(nextEventTime);
113         assertLessThan("Rate", rate, 1000f);
114     }
115 
116     @SmallTest
testGetRateWithoutUpdate()117     public void testGetRateWithoutUpdate() throws Exception {
118         final float rate = mEstimator.getRate(mTestStartTime);
119         assertLessThan("Rate", rate, 0.1f);
120     }
121 
122     @SmallTest
testGetRateWithOneUpdate()123     public void testGetRateWithOneUpdate() throws Exception {
124         assertUpdateTime(mTestStartTime);
125         final float rate = mEstimator.getRate(mTestStartTime+1);
126         assertLessThan("Rate", rate, 1f);
127     }
128 
assertLessThan(String label, float a, float b)129     private void assertLessThan(String label, float a, float b)  {
130         assertTrue(String.format("%s was %f, but should be less than %f", label, a, b), a <= b);
131     }
132 
assertGreaterThan(String label, float a, float b)133     private void assertGreaterThan(String label, float a, float b)  {
134         assertTrue(String.format("%s was %f, but should be more than %f", label, a, b), a >= b);
135     }
136 
137     /** @returns the next event time. */
postEvents(long start, long dt, int num)138     private long postEvents(long start, long dt, int num) {
139         long time = start;
140         for (int i = 0; i < num; i++) {
141             mEstimator.update(time);
142             time += dt;
143         }
144         return time;
145     }
146 
assertUpdateTime(long time)147     private void assertUpdateTime(long time) {
148         final float rate = mEstimator.update(time);
149         assertFalse(Float.isInfinite(rate));
150         assertFalse(Float.isNaN(rate));
151     }
152 }
153