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 */ 42 public boolean run() throws Exception; 43 44 /** 45 * Cancel the operation. 46 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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 */ 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