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