1 /* 2 * Copyright (C) 2016 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 17 package com.android.cts.net; 18 19 import com.android.compatibility.common.tradefed.build.CompatibilityBuildHelper; 20 import com.android.ddmlib.Log; 21 import com.android.ddmlib.testrunner.RemoteAndroidTestRunner; 22 import com.android.ddmlib.testrunner.TestResult.TestStatus; 23 import com.android.tradefed.build.IBuildInfo; 24 import com.android.tradefed.device.DeviceNotAvailableException; 25 import com.android.tradefed.result.CollectingTestListener; 26 import com.android.tradefed.result.TestDescription; 27 import com.android.tradefed.result.TestResult; 28 import com.android.tradefed.result.TestRunResult; 29 import com.android.tradefed.testtype.DeviceTestCase; 30 import com.android.tradefed.testtype.IAbi; 31 import com.android.tradefed.testtype.IAbiReceiver; 32 import com.android.tradefed.testtype.IBuildReceiver; 33 34 import java.io.FileNotFoundException; 35 import java.util.Map; 36 import java.util.regex.Matcher; 37 import java.util.regex.Pattern; 38 39 abstract class HostsideNetworkTestCase extends DeviceTestCase implements IAbiReceiver, 40 IBuildReceiver { 41 protected static final boolean DEBUG = false; 42 protected static final String TAG = "HostsideNetworkTests"; 43 protected static final String TEST_PKG = "com.android.cts.net.hostside"; 44 protected static final String TEST_APK = "CtsHostsideNetworkTestsApp.apk"; 45 protected static final String TEST_APP2_PKG = "com.android.cts.net.hostside.app2"; 46 protected static final String TEST_APP2_APK = "CtsHostsideNetworkTestsApp2.apk"; 47 48 private IAbi mAbi; 49 private IBuildInfo mCtsBuild; 50 51 @Override setAbi(IAbi abi)52 public void setAbi(IAbi abi) { 53 mAbi = abi; 54 } 55 56 @Override setBuild(IBuildInfo buildInfo)57 public void setBuild(IBuildInfo buildInfo) { 58 mCtsBuild = buildInfo; 59 } 60 61 @Override setUp()62 protected void setUp() throws Exception { 63 super.setUp(); 64 65 assertNotNull(mAbi); 66 assertNotNull(mCtsBuild); 67 68 uninstallPackage(TEST_PKG, false); 69 installPackage(TEST_APK); 70 } 71 72 @Override tearDown()73 protected void tearDown() throws Exception { 74 super.tearDown(); 75 76 uninstallPackage(TEST_PKG, true); 77 } 78 installPackage(String apk)79 protected void installPackage(String apk) throws FileNotFoundException, 80 DeviceNotAvailableException { 81 CompatibilityBuildHelper buildHelper = new CompatibilityBuildHelper(mCtsBuild); 82 assertNull(getDevice().installPackage(buildHelper.getTestFile(apk), 83 false /* reinstall */, true /* grantPermissions */, "-t")); 84 } 85 uninstallPackage(String packageName, boolean shouldSucceed)86 protected void uninstallPackage(String packageName, boolean shouldSucceed) 87 throws DeviceNotAvailableException { 88 final String result = getDevice().uninstallPackage(packageName); 89 if (shouldSucceed) { 90 assertNull("uninstallPackage(" + packageName + ") failed: " + result, result); 91 } 92 } 93 assertPackageUninstalled(String packageName)94 protected void assertPackageUninstalled(String packageName) throws DeviceNotAvailableException, 95 InterruptedException { 96 final String command = "cmd package list packages " + packageName; 97 final int max_tries = 5; 98 for (int i = 1; i <= max_tries; i++) { 99 final String result = runCommand(command); 100 if (result.trim().isEmpty()) { 101 return; 102 } 103 // 'list packages' filters by substring, so we need to iterate with the results 104 // and check one by one, otherwise 'com.android.cts.net.hostside' could return 105 // 'com.android.cts.net.hostside.app2' 106 boolean found = false; 107 for (String line : result.split("[\\r\\n]+")) { 108 if (line.endsWith(packageName)) { 109 found = true; 110 break; 111 } 112 } 113 if (!found) { 114 return; 115 } 116 i++; 117 Log.v(TAG, "Package " + packageName + " not uninstalled yet (" + result 118 + "); sleeping 1s before polling again"); 119 Thread.sleep(1000); 120 } 121 fail("Package '" + packageName + "' not uinstalled after " + max_tries + " seconds"); 122 } 123 runDeviceTests(String packageName, String testClassName)124 protected void runDeviceTests(String packageName, String testClassName) 125 throws DeviceNotAvailableException { 126 runDeviceTests(packageName, testClassName, null); 127 } 128 runDeviceTests(String packageName, String testClassName, String methodName)129 protected void runDeviceTests(String packageName, String testClassName, String methodName) 130 throws DeviceNotAvailableException { 131 RemoteAndroidTestRunner testRunner = new RemoteAndroidTestRunner(packageName, 132 "androidx.test.runner.AndroidJUnitRunner", getDevice().getIDevice()); 133 134 if (testClassName != null) { 135 if (methodName != null) { 136 testRunner.setMethodName(testClassName, methodName); 137 } else { 138 testRunner.setClassName(testClassName); 139 } 140 } 141 142 final CollectingTestListener listener = new CollectingTestListener(); 143 getDevice().runInstrumentationTests(testRunner, listener); 144 145 final TestRunResult result = listener.getCurrentRunResults(); 146 if (result.isRunFailure()) { 147 throw new AssertionError("Failed to successfully run device tests for " 148 + result.getName() + ": " + result.getRunFailureMessage()); 149 } 150 151 if (result.hasFailedTests()) { 152 // build a meaningful error message 153 StringBuilder errorBuilder = new StringBuilder("on-device tests failed:\n"); 154 for (Map.Entry<TestDescription, TestResult> resultEntry : 155 result.getTestResults().entrySet()) { 156 final TestStatus testStatus = resultEntry.getValue().getStatus(); 157 if (!TestStatus.PASSED.equals(testStatus) 158 && !TestStatus.ASSUMPTION_FAILURE.equals(testStatus)) { 159 errorBuilder.append(resultEntry.getKey().toString()); 160 errorBuilder.append(":\n"); 161 errorBuilder.append(resultEntry.getValue().getStackTrace()); 162 } 163 } 164 throw new AssertionError(errorBuilder.toString()); 165 } 166 } 167 168 private static final Pattern UID_PATTERN = 169 Pattern.compile(".*userId=([0-9]+)$", Pattern.MULTILINE); 170 getUid(String packageName)171 protected int getUid(String packageName) throws DeviceNotAvailableException { 172 final String output = runCommand("dumpsys package " + packageName); 173 final Matcher matcher = UID_PATTERN.matcher(output); 174 while (matcher.find()) { 175 final String match = matcher.group(1); 176 return Integer.parseInt(match); 177 } 178 throw new RuntimeException("Did not find regexp '" + UID_PATTERN + "' on adb output\n" 179 + output); 180 } 181 runCommand(String command)182 protected String runCommand(String command) throws DeviceNotAvailableException { 183 Log.d(TAG, "Command: '" + command + "'"); 184 final String output = getDevice().executeShellCommand(command); 185 if (DEBUG) Log.v(TAG, "Output: " + output.trim()); 186 return output; 187 } 188 } 189