1 /*
2  * Copyright (C) 2019 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.power;
18 
19 import static org.junit.Assert.assertEquals;
20 import static org.mockito.Mockito.spy;
21 import static org.mockito.Mockito.when;
22 
23 import android.os.PowerManager;
24 
25 import org.junit.Test;
26 
27 import java.io.PrintWriter;
28 import java.io.StringWriter;
29 import java.text.SimpleDateFormat;
30 import java.util.TimeZone;
31 
32 /**
33  * Tests for {@link WakeLockLog}.
34  */
35 public class WakeLockLogTest {
36 
37     @Test
testAddTwoItems()38     public void testAddTwoItems() {
39         final int tagDatabaseSize = 128;
40         final int logSize = 20;
41         TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
42         WakeLockLog log = new WakeLockLog(injectorSpy);
43 
44         when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
45         log.onWakeLockAcquired("TagPartial", 101,
46                 PowerManager.PARTIAL_WAKE_LOCK | PowerManager.ON_AFTER_RELEASE);
47 
48         when(injectorSpy.currentTimeMillis()).thenReturn(1150L);
49         log.onWakeLockAcquired("TagFull", 102,
50                 PowerManager.FULL_WAKE_LOCK | PowerManager.ACQUIRE_CAUSES_WAKEUP);
51 
52         assertEquals("Wake Lock Log\n"
53                 + "  01-01 00:00:01.000 - 101 - ACQ TagPartial (partial,on-after-release)\n"
54                 + "  01-01 00:00:01.150 - 102 - ACQ TagFull (full,acq-causes-wake)\n"
55                 + "  -\n"
56                 + "  Events: 2, Time-Resets: 0\n"
57                 + "  Buffer, Bytes used: 6\n",
58                 dumpLog(log, false));
59     }
60 
61     @Test
testAddTwoItemsWithTimeReset()62     public void testAddTwoItemsWithTimeReset() {
63         final int tagDatabaseSize = 128;
64         final int logSize = 20;
65         TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
66         WakeLockLog log = new WakeLockLog(injectorSpy);
67 
68         when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
69         log.onWakeLockAcquired("TagPartial", 101, PowerManager.PARTIAL_WAKE_LOCK);
70 
71         when(injectorSpy.currentTimeMillis()).thenReturn(1350L);
72         log.onWakeLockAcquired("TagFull", 102, PowerManager.FULL_WAKE_LOCK);
73 
74         assertEquals("Wake Lock Log\n"
75                 + "  01-01 00:00:01.000 - 101 - ACQ TagPartial (partial)\n"
76                 + "  01-01 00:00:01.350 - 102 - ACQ TagFull (full)\n"
77                 + "  -\n"
78                 + "  Events: 2, Time-Resets: 1\n"
79                 + "  Buffer, Bytes used: 15\n",
80                 dumpLog(log, false));
81     }
82 
83     @Test
testAddTwoItemsWithTagOverwrite()84     public void testAddTwoItemsWithTagOverwrite() {
85         final int tagDatabaseSize = 2;
86         final int logSize = 20;
87         TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
88         WakeLockLog log = new WakeLockLog(injectorSpy);
89 
90         when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
91         log.onWakeLockAcquired("TagPartial", 101, PowerManager.PARTIAL_WAKE_LOCK);
92 
93         when(injectorSpy.currentTimeMillis()).thenReturn(1150L);
94         log.onWakeLockAcquired("TagFull", 102, PowerManager.FULL_WAKE_LOCK);
95 
96         assertEquals("Wake Lock Log\n"
97                 + "  01-01 00:00:01.000 - --- - ACQ UNKNOWN (partial)\n"
98                 + "  01-01 00:00:01.150 - 102 - ACQ TagFull (full)\n"
99                 + "  -\n"
100                 + "  Events: 2, Time-Resets: 0\n"
101                 + "  Buffer, Bytes used: 6\n",
102                 dumpLog(log, false));
103     }
104 
105     @Test
testAddFourItemsWithRingBufferOverflow()106     public void testAddFourItemsWithRingBufferOverflow() {
107         final int tagDatabaseSize = 6;
108         final int logSize = 10;
109         TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
110         WakeLockLog log = new WakeLockLog(injectorSpy);
111 
112         // This first item will get deleted when ring buffer loops around
113         when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
114         log.onWakeLockAcquired("TagPartial", 101, PowerManager.PARTIAL_WAKE_LOCK);
115 
116         when(injectorSpy.currentTimeMillis()).thenReturn(1150L);
117         log.onWakeLockAcquired("TagFull", 102, PowerManager.FULL_WAKE_LOCK);
118         when(injectorSpy.currentTimeMillis()).thenReturn(1151L);
119         log.onWakeLockAcquired("TagThree", 101, PowerManager.PARTIAL_WAKE_LOCK);
120         when(injectorSpy.currentTimeMillis()).thenReturn(1152L);
121         log.onWakeLockAcquired("TagFour", 101, PowerManager.PARTIAL_WAKE_LOCK);
122 
123         assertEquals("Wake Lock Log\n"
124                 + "  01-01 00:00:01.150 - 102 - ACQ TagFull (full)\n"
125                 + "  01-01 00:00:01.151 - 101 - ACQ TagThree (partial)\n"
126                 + "  01-01 00:00:01.152 - 101 - ACQ TagFour (partial)\n"
127                 + "  -\n"
128                 + "  Events: 3, Time-Resets: 0\n"
129                 + "  Buffer, Bytes used: 9\n",
130                 dumpLog(log, false));
131     }
132 
133     @Test
testAddItemWithBadTag()134     public void testAddItemWithBadTag() {
135         final int tagDatabaseSize = 6;
136         final int logSize = 10;
137         TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
138         WakeLockLog log = new WakeLockLog(injectorSpy);
139 
140         // Bad tag means it wont get written
141         when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
142         log.onWakeLockAcquired(null /* tag */, 0 /* ownerUid */, PowerManager.PARTIAL_WAKE_LOCK);
143 
144         assertEquals("Wake Lock Log\n"
145                 + "  -\n"
146                 + "  Events: 0, Time-Resets: 0\n"
147                 + "  Buffer, Bytes used: 0\n",
148                 dumpLog(log, false));
149     }
150 
151     @Test
testAddItemWithReducedTagName()152     public void testAddItemWithReducedTagName() {
153         final int tagDatabaseSize = 6;
154         final int logSize = 10;
155         TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
156         WakeLockLog log = new WakeLockLog(injectorSpy);
157 
158         when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
159         log.onWakeLockAcquired("*job*/com.one.two.3hree/.one..Last", 101,
160                 PowerManager.PARTIAL_WAKE_LOCK);
161 
162         assertEquals("Wake Lock Log\n"
163                 + "  01-01 00:00:01.000 - 101 - ACQ *job*/c.o.t.3/.o..Last (partial)\n"
164                 + "  -\n"
165                 + "  Events: 1, Time-Resets: 0\n"
166                 + "  Buffer, Bytes used: 3\n",
167                 dumpLog(log, false));
168     }
169 
170     @Test
testAddAcquireAndReleaseWithRepeatTagName()171     public void testAddAcquireAndReleaseWithRepeatTagName() {
172         final int tagDatabaseSize = 6;
173         final int logSize = 10;
174         TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
175         WakeLockLog log = new WakeLockLog(injectorSpy);
176 
177         when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
178         log.onWakeLockAcquired("HowdyTag", 101, PowerManager.PARTIAL_WAKE_LOCK);
179         when(injectorSpy.currentTimeMillis()).thenReturn(1001L);
180         log.onWakeLockReleased("HowdyTag", 101);
181 
182         assertEquals("Wake Lock Log\n"
183                 + "  01-01 00:00:01.000 - 101 - ACQ HowdyTag (partial)\n"
184                 + "  01-01 00:00:01.001 - 101 - REL HowdyTag\n"
185                 + "  -\n"
186                 + "  Events: 2, Time-Resets: 0\n"
187                 + "  Buffer, Bytes used: 5\n"
188                 + "  Tag Database: size(5), entries: 1, Bytes used: 80\n",
189                 dumpLog(log, true));
190     }
191 
192     @Test
testAddAcquireAndReleaseWithTimeTravel()193     public void testAddAcquireAndReleaseWithTimeTravel() {
194         final int tagDatabaseSize = 6;
195         final int logSize = 10;
196         TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
197         WakeLockLog log = new WakeLockLog(injectorSpy);
198 
199         when(injectorSpy.currentTimeMillis()).thenReturn(1100L);
200         log.onWakeLockAcquired("HowdyTag", 101, PowerManager.PARTIAL_WAKE_LOCK);
201 
202         // New element goes back in time...should not be written to log.
203         when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
204         log.onWakeLockReleased("HowdyTag", 101);
205 
206         assertEquals("Wake Lock Log\n"
207                 + "  01-01 00:00:01.100 - 101 - ACQ HowdyTag (partial)\n"
208                 + "  -\n"
209                 + "  Events: 1, Time-Resets: 0\n"
210                 + "  Buffer, Bytes used: 3\n",
211                 dumpLog(log, false));
212     }
213 
214     @Test
testAddSystemWakelock()215     public void testAddSystemWakelock() {
216         final int tagDatabaseSize = 6;
217         final int logSize = 10;
218         TestInjector injectorSpy = spy(new TestInjector(tagDatabaseSize, logSize));
219         WakeLockLog log = new WakeLockLog(injectorSpy);
220 
221         when(injectorSpy.currentTimeMillis()).thenReturn(1000L);
222         log.onWakeLockAcquired("TagPartial", 101,
223                 PowerManager.PARTIAL_WAKE_LOCK | PowerManager.SYSTEM_WAKELOCK);
224 
225         assertEquals("Wake Lock Log\n"
226                         + "  01-01 00:00:01.000 - 101 - ACQ TagPartial (partial,system-wakelock)\n"
227                         + "  -\n"
228                         + "  Events: 1, Time-Resets: 0\n"
229                         + "  Buffer, Bytes used: 3\n",
230                 dumpLog(log, false));
231     }
232 
dumpLog(WakeLockLog log, boolean includeTagDb)233     private String dumpLog(WakeLockLog log, boolean includeTagDb) {
234         StringWriter sw = new StringWriter();
235         PrintWriter pw = new PrintWriter(sw);
236         log.dump(pw, includeTagDb);
237         return sw.toString();
238     }
239 
240     public class TestInjector extends WakeLockLog.Injector {
241         private final int mTagDatabaseSize;
242         private final int mLogSize;
243 
TestInjector(int tagDatabaseSize, int logSize)244         public TestInjector(int tagDatabaseSize, int logSize) {
245             mTagDatabaseSize = tagDatabaseSize;
246             mLogSize = logSize;
247         }
248 
249         @Override
getTagDatabaseSize()250         public int getTagDatabaseSize() {
251             return mTagDatabaseSize;
252         }
253 
254         @Override
getLogSize()255         public int getLogSize() {
256             return mLogSize;
257         }
258 
259         @Override
getDateFormat()260         public SimpleDateFormat getDateFormat() {
261             SimpleDateFormat format = new SimpleDateFormat(super.getDateFormat().toPattern());
262             format.setTimeZone(TimeZone.getTimeZone("UTC"));
263             return format;
264         }
265     }
266 }
267