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