blob: 442ece5a884dc2e660616609276661b75bd465c5 [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 Wagnerdc797542018-10-29 13:21:34 +0000221 private void setupDirectory(Path processPath, int[] threadIds, String processName,
222 String[] threadNames, int[] cpuFrequencies, int[][] cpuTimes) throws IOException {
223 // Make /proc/$PID
224 assertTrue(processPath.toFile().mkdirs());
225
226 // Make /proc/$PID/task
227 final Path selfThreadsPath = processPath.resolve("task");
Misha Wagner566903a2018-10-02 10:50:12 +0100228 assertTrue(selfThreadsPath.toFile().mkdirs());
229
Misha Wagnerdc797542018-10-29 13:21:34 +0000230 // Make /proc/$PID/cmdline
231 Files.write(processPath.resolve("cmdline"), processName.getBytes());
Misha Wagner566903a2018-10-02 10:50:12 +0100232
233 // Make thread directories in reverse order, as they are read in order of creation by
234 // CpuThreadProcReader
Misha Wagnerdc797542018-10-29 13:21:34 +0000235 for (int i = 0; i < threadIds.length; i++) {
236 // Make /proc/$PID/task/$TID
237 final Path threadPath = selfThreadsPath.resolve(String.valueOf(threadIds[i]));
Misha Wagner566903a2018-10-02 10:50:12 +0100238 assertTrue(threadPath.toFile().mkdirs());
239
Misha Wagnerdc797542018-10-29 13:21:34 +0000240 // Make /proc/$PID/task/$TID/comm
241 Files.write(threadPath.resolve("comm"), threadNames[i].getBytes());
Misha Wagner566903a2018-10-02 10:50:12 +0100242
Misha Wagnerdc797542018-10-29 13:21:34 +0000243 // Make /proc/$PID/task/$TID/time_in_state
Misha Wagner566903a2018-10-02 10:50:12 +0100244 final OutputStream timeInStateStream =
245 Files.newOutputStream(threadPath.resolve("time_in_state"));
Misha Wagnerdc797542018-10-29 13:21:34 +0000246 for (int j = 0; j < cpuFrequencies.length; j++) {
247 final String line = String.valueOf(cpuFrequencies[j]) + " "
248 + String.valueOf(cpuTimes[i][j]) + "\n";
Misha Wagner566903a2018-10-02 10:50:12 +0100249 timeInStateStream.write(line.getBytes());
250 }
251 timeInStateStream.close();
252 }
Misha Wagnerdc797542018-10-29 13:21:34 +0000253 }
Misha Wagner566903a2018-10-02 10:50:12 +0100254
Misha Wagnerdc797542018-10-29 13:21:34 +0000255 private void checkResults(KernelCpuThreadReader.ProcessCpuUsage processCpuUsage,
256 int[] readerCpuFrequencies, int uid, int processId, int[] threadIds, String processName,
257 String[] threadNames, int[] cpuFrequencies, int[][] cpuTimes) {
Misha Wagner566903a2018-10-02 10:50:12 +0100258 assertNotNull(processCpuUsage);
Misha Wagnerdc797542018-10-29 13:21:34 +0000259 assertEquals(processId, processCpuUsage.processId);
260 assertEquals(uid, processCpuUsage.uid);
261 assertEquals(processName, processCpuUsage.processName);
Misha Wagner566903a2018-10-02 10:50:12 +0100262
263 // Sort the thread CPU usages to compare with test case
264 final ArrayList<KernelCpuThreadReader.ThreadCpuUsage> threadCpuUsages =
265 new ArrayList<>(processCpuUsage.threadCpuUsages);
266 threadCpuUsages.sort(Comparator.comparingInt(a -> a.threadId));
267
268 int threadCount = 0;
269 for (KernelCpuThreadReader.ThreadCpuUsage threadCpuUsage : threadCpuUsages) {
Misha Wagnerdc797542018-10-29 13:21:34 +0000270 assertEquals(threadIds[threadCount], threadCpuUsage.threadId);
271 assertEquals(threadNames[threadCount], threadCpuUsage.threadName);
Misha Wagner566903a2018-10-02 10:50:12 +0100272
273 for (int i = 0; i < threadCpuUsage.usageTimesMillis.length; i++) {
274 assertEquals(
Misha Wagnerdc797542018-10-29 13:21:34 +0000275 cpuTimes[threadCount][i] * 10,
Misha Wagner566903a2018-10-02 10:50:12 +0100276 threadCpuUsage.usageTimesMillis[i]);
277 assertEquals(
Misha Wagnerdc797542018-10-29 13:21:34 +0000278 cpuFrequencies[i],
279 readerCpuFrequencies[i]);
Misha Wagner566903a2018-10-02 10:50:12 +0100280 }
281 threadCount++;
282 }
283
Misha Wagnerdc797542018-10-29 13:21:34 +0000284 assertEquals(threadCount, threadIds.length);
Misha Wagner566903a2018-10-02 10:50:12 +0100285 }
Misha Wagner0c5edc362018-10-24 11:28:57 +0100286
287 @Test
288 public void testBucketSetup_simple() {
289 long[] frequencies = {1, 2, 3, 4, 1, 2, 3, 4};
290 KernelCpuThreadReader.FrequencyBucketCreator
291 frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
292 frequencies, 4);
293 assertArrayEquals(
294 new int[]{1, 3, 1, 3},
295 frequencyBucketCreator.getBucketMinFrequencies(frequencies));
296 assertArrayEquals(
297 new int[]{2, 2, 2, 2},
298 frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
299 }
300
301 @Test
302 public void testBucketSetup_noBig() {
303 long[] frequencies = {1, 2, 3, 4, 5, 6, 7, 8};
304 KernelCpuThreadReader.FrequencyBucketCreator
305 frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
306 frequencies, 4);
307 assertArrayEquals(
308 new int[]{1, 3, 5, 7},
309 frequencyBucketCreator.getBucketMinFrequencies(frequencies));
310 assertArrayEquals(
311 new int[]{2, 2, 2, 2},
312 frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
313 }
314
315 @Test
316 public void testBucketSetup_moreLittle() {
317 long[] frequencies = {1, 2, 3, 4, 5, 1, 2, 3};
318 KernelCpuThreadReader.FrequencyBucketCreator
319 frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
320 frequencies, 4);
321 assertArrayEquals(
322 new int[]{1, 3, 1, 2},
323 frequencyBucketCreator.getBucketMinFrequencies(frequencies));
324 assertArrayEquals(
325 new int[]{2, 3, 1, 2},
326 frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
327 }
328
329 @Test
330 public void testBucketSetup_moreBig() {
331 long[] frequencies = {1, 2, 3, 1, 2, 3, 4, 5};
332 KernelCpuThreadReader.FrequencyBucketCreator
333 frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
334 frequencies, 4);
335 assertArrayEquals(
336 new int[]{1, 2, 1, 3},
337 frequencyBucketCreator.getBucketMinFrequencies(frequencies));
338 assertArrayEquals(
339 new int[]{1, 2, 2, 3},
340 frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
341 }
342
343 @Test
344 public void testBucketSetup_equalBuckets() {
345 long[] frequencies = {1, 2, 3, 4, 1, 2, 3, 4};
346 KernelCpuThreadReader.FrequencyBucketCreator
347 frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
348 frequencies, 8);
349 assertArrayEquals(
350 new int[]{1, 2, 3, 4, 1, 2, 3, 4},
351 frequencyBucketCreator.getBucketMinFrequencies(frequencies));
352 assertArrayEquals(
353 new int[]{1, 1, 1, 1, 1, 1, 1, 1},
354 frequencyBucketCreator.getBucketedValues(new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
355 }
356
357 @Test
358 public void testBucketSetup_moreBigBucketsThanFrequencies() {
359 long[] frequencies = {1, 2, 3, 4, 5, 6, 7, 8, 9, 1, 2, 3};
360 KernelCpuThreadReader.FrequencyBucketCreator
361 frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
362 frequencies, 8);
363 assertArrayEquals(
364 new int[]{1, 3, 5, 7, 1, 2, 3},
365 frequencyBucketCreator.getBucketMinFrequencies(frequencies));
366 assertArrayEquals(
367 new int[]{2, 2, 2, 3, 1, 1, 1},
368 frequencyBucketCreator.getBucketedValues(
369 new long[]{1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 1}));
370 }
371
372 @Test
373 public void testBucketSetup_oneBucket() {
374 long[] frequencies = {1, 2, 3, 4, 2, 3, 4, 5};
375 KernelCpuThreadReader.FrequencyBucketCreator
376 frequencyBucketCreator = new KernelCpuThreadReader.FrequencyBucketCreator(
377 frequencies, 1);
378 assertArrayEquals(
379 new int[]{1},
380 frequencyBucketCreator.getBucketMinFrequencies(frequencies));
381 assertArrayEquals(
382 new int[]{8},
383 frequencyBucketCreator.getBucketedValues(
384 new long[]{1, 1, 1, 1, 1, 1, 1, 1}));
385 }
386
Misha Wagner0c5edc362018-10-24 11:28:57 +0100387 @Test
388 public void testGetBigFrequenciesStartIndex_simple() {
389 assertEquals(
390 3, KernelCpuThreadReader.FrequencyBucketCreator.getBigFrequenciesStartIndex(
391 new long[]{1, 2, 3, 1, 2, 3}));
392 }
393
394 @Test
395 public void testGetBigFrequenciesStartIndex_moreLittle() {
396 assertEquals(
397 4, KernelCpuThreadReader.FrequencyBucketCreator.getBigFrequenciesStartIndex(
398 new long[]{1, 2, 3, 4, 1, 2}));
399 }
400
401 @Test
402 public void testGetBigFrequenciesStartIndex_moreBig() {
403 assertEquals(
404 2, KernelCpuThreadReader.FrequencyBucketCreator.getBigFrequenciesStartIndex(
405 new long[]{1, 2, 1, 2, 3, 4}));
406 }
407
408 @Test
409 public void testGetBigFrequenciesStartIndex_noBig() {
410 assertEquals(
411 4, KernelCpuThreadReader.FrequencyBucketCreator.getBigFrequenciesStartIndex(
412 new long[]{1, 2, 3, 4}));
413 }
Misha Wagner4b32c9f2019-01-25 15:30:14 +0000414
415 @Test
416 public void testUidPredicate_singleRange() {
417 KernelCpuThreadReaderSettingsObserver.UidPredicate uidPredicate =
418 KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("1000-1999");
419 assertTrue(uidPredicate.test(1000));
420 assertTrue(uidPredicate.test(1050));
421 assertTrue(uidPredicate.test(1999));
422 assertFalse(uidPredicate.test(2000));
423 assertFalse(uidPredicate.test(0));
424 assertFalse(uidPredicate.test(10000));
425 assertFalse(uidPredicate.test(-100));
426 }
427
428 @Test
429 public void testUidPredicate_singleUid() {
430 KernelCpuThreadReaderSettingsObserver.UidPredicate uidPredicate =
431 KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("1234-1234");
432 assertTrue(uidPredicate.test(1234));
433 assertFalse(uidPredicate.test(1235));
434 assertFalse(uidPredicate.test(1232));
435 assertFalse(uidPredicate.test(0));
436 assertFalse(uidPredicate.test(-1234));
437 }
438
439 @Test
440 public void testUidPredicate_uidAndRange() {
441 KernelCpuThreadReaderSettingsObserver.UidPredicate uidPredicate =
442 KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString(
443 "1000-1000;1050-1060");
444 assertTrue(uidPredicate.test(1000));
445 assertTrue(uidPredicate.test(1050));
446 assertTrue(uidPredicate.test(1054));
447 assertTrue(uidPredicate.test(1060));
448 assertFalse(uidPredicate.test(1040));
449 assertFalse(uidPredicate.test(1001));
450 assertFalse(uidPredicate.test(0));
451 assertFalse(uidPredicate.test(-1000));
452 }
453
454 @Test
455 public void testUidPredicate_multiple() {
456 KernelCpuThreadReaderSettingsObserver.UidPredicate uidPredicate =
457 KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString(
458 "1000-1000;1050-1060;1001-1001;2000-3000");
459 assertTrue(uidPredicate.test(1000));
460 assertTrue(uidPredicate.test(1001));
461 assertTrue(uidPredicate.test(1050));
462 assertTrue(uidPredicate.test(1054));
463 assertTrue(uidPredicate.test(1060));
464 assertTrue(uidPredicate.test(1001));
465 assertTrue(uidPredicate.test(2000));
466 assertTrue(uidPredicate.test(2444));
467 assertTrue(uidPredicate.test(3000));
468 assertFalse(uidPredicate.test(0));
469 assertFalse(uidPredicate.test(1040));
470 assertFalse(uidPredicate.test(3001));
471 assertFalse(uidPredicate.test(1999));
472 }
473
474 @Test
475 public void testUidPredicate_emptyRangeString() {
476 assertThrows(
477 NumberFormatException.class,
478 () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString(""));
479 }
480
481 @Test
482 public void testUidPredicate_singleNumber() {
483 assertThrows(
484 NumberFormatException.class,
485 () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("1000"));
486 }
487
488 @Test
489 public void testUidPredicate_lettersInRange() {
490 assertThrows(
491 NumberFormatException.class,
492 () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString(
493 "0-0;1-1;a;3-3"));
494 }
495
496 @Test
497 public void testUidPredicate_onlyLetters() {
498 assertThrows(
499 NumberFormatException.class,
500 () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("abc"));
501 }
502
503 @Test
504 public void testUidPredicate_backwardsRange() {
505 assertThrows(
506 IllegalArgumentException.class,
507 () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("20-10"));
508 }
509
510 @Test
511 public void testUidPredicate_comma() {
512 assertThrows(
513 NumberFormatException.class,
514 () -> KernelCpuThreadReaderSettingsObserver.UidPredicate.fromString("1-1,2-2,3-3"));
515 }
Misha Wagner566903a2018-10-02 10:50:12 +0100516}