blob: 7ab956943e3efea37e690a5904ae525acfabec96 [file] [log] [blame]
Sudheer Shanka9b735c52017-05-09 18:26:18 -07001/*
2 * Copyright (C) 2017 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
17package com.android.internal.os;
18
19import static org.mockito.Mockito.verify;
20import static org.mockito.Mockito.verifyNoMoreInteractions;
Sudheer Shanka59f5c002017-05-15 10:57:15 -070021import static org.mockito.Mockito.verifyZeroInteractions;
Sudheer Shanka9b735c52017-05-09 18:26:18 -070022import static org.mockito.Mockito.when;
23
24import android.support.test.filters.SmallTest;
25import android.support.test.runner.AndroidJUnit4;
26
27import org.junit.Before;
28import org.junit.Test;
29import org.junit.runner.RunWith;
30import org.mockito.Mock;
Sudheer Shanka59f5c002017-05-15 10:57:15 -070031import org.mockito.Mockito;
Sudheer Shanka9b735c52017-05-09 18:26:18 -070032import org.mockito.MockitoAnnotations;
33
34import java.io.BufferedReader;
35
36/**
37 * Test class for {@link KernelUidCpuFreqTimeReader}.
38 *
39 * To run the tests, use
40 *
41 * runtest -c com.android.internal.os.KernelUidCpuFreqTimeReaderTest frameworks-core
42 *
43 * or the following steps:
44 *
45 * Build: m FrameworksCoreTests
46 * Install: adb install -r \
47 * ${ANDROID_PRODUCT_OUT}/data/app/FrameworksCoreTests/FrameworksCoreTests.apk
48 * Run: adb shell am instrument -e class com.android.internal.os.KernelUidCpuFreqTimeReaderTest -w \
49 * com.android.frameworks.coretests/android.support.test.runner.AndroidJUnitRunner
50 */
51@SmallTest
52@RunWith(AndroidJUnit4.class)
53public class KernelUidCpuFreqTimeReaderTest {
54 @Mock private BufferedReader mBufferedReader;
55 @Mock private KernelUidCpuFreqTimeReader.Callback mCallback;
56
57 private KernelUidCpuFreqTimeReader mKernelUidCpuFreqTimeReader;
58
59 @Before
60 public void setUp() {
61 MockitoAnnotations.initMocks(this);
62 mKernelUidCpuFreqTimeReader = new KernelUidCpuFreqTimeReader();
63 }
64
65 @Test
66 public void testReadDelta() throws Exception {
67 final long[] freqs = {1, 12, 123, 1234, 12345, 123456};
68 final int[] uids = {1, 22, 333, 4444, 5555};
69 final long[][] times = new long[uids.length][freqs.length];
70 for (int i = 0; i < uids.length; ++i) {
71 for (int j = 0; j < freqs.length; ++j) {
72 times[i][j] = uids[i] * freqs[j] * 10;
73 }
74 }
Sudheer Shanka9b735c52017-05-09 18:26:18 -070075 when(mBufferedReader.readLine())
Sudheer Shanka59f5c002017-05-15 10:57:15 -070076 .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, times));
Sudheer Shanka9b735c52017-05-09 18:26:18 -070077 mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
78 verify(mCallback).onCpuFreqs(freqs);
79 for (int i = 0; i < uids.length; ++i) {
80 verify(mCallback).onUidCpuFreqTime(uids[i], times[i]);
81 }
82 verifyNoMoreInteractions(mCallback);
Sudheer Shanka59f5c002017-05-15 10:57:15 -070083
84 // Verify that a second call will only return deltas.
85 Mockito.reset(mCallback, mBufferedReader);
86 final long[][] newTimes1 = new long[uids.length][freqs.length];
87 for (int i = 0; i < uids.length; ++i) {
88 for (int j = 0; j < freqs.length; ++j) {
89 newTimes1[i][j] = (times[i][j] + uids[i] + freqs[j]) * 10;
90 }
91 }
92 when(mBufferedReader.readLine())
93 .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes1));
94 mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
95 verify(mCallback).onCpuFreqs(freqs);
96 for (int i = 0; i < uids.length; ++i) {
97 verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes1[i], times[i]));
98 }
99 verifyNoMoreInteractions(mCallback);
100
Sudheer Shanka00857522017-07-06 18:28:14 -0700101 // Verify that there won't be a callback if the proc file values didn't change.
102 Mockito.reset(mCallback, mBufferedReader);
103 when(mBufferedReader.readLine())
104 .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes1));
105 mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
106 verify(mCallback).onCpuFreqs(freqs);
107 verifyNoMoreInteractions(mCallback);
108
Sudheer Shanka59f5c002017-05-15 10:57:15 -0700109 // Verify that calling with a null callback doesn't result in any crashes
110 Mockito.reset(mCallback, mBufferedReader);
111 final long[][] newTimes2 = new long[uids.length][freqs.length];
112 for (int i = 0; i < uids.length; ++i) {
113 for (int j = 0; j < freqs.length; ++j) {
114 newTimes2[i][j] = (newTimes1[i][j] + uids[i] * freqs[j]) * 10;
115 }
116 }
117 when(mBufferedReader.readLine())
118 .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes2));
119 mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, null);
120 verifyZeroInteractions(mCallback);
121
122 // Verify that the readDelta call will only return deltas when
123 // the previous call had null callback.
124 Mockito.reset(mCallback, mBufferedReader);
125 final long[][] newTimes3 = new long[uids.length][freqs.length];
126 for (int i = 0; i < uids.length; ++i) {
127 for (int j = 0; j < freqs.length; ++j) {
128 newTimes3[i][j] = (newTimes2[i][j] * (uids[i] + freqs[j])) * 10;
129 }
130 }
131 when(mBufferedReader.readLine())
132 .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes3));
133 mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
134 verify(mCallback).onCpuFreqs(freqs);
135 for (int i = 0; i < uids.length; ++i) {
136 verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes3[i], newTimes2[i]));
137 }
138 verifyNoMoreInteractions(mCallback);
139 }
140
Sudheer Shanka00857522017-07-06 18:28:14 -0700141 @Test
142 public void testReadDelta_malformedData() throws Exception {
143 final long[] freqs = {1, 12, 123, 1234, 12345, 123456};
144 final int[] uids = {1, 22, 333, 4444, 5555};
145 final long[][] times = new long[uids.length][freqs.length];
146 for (int i = 0; i < uids.length; ++i) {
147 for (int j = 0; j < freqs.length; ++j) {
148 times[i][j] = uids[i] * freqs[j] * 10;
149 }
150 }
151 when(mBufferedReader.readLine())
152 .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, times));
153 mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
154 verify(mCallback).onCpuFreqs(freqs);
155 for (int i = 0; i < uids.length; ++i) {
156 verify(mCallback).onUidCpuFreqTime(uids[i], times[i]);
157 }
158 verifyNoMoreInteractions(mCallback);
159
160 // Verify that there is no callback if any value in the proc file is -ve.
161 Mockito.reset(mCallback, mBufferedReader);
162 final long[][] newTimes1 = new long[uids.length][freqs.length];
163 for (int i = 0; i < uids.length; ++i) {
164 for (int j = 0; j < freqs.length; ++j) {
165 newTimes1[i][j] = (times[i][j] + uids[i] + freqs[j]) * 10;
166 }
167 }
168 newTimes1[uids.length - 1][freqs.length - 1] *= -1;
169 when(mBufferedReader.readLine())
170 .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes1));
171 mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
172 verify(mCallback).onCpuFreqs(freqs);
173 for (int i = 0; i < uids.length; ++i) {
174 if (i == uids.length - 1) {
175 continue;
176 }
177 verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes1[i], times[i]));
178 }
179 verifyNoMoreInteractions(mCallback);
180
181 // Verify that the internal state was not modified when the proc file had -ve value.
182 Mockito.reset(mCallback, mBufferedReader);
183 for (int i = 0; i < freqs.length; ++i) {
184 newTimes1[uids.length - 1][i] = times[uids.length - 1][i];
185 }
186 when(mBufferedReader.readLine())
187 .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes1));
188 mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
189 verify(mCallback).onCpuFreqs(freqs);
190 verifyNoMoreInteractions(mCallback);
191
192 // Verify that there is no callback if the values in the proc file are decreased.
193 Mockito.reset(mCallback, mBufferedReader);
194 final long[][] newTimes2 = new long[uids.length][freqs.length];
195 for (int i = 0; i < uids.length; ++i) {
196 for (int j = 0; j < freqs.length; ++j) {
197 newTimes2[i][j] = (newTimes1[i][j] + uids[i] * freqs[j]) * 10;
198 }
199 }
200 newTimes2[uids.length - 1][freqs.length - 1] =
201 newTimes1[uids.length - 1][freqs.length - 1] - 222;
202 when(mBufferedReader.readLine())
203 .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes2));
204 mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
205 verify(mCallback).onCpuFreqs(freqs);
206 for (int i = 0; i < uids.length; ++i) {
207 if (i == uids.length - 1) {
208 continue;
209 }
210 verify(mCallback).onUidCpuFreqTime(uids[i], subtract(newTimes2[i], newTimes1[i]));
211 }
212 verifyNoMoreInteractions(mCallback);
213
214 // Verify that the internal state was not modified when the proc file had decreasing values.
215 Mockito.reset(mCallback, mBufferedReader);
216 for (int i = 0; i < freqs.length; ++i) {
217 newTimes2[uids.length - 1][i] = newTimes1[uids.length - 1][i];
218 }
219 when(mBufferedReader.readLine())
220 .thenReturn(getFreqsLine(freqs), getUidTimesLines(uids, newTimes2));
221 mKernelUidCpuFreqTimeReader.readDelta(mBufferedReader, mCallback);
222 verify(mCallback).onCpuFreqs(freqs);
223 verifyNoMoreInteractions(mCallback);
224 }
225
Sudheer Shanka59f5c002017-05-15 10:57:15 -0700226 private long[] subtract(long[] a1, long[] a2) {
227 long[] val = new long[a1.length];
228 for (int i = 0; i < val.length; ++i) {
229 val[i] = a1[i] - a2[i];
230 }
231 return val;
Sudheer Shanka9b735c52017-05-09 18:26:18 -0700232 }
233
234 private String getFreqsLine(long[] freqs) {
235 final StringBuilder sb = new StringBuilder();
236 sb.append("uid:");
237 for (int i = 0; i < freqs.length; ++i) {
238 sb.append(" " + freqs[i]);
239 }
240 return sb.toString();
241 }
242
243 private String[] getUidTimesLines(int[] uids, long[][] times) {
Sudheer Shanka59f5c002017-05-15 10:57:15 -0700244 final String[] lines = new String[uids.length + 1];
Sudheer Shanka9b735c52017-05-09 18:26:18 -0700245 final StringBuilder sb = new StringBuilder();
246 for (int i = 0; i < uids.length; ++i) {
247 sb.setLength(0);
248 sb.append(uids[i] + ":");
249 for (int j = 0; j < times[i].length; ++j) {
250 sb.append(" " + times[i][j] / 10);
251 }
252 lines[i] = sb.toString();
253 }
Sudheer Shanka59f5c002017-05-15 10:57:15 -0700254 lines[uids.length] = null;
Sudheer Shanka9b735c52017-05-09 18:26:18 -0700255 return lines;
256 }
257}