1 /* 2 * Copyright (C) 2014 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.tradefed.testtype; 18 19 import com.android.cts.tradefed.build.CtsBuildHelper; 20 import com.android.ddmlib.testrunner.TestIdentifier; 21 import com.android.tradefed.build.IBuildInfo; 22 import com.android.tradefed.config.Option; 23 import com.android.tradefed.config.Option.Importance; 24 import com.android.tradefed.device.DeviceNotAvailableException; 25 import com.android.tradefed.device.ITestDevice; 26 import com.android.tradefed.log.LogUtil.CLog; 27 import com.android.tradefed.result.ITestInvocationListener; 28 import com.android.tradefed.testtype.IAbi; 29 import com.android.tradefed.testtype.IBuildReceiver; 30 import com.android.tradefed.testtype.IDeviceTest; 31 import com.android.tradefed.testtype.IRemoteTest; 32 import com.android.tradefed.util.AbiFormatter; 33 import com.android.tradefed.util.ArrayUtil; 34 35 import junit.framework.Assert; 36 import junit.framework.Test; 37 38 import java.io.File; 39 import java.io.FileNotFoundException; 40 import java.util.ArrayList; 41 import java.util.Arrays; 42 import java.util.Collection; 43 import java.util.Collections; 44 import java.util.HashSet; 45 import java.util.List; 46 import java.util.Set; 47 import java.util.concurrent.TimeUnit; 48 49 /** 50 * {@link Test} for running CTS JUnit tests on the device. 51 */ 52 public class JUnitDeviceTest implements IDeviceTest, IRemoteTest, IBuildReceiver { 53 54 private static final String TMP_DIR = "/data/local/tmp/"; 55 56 @Option(name = "junit-device-runtime", 57 description = "The name of the runtime to use on the device", 58 importance = Importance.ALWAYS) 59 private String mRuntimePath = "dalvikvm|#ABI#|"; 60 61 @Option(name = "junit-device-tmpdir", description = "Device path where to store the test jars." 62 , importance = Importance.IF_UNSET) 63 private String mDeviceTestTmpPath = TMP_DIR; 64 65 66 67 // default to no timeout 68 private long mMaxTimeToOutputResponse = 0; 69 70 private ITestDevice mDevice; 71 private String mRunName; 72 private Collection<TestIdentifier> mTests; 73 private CtsBuildHelper mCtsBuild = null; 74 75 private List<String> mJarPaths = new ArrayList<String>(); 76 77 private String mRuntimeArgs; 78 79 private IAbi mAbi; 80 81 private static final String JUNIT_JAR = "cts-junit.jar"; 82 83 private Set<String> mTestJars = new HashSet<String>(Arrays.asList(JUNIT_JAR)); 84 85 /** 86 * @param abi The ABI to run the test on 87 */ setAbi(IAbi abi)88 public void setAbi(IAbi abi) { 89 mAbi = abi; 90 } 91 92 @Override getDevice()93 public ITestDevice getDevice() { 94 return mDevice; 95 } 96 97 @Override setDevice(ITestDevice device)98 public void setDevice(ITestDevice device) { 99 mDevice = device; 100 } 101 addTestJarFileName(String jarFileName)102 public void addTestJarFileName(String jarFileName) { 103 mTestJars.add(jarFileName); 104 } 105 setRunName(String runName)106 public void setRunName(String runName) { 107 mRunName = runName; 108 } 109 setTests(Collection<TestIdentifier> tests)110 public void setTests(Collection<TestIdentifier> tests) { 111 mTests = tests; 112 } 113 getTests()114 public Collection<TestIdentifier> getTests() { 115 return mTests; 116 } 117 118 @Override run(ITestInvocationListener listener)119 public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { 120 addTestJarFileName(JUNIT_JAR); 121 checkFields(); 122 long startTime = System.currentTimeMillis(); 123 listener.testRunStarted(mRunName, mTests.size()); 124 try { 125 installJars(); 126 String jarPath = ArrayUtil.join(":", mJarPaths); 127 for (TestIdentifier testId : mTests) { 128 SingleJUnitTestResultParser resultParser = new SingleJUnitTestResultParser( 129 testId, listener); 130 String cmdLine = String.format("ANDROID_DATA=%s %s -cp %s %s " + 131 "com.android.cts.junit.SingleJUnitTestRunner %s#%s", 132 mDeviceTestTmpPath, mRuntimePath, jarPath, mRuntimeArgs, 133 testId.getClassName(), testId.getTestName()); 134 String cmd = AbiFormatter.formatCmdForAbi(cmdLine, mAbi.getBitness()); 135 CLog.d("Running %s", cmd); 136 listener.testStarted(testId); 137 mDevice.executeShellCommand(cmd, resultParser, mMaxTimeToOutputResponse, 138 TimeUnit.MILLISECONDS, 0); 139 } 140 } finally { 141 listener.testRunEnded(System.currentTimeMillis() - startTime, 142 Collections.<String, String> emptyMap()); 143 // Remove jar files from device 144 removeJars(); 145 } 146 } 147 148 /** 149 * Installs the jar files on the device under test. 150 * 151 * @throws DeviceNotAvailableException 152 */ installJars()153 protected void installJars() throws DeviceNotAvailableException { 154 for (String f : mTestJars) { 155 CLog.d("Installing %s on %s", f, getDevice().getSerialNumber()); 156 File jarFile; 157 try { 158 String fullJarPath = String.format("%s%s", mDeviceTestTmpPath, f); 159 jarFile = mCtsBuild.getTestApp(f); 160 boolean result = getDevice().pushFile(jarFile, fullJarPath); 161 Assert.assertTrue(String.format("Failed to push file to %s", fullJarPath), result); 162 mJarPaths.add(fullJarPath); 163 } catch (FileNotFoundException e) { 164 Assert.fail(String.format("Could not find file %s", f)); 165 } 166 } 167 } 168 169 /** 170 * Cleans up the jar files from the device under test. 171 * 172 * @throws DeviceNotAvailableException 173 */ removeJars()174 protected void removeJars() throws DeviceNotAvailableException { 175 for (String f : mTestJars) { 176 String fullJarPath = String.format("%s%s", mDeviceTestTmpPath, f); 177 CLog.d("Uninstalling %s on %s", fullJarPath, getDevice().getSerialNumber()); 178 getDevice().executeShellCommand(String.format("rm %s", fullJarPath)); 179 } 180 } 181 182 @Override setBuild(IBuildInfo buildInfo)183 public void setBuild(IBuildInfo buildInfo) { 184 mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo); 185 } 186 187 /** 188 * Checks that all mandatory member fields has been set. 189 */ checkFields()190 protected void checkFields() { 191 if (mRunName == null) { 192 throw new IllegalArgumentException("run name has not been set"); 193 } 194 if (mDevice == null) { 195 throw new IllegalArgumentException("Device has not been set"); 196 } 197 if (mTestJars.isEmpty()) { 198 throw new IllegalArgumentException("No test jar has been set"); 199 } 200 if (mTests == null) { 201 throw new IllegalArgumentException("tests has not been set"); 202 } 203 if (mCtsBuild == null) { 204 throw new IllegalArgumentException("build has not been set"); 205 } 206 for (String f : mTestJars) { 207 try { 208 209 mCtsBuild.getTestApp(f); 210 } catch (FileNotFoundException e) { 211 throw new IllegalArgumentException(String.format( 212 "Could not find jar %s in CTS build %s", f, 213 mCtsBuild.getRootDir().getAbsolutePath())); 214 } 215 } 216 } 217 218 /** 219 * Add runtime arguments to run the tests with. 220 * 221 * @param mRunTimeArgs 222 */ addRunTimeArgs(String mRunTimeArgs)223 public void addRunTimeArgs(String mRunTimeArgs) { 224 mRuntimeArgs = mRunTimeArgs; 225 } 226 } 227