1d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski/* 2d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski * Copyright (C) 2016 The Android Open Source Project 3d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski * 4d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski * Licensed under the Apache License, Version 2.0 (the "License"); you may not 5d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski * use this file except in compliance with the License. You may obtain a copy of 6d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski * the License at 7d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski * 8d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski * http://www.apache.org/licenses/LICENSE-2.0 9d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski * 10d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski * Unless required by applicable law or agreed to in writing, software 11d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT 12d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the 13d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski * License for the specific language governing permissions and limitations under 14d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski * the License. 15d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski */ 16d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinskipackage com.android.internal.os; 17d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 18d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinskiimport android.support.test.filters.SmallTest; 19d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 20d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinskiimport junit.framework.TestCase; 21d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 22d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinskiimport java.nio.charset.Charset; 23d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 24d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinskipublic class KernelWakelockReaderTest extends TestCase { 25d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski /** 26d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski * Helper class that builds the mock Kernel module file /d/wakeup_sources. 27d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski */ 28d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski private static class ProcFileBuilder { 29d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski private final static String sHeader = "name\t\tactive_count\tevent_count\twakeup_count\t" + 30d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski "expire_count\tactive_since\ttotal_time\tmax_time\tlast_change\t" + 31d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski "prevent_suspend_time\n"; 32d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 33d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski private StringBuilder mStringBuilder; 34d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 35d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski private void ensureHeader() { 36d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski if (mStringBuilder == null) { 37d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski mStringBuilder = new StringBuilder(); 38d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski mStringBuilder.append(sHeader); 39d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski } 40d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski } 41d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 42d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski public ProcFileBuilder addLine(String name, int count, long timeMillis) { 43d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski ensureHeader(); 44d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski mStringBuilder.append(name).append("\t").append(count).append("\t0\t0\t0\t0\t") 45d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski .append(timeMillis).append("\t0\t0\t0\n"); 46d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski return this; 47d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski } 48d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 49d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski public byte[] getBytes() throws Exception { 50d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski ensureHeader(); 51d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski byte[] data = mStringBuilder.toString().getBytes(Charset.forName("UTF-8")); 52d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 53d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski // The Kernel puts a \0 at the end of the data. Since each of our lines ends with \n, 54d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski // we override the last \n with a \0. 55d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski data[data.length - 1] = 0; 56d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski return data; 57d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski } 58d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski } 59d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 60d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski private KernelWakelockReader mReader; 61d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 62d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski @Override 63d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski public void setUp() throws Exception { 64d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski super.setUp(); 65d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski mReader = new KernelWakelockReader(); 66d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski } 67d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 68d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski @SmallTest 69d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski public void testParseEmptyFile() throws Exception { 70d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski KernelWakelockStats staleStats = mReader.parseProcWakelocks(new byte[0], 0, true, 71d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski new KernelWakelockStats()); 72d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertTrue(staleStats.isEmpty()); 73d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski } 74d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 75d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski @SmallTest 76d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski public void testOnlyHeader() throws Exception { 77d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski byte[] buffer = new ProcFileBuilder().getBytes(); 78d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski KernelWakelockStats staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true, 79d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski new KernelWakelockStats()); 80d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertTrue(staleStats.isEmpty()); 81d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski } 82d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 83d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski @SmallTest 84d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski public void testOneWakelock() throws Exception { 85d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski byte[] buffer = new ProcFileBuilder() 86d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski .addLine("Wakelock", 34, 123) // Milliseconds 87d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski .getBytes(); 88d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski KernelWakelockStats staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true, 89d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski new KernelWakelockStats()); 90d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertEquals(1, staleStats.size()); 91d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertTrue(staleStats.containsKey("Wakelock")); 92d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 93d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski KernelWakelockStats.Entry entry = staleStats.get("Wakelock"); 94d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertEquals(34, entry.mCount); 95d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertEquals(123 * 1000, entry.mTotalTime); // Microseconds 96d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski } 97d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 98d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski @SmallTest 99d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski public void testTwoWakelocks() throws Exception { 100d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski byte[] buffer = new ProcFileBuilder() 101d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski .addLine("Wakelock", 1, 10) 102d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski .addLine("Fakelock", 2, 20) 103d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski .getBytes(); 104d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski KernelWakelockStats staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true, 105d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski new KernelWakelockStats()); 106d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertEquals(2, staleStats.size()); 107d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertTrue(staleStats.containsKey("Wakelock")); 108d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertTrue(staleStats.containsKey("Fakelock")); 109d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski } 110d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 111d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski @SmallTest 112d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski public void testDuplicateWakelocksAccumulate() throws Exception { 113d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski byte[] buffer = new ProcFileBuilder() 114d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski .addLine("Wakelock", 1, 10) // Milliseconds 115d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski .addLine("Wakelock", 1, 10) // Milliseconds 116d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski .getBytes(); 117d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski KernelWakelockStats staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true, 118d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski new KernelWakelockStats()); 119d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertEquals(1, staleStats.size()); 120d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertTrue(staleStats.containsKey("Wakelock")); 121d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 122d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski KernelWakelockStats.Entry entry = staleStats.get("Wakelock"); 123d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertEquals(2, entry.mCount); 124d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertEquals(20 * 1000, entry.mTotalTime); // Microseconds 125d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski } 126d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 127d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski @SmallTest 128d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski public void testWakelocksBecomeStale() throws Exception { 129d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski byte[] buffer = new ProcFileBuilder() 130d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski .addLine("Fakelock", 3, 30) 131d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski .getBytes(); 132d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski KernelWakelockStats staleStats = new KernelWakelockStats(); 133d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 134d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true, staleStats); 135d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertEquals(1, staleStats.size()); 136d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertTrue(staleStats.containsKey("Fakelock")); 137d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 138d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski buffer = new ProcFileBuilder() 139d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski .addLine("Wakelock", 1, 10) 140d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski .getBytes(); 141d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski 142d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski staleStats = mReader.parseProcWakelocks(buffer, buffer.length, true, staleStats); 143d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertEquals(1, staleStats.size()); 144d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertTrue(staleStats.containsKey("Wakelock")); 145d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski assertFalse(staleStats.containsKey("Fakelock")); 146d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski } 147d84ad30ee62ee9610ed4a59a8ce4dcbb8eddf7d8Adam Lesinski} 148