From 6c50d5ae1fc8ff780505cdd3854e3ef6533446cd Mon Sep 17 00:00:00 2001 From: Ethan Lee Date: Wed, 31 May 2023 01:21:42 +0000 Subject: [PATCH] Don't throw exception on empty line in CPUs file. Empty line in CPUs file is a valid use case and the CpuInfoReader must not throw exception. It should gracefully handle this case. Cherry picked I9d1b97c9ff0791d1ac49d333cd75656432ccabe2 to master due to b/286408867. Code was merged via `-s ours` and is missing even though the sha exists on the target branch. Cherry pick is required to bring in the code. Manually remove the "Merged in" directive to allow for downstream propagation. Test: atest CpuInfoReaderTest Fixes: 284537086 (cherry picked from https://googleplex-android-review.googlesource.com/q/commit:fe20e634351512d9be270830d4fc66345ddfe6b4) Change-Id: Ifc5f1614fc4c70e3d0e5ee753d9ba1ac2ab48417 --- .../com/android/server/cpu/CpuInfoReader.java | 12 +- .../policy0/affected_cpus | 1 + .../policy0/related_cpus | 1 + .../policy0/scaling_cur_freq | 1 + .../policy0/scaling_max_freq | 1 + .../policy0/stats/time_in_state | 4 + .../policy1/affected_cpus | 1 + .../policy1/related_cpus | 1 + .../policy1/scaling_cur_freq | 1 + .../policy1/scaling_max_freq | 1 + .../policy1/stats/time_in_state | 4 + .../policy0/affected_cpus | 1 + .../policy0/related_cpus | 1 + .../policy0/scaling_cur_freq | 1 + .../policy0/scaling_max_freq | 1 + .../policy0/stats/time_in_state | 4 + .../policy1/affected_cpus | 1 + .../policy1/related_cpus | 1 + .../policy1/scaling_cur_freq | 1 + .../policy1/scaling_max_freq | 1 + .../policy1/stats/time_in_state | 4 + .../background/cpus | 1 + .../valid_cpuset_with_empty_cpus/top-app/cpus | 1 + .../android/server/cpu/CpuInfoReaderTest.java | 103 ++++++++++++++++++ 24 files changed, 146 insertions(+), 3 deletions(-) create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/affected_cpus create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/related_cpus create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/scaling_cur_freq create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/scaling_max_freq create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/stats/time_in_state create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/affected_cpus create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/related_cpus create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/scaling_cur_freq create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/scaling_max_freq create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/stats/time_in_state create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/affected_cpus create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/related_cpus create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/scaling_cur_freq create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/scaling_max_freq create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/stats/time_in_state create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/affected_cpus create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/related_cpus create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/scaling_cur_freq create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/scaling_max_freq create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/stats/time_in_state create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpuset_with_empty_cpus/background/cpus create mode 100644 services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpuset_with_empty_cpus/top-app/cpus diff --git a/services/core/java/com/android/server/cpu/CpuInfoReader.java b/services/core/java/com/android/server/cpu/CpuInfoReader.java index 92bbfab63b427..984ad1dd72882 100644 --- a/services/core/java/com/android/server/cpu/CpuInfoReader.java +++ b/services/core/java/com/android/server/cpu/CpuInfoReader.java @@ -593,9 +593,12 @@ public final class CpuInfoReader { List lines = Files.readAllLines(file.toPath()); IntArray cpuCores = new IntArray(0); for (int i = 0; i < lines.size(); i++) { - String line = lines.get(i); - String[] pairs = line.contains(",") ? line.trim().split(",") - : line.trim().split(" "); + String line = lines.get(i).trim(); + if (line.isEmpty()) { + continue; + } + String[] pairs = line.contains(",") ? line.split(",") + : line.split(" "); for (int j = 0; j < pairs.length; j++) { String[] minMaxPairs = pairs[j].split("-"); if (minMaxPairs.length >= 2) { @@ -615,6 +618,9 @@ public final class CpuInfoReader { } } return cpuCores; + } catch (NumberFormatException e) { + Slogf.e(TAG, e, "Failed to read CPU cores from %s due to incorrect file format", + file.getAbsolutePath()); } catch (Exception e) { Slogf.e(TAG, e, "Failed to read CPU cores from %s", file.getAbsolutePath()); } diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/affected_cpus b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/affected_cpus new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/affected_cpus @@ -0,0 +1 @@ + diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/related_cpus b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/related_cpus new file mode 100644 index 0000000000000..c227083464fb9 --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/related_cpus @@ -0,0 +1 @@ +0 \ No newline at end of file diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/scaling_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/scaling_cur_freq new file mode 100644 index 0000000000000..dadd9737778df --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/scaling_cur_freq @@ -0,0 +1 @@ +1230000 diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/scaling_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/scaling_max_freq new file mode 100644 index 0000000000000..a93d6f7b2c09a --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/scaling_max_freq @@ -0,0 +1 @@ +2500000 diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/stats/time_in_state b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/stats/time_in_state new file mode 100644 index 0000000000000..5121f6661a7e0 --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy0/stats/time_in_state @@ -0,0 +1,4 @@ +200000 500 +350000 500 +500000 1000 +2500000 100 diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/affected_cpus b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/affected_cpus new file mode 100644 index 0000000000000..d00491fd7e5bb --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/affected_cpus @@ -0,0 +1 @@ +1 diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/related_cpus b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/related_cpus new file mode 100644 index 0000000000000..56a6051ca2b02 --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/related_cpus @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/scaling_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/scaling_cur_freq new file mode 100644 index 0000000000000..2bc4ce96ec986 --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/scaling_cur_freq @@ -0,0 +1 @@ +1450000 diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/scaling_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/scaling_max_freq new file mode 100644 index 0000000000000..c754f1a461ab6 --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/scaling_max_freq @@ -0,0 +1 @@ +2800000 diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/stats/time_in_state b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/stats/time_in_state new file mode 100644 index 0000000000000..7ed12cfce58d1 --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_affected_cpus/policy1/stats/time_in_state @@ -0,0 +1,4 @@ +200000 500 +350000 500 +500000 1000 +2800000 100 diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/affected_cpus b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/affected_cpus new file mode 100644 index 0000000000000..573541ac9702d --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/affected_cpus @@ -0,0 +1 @@ +0 diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/related_cpus b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/related_cpus new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/related_cpus @@ -0,0 +1 @@ + diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/scaling_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/scaling_cur_freq new file mode 100644 index 0000000000000..dadd9737778df --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/scaling_cur_freq @@ -0,0 +1 @@ +1230000 diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/scaling_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/scaling_max_freq new file mode 100644 index 0000000000000..a93d6f7b2c09a --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/scaling_max_freq @@ -0,0 +1 @@ +2500000 diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/stats/time_in_state b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/stats/time_in_state new file mode 100644 index 0000000000000..5121f6661a7e0 --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy0/stats/time_in_state @@ -0,0 +1,4 @@ +200000 500 +350000 500 +500000 1000 +2500000 100 diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/affected_cpus b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/affected_cpus new file mode 100644 index 0000000000000..d00491fd7e5bb --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/affected_cpus @@ -0,0 +1 @@ +1 diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/related_cpus b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/related_cpus new file mode 100644 index 0000000000000..56a6051ca2b02 --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/related_cpus @@ -0,0 +1 @@ +1 \ No newline at end of file diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/scaling_cur_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/scaling_cur_freq new file mode 100644 index 0000000000000..2bc4ce96ec986 --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/scaling_cur_freq @@ -0,0 +1 @@ +1450000 diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/scaling_max_freq b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/scaling_max_freq new file mode 100644 index 0000000000000..c754f1a461ab6 --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/scaling_max_freq @@ -0,0 +1 @@ +2800000 diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/stats/time_in_state b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/stats/time_in_state new file mode 100644 index 0000000000000..7ed12cfce58d1 --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpufreq_with_empty_related_cpus/policy1/stats/time_in_state @@ -0,0 +1,4 @@ +200000 500 +350000 500 +500000 1000 +2800000 100 diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpuset_with_empty_cpus/background/cpus b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpuset_with_empty_cpus/background/cpus new file mode 100644 index 0000000000000..8b137891791fe --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpuset_with_empty_cpus/background/cpus @@ -0,0 +1 @@ + diff --git a/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpuset_with_empty_cpus/top-app/cpus b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpuset_with_empty_cpus/top-app/cpus new file mode 100644 index 0000000000000..40c7bb2f1a2a5 --- /dev/null +++ b/services/tests/mockingservicestests/assets/CpuInfoReaderTest/valid_cpuset_with_empty_cpus/top-app/cpus @@ -0,0 +1 @@ +0-3 diff --git a/services/tests/mockingservicestests/src/com/android/server/cpu/CpuInfoReaderTest.java b/services/tests/mockingservicestests/src/com/android/server/cpu/CpuInfoReaderTest.java index e2c2bec729ad3..2fbe8aab73d05 100644 --- a/services/tests/mockingservicestests/src/com/android/server/cpu/CpuInfoReaderTest.java +++ b/services/tests/mockingservicestests/src/com/android/server/cpu/CpuInfoReaderTest.java @@ -48,6 +48,11 @@ public final class CpuInfoReaderTest extends ExpectableTestCase { private static final String TAG = CpuInfoReaderTest.class.getSimpleName(); private static final String ROOT_DIR_NAME = "CpuInfoReaderTest"; private static final String VALID_CPUSET_DIR = "valid_cpuset"; + private static final String VALID_CPUSET_WITH_EMPTY_CPUS = "valid_cpuset_with_empty_cpus"; + private static final String VALID_CPUFREQ_WITH_EMPTY_AFFECTED_CPUS = + "valid_cpufreq_with_empty_affected_cpus"; + private static final String VALID_CPUFREQ_WITH_EMPTY_RELATED_CPUS = + "valid_cpufreq_with_empty_related_cpus"; private static final String VALID_CPUFREQ_WITH_TIME_IN_STATE_DIR = "valid_cpufreq_with_time_in_state"; private static final String VALID_CPUFREQ_WITH_TIME_IN_STATE_2_DIR = @@ -402,6 +407,104 @@ public final class CpuInfoReaderTest extends ExpectableTestCase { .isNull(); } + @Test + public void testReadCpuInfoWithEmptyRelatedCpus() throws Exception { + CpuInfoReader cpuInfoReader = newCpuInfoReader(getCacheFile(VALID_CPUSET_DIR), + getCacheFile(VALID_CPUFREQ_WITH_EMPTY_RELATED_CPUS), + getCacheFile(VALID_PROC_STAT)); + + SparseArray actualCpuInfos = cpuInfoReader.readCpuInfos(); + SparseArray expectedCpuInfos = new SparseArray<>(); + + expectedCpuInfos.append(1, new CpuInfoReader.CpuInfo(/* cpuCore= */ 1, + FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 1_450_000, + /* maxCpuFreqKHz= */ 2_800_000, /* avgTimeInStateCpuFreqKHz= */ 502_380, + /* normalizedAvailableCpuFreqKHz= */ 2_693_525, + new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 28_949_280, + /* niceTimeMillis= */ 7_799_450, /* systemTimeMillis= */ 54_004_020, + /* idleTimeMillis= */ 402_707_120, /* iowaitTimeMillis= */ 1_186_960, + /* irqTimeMillis= */ 14_786_940, /* softirqTimeMillis= */ 1_498_130, + /* stealTimeMillis= */ 78_780, /* guestTimeMillis= */ 0, + /* guestNiceTimeMillis= */ 0))); + + compareCpuInfos("CPU infos with policy 0 containing an empty related_cpus file", + expectedCpuInfos, actualCpuInfos); + } + + @Test + public void testReadCpuInfoWithEmptyCpusetCpus() throws Exception { + CpuInfoReader cpuInfoReader = newCpuInfoReader(getCacheFile(VALID_CPUSET_WITH_EMPTY_CPUS), + getCacheFile(VALID_CPUFREQ_WITH_TIME_IN_STATE_DIR), + getCacheFile(VALID_PROC_STAT)); + + SparseArray actualCpuInfos = cpuInfoReader.readCpuInfos(); + SparseArray expectedCpuInfos = new SparseArray<>(); + expectedCpuInfos.append(0, new CpuInfoReader.CpuInfo(/* cpuCore= */ 0, + FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 1_230_000, + /* maxCpuFreqKHz= */ 2_500_000, /* avgTimeInStateCpuFreqKHz= */ 488_095, + new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 32_249_610, + /* niceTimeMillis= */ 7_950_930, /* systemTimeMillis= */ 52_227_050, + /* idleTimeMillis= */ 409_036_950, /* iowaitTimeMillis= */ 1_322_810, + /* irqTimeMillis= */ 8_146_740, /* softirqTimeMillis= */ 428_970, + /* stealTimeMillis= */ 81_950, /* guestTimeMillis= */ 0, + /* guestNiceTimeMillis= */ 0))); + expectedCpuInfos.append(1, new CpuInfoReader.CpuInfo(/* cpuCore= */ 1, + FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 1_450_000, + /* maxCpuFreqKHz= */ 2_800_000, /* avgTimeInStateCpuFreqKHz= */ 502_380, + new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 28_949_280, + /* niceTimeMillis= */ 7_799_450, /* systemTimeMillis= */ 54_004_020, + /* idleTimeMillis= */ 402_707_120, /* iowaitTimeMillis= */ 1_186_960, + /* irqTimeMillis= */ 14_786_940, /* softirqTimeMillis= */ 1_498_130, + /* stealTimeMillis= */ 78_780, /* guestTimeMillis= */ 0, + /* guestNiceTimeMillis= */ 0))); + expectedCpuInfos.append(2, new CpuInfoReader.CpuInfo(/* cpuCore= */ 2, + FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 1_000_000, + /* maxCpuFreqKHz= */ 2_000_000, /* avgTimeInStateCpuFreqKHz= */ 464_285, + new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 28_959_280, + /* niceTimeMillis= */ 7_789_450, /* systemTimeMillis= */ 54_014_020, + /* idleTimeMillis= */ 402_717_120, /* iowaitTimeMillis= */ 1_166_960, + /* irqTimeMillis= */ 14_796_940, /* softirqTimeMillis= */ 1_478_130, + /* stealTimeMillis= */ 88_780, /* guestTimeMillis= */ 0, + /* guestNiceTimeMillis= */ 0))); + expectedCpuInfos.append(3, new CpuInfoReader.CpuInfo(/* cpuCore= */ 3, + FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 1_000_000, + /* maxCpuFreqKHz= */ 2_000_000, /* avgTimeInStateCpuFreqKHz= */ 464_285, + /* normalizedAvailableCpuFreqKHz= */ 1_907_125, + new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 32_349_610, + /* niceTimeMillis= */ 7_850_930, /* systemTimeMillis= */ 52_127_050, + /* idleTimeMillis= */ 409_136_950, /* iowaitTimeMillis= */ 1_332_810, + /* irqTimeMillis= */ 8_136_740, /* softirqTimeMillis= */ 438_970, + /* stealTimeMillis= */ 71_950, /* guestTimeMillis= */ 0, + /* guestNiceTimeMillis= */ 0))); + + compareCpuInfos("CPU infos with empty background cpu set", expectedCpuInfos, + actualCpuInfos); + } + + @Test + public void testReadCpuInfoWithEmptyAffectedCpus() throws Exception { + CpuInfoReader cpuInfoReader = newCpuInfoReader(getCacheFile(VALID_CPUSET_DIR), + getCacheFile(VALID_CPUFREQ_WITH_EMPTY_AFFECTED_CPUS), + getCacheFile(VALID_PROC_STAT)); + + SparseArray actualCpuInfos = cpuInfoReader.readCpuInfos(); + SparseArray expectedCpuInfos = new SparseArray<>(); + + expectedCpuInfos.append(1, new CpuInfoReader.CpuInfo(/* cpuCore= */ 1, + FLAG_CPUSET_CATEGORY_TOP_APP, /* isOnline= */ true, /* curCpuFreqKHz= */ 1_450_000, + /* maxCpuFreqKHz= */ 2_800_000, /* avgTimeInStateCpuFreqKHz= */ 502_380, + /* normalizedAvailableCpuFreqKHz= */ 2_693_525, + new CpuInfoReader.CpuUsageStats(/* userTimeMillis= */ 28_949_280, + /* niceTimeMillis= */ 7_799_450, /* systemTimeMillis= */ 54_004_020, + /* idleTimeMillis= */ 402_707_120, /* iowaitTimeMillis= */ 1_186_960, + /* irqTimeMillis= */ 14_786_940, /* softirqTimeMillis= */ 1_498_130, + /* stealTimeMillis= */ 78_780, /* guestTimeMillis= */ 0, + /* guestNiceTimeMillis= */ 0))); + + compareCpuInfos("CPU infos with policy 0 containing an empty affected_cpus file", + expectedCpuInfos, actualCpuInfos); + } + @Test public void testReadCpuInfoWithEmptyProcStat() throws Exception { File emptyFile = getCacheFile(EMPTY_FILE);