1 /* 2 * Copyright (C) 2018 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 package com.android.tradefed.targetprep.adb; 17 18 import com.android.annotations.VisibleForTesting; 19 import com.android.tradefed.build.IBuildInfo; 20 import com.android.tradefed.config.GlobalConfiguration; 21 import com.android.tradefed.config.Option; 22 import com.android.tradefed.config.OptionClass; 23 import com.android.tradefed.device.DeviceNotAvailableException; 24 import com.android.tradefed.device.IDeviceManager; 25 import com.android.tradefed.invoker.ExecutionFiles.FilesKey; 26 import com.android.tradefed.invoker.TestInformation; 27 import com.android.tradefed.log.LogUtil.CLog; 28 import com.android.tradefed.targetprep.BaseTargetPreparer; 29 import com.android.tradefed.targetprep.BuildError; 30 import com.android.tradefed.targetprep.SemaphoreTokenTargetPreparer; 31 import com.android.tradefed.targetprep.TargetSetupError; 32 import com.android.tradefed.util.CommandResult; 33 import com.android.tradefed.util.CommandStatus; 34 import com.android.tradefed.util.FileUtil; 35 import com.android.tradefed.util.IRunUtil; 36 import com.android.tradefed.util.RunUtil; 37 38 import java.io.File; 39 import java.io.IOException; 40 41 /** 42 * Target preparer to stop adb server on the host before and after running adb tests. 43 * 44 * <p>This preparer should be used with care as it stops and restart adb on the hosts. It should 45 * usually be tight with {@link SemaphoreTokenTargetPreparer} to avoid other tests from running at 46 * the same time. 47 */ 48 @OptionClass(alias = "adb-stop-server-preparer") 49 public class AdbStopServerPreparer extends BaseTargetPreparer { 50 51 public static final String ADB_BINARY_KEY = "adb_path"; 52 53 @Option( 54 name = "restart-new-adb-version", 55 description = "Whether or not to restart adb with the new version after stopping it." 56 ) 57 private boolean mRestartNewVersion = true; 58 59 private static final long CMD_TIMEOUT = 60000L; 60 private static final String ANDROID_HOST_OUT = "ANDROID_HOST_OUT"; 61 62 private IRunUtil mRunUtil; 63 private File mTmpDir; 64 65 /** {@inheritDoc} */ 66 @Override setUp(TestInformation testInfo)67 public void setUp(TestInformation testInfo) 68 throws TargetSetupError, BuildError, DeviceNotAvailableException { 69 IBuildInfo buildInfo = testInfo.getBuildInfo(); 70 getDeviceManager().stopAdbBridge(); 71 72 // Kill the default adb server 73 getRunUtil().runTimedCmd(CMD_TIMEOUT, "adb", "kill-server"); 74 // Let the adb process finish 75 getRunUtil().sleep(2000); 76 77 if (!mRestartNewVersion) { 78 CLog.d("Skipping restarting of new adb version."); 79 return; 80 } 81 82 File adb = null; 83 if (getEnvironment(ANDROID_HOST_OUT) != null) { 84 String hostOut = getEnvironment(ANDROID_HOST_OUT); 85 adb = new File(hostOut, "bin/adb"); 86 if (adb.exists()) { 87 adb.setExecutable(true); 88 } else { 89 adb = null; 90 } 91 } 92 93 if (adb == null && buildInfo.getFile("adb") != null) { 94 adb = buildInfo.getFile("adb"); 95 adb = renameAdbBinary(adb); 96 // Track the updated adb file. 97 testInfo.executionFiles().put(FilesKey.ADB_BINARY, adb); 98 } 99 100 if (adb != null) { 101 CLog.d("Restarting adb from %s", adb.getAbsolutePath()); 102 IRunUtil restartAdb = createRunUtil(); 103 CommandResult result = 104 restartAdb.runTimedCmd(CMD_TIMEOUT, adb.getAbsolutePath(), "start-server"); 105 if (!CommandStatus.SUCCESS.equals(result.getStatus())) { 106 throw new TargetSetupError( 107 String.format( 108 "Failed to restart adb with the build info one. stdout: %s.\n" 109 + "sterr: %s", 110 result.getStdout(), result.getStderr()), 111 testInfo.getDevice().getDeviceDescriptor()); 112 } 113 } else { 114 getRunUtil().runTimedCmd(CMD_TIMEOUT, "adb", "start-server"); 115 throw new TargetSetupError( 116 "Could not find a new version of adb to tests.", 117 testInfo.getDevice().getDeviceDescriptor()); 118 } 119 } 120 121 /** {@inheritDoc} */ 122 @Override tearDown(TestInformation testInfo, Throwable e)123 public void tearDown(TestInformation testInfo, Throwable e) throws DeviceNotAvailableException { 124 FileUtil.recursiveDelete(mTmpDir); 125 // Kill the test adb server 126 getRunUtil().runTimedCmd(CMD_TIMEOUT, "adb", "kill-server"); 127 // Restart the one from the parent PATH (original one) 128 CommandResult restart = getRunUtil().runTimedCmd(CMD_TIMEOUT, "adb", "start-server"); 129 CLog.d("Restart adb - stdout: %s\nstderr: %s", restart.getStdout(), restart.getStderr()); 130 // Restart device manager monitor 131 getDeviceManager().restartAdbBridge(); 132 } 133 134 @VisibleForTesting getDeviceManager()135 IDeviceManager getDeviceManager() { 136 return GlobalConfiguration.getDeviceManagerInstance(); 137 } 138 139 @VisibleForTesting createRunUtil()140 IRunUtil createRunUtil() { 141 return new RunUtil(); 142 } 143 144 @VisibleForTesting getEnvironment(String key)145 String getEnvironment(String key) { 146 return System.getenv(key); 147 } 148 getRunUtil()149 private IRunUtil getRunUtil() { 150 if (mRunUtil == null) { 151 mRunUtil = createRunUtil(); 152 } 153 return mRunUtil; 154 } 155 renameAdbBinary(File originalAdb)156 private File renameAdbBinary(File originalAdb) { 157 try { 158 mTmpDir = FileUtil.createTempDir("adb"); 159 } catch (IOException e) { 160 CLog.e("Cannot create temp directory"); 161 FileUtil.recursiveDelete(mTmpDir); 162 return null; 163 } 164 File renamedAdbBinary = new File(mTmpDir, "adb"); 165 if (!originalAdb.renameTo(renamedAdbBinary)) { 166 CLog.e("Cannot rename adb binary"); 167 return null; 168 } 169 if (!renamedAdbBinary.setExecutable(true)) { 170 CLog.e("Cannot set adb binary executable"); 171 return null; 172 } 173 return renamedAdbBinary; 174 } 175 } 176