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