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 package com.android.server.am; 18 19 import static org.junit.Assert.assertEquals; 20 import static org.junit.Assert.assertFalse; 21 import static org.junit.Assert.assertTrue; 22 23 import android.os.SystemClock; 24 25 import org.junit.Before; 26 import org.junit.Test; 27 28 /** 29 * Test class for {@link DropboxRateLimiter}. 30 * 31 * Build/Install/Run: 32 * atest DropboxRateLimiterTest 33 */ 34 public class DropboxRateLimiterTest { 35 private DropboxRateLimiter mRateLimiter; 36 private TestClock mClock; 37 38 @Before setUp()39 public void setUp() { 40 mClock = new TestClock(); 41 mRateLimiter = new DropboxRateLimiter(mClock); 42 } 43 44 @Test testMultipleProcesses()45 public void testMultipleProcesses() { 46 // The first 5 entries should not be rate limited. 47 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 48 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 49 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 50 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 51 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 52 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 53 // Different processes and tags should not get rate limited either. 54 assertFalse(mRateLimiter.shouldRateLimit("tag", "process2").shouldRateLimit()); 55 assertFalse(mRateLimiter.shouldRateLimit("tag2", "process").shouldRateLimit()); 56 // The 7th entry of the same process should be rate limited. 57 assertTrue(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 58 } 59 60 @Test testBufferClearing()61 public void testBufferClearing() throws Exception { 62 // The first 5 entries should not be rate limited. 63 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 64 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 65 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 66 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 67 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 68 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 69 // The 7th entry of the same process should be rate limited. 70 assertTrue(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 71 72 // After 11 minutes there should be nothing left in the buffer and the same type of entry 73 // should not get rate limited anymore. 74 mClock.setOffsetMillis(11 * 60 * 1000); 75 76 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 77 } 78 79 @Test testRecentlyDroppedCount()80 public void testRecentlyDroppedCount() throws Exception { 81 assertEquals(0, 82 mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated()); 83 assertEquals(0, 84 mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated()); 85 assertEquals(0, 86 mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated()); 87 assertEquals(0, 88 mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated()); 89 assertEquals(0, 90 mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated()); 91 assertEquals(0, 92 mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated()); 93 assertEquals(1, 94 mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated()); 95 assertEquals(2, 96 mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated()); 97 98 // After 11 minutes the rate limiting buffer will be cleared and rate limiting will stop. 99 mClock.setOffsetMillis(11 * 60 * 1000); 100 101 // The first call after rate limiting stops will still return the number of dropped events. 102 assertEquals(2, 103 mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated()); 104 // The next call should show that the dropped event counter was reset. 105 assertEquals(0, 106 mRateLimiter.shouldRateLimit("tag", "p").droppedCountSinceRateLimitActivated()); 107 } 108 109 @Test testStrictRepeatedLimiting()110 public void testStrictRepeatedLimiting() throws Exception { 111 // The first 6 entries should not be rate limited. 112 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 113 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 114 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 115 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 116 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 117 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 118 // The 7th entry of the same process should be rate limited. 119 assertTrue(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 120 121 // After 11 minutes there should be nothing left in the buffer and the same type of entry 122 // should not get rate limited anymore. 123 mClock.setOffsetMillis(11 * 60 * 1000); 124 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 125 // The first 6 entries should not be rate limited again. 126 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 127 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 128 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 129 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 130 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 131 132 // The 7th entry of the same process should be rate limited. 133 assertTrue(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 134 135 // After 11 more minutes there should be nothing left in the buffer and the same type of 136 // entry should not get rate limited anymore. 137 mClock.setOffsetMillis(22 * 60 * 1000); 138 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 139 140 // Repeated crashes after the last reset being rate limited should be restricted faster. 141 assertTrue(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 142 143 // We now need to wait 21 minutes for the buffer should be empty again. 144 mClock.setOffsetMillis(43 * 60 * 1000); 145 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 146 147 // After yet another 21 minutes, this time without triggering rate limiting, the strict 148 // limiting should be turnd off. 149 mClock.setOffsetMillis(64 * 60 * 1000); 150 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 151 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 152 153 // As rate limiting was not triggered in the last reset, after another 11 minutes the 154 // buffer should still act as normal. 155 mClock.setOffsetMillis(75 * 60 * 1000); 156 // The first 6 entries should not be rate limited. 157 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 158 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 159 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 160 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 161 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 162 assertFalse(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 163 // The 7th entry of the same process should be rate limited. 164 assertTrue(mRateLimiter.shouldRateLimit("tag", "process").shouldRateLimit()); 165 } 166 167 private static class TestClock implements DropboxRateLimiter.Clock { 168 long mOffsetMillis = 0L; 169 uptimeMillis()170 public long uptimeMillis() { 171 return mOffsetMillis + SystemClock.uptimeMillis(); 172 } 173 setOffsetMillis(long millis)174 public void setOffsetMillis(long millis) { 175 mOffsetMillis = millis; 176 } 177 } 178 } 179