1 /* 2 * Copyright (C) 2011 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.ITestRunListener; 21 import com.android.tradefed.build.IBuildInfo; 22 import com.android.tradefed.device.DeviceNotAvailableException; 23 import com.android.tradefed.device.ITestDevice; 24 import com.android.tradefed.log.LogUtil.CLog; 25 import com.android.tradefed.result.ITestInvocationListener; 26 import com.android.tradefed.testtype.IAbi; 27 import com.android.tradefed.testtype.IBuildReceiver; 28 import com.android.tradefed.testtype.IDeviceTest; 29 import com.android.tradefed.testtype.IRemoteTest; 30 31 import java.io.File; 32 33 /** 34 * Test runner for native gTests. 35 * 36 * TODO: This is similar to Tradefed's existing GTest, but it doesn't confirm 37 * each directory segment exists using ddmlib's file service. This was 38 * a problem since /data is not visible on a user build, but it is 39 * executable. It's also a lot more verbose when it comes to errors. 40 */ 41 public class GeeTest implements IBuildReceiver, IDeviceTest, IRemoteTest { 42 43 private static final String NATIVE_TESTS_DIRECTORY = "/data/local/tmp/cts-native-tests"; 44 private static final String NATIVE_TESTS_DIRECTORY_TMP = "/data/local/tmp"; 45 private static final String ANDROID_PATH_SEPARATOR = "/"; 46 47 private int mMaxTestTimeMs = 1 * 60 * 1000; 48 49 private CtsBuildHelper mCtsBuild; 50 private ITestDevice mDevice; 51 private IAbi mAbi; 52 private String mExeName; 53 54 private final String mPackageName; 55 56 public GeeTest(String packageName, String exeName) { 57 mPackageName = packageName; 58 mExeName = exeName; 59 } 60 61 /** 62 * @param abi The ABI to run the test on 63 */ 64 public void setAbi(IAbi abi) { 65 mAbi = abi; 66 mExeName += mAbi.getBitness(); 67 } 68 69 @Override 70 public void run(ITestInvocationListener listener) throws DeviceNotAvailableException { 71 if (installTest()) { 72 runTest(listener); 73 } else { 74 CLog.e("Failed to install native tests"); 75 } 76 } 77 78 private boolean installTest() throws DeviceNotAvailableException { 79 if (!createRemoteDir(NATIVE_TESTS_DIRECTORY)) { 80 CLog.e("Could not create directory for native tests: " + NATIVE_TESTS_DIRECTORY); 81 return false; 82 } 83 84 File nativeExe = new File(mCtsBuild.getTestCasesDir(), mExeName); 85 if (!nativeExe.exists()) { 86 CLog.e("Native test not found: " + nativeExe); 87 return false; 88 } 89 90 String devicePath = NATIVE_TESTS_DIRECTORY + ANDROID_PATH_SEPARATOR + mExeName; 91 if (!mDevice.pushFile(nativeExe, devicePath)) { 92 CLog.e("Failed to push native test to device"); 93 return false; 94 } 95 return true; 96 } 97 98 private boolean createRemoteDir(String remoteFilePath) throws DeviceNotAvailableException { 99 if (mDevice.doesFileExist(remoteFilePath)) { 100 return true; 101 } 102 if (!(mDevice.doesFileExist(NATIVE_TESTS_DIRECTORY_TMP))) { 103 CLog.e("Could not find the /data/local/tmp directory"); 104 return false; 105 } 106 107 mDevice.executeShellCommand(String.format("mkdir %s", remoteFilePath)); 108 return mDevice.doesFileExist(remoteFilePath); 109 } 110 111 void runTest(ITestRunListener listener) throws DeviceNotAvailableException { 112 GeeTestResultParser resultParser = new GeeTestResultParser(mPackageName, listener); 113 resultParser.setFakePackagePrefix(mPackageName + "."); 114 115 String fullPath = NATIVE_TESTS_DIRECTORY + ANDROID_PATH_SEPARATOR + mExeName; 116 String flags = ""; 117 CLog.v("Running gtest %s %s on %s", fullPath, flags, mDevice.getSerialNumber()); 118 // force file to be executable 119 CLog.v("%s", mDevice.executeShellCommand(String.format("chmod 755 %s", fullPath))); 120 121 try { 122 mDevice.executeShellCommand(String.format("%s %s", fullPath, flags), resultParser, 123 mMaxTestTimeMs /* maxTimeToShellOutputResponse */, 124 0 /* retryAttempts */); 125 } catch (DeviceNotAvailableException e) { 126 resultParser.flush(); 127 throw e; 128 } catch (RuntimeException e) { 129 resultParser.flush(); 130 throw e; 131 } 132 } 133 134 135 @Override 136 public void setBuild(IBuildInfo buildInfo) { 137 mCtsBuild = CtsBuildHelper.createBuildHelper(buildInfo); 138 } 139 140 @Override 141 public void setDevice(ITestDevice device) { 142 mDevice = device; 143 } 144 145 @Override 146 public ITestDevice getDevice() { 147 return mDevice; 148 } 149 } 150