1 /* 2 * Copyright (C) 2010 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.tradefed.util; 18 19 import com.android.tradefed.command.CommandScheduler; 20 21 import java.io.File; 22 import java.io.IOException; 23 import java.io.OutputStream; 24 import java.util.List; 25 26 /** 27 * Interface for running timed operations and system commands. 28 */ 29 public interface IRunUtil { 30 31 /** 32 * An interface for asynchronously executing an operation that returns a boolean status. 33 */ 34 public static interface IRunnableResult { 35 /** 36 * Execute the operation. 37 * 38 * @return <code>true</code> if operation is performed successfully, <code>false</code> 39 * otherwise 40 * @throws Exception if operation terminated abnormally 41 */ run()42 public boolean run() throws Exception; 43 44 /** 45 * Cancel the operation. 46 */ cancel()47 public void cancel(); 48 } 49 50 /** 51 * Sets the working directory for system commands. 52 * 53 * @param dir the working directory 54 * 55 * @see ProcessBuilder#directory(File) 56 */ setWorkingDir(File dir)57 public void setWorkingDir(File dir); 58 59 /** 60 * Sets a environment variable to be used when running system commands. 61 * 62 * @param key the variable name 63 * @param value the variable value 64 * 65 * @see ProcessBuilder#environment() 66 * 67 */ setEnvVariable(String key, String value)68 public void setEnvVariable(String key, String value); 69 70 /** 71 * Unsets an environment variable, so the system commands run without this environment variable. 72 * 73 * @param key the variable name 74 * 75 * @see ProcessBuilder#environment() 76 */ unsetEnvVariable(String key)77 public void unsetEnvVariable(String key); 78 79 /** 80 * Helper method to execute a system command, and aborting if it takes longer than a specified 81 * time. 82 * 83 * @param timeout maximum time to wait in ms. 0 means no timeout. 84 * @param command the specified system command and optionally arguments to exec 85 * @return a {@link CommandResult} containing result from command run 86 */ runTimedCmd(final long timeout, final String... command)87 public CommandResult runTimedCmd(final long timeout, final String... command); 88 89 /** 90 * Helper method to execute a system command, abort if it takes longer than a specified time, 91 * and redirect output to files if specified. When {@link OutputStream} are provided this way, 92 * they will be left open at the end of the function. 93 * 94 * @param timeout timeout maximum time to wait in ms. 0 means no timeout. 95 * @param stdout {@link OutputStream} where the std output will be redirected. Can be null. 96 * @param stderr {@link OutputStream} where the error output will be redirected. Can be null. 97 * @param command the specified system command and optionally arguments to exec 98 * @return a {@link CommandResult} containing result from command run 99 */ runTimedCmd( final long timeout, OutputStream stdout, OutputStream stderr, final String... command)100 public CommandResult runTimedCmd( 101 final long timeout, OutputStream stdout, OutputStream stderr, final String... command); 102 103 /** 104 * Helper method to execute a system command, and aborting if it takes longer than a specified 105 * time. 106 * 107 * @param timeout maximum time to wait in ms for each attempt 108 * @param command the specified system command and optionally arguments to exec 109 * @param retryInterval time to wait between command retries 110 * @param attempts the maximum number of attempts to try 111 * @return a {@link CommandResult} containing result from command run 112 */ runTimedCmdRetry(final long timeout, long retryInterval, int attempts, final String... command)113 public CommandResult runTimedCmdRetry(final long timeout, long retryInterval, 114 int attempts, final String... command); 115 116 /** 117 * Helper method to execute a system command, and aborting if it takes longer than a specified 118 * time. Similar to {@link #runTimedCmd(long, String...)}, but does not log any errors on 119 * exception. 120 * 121 * @param timeout maximum time to wait in ms 122 * @param command the specified system command and optionally arguments to exec 123 * @return a {@link CommandResult} containing result from command run 124 */ runTimedCmdSilently(final long timeout, final String... command)125 public CommandResult runTimedCmdSilently(final long timeout, final String... command); 126 127 /** 128 * Helper method to execute a system command, and aborting if it takes longer than a specified 129 * time. Similar to {@link #runTimedCmdRetry(long, long, int, String[])}, 130 * but does not log any errors on exception. 131 * 132 * @param timeout maximum time to wait in ms 133 * @param command the specified system command and optionally arguments to exec 134 * @param retryInterval time to wait between command retries 135 * @param attempts the maximum number of attempts to try 136 * @return a {@link CommandResult} containing result from command run 137 */ runTimedCmdSilentlyRetry(final long timeout, long retryInterval, int attempts, final String... command)138 public CommandResult runTimedCmdSilentlyRetry(final long timeout, long retryInterval, 139 int attempts, final String... command); 140 141 /** 142 * Helper method to execute a system command that requires stdin input, and aborting if it 143 * takes longer than a specified time. 144 * 145 * @param timeout maximum time to wait in ms 146 * @param input the stdin input to pass to process 147 * @param command the specified system command and optionally arguments to exec 148 * @return a {@link CommandResult} containing result from command run 149 */ runTimedCmdWithInput(long timeout, String input, String... command)150 CommandResult runTimedCmdWithInput(long timeout, String input, String... command); 151 152 /** 153 * Helper method to execute a system command that requires stdin input, and aborting if it 154 * takes longer than a specified time. 155 * 156 * @param timeout maximum time to wait in ms 157 * @param input the stdin input to pass to process 158 * @param command {@link List} containing the system command and optionally arguments to exec 159 * @return a {@link CommandResult} containing result from command run 160 */ runTimedCmdWithInput(long timeout, String input, List<String> command)161 CommandResult runTimedCmdWithInput(long timeout, String input, List<String> command); 162 163 /** 164 * Helper method to execute a system command asynchronously. 165 * <p/> 166 * Will return immediately after launching command. 167 * 168 * @param command the specified system command and optionally arguments to exec 169 * @return the {@link Process} of the executed command 170 * @throws IOException if command failed to run 171 */ runCmdInBackground(String... command)172 public Process runCmdInBackground(String... command) throws IOException; 173 174 /** 175 * An alternate {@link #runCmdInBackground(String...)} method that accepts the command arguments 176 * in {@link List} form. 177 * 178 * @param command the {@link List} containing specified system command and optionally arguments 179 * to exec 180 * @return the {@link Process} of the executed command 181 * @throws IOException if command failed to run 182 */ runCmdInBackground(List<String> command)183 public Process runCmdInBackground(List<String> command) throws IOException; 184 185 /** 186 * Running command with a {@link OutputStream} log the output of the command. 187 * Stdout and stderr are merged together. 188 * @param command the command to run 189 * @param output the OutputStream to save the output 190 * @return the {@link Process} running the command 191 * @throws IOException 192 */ runCmdInBackground(List<String> command, OutputStream output)193 public Process runCmdInBackground(List<String> command, OutputStream output) 194 throws IOException; 195 196 /** 197 * Block and executes an operation, aborting if it takes longer than a specified time. 198 * 199 * @param timeout maximum time to wait in ms 200 * @param runnable {@link IRunUtil.IRunnableResult} to execute 201 * @param logErrors log errors on exception or not. 202 * @return the {@link CommandStatus} result of operation. 203 */ runTimed(long timeout, IRunUtil.IRunnableResult runnable, boolean logErrors)204 public CommandStatus runTimed(long timeout, IRunUtil.IRunnableResult runnable, 205 boolean logErrors); 206 207 /** 208 * Block and executes an operation multiple times until it is successful. 209 * 210 * @param opTimeout maximum time to wait in ms for one operation attempt 211 * @param pollInterval time to wait between command retries 212 * @param attempts the maximum number of attempts to try 213 * @param runnable {@link IRunUtil.IRunnableResult} to execute 214 * @return <code>true</code> if operation completed successfully before attempts reached. 215 */ runTimedRetry(long opTimeout, long pollInterval, int attempts, IRunUtil.IRunnableResult runnable)216 public boolean runTimedRetry(long opTimeout, long pollInterval, int attempts, 217 IRunUtil.IRunnableResult runnable); 218 219 /** 220 * Block and executes an operation multiple times until it is successful. 221 * 222 * @param opTimeout maximum time to wait in ms for a single operation attempt 223 * @param pollInterval initial time to wait between operation attempts 224 * @param maxTime the total approximate maximum time to keep trying the operation 225 * @param runnable {@link IRunUtil.IRunnableResult} to execute 226 * @return <code>true</code> if operation completed successfully before maxTime expired 227 */ runFixedTimedRetry(final long opTimeout, final long pollInterval, final long maxTime, final IRunUtil.IRunnableResult runnable)228 public boolean runFixedTimedRetry(final long opTimeout, final long pollInterval, 229 final long maxTime, final IRunUtil.IRunnableResult runnable); 230 231 /** 232 * Block and executes an operation multiple times until it is successful. 233 * <p/> 234 * Exponentially increase the wait time between operation attempts. This is intended to be used 235 * when performing an operation such as polling a server, to give it time to recover in case it 236 * is temporarily down. 237 * 238 * @param opTimeout maximum time to wait in ms for a single operation attempt 239 * @param initialPollInterval initial time to wait between operation attempts 240 * @param maxPollInterval the max time to wait between operation attempts 241 * @param maxTime the total approximate maximum time to keep trying the operation 242 * @param runnable {@link IRunUtil.IRunnableResult} to execute 243 * @return <code>true</code> if operation completed successfully before maxTime expired 244 */ runEscalatingTimedRetry(final long opTimeout, final long initialPollInterval, final long maxPollInterval, final long maxTime, final IRunUtil.IRunnableResult runnable)245 public boolean runEscalatingTimedRetry(final long opTimeout, final long initialPollInterval, 246 final long maxPollInterval, final long maxTime, final IRunUtil.IRunnableResult 247 runnable); 248 249 /** 250 * Helper method to sleep for given time, ignoring any exceptions. 251 * 252 * @param time ms to sleep. values less than or equal to 0 will be ignored 253 */ sleep(long time)254 public void sleep(long time); 255 256 /** 257 * Allows/disallows run interrupts on the current thread. If it is allowed, run operations of 258 * the current thread can be interrupted from other threads via {@link #interrupt} method. 259 * 260 * @param allow whether to allow run interrupts on the current thread. 261 */ allowInterrupt(boolean allow)262 public void allowInterrupt(boolean allow); 263 264 /** 265 * Give the interrupt status of the RunUtil. 266 * @return true if the Run can be interrupted, false otherwise. 267 */ isInterruptAllowed()268 public boolean isInterruptAllowed(); 269 270 /** 271 * Set as interruptible after some waiting time. 272 * {@link CommandScheduler#shutdownHard()} to enforce we terminate eventually. 273 * 274 * @param thread the thread that will become interruptible. 275 * @param timeMs time to wait before setting interruptible. 276 */ setInterruptibleInFuture(Thread thread, long timeMs)277 public void setInterruptibleInFuture(Thread thread, long timeMs); 278 279 /** 280 * Interrupts the ongoing/forthcoming run operations on the given thread. The run operations on 281 * the given thread will throw {@link RunInterruptedException}. 282 * 283 * @param thread 284 * @param message the message for {@link RunInterruptedException}. 285 */ interrupt(Thread thread, String message)286 public void interrupt(Thread thread, String message); 287 288 /** 289 * Decide whether or not when creating a process, unsetting environment variable is higher 290 * priority than setting them. 291 * By Default, unsetting is higher priority: meaning if an attempt to set a variable with the 292 * same name is made, it won't happen since the variable will be unset. 293 * Cannot be used on the default {@link IRunUtil} instance. 294 */ setEnvVariablePriority(EnvPriority priority)295 public void setEnvVariablePriority(EnvPriority priority); 296 297 /** 298 * Enum that defines whether setting or unsetting a particular env. variable has priority. 299 */ 300 public enum EnvPriority { 301 SET, 302 UNSET 303 } 304 } 305