| /* |
| * Copyright (C) 2017 The Android Open Source Project |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| */ |
| |
| package android.dumpsys.cts; |
| |
| import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; |
| |
| import java.io.BufferedReader; |
| import java.io.StringReader; |
| import java.util.Date; |
| import java.util.regex.Matcher; |
| import java.util.regex.Pattern; |
| import java.text.SimpleDateFormat; |
| |
| /** |
| * Test to check the format of the dumps of the processstats test. |
| */ |
| public class StoragedDumpsysTest extends BaseDumpsysTest { |
| private static final String DEVICE_SIDE_TEST_APK = "CtsStoragedTestApp.apk"; |
| private static final String DEVICE_SIDE_TEST_PACKAGE = "com.android.server.cts.storaged"; |
| |
| @Override |
| protected void tearDown() throws Exception { |
| super.tearDown(); |
| getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE); |
| } |
| |
| private String getCgroupFromLog(String log) { |
| Pattern pattern = Pattern.compile("cgroup:([^\\s]+)", Pattern.MULTILINE); |
| Matcher matcher = pattern.matcher(log); |
| if (matcher.find()) { |
| return matcher.group(1); |
| } |
| return null; |
| } |
| |
| private String getCurrentLogcatDate() throws Exception { |
| long timestampMs = getDevice().getDeviceDate(); |
| return new SimpleDateFormat("MM-dd HH:mm:ss.SSS") |
| .format(new Date(timestampMs)); |
| } |
| |
| /** |
| * Tests the output of "dumpsys storaged --force --hours 0.01". |
| * |
| * @throws Exception |
| */ |
| public void testStoragedOutput() throws Exception { |
| String result = mDevice.executeShellCommand("stat /proc/uid_io/stats"); |
| if(result.contains("No such file or directory")) { |
| return; |
| } |
| |
| if (mDevice.getAppPackageInfo(DEVICE_SIDE_TEST_APK) != null) { |
| getDevice().uninstallPackage(DEVICE_SIDE_TEST_PACKAGE); |
| } |
| |
| CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild); |
| mDevice.installPackage(buildHelper.getTestFile(DEVICE_SIDE_TEST_APK), true); |
| |
| mDevice.executeShellCommand("dumpsys storaged --force"); |
| |
| String logcatDate = getCurrentLogcatDate(); |
| |
| runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, |
| "com.android.server.cts.storaged.StoragedTest", |
| "testBackgroundIO"); |
| String log = mDevice.executeAdbCommand( |
| "logcat", "-v", "brief", "-d", "-t", logcatDate, |
| "SimpleIOService:I", "*:S"); |
| String serviceCgroup = getCgroupFromLog(log); |
| if (serviceCgroup != null && serviceCgroup.equals("/top")) { |
| System.out.println("WARNING: Service was not in the correct cgroup; ActivityManager may be unresponsive."); |
| } |
| |
| runDeviceTests(DEVICE_SIDE_TEST_PACKAGE, |
| "com.android.server.cts.storaged.StoragedTest", |
| "testForegroundIO"); |
| |
| String output = mDevice.executeShellCommand("dumpsys storaged --force --hours 0.01"); |
| assertNotNull(output); |
| assertTrue(output.length() > 0); |
| |
| boolean hasTestIO = false; |
| try (BufferedReader reader = new BufferedReader( |
| new StringReader(output))) { |
| |
| String line; |
| String[] parts; |
| while ((line = reader.readLine()) != null) { |
| if (line.isEmpty()) { |
| continue; |
| } |
| |
| if (line.contains(",")) { |
| parts = line.split(","); |
| assertTrue(parts.length == 2); |
| if (!parts[0].isEmpty()) { |
| assertInteger(parts[0]); |
| } |
| assertInteger(parts[1]); |
| continue; |
| } |
| |
| parts = line.split(" "); |
| assertTrue(parts.length == 9); |
| for (int i = 1; i < parts.length; i++) { |
| assertInteger(parts[i]); |
| } |
| |
| if (parts[0].equals(DEVICE_SIDE_TEST_PACKAGE)) { |
| /* |
| * order of parts in StoragedService::dumpUidRecords |
| * [0] DEVICE_SIDE_TEST_PACKAGE |
| * [1] read foreground charger_off |
| * [2] write foreground charger_off |
| * [3] read background charger_off |
| * [4] write background charger_off |
| * [5] read foreground charger_on |
| * [6] write foreground charger_on |
| * [7] read background charger_on |
| * [8] write background charger_on |
| */ |
| if ((Integer.parseInt(parts[6]) >= 8192 && Integer.parseInt(parts[8]) == 0) || |
| (Integer.parseInt(parts[2]) >= 8192 && Integer.parseInt(parts[4]) == 0)) { |
| System.out.print("WARNING: Background I/O was attributed to the " |
| + "foreground. This could indicate a broken or malfunctioning " |
| + "ActivityManager or UsageStatsService.\n"); |
| } else if ((Integer.parseInt(parts[2]) >= 4096 && Integer.parseInt(parts[4]) >= 4096) || |
| Integer.parseInt(parts[4]) >= 8192) { |
| System.out.print("WARNING: charger on I/O was attributed to " |
| + "charger off. This could indicate a broken or malfunctioning " |
| + "ADB USB connection, or device that refuses to charge at the " |
| + "typical 500mA because it is less than 0.05C.\n"); |
| } else { |
| assertTrue((Integer.parseInt(parts[6]) >= 4096 && Integer.parseInt(parts[8]) >= 4096) || |
| Integer.parseInt(parts[8]) >= 8192); |
| } |
| hasTestIO = true; |
| } |
| } |
| |
| assertTrue(hasTestIO); |
| } |
| } |
| } |