blob: e6e7a85ae16e6f06b5ac9b062f8ac5c3b18fbf3d [file] [log] [blame]
Misha Wagner566903a2018-10-02 10:50:12 +01001/*
2 * Copyright (C) 2018 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
Misha Wagner0c5edc362018-10-24 11:28:57 +010019import static org.junit.Assert.assertArrayEquals;
Misha Wagner566903a2018-10-02 10:50:12 +010020import static org.junit.Assert.assertEquals;
Misha Wagner4b32c9f2019-01-25 15:30:14 +000021import static org.junit.Assert.assertFalse;
Misha Wagner566903a2018-10-02 10:50:12 +010022import static org.junit.Assert.assertNotNull;
23import static org.junit.Assert.assertTrue;
Misha Wagner4b32c9f2019-01-25 15:30:14 +000024import static org.testng.Assert.assertThrows;
Misha Wagner566903a2018-10-02 10:50:12 +010025
26import android.content.Context;
27import android.os.FileUtils;
Tadashi G. Takaokab4470f22019-01-15 18:29:15 +090028
29import androidx.test.InstrumentationRegistry;
30import androidx.test.filters.SmallTest;
31import androidx.test.runner.AndroidJUnit4;
Misha Wagner566903a2018-10-02 10:50:12 +010032
33import org.junit.After;
34import org.junit.Before;
35import org.junit.Test;
36import org.junit.runner.RunWith;
37
38import java.io.File;
39import java.io.IOException;
40import java.io.OutputStream;
41import java.nio.file.Files;
42import java.nio.file.Path;
43import java.util.ArrayList;
44import java.util.Comparator;
Misha Wagnerdc797542018-10-29 13:21:34 +000045import java.util.function.Predicate;
Misha Wagner566903a2018-10-02 10:50:12 +010046
47@SmallTest
48@RunWith(AndroidJUnit4.class)
49public class KernelCpuThreadReaderTest {
50
Misha Wagnerdc797542018-10-29 13:21:34 +000051 private static final int UID = 1000;
52 private static final int PROCESS_ID = 1234;
Misha Wagner566903a2018-10-02 10:50:12 +010053 private static final int[] THREAD_IDS = {0, 1000, 1235, 4321};
Misha Wagnerdc797542018-10-29 13:21:34 +000054 private static final String PROCESS_NAME = "test_process";
Misha Wagner566903a2018-10-02 10:50:12 +010055 private static final String[] THREAD_NAMES = {
56 "test_thread_1", "test_thread_2", "test_thread_3", "test_thread_4"
57 };
58 private static final int[] THREAD_CPU_FREQUENCIES = {
59 1000, 2000, 3000, 4000,
60 };
61 private static final int[][] THREAD_CPU_TIMES = {
Misha Wagner9a30c112018-11-27 10:33:06 +000062 {1, 0, 0, 1},
63 {0, 0, 0, 0},
Misha Wagner566903a2018-10-02 10:50:12 +010064 {1000, 1000, 1000, 1000},
65 {0, 1, 2, 3},
66 };
67
68 private File mProcDirectory;
69
70 @Before
71 public void setUp() {
72 Context context = InstrumentationRegistry.getContext();
73 mProcDirectory = context.getDir("proc", Context.MODE_PRIVATE);
74 }
75
76 @After
77 public void tearDown() throws Exception {
78 FileUtils.deleteContents(mProcDirectory);
79 }
80
81 @Test
Misha Wagnerdc797542018-10-29 13:21:34 +000082 public void testReader_currentProcess() throws IOException {
83 KernelCpuThreadReader.Injector processUtils =
84 new KernelCpuThreadReader.Injector() {
85 @Override
86 public int myPid() {
87 return PROCESS_ID;
88 }
Misha Wagner566903a2018-10-02 10:50:12 +010089
Misha Wagnerdc797542018-10-29 13:21:34 +000090 @Override
91 public int myUid() {
92 return UID;
93 }
94
95 @Override
96 public int getUidForPid(int pid) {
97 return 0;
98 }
99 };
100 setupDirectory(mProcDirectory.toPath().resolve("self"), THREAD_IDS, PROCESS_NAME,
101 THREAD_NAMES, THREAD_CPU_FREQUENCIES, THREAD_CPU_TIMES);
102
103 final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader(
Misha Wagner4b32c9f2019-01-25 15:30:14 +0000104 8,
105 uid -> 1000 <= uid && uid < 2000,
Misha Wagner648d2032019-02-11 10:43:27 +0000106 0,
Misha Wagnerdc797542018-10-29 13:21:34 +0000107 mProcDirectory.toPath(),
108 mProcDirectory.toPath().resolve("self/task/" + THREAD_IDS[0] + "/time_in_state"),
109 processUtils);
110 final KernelCpuThreadReader.ProcessCpuUsage processCpuUsage =
111 kernelCpuThreadReader.getCurrentProcessCpuUsage();
112 checkResults(processCpuUsage, kernelCpuThreadReader.getCpuFrequenciesKhz(), UID, PROCESS_ID,
113 THREAD_IDS, PROCESS_NAME, THREAD_NAMES, THREAD_CPU_FREQUENCIES, THREAD_CPU_TIMES);
114 }
115
116 @Test
117 public void testReader_byUids() throws IOException {
118 int[] uids = new int[]{0, 2, 3, 4, 5, 6000};
119 Predicate<Integer> uidPredicate = uid -> uid == 0 || uid >= 4;
120 int[] expectedUids = new int[]{0, 4, 5, 6000};
121 KernelCpuThreadReader.Injector processUtils =
122 new KernelCpuThreadReader.Injector() {
123 @Override
124 public int myPid() {
125 return 0;
126 }
127
128 @Override
129 public int myUid() {
130 return 0;
131 }
132
133 @Override
134 public int getUidForPid(int pid) {
135 return pid;
136 }
137 };
138
139 for (int uid : uids) {
140 setupDirectory(mProcDirectory.toPath().resolve(String.valueOf(uid)),
141 new int[]{uid * 10},
142 "process" + uid, new String[]{"thread" + uid}, new int[]{1000},
Misha Wagner9a30c112018-11-27 10:33:06 +0000143 new int[][]{{uid}});
Misha Wagnerdc797542018-10-29 13:21:34 +0000144 }
145 final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader(
Misha Wagner4b32c9f2019-01-25 15:30:14 +0000146 8,
147 uidPredicate,
Misha Wagner648d2032019-02-11 10:43:27 +0000148 0,
Misha Wagnerdc797542018-10-29 13:21:34 +0000149 mProcDirectory.toPath(),
150 mProcDirectory.toPath().resolve(uids[0] + "/task/" + uids[0] + "/time_in_state"),
151 processUtils);
152 ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsageByUids =
Misha Wagner4b32c9f2019-01-25 15:30:14 +0000153 kernelCpuThreadReader.getProcessCpuUsageByUids();
Misha Wagnerdc797542018-10-29 13:21:34 +0000154 processCpuUsageByUids.sort(Comparator.comparing(usage -> usage.processId));
155
156 assertEquals(expectedUids.length, processCpuUsageByUids.size());
157 for (int i = 0; i < expectedUids.length; i++) {
158 KernelCpuThreadReader.ProcessCpuUsage processCpuUsage =
159 processCpuUsageByUids.get(i);
160 int uid = expectedUids[i];
161 checkResults(processCpuUsage, kernelCpuThreadReader.getCpuFrequenciesKhz(),
162 uid, uid, new int[]{uid * 10}, "process" + uid, new String[]{"thread" + uid},
Misha Wagner9a30c112018-11-27 10:33:06 +0000163 new int[]{1000}, new int[][]{{uid}});
Misha Wagnerdc797542018-10-29 13:21:34 +0000164 }
165 }
166
Misha Wagner648d2032019-02-11 10:43:27 +0000167 @Test
168 public void testReader_filtersLowUsage() throws IOException {
169 int[] uids = new int[]{0, 1, 2, 3, 4};
170 int[] cpuUsage = new int[]{10, 0, 2, 100, 3};
171 int[] expectedUids = new int[]{0, 3, 4};
172 Predicate<Integer> uidPredicate = uid -> true;
173 KernelCpuThreadReader.Injector processUtils =
174 new KernelCpuThreadReader.Injector() {
175 @Override
176 public int myPid() {
177 return 0;
178 }
179
180 @Override
181 public int myUid() {
182 return 0;
183 }
184
185 @Override
186 public int getUidForPid(int pid) {
187 return pid;
188 }
189 };
190
191 for (int i = 0; i < uids.length; i++) {
192 int uid = uids[i];
193 setupDirectory(
194 mProcDirectory.toPath().resolve(String.valueOf(uid)),
195 new int[]{uid * 10},
196 "process" + uid,
197 new String[]{"thread" + uid},
198 new int[]{1000},
199 new int[][]{{cpuUsage[i]}});
200 }
201 final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader(
202 8,
203 uidPredicate,
204 30,
205 mProcDirectory.toPath(),
206 mProcDirectory.toPath().resolve(uids[0] + "/task/" + uids[0] + "/time_in_state"),
207 processUtils);
208 ArrayList<KernelCpuThreadReader.ProcessCpuUsage> processCpuUsageByUids =
209 kernelCpuThreadReader.getProcessCpuUsageByUids();
210 processCpuUsageByUids.sort(Comparator.comparing(usage -> usage.uid));
211
212 assertEquals(expectedUids.length, processCpuUsageByUids.size());
213 for (int i = 0; i < expectedUids.length; i++) {
214 KernelCpuThreadReader.ProcessCpuUsage processCpuUsage =
215 processCpuUsageByUids.get(i);
216 assertEquals(expectedUids[i], processCpuUsage.uid);
217 }
218
219 }
220
Misha Wagnere51e5202019-02-26 15:21:45 +0000221 @Test
222 public void testReader_otherThreads() throws IOException {
223 final Path processPath = mProcDirectory.toPath().resolve("self");
224 setupDirectory(
225 processPath,
226 new int[]{1, 2, 3},
227 "process",
228 new String[]{"thread1", "thread2", "thread3"},
229 new int[]{1000, 2000},
230 new int[][]{{0, 100}, {10, 0}, {0, 300}});
231 final KernelCpuThreadReader kernelCpuThreadReader = new KernelCpuThreadReader(
232 8,
233 i -> true,
234 2000,
235 mProcDirectory.toPath(),
236 processPath.resolve("task/1/time_in_state"),
237 new KernelCpuThreadReader.Injector() {
238 @Override
239 public int myPid() {
240 return 1000;
241 }
242
243 @Override
244 public int myUid() {
245 return 0;
246 }
247
248 @Override
249 public int getUidForPid(int pid) {
250 return 0;
251 }
252 });
253 checkResults(
254 kernelCpuThreadReader.getCurrentProcessCpuUsage(),
255 kernelCpuThreadReader.getCpuFrequenciesKhz(),
256 0,
257 1000,
258 new int[]{-1, 3},
259 "process",
260 new String[]{"__OTHER_THREADS", "thread3"},
261 new int[]{1000, 2000},
262 new int[][]{{100, 1000}, {0, 3000}}
263 );
264 }
265
Misha Wagnerdc797542018-10-29 13:21:34 +0000266 private void setupDirectory(Path processPath, int[] threadIds, String processName,
267 String[] threadNames, int[] cpuFrequencies, int[][] cpuTimes) throws IOException {
268 // Make /proc/$PID
269 assertTrue(processPath.toFile().mkdirs());
270
271 // Make /proc/$PID/task
272 final Path selfThreadsPath = processPath.resolve("task");
Misha Wagner566903a2018-10-02 10:50:12 +0100273 assertTrue(selfThreadsPath.toFile().mkdirs());
274
Misha Wagnerdc797542018-10-29 13:21:34 +0000275 // Make /proc/$PID/cmdline
276 Files.write(processPath.resolve("cmdline"), processName.getBytes());
Misha Wagner566903a2018-10-02 10:50:12 +0100277
278 // Make thread directories in reverse order, as they are read in order of creation by
279 // CpuThreadProcReader
Misha Wagnerdc797542018-10-29 13:21:34 +0000280 for (int i = 0; i < threadIds.length; i++) {
281 // Make /proc/$PID/task/$TID
282 final Path threadPath = selfThreadsPath.resolve(String.valueOf(threadIds[i]));
Misha Wagner566903a2018-10-02 10:50:12 +0100283 assertTrue(threadPath.toFile().mkdirs());
284
Misha Wagnerdc797542018-10-29 13:21:34 +0000285 // Make /proc/$PID/task/$TID/comm
286 Files.write(threadPath.resolve("comm"), threadNames[i].getBytes());
Misha Wagner566903a2018-10-02 10:50:12 +0100287
Misha Wagnerdc797542018-10-29 13:21:34 +0000288 // Make /proc/$PID/task/$TID/time_in_state
Misha Wagner566903a2018-10-02 10:50:12 +0100289 final OutputStream timeInStateStream =
290 Files.newOutputStream(threadPath.resolve("time_in_state"));
Misha Wagnerdc797542018-10-29 13:21:34 +0000291 for (int j = 0; j < cpuFrequencies.length; j++) {
292 final String line = String.valueOf(cpuFrequencies[j]) + " "
293 + String.valueOf(cpuTimes[i][j]) + "\n";
Misha Wagner566903a2018-10-02 10:50:12 +0100294 timeInStateStream.write(line.getBytes());
295 }
296 timeInStateStream.close();
297 }
Misha Wagnerdc797542018-10-29 13:21:34 +0000298 }
Misha Wagner566903a2018-10-02 10:50:12 +0100299
Misha Wagnerdc797542018-10-29 13:21:34 +0000300 private void checkResults(KernelCpuThreadReader.ProcessCpuUsage processCpuUsage,
301 int[] readerCpuFrequencies, int uid, int processId, int[] threadIds, String processName,
302 String[] threadNames, int[] cpuFrequencies, int[][] cpuTimes) {
Misha Wagner566903a2018-10-02 10:50:12 +0100303 assertNotNull(processCpuUsage);
Misha Wagnerdc797542018-10-29 13:21:34 +0000304 assertEquals(processId, processCpuUsage.processId);
305 assertEquals(uid, processCpuUsage.uid);
306 assertEquals(processName, processCpuUsage.processName);
Misha Wagnere51e5202019-02-26 15:21:45 +0000307 assertEquals(threadIds.length, processCpuUsage.threadCpuUsages.size());
Misha Wagner566903a2018-10-02 10:50:12 +0100308
309 // Sort the thread CPU usages to compare with test case
310 final ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages =
311 new ArrayList<>(processCpuUsage.threadCpuUsages);
312 threadCpuUsages.sort(Comparator.comparingInt(a -> a.threadId));
313
314 int threadCount = 0;
315 for (KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage : threadCpuUsages) {
Misha Wagnerdc797542018-10-29 13:21:34 +0000316 assertEquals(threadIds[threadCount], threadCpuUsage.threadId);
317 assertEquals(threadNames[threadCount], threadCpuUsage.threadName);
Misha Wagner566903a2018-10-02 10:50:12 +0100318
319 for (int i = 0; i < threadCpuUsage.usageTimesMillis.length; i++) {
320 assertEquals(
Misha Wagnerdc797542018-10-29 13:21:34 +0000321 cpuTimes[threadCount][i] * 10,
Misha Wagner566903a2018-10-02 10:50:12 +0100322 threadCpuUsage.usageTimesMillis[i]);
323 assertEquals(
Misha Wagnerdc797542018-10-29 13:21:34 +0000324 cpuFrequencies[i],
325 readerCpuFrequencies[i]);
Misha Wagner566903a2018-10-02 10:50:12 +0100326 }
327 threadCount++;
328 }
329
Misha Wagnerdc797542018-10-29 13:21:34 +0000330 assertEquals(threadCount, threadIds.length);
Misha Wagner566903a2018-10-02 10:50:12 +0100331 }
Misha Wagner0c5edc362018-10-24 11:28:57 +0100332
333 @Test
334 public void testBucketSetup_simple() {
335 long[] frequencies = {1, 2, 3, 4, 1, 2, 3, 4};
336 KernelCpuThreadReader.FrequencyBucketCreator
337 frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
338 frequencies, 4);
339 assertArrayEquals(
340 new int[]{1, 3, 1, 3},
341 frequencyBucketCreator.getBucketMinFrequencies(frequencies));
342 assertArrayEquals(
343 new int[]{2, 2, 2, 2},
344 frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
345 }
346
347 @Test
348 public void testBucketSetup_noBig() {
349 long[] frequencies = {1, 2, 3, 4, 5, 6, 7, 8};
350 KernelCpuThreadReader.FrequencyBucketCreator
351 frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
352 frequencies, 4);
353 assertArrayEquals(
354 new int[]{1, 3, 5, 7},
355 frequencyBucketCreator.getBucketMinFrequencies(frequencies));
356 assertArrayEquals(
357 new int[]{2, 2, 2, 2},
358 frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
359 }
360
361 @Test
362 public void testBucketSetup_moreLittle() {
363 long[] frequencies = {1, 2, 3, 4, 5, 1, 2, 3};
364 KernelCpuThreadReader.FrequencyBucketCreator
365 frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
366 frequencies, 4);
367 assertArrayEquals(
368 new int[]{1, 3, 1, 2},
369 frequencyBucketCreator.getBucketMinFrequencies(frequencies));
370 assertArrayEquals(
371 new int[]{2, 3, 1, 2},
372 frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
373 }
374
375 @Test
376 public void testBucketSetup_moreBig() {
377 long[] frequencies = {1, 2, 3, 1, 2, 3, 4, 5};
378 KernelCpuThreadReader.FrequencyBucketCreator
379 frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
380 frequencies, 4);
381 assertArrayEquals(
382 new int[]{1, 2, 1, 3},
383 frequencyBucketCreator.getBucketMinFrequencies(frequencies));
384 assertArrayEquals(
385 new int[]{1, 2, 2, 3},
386 frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
387 }
388
389 @Test
390 public void testBucketSetup_equalBuckets() {
391 long[] frequencies = {1, 2, 3, 4, 1, 2, 3, 4};
392 KernelCpuThreadReader.FrequencyBucketCreator
393 frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
394 frequencies, 8);
395 assertArrayEquals(
396 new int[]{1, 2, 3, 4, 1, 2, 3, 4},
397 frequencyBucketCreator.getBucketMinFrequencies(frequencies));
398 assertArrayEquals(
399 new int[]{1, 1, 1, 1, 1, 1, 1, 1},
400 frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
401 }
402
403 @Test
404 public void testBucketSetup_moreBigBucketsThanFrequencies() {
405 long[] frequencies = {1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3};
406 KernelCpuThreadReader.FrequencyBucketCreator
407 frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
408 frequencies, 8);
409 assertArrayEquals(
410 new int[]{1, 3, 5, 7, 1, 2, 3},
411 frequencyBucketCreator.getBucketMinFrequencies(frequencies));
412 assertArrayEquals(
413 new int[]{2, 2, 2, 3, 1, 1, 1},
414 frequencyBucketCreator.getBucketedValues(
415 new long[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}));
416 }
417
418 @Test
419 public void testBucketSetup_oneBucket() {
420 long[] frequencies = {1, 2, 3, 4, 2, 3, 4, 5};
421 KernelCpuThreadReader.FrequencyBucketCreator
422 frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
423 frequencies, 1);
424 assertArrayEquals(
425 new int[]{1},
426 frequencyBucketCreator.getBucketMinFrequencies(frequencies));
427 assertArrayEquals(
428 new int[]{8},
429 frequencyBucketCreator.getBucketedValues(
430 new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
431 }
432
Misha Wagner0c5edc362018-10-24 11:28:57 +0100433 @Test
434 public void testGetBigFrequenciesStartIndex_simple() {
435 assertEquals(
436 3, KernelCpuThreadReader.FrequencyBucketCreator.getBigFrequenciesStartIndex(
437 new long[]{1, 2, 3, 1, 2, 3}));
438 }
439
440 @Test
441 public void testGetBigFrequenciesStartIndex_moreLittle() {
442 assertEquals(
443 4, KernelCpuThreadReader.FrequencyBucketCreator.getBigFrequenciesStartIndex(
444 new long[]{1, 2, 3, 4, 1, 2}));
445 }
446
447 @Test
448 public void testGetBigFrequenciesStartIndex_moreBig() {
449 assertEquals(
450 2, KernelCpuThreadReader.FrequencyBucketCreator.getBigFrequenciesStartIndex(
451 new long[]{1, 2, 1, 2, 3, 4}));
452 }
453
454 @Test
455 public void testGetBigFrequenciesStartIndex_noBig() {
456 assertEquals(
457 4, KernelCpuThreadReader.FrequencyBucketCreator.getBigFrequenciesStartIndex(
458 new long[]{1, 2, 3, 4}));
459 }
Misha Wagner4b32c9f2019-01-25 15:30:14 +0000460
461 @Test
462 public void testUidPredicate_singleRange() {
463 KernelCpuThreadReaderSettingsObserver.UidPredicate uidPredicate =
464 KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("1000-1999");
465 assertTrue(uidPredicate.test(1000));
466 assertTrue(uidPredicate.test(1050));
467 assertTrue(uidPredicate.test(1999));
468 assertFalse(uidPredicate.test(2000));
469 assertFalse(uidPredicate.test(0));
470 assertFalse(uidPredicate.test(10000));
471 assertFalse(uidPredicate.test(-100));
472 }
473
474 @Test
475 public void testUidPredicate_singleUid() {
476 KernelCpuThreadReaderSettingsObserver.UidPredicate uidPredicate =
477 KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("1234-1234");
478 assertTrue(uidPredicate.test(1234));
479 assertFalse(uidPredicate.test(1235));
480 assertFalse(uidPredicate.test(1232));
481 assertFalse(uidPredicate.test(0));
482 assertFalse(uidPredicate.test(-1234));
483 }
484
485 @Test
486 public void testUidPredicate_uidAndRange() {
487 KernelCpuThreadReaderSettingsObserver.UidPredicate uidPredicate =
488 KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString(
489 "1000-1000;1050-1060");
490 assertTrue(uidPredicate.test(1000));
491 assertTrue(uidPredicate.test(1050));
492 assertTrue(uidPredicate.test(1054));
493 assertTrue(uidPredicate.test(1060));
494 assertFalse(uidPredicate.test(1040));
495 assertFalse(uidPredicate.test(1001));
496 assertFalse(uidPredicate.test(0));
497 assertFalse(uidPredicate.test(-1000));
498 }
499
500 @Test
501 public void testUidPredicate_multiple() {
502 KernelCpuThreadReaderSettingsObserver.UidPredicate uidPredicate =
503 KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString(
504 "1000-1000;1050-1060;1001-1001;2000-3000");
505 assertTrue(uidPredicate.test(1000));
506 assertTrue(uidPredicate.test(1001));
507 assertTrue(uidPredicate.test(1050));
508 assertTrue(uidPredicate.test(1054));
509 assertTrue(uidPredicate.test(1060));
510 assertTrue(uidPredicate.test(1001));
511 assertTrue(uidPredicate.test(2000));
512 assertTrue(uidPredicate.test(2444));
513 assertTrue(uidPredicate.test(3000));
514 assertFalse(uidPredicate.test(0));
515 assertFalse(uidPredicate.test(1040));
516 assertFalse(uidPredicate.test(3001));
517 assertFalse(uidPredicate.test(1999));
518 }
519
520 @Test
Misha Wagnerd250dd82019-03-01 16:06:28 +0000521 public void testUidPredicate_zero() {
522 KernelCpuThreadReaderSettingsObserver.UidPredicate uidPredicate =
523 KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("0-0");
524 assertTrue(uidPredicate.test(0));
525 assertFalse(uidPredicate.test(1));
526 assertFalse(uidPredicate.test(2000));
527 assertFalse(uidPredicate.test(10000));
528 assertFalse(uidPredicate.test(-100));
529 }
530
531 @Test
Misha Wagner4b32c9f2019-01-25 15:30:14 +0000532 public void testUidPredicate_emptyRangeString() {
533 assertThrows(
534 NumberFormatException.class,
535 () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString(""));
536 }
537
538 @Test
539 public void testUidPredicate_singleNumber() {
540 assertThrows(
541 NumberFormatException.class,
542 () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("1000"));
543 }
544
545 @Test
546 public void testUidPredicate_lettersInRange() {
547 assertThrows(
548 NumberFormatException.class,
549 () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString(
550 "0-0;1-1;a;3-3"));
551 }
552
553 @Test
554 public void testUidPredicate_onlyLetters() {
555 assertThrows(
556 NumberFormatException.class,
557 () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("abc"));
558 }
559
560 @Test
561 public void testUidPredicate_backwardsRange() {
562 assertThrows(
563 IllegalArgumentException.class,
564 () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("20-10"));
565 }
566
567 @Test
568 public void testUidPredicate_comma() {
569 assertThrows(
570 NumberFormatException.class,
571 () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("1-1,2-2,3-3"));
572 }
Misha Wagner566903a2018-10-02 10:50:12 +0100573}