• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.annotations.Nullable;
20 import com.android.tradefed.result.error.ErrorIdentifier;
21 
22 import java.io.File;
23 import java.io.IOException;
24 import java.io.OutputStream;
25 import java.lang.ProcessBuilder.Redirect;
26 import java.util.List;
27 
28 /**
29  * Interface for running timed operations and system commands.
30  */
31 public interface IRunUtil {
32 
33     /**
34      * An interface for asynchronously executing an operation that returns a boolean status.
35      */
36     public static interface IRunnableResult {
37         /**
38          * Execute the operation.
39          *
40          * @return <code>true</code> if operation is performed successfully, <code>false</code>
41          *         otherwise
42          * @throws Exception if operation terminated abnormally
43          */
run()44         public boolean run() throws Exception;
45 
46         /**
47          * Cancel the operation.
48          */
cancel()49         public void cancel();
50 
51         /** Returns the command associated with the runnable. */
getCommand()52         public default List<String> getCommand() {
53             return null;
54         }
55 
56         /** Returns the {@link CommandResult} associated with the command. */
getResult()57         public default CommandResult getResult() {
58             return null;
59         }
60 
61         /**
62          * Checks if the currently running operation has made progress since the last check.
63          *
64          * @param idleOutputTimeout ms idle with no observed progress before beginning to assume no
65          *     progress is being made.
66          * @return true if progress has been detected otherwise false.
67          */
checkOutputMonitor(Long idleOutputTimeout)68         public default boolean checkOutputMonitor(Long idleOutputTimeout) {
69             // Allow existing implementations not to implement this method.
70             throw new UnsupportedOperationException("checkOutputMonitor() has no implementation.");
71         }
72     }
73 
74     /**
75      * Sets the working directory for system commands.
76      *
77      * @param dir the working directory
78      *
79      * @see ProcessBuilder#directory(File)
80      */
setWorkingDir(File dir)81     public void setWorkingDir(File dir);
82 
83     /**
84      * Sets a environment variable to be used when running system commands.
85      *
86      * @param key the variable name
87      * @param value the variable value
88      *
89      * @see ProcessBuilder#environment()
90      *
91      */
setEnvVariable(String key, String value)92     public void setEnvVariable(String key, String value);
93 
94     /**
95      * Unsets an environment variable, so the system commands run without this environment variable.
96      *
97      * @param key the variable name
98      *
99      * @see ProcessBuilder#environment()
100      */
unsetEnvVariable(String key)101     public void unsetEnvVariable(String key);
102 
103     /**
104      * Set the standard error stream to redirect to the standard output stream when running system
105      * commands. Initial value is false.
106      *
107      * @param redirect new value for whether or not to redirect
108      * @see ProcessBuilder#redirectErrorStream(boolean)
109      */
setRedirectStderrToStdout(boolean redirect)110     public void setRedirectStderrToStdout(boolean redirect);
111 
112     /**
113      * Helper method to execute a system command, and aborting if it takes longer than a specified
114      * time.
115      *
116      * @param timeout maximum time to wait in ms. 0 means no timeout.
117      * @param command the specified system command and optionally arguments to exec
118      * @return a {@link CommandResult} containing result from command run
119      */
runTimedCmd(final long timeout, final String... command)120     public CommandResult runTimedCmd(final long timeout, final String... command);
121 
122     /**
123      * Helper method to execute a system command, and aborting if it takes longer than a specified
124      * time. Also monitors the output streams for activity, aborting if no stream activity is
125      * observed for a specified time. If the idleOutputTimeout is set to zero, no stream monitoring
126      * will occur.
127      *
128      * @param timeout maximum time to wait in ms. 0 means no timeout.
129      * @param idleOutputTimeout maximum time to wait in ms for output on the output streams
130      * @param command the specified system command and optionally arguments to exec
131      * @return a {@link CommandResult} containing result from command run
132      */
runTimedCmdWithOutputMonitor( final long timeout, final long idleOutputTimeout, final String... command)133     public CommandResult runTimedCmdWithOutputMonitor(
134             final long timeout, final long idleOutputTimeout, final String... command);
135 
136     /**
137      * Helper method to execute a system command, abort if it takes longer than a specified time,
138      * and redirect output to files if specified. When {@link OutputStream} are provided this way,
139      * they will be left open at the end of the function.
140      *
141      * @param timeout timeout maximum time to wait in ms. 0 means no timeout.
142      * @param idleOutputTimeout maximum time to wait in ms for output on the output streams
143      * @param stdout {@link OutputStream} where the std output will be redirected. Can be null.
144      * @param stderr {@link OutputStream} where the error output will be redirected. Can be null.
145      * @param command the specified system command and optionally arguments to exec
146      * @return a {@link CommandResult} containing result from command run
147      */
runTimedCmdWithOutputMonitor( final long timeout, final long idleOutputTimeout, OutputStream stdout, OutputStream stderr, final String... command)148     public CommandResult runTimedCmdWithOutputMonitor(
149             final long timeout,
150             final long idleOutputTimeout,
151             OutputStream stdout,
152             OutputStream stderr,
153             final String... command);
154 
155     /**
156      * Helper method to execute a system command, abort if it takes longer than a specified time,
157      * and redirect output to files if specified. When {@link OutputStream} are provided this way,
158      * they will be left open at the end of the function.
159      *
160      * @param timeout timeout maximum time to wait in ms. 0 means no timeout.
161      * @param stdout {@link OutputStream} where the std output will be redirected. Can be null.
162      * @param stderr {@link OutputStream} where the error output will be redirected. Can be null.
163      * @param command the specified system command and optionally arguments to exec
164      * @return a {@link CommandResult} containing result from command run
165      */
runTimedCmd( final long timeout, OutputStream stdout, OutputStream stderr, final String... command)166     public CommandResult runTimedCmd(
167             final long timeout, OutputStream stdout, OutputStream stderr, final String... command);
168 
169     /**
170      * Helper method to execute a system command, and aborting if it takes longer than a specified
171      * time.
172      *
173      * @param timeout maximum time to wait in ms for each attempt
174      * @param command the specified system command and optionally arguments to exec
175      * @param retryInterval time to wait between command retries
176      * @param attempts the maximum number of attempts to try
177      * @return a {@link CommandResult} containing result from command run
178      */
runTimedCmdRetry(final long timeout, long retryInterval, int attempts, final String... command)179     public CommandResult runTimedCmdRetry(final long timeout, long retryInterval,
180             int attempts, final String... command);
181 
182     /**
183      * Helper method to execute a system command, and aborting if it takes longer than a specified
184      * time. Also monitors the output streams for activity, aborting if no stream activity is
185      * observed for a specified time. If the idleOutputTimeout is set to zero, no stream monitoring
186      * will occur.
187      *
188      * @param timeout maximum time to wait in ms for each attempt
189      * @param idleOutputTimeout maximum time to wait in ms for output on the output streams
190      * @param command the specified system command and optionally arguments to exec
191      * @param retryInterval time to wait between command retries
192      * @param attempts the maximum number of attempts to try
193      * @return a {@link CommandResult} containing result from command run
194      */
runTimedCmdRetryWithOutputMonitor( final long timeout, final long idleOutputTimeout, long retryInterval, int attempts, final String... command)195     public CommandResult runTimedCmdRetryWithOutputMonitor(
196             final long timeout,
197             final long idleOutputTimeout,
198             long retryInterval,
199             int attempts,
200             final String... command);
201 
202     /**
203      * Helper method to execute a system command, and aborting if it takes longer than a specified
204      * time. Similar to {@link #runTimedCmd(long, String...)}, but does not log any errors on
205      * exception.
206      *
207      * @param timeout maximum time to wait in ms
208      * @param command the specified system command and optionally arguments to exec
209      * @return a {@link CommandResult} containing result from command run
210      */
runTimedCmdSilently(final long timeout, final String... command)211     public CommandResult runTimedCmdSilently(final long timeout, final String... command);
212 
213     /**
214      * Helper method to execute a system command, and aborting if it takes longer than a specified
215      * time. Similar to {@link #runTimedCmdRetry(long, long, int, String[])},
216      * but does not log any errors on exception.
217      *
218      * @param timeout maximum time to wait in ms
219      * @param command the specified system command and optionally arguments to exec
220      * @param retryInterval time to wait between command retries
221      * @param attempts the maximum number of attempts to try
222      * @return a {@link CommandResult} containing result from command run
223      */
runTimedCmdSilentlyRetry(final long timeout, long retryInterval, int attempts, final String... command)224     public CommandResult runTimedCmdSilentlyRetry(final long timeout, long retryInterval,
225             int attempts, final String... command);
226 
227     /**
228      * Helper method to execute a system command that requires stdin input, and aborting if it
229      * takes longer than a specified time.
230      *
231      * @param timeout maximum time to wait in ms
232      * @param input the stdin input to pass to process
233      * @param command the specified system command and optionally arguments to exec
234      * @return a {@link CommandResult} containing result from command run
235      */
runTimedCmdWithInput(long timeout, String input, String... command)236     CommandResult runTimedCmdWithInput(long timeout, String input, String... command);
237 
238     /**
239      * Helper method to execute a system command that requires stdin input, and aborting if it
240      * takes longer than a specified time.
241      *
242      * @param timeout maximum time to wait in ms
243      * @param input the stdin input to pass to process
244      * @param command {@link List} containing the system command and optionally arguments to exec
245      * @return a {@link CommandResult} containing result from command run
246      */
runTimedCmdWithInput(long timeout, String input, List<String> command)247     CommandResult runTimedCmdWithInput(long timeout, String input, List<String> command);
248 
249     /**
250      * Helper method to execute a system command, abort if it takes longer than a specified time,
251      * and redirect output to files if specified.
252      *
253      * @param timeout timeout maximum time to wait in ms. 0 means no timeout.
254      * @param input the stdin input to pass to process
255      * @param command the specified system command and optionally arguments to exec
256      * @param stdoutFile {@link File} where the std output will be redirected. Can be null.
257      * @param stderrFile {@link File} where the error output will be redirected. Can be null.
258      * @return a {@link CommandResult} containing result from command run
259      */
runTimedCmdWithInput( long timeout, String input, File stdoutFile, File stderrFile, final String... command)260     public CommandResult runTimedCmdWithInput(
261             long timeout, String input, File stdoutFile, File stderrFile, final String... command);
262 
263     /**
264      * Helper method to execute a system command that requires redirecting Stdin from a file, and
265      * aborting if it takes longer than a specified time.
266      *
267      * @param timeout maximum time to wait in ms
268      * @param inputRedirect the {@link File} to redirect as standard input using {@link
269      *     ProcessBuilder#redirectInput()}. If null, stdin won't be redirected.
270      * @param command the specified system command and optionally arguments to exec
271      * @return a {@link CommandResult} containing result from command run
272      */
runTimedCmdWithInputRedirect( long timeout, @Nullable File inputRedirect, String... command)273     CommandResult runTimedCmdWithInputRedirect(
274             long timeout, @Nullable File inputRedirect, String... command);
275 
276     /**
277      * Helper method to execute a system command asynchronously.
278      *
279      * <p>Will return immediately after launching command.
280      *
281      * @param command the specified system command and optionally arguments to exec
282      * @return the {@link Process} of the executed command
283      * @throws IOException if command failed to run
284      */
runCmdInBackground(String... command)285     public Process runCmdInBackground(String... command) throws IOException;
286 
287     /**
288      * Helper method to execute a system command asynchronously.
289      *
290      * <p>Will return immediately after launching command.
291      *
292      * @param redirect The {@link Redirect} to apply to the {@link ProcessBuilder}.
293      * @param command the specified system command and optionally arguments to exec
294      * @return the {@link Process} of the executed command
295      * @throws IOException if command failed to run
296      */
runCmdInBackground(Redirect redirect, final String... command)297     public Process runCmdInBackground(Redirect redirect, final String... command)
298             throws IOException;
299 
300     /**
301      * An alternate {@link #runCmdInBackground(String...)} method that accepts the command arguments
302      * in {@link List} form.
303      *
304      * @param command the {@link List} containing specified system command and optionally arguments
305      *            to exec
306      * @return the {@link Process} of the executed command
307      * @throws IOException if command failed to run
308      */
runCmdInBackground(List<String> command)309     public Process runCmdInBackground(List<String> command) throws IOException;
310 
311     /**
312      * An alternate {@link #runCmdInBackground(String...)} method that accepts the command arguments
313      * in {@link List} form.
314      *
315      * @param redirect The {@link Redirect} to apply to the {@link ProcessBuilder}.
316      * @param command the {@link List} containing specified system command and optionally arguments
317      *     to exec
318      * @return the {@link Process} of the executed command
319      * @throws IOException if command failed to run
320      */
runCmdInBackground(Redirect redirect, List<String> command)321     public Process runCmdInBackground(Redirect redirect, List<String> command) throws IOException;
322 
323     /**
324      * Running command with a {@link OutputStream} log the output of the command.
325      * Stdout and stderr are merged together.
326      * @param command the command to run
327      * @param output the OutputStream to save the output
328      * @return the {@link Process} running the command
329      * @throws IOException
330      */
runCmdInBackground(List<String> command, OutputStream output)331     public Process runCmdInBackground(List<String> command, OutputStream output)
332             throws IOException;
333 
334     /**
335      * Block and executes an operation, aborting if it takes longer than a specified time.
336      *
337      * @param timeout maximum time to wait in ms
338      * @param runnable {@link IRunUtil.IRunnableResult} to execute
339      * @param logErrors log errors on exception or not.
340      * @return the {@link CommandStatus} result of operation.
341      */
runTimed(long timeout, IRunUtil.IRunnableResult runnable, boolean logErrors)342     public CommandStatus runTimed(long timeout, IRunUtil.IRunnableResult runnable,
343             boolean logErrors);
344 
345     /**
346      * Block and executes an operation, aborting if it takes longer than a specified time. Also
347      * monitors the output streams for activity, aborting if no stream activity is observed for a
348      * specified time. If the idleOutputTimeout is set to zero, no stream monitoring will occur.
349      *
350      * @param timeout maximum time to wait in ms
351      * @param idleOutputTimeout maximum time to wait in ms for output on the output streams
352      * @param runnable {@link IRunUtil.IRunnableResult} to execute
353      * @param logErrors log errors on exception or not.
354      * @return the {@link CommandStatus} result of operation.
355      */
runTimedWithOutputMonitor( final long timeout, final long idleOutputTimeout, IRunUtil.IRunnableResult runnable, boolean logErrors)356     public CommandStatus runTimedWithOutputMonitor(
357             final long timeout,
358             final long idleOutputTimeout,
359             IRunUtil.IRunnableResult runnable,
360             boolean logErrors);
361 
362     /**
363      * Block and executes an operation multiple times until it is successful.
364      *
365      * @param opTimeout maximum time to wait in ms for one operation attempt
366      * @param pollInterval time to wait between command retries
367      * @param attempts the maximum number of attempts to try
368      * @param runnable {@link IRunUtil.IRunnableResult} to execute
369      * @return <code>true</code> if operation completed successfully before attempts reached.
370      */
runTimedRetry(long opTimeout, long pollInterval, int attempts, IRunUtil.IRunnableResult runnable)371     public boolean runTimedRetry(long opTimeout, long pollInterval, int attempts,
372             IRunUtil.IRunnableResult runnable);
373 
374     /**
375      * Block and executes an operation multiple times until it is successful. Also monitors the
376      * output streams for activity, aborting if no stream activity is observed for a specified time.
377      * If the idleOutputTimeout is set to zero, no stream monitoring will occur.
378      *
379      * @param opTimeout maximum time to wait in ms for one operation attempt
380      * @param idleOutputTimeout maximum time to wait in ms for output on the output streams
381      * @param pollInterval time to wait between command retries
382      * @param attempts the maximum number of attempts to try
383      * @param runnable {@link IRunUtil.IRunnableResult} to execute
384      * @return <code>true</code> if operation completed successfully before attempts reached.
385      */
runTimedRetryWithOutputMonitor( final long opTimeout, final long idleOutputTimeout, long pollInterval, int attempts, IRunUtil.IRunnableResult runnable)386     public boolean runTimedRetryWithOutputMonitor(
387             final long opTimeout,
388             final long idleOutputTimeout,
389             long pollInterval,
390             int attempts,
391             IRunUtil.IRunnableResult runnable);
392 
393     /**
394      * Block and executes an operation multiple times until it is successful.
395      *
396      * @param opTimeout maximum time to wait in ms for a single operation attempt
397      * @param pollInterval initial time to wait between operation attempts
398      * @param maxTime the total approximate maximum time to keep trying the operation
399      * @param runnable {@link IRunUtil.IRunnableResult} to execute
400      * @return <code>true</code> if operation completed successfully before maxTime expired
401      */
runFixedTimedRetry(final long opTimeout, final long pollInterval, final long maxTime, final IRunUtil.IRunnableResult runnable)402     public boolean runFixedTimedRetry(final long opTimeout, final long pollInterval,
403             final long maxTime, final IRunUtil.IRunnableResult runnable);
404 
405     /**
406      * Block and executes an operation multiple times until it is successful. Also monitors the
407      * output streams for activity, aborting if no stream activity is observed for a specified time.
408      * If the idleOutputTimeout is set to zero, no stream monitoring will occur.
409      *
410      * @param opTimeout maximum time to wait in ms for a single operation attempt
411      * @param idleOutputTimeout maximum time to wait in ms for output on the output streams
412      * @param pollInterval initial time to wait between operation attempts
413      * @param maxTime the total approximate maximum time to keep trying the operation
414      * @param runnable {@link IRunUtil.IRunnableResult} to execute
415      * @return <code>true</code> if operation completed successfully before maxTime expired
416      */
runFixedTimedRetryWithOutputMonitor( final long opTimeout, final long idleOutputTimeout, final long pollInterval, final long maxTime, final IRunUtil.IRunnableResult runnable)417     public boolean runFixedTimedRetryWithOutputMonitor(
418             final long opTimeout,
419             final long idleOutputTimeout,
420             final long pollInterval,
421             final long maxTime,
422             final IRunUtil.IRunnableResult runnable);
423 
424     /**
425      * Block and executes an operation multiple times until it is successful.
426      * <p/>
427      * Exponentially increase the wait time between operation attempts. This is intended to be used
428      * when performing an operation such as polling a server, to give it time to recover in case it
429      * is temporarily down.
430      *
431      * @param opTimeout maximum time to wait in ms for a single operation attempt
432      * @param initialPollInterval initial time to wait between operation attempts
433      * @param maxPollInterval the max time to wait between operation attempts
434      * @param maxTime the total approximate maximum time to keep trying the operation
435      * @param runnable {@link IRunUtil.IRunnableResult} to execute
436      * @return <code>true</code> if operation completed successfully before maxTime expired
437      */
runEscalatingTimedRetry(final long opTimeout, final long initialPollInterval, final long maxPollInterval, final long maxTime, final IRunUtil.IRunnableResult runnable)438     public boolean runEscalatingTimedRetry(final long opTimeout, final long initialPollInterval,
439             final long maxPollInterval, final long maxTime, final IRunUtil.IRunnableResult
440             runnable);
441 
442     /**
443      * Helper method to sleep for given time, ignoring any exceptions.
444      *
445      * @param time ms to sleep. values less than or equal to 0 will be ignored
446      */
sleep(long time)447     public void sleep(long time);
448 
449     /**
450      * Allows/disallows run interrupts on the current thread. If it is allowed, run operations of
451      * the current thread can be interrupted from other threads via {@link #interrupt} method.
452      *
453      * @param allow whether to allow run interrupts on the current thread.
454      */
allowInterrupt(boolean allow)455     public void allowInterrupt(boolean allow);
456 
457     /**
458      * Give the interrupt status of the RunUtil.
459      * @return true if the Run can be interrupted, false otherwise.
460      */
isInterruptAllowed()461     public boolean isInterruptAllowed();
462 
463     /**
464      * Set as interruptible after some waiting time.
465      * {@link CommandScheduler#shutdownHard()} to enforce we terminate eventually.
466      *
467      * @param thread the thread that will become interruptible.
468      * @param timeMs time to wait before setting interruptible.
469      */
setInterruptibleInFuture(Thread thread, long timeMs)470     public void setInterruptibleInFuture(Thread thread, long timeMs);
471 
472     /**
473      * Interrupts the ongoing/forthcoming run operations on the given thread. The run operations on
474      * the given thread will throw {@link RunInterruptedException}.
475      *
476      * @param thread
477      * @param message the message for {@link RunInterruptedException}.
478      */
interrupt(Thread thread, String message)479     public void interrupt(Thread thread, String message);
480 
481     /**
482      * Interrupts the ongoing/forthcoming run operations on the given thread. The run operations on
483      * the given thread will throw {@link RunInterruptedException}.
484      *
485      * @param thread
486      * @param message the message for {@link RunInterruptedException}.
487      * @param errorId Representing the cause of the interruption when known.
488      */
interrupt(Thread thread, String message, ErrorIdentifier errorId)489     public void interrupt(Thread thread, String message, ErrorIdentifier errorId);
490 
491     /**
492      * Decide whether or not when creating a process, unsetting environment variable is higher
493      * priority than setting them.
494      * By Default, unsetting is higher priority: meaning if an attempt to set a variable with the
495      * same name is made, it won't happen since the variable will be unset.
496      * Cannot be used on the default {@link IRunUtil} instance.
497      */
setEnvVariablePriority(EnvPriority priority)498     public void setEnvVariablePriority(EnvPriority priority);
499 
500     /**
501      * Allow to use linux 'kill' interruption on process running through #runTimed methods when it
502      * reaches a timeout.
503      *
504      * Cannot be used on the default {@link IRunUtil} instance.
505      */
setLinuxInterruptProcess(boolean interrupt)506     public void setLinuxInterruptProcess(boolean interrupt);
507 
508     /**
509      * Enum that defines whether setting or unsetting a particular env. variable has priority.
510      */
511     public enum EnvPriority {
512         SET,
513         UNSET
514     }
515 }
516