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
This commit is contained in:
Ethan Lee
2023-05-31 01:21:42 +00:00
committed by Brian Egizi
parent 23e806a89c
commit 6c50d5ae1f
24 changed files with 146 additions and 3 deletions

View File

@@ -593,9 +593,12 @@ public final class CpuInfoReader {
List<String> 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());
}

View File

@@ -0,0 +1,4 @@
200000 500
350000 500
500000 1000
2500000 100

View File

@@ -0,0 +1,4 @@
200000 500
350000 500
500000 1000
2800000 100

View File

@@ -0,0 +1,4 @@
200000 500
350000 500
500000 1000
2500000 100

View File

@@ -0,0 +1,4 @@
200000 500
350000 500
500000 1000
2800000 100

View File

@@ -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<CpuInfoReader.CpuInfo> actualCpuInfos = cpuInfoReader.readCpuInfos();
SparseArray<CpuInfoReader.CpuInfo> 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<CpuInfoReader.CpuInfo> actualCpuInfos = cpuInfoReader.readCpuInfos();
SparseArray<CpuInfoReader.CpuInfo> 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<CpuInfoReader.CpuInfo> actualCpuInfos = cpuInfoReader.readCpuInfos();
SparseArray<CpuInfoReader.CpuInfo> 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);