• 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.command;
18 
19 import com.android.tradefed.clearcut.ClearcutClient;
20 import com.android.tradefed.command.CommandRunner.ExitCode;
21 import com.android.tradefed.config.ConfigurationException;
22 import com.android.tradefed.config.IConfigurationFactory;
23 import com.android.tradefed.device.FreeDeviceState;
24 import com.android.tradefed.device.ITestDevice;
25 import com.android.tradefed.device.NoDeviceException;
26 import com.android.tradefed.invoker.IInvocationContext;
27 import com.android.tradefed.invoker.ITestInvocation;
28 import com.android.tradefed.result.ITestInvocationListener;
29 import com.android.tradefed.util.Pair;
30 
31 import java.io.PrintWriter;
32 import java.util.List;
33 import java.util.Map;
34 
35 /**
36  * A scheduler for running TradeFederation commands.
37  */
38 public interface ICommandScheduler {
39 
40     /**
41     * Listener for invocation events when invocation completes.
42     * @see #execCommand(IScheduledInvocationListener, String[])
43     */
44     public static interface IScheduledInvocationListener extends ITestInvocationListener {
45         /**
46          * Callback when an invocation is initiated. This is called before any builds are fetched.
47          *
48          * @param context
49          */
invocationInitiated(IInvocationContext context)50         public default void invocationInitiated(IInvocationContext context) {}
51 
52         /**
53          * Callback associated with {@link ICommandOptions#earlyDeviceRelease()} to release the
54          * devices when done with them.
55          *
56          * @param context
57          * @param devicesStates
58          */
releaseDevices( IInvocationContext context, Map<ITestDevice, FreeDeviceState> devicesStates)59         public default void releaseDevices(
60                 IInvocationContext context, Map<ITestDevice, FreeDeviceState> devicesStates) {}
61 
62         /**
63          * Callback when entire invocation has completed, including all {@link
64          * ITestInvocationListener#invocationEnded(long)} events.
65          *
66          * @param context
67          * @param devicesStates
68          */
invocationComplete( IInvocationContext context, Map<ITestDevice, FreeDeviceState> devicesStates)69         public void invocationComplete(
70                 IInvocationContext context, Map<ITestDevice, FreeDeviceState> devicesStates);
71     }
72 
73     /**
74      * Adds a command to the scheduler.
75      *
76      * <p>A command is essentially an instance of a configuration to run and its associated
77      * arguments.
78      *
79      * <p>If "--help" argument is specified the help text for the config will be outputed to stdout.
80      * Otherwise, the config will be added to the queue to run.
81      *
82      * @param args the config arguments.
83      * @return A pair of values, first value is a Boolean <code>true</code> if command was added
84      *     successfully. Second value is the known command tracker id(non-negative value) if the
85      *     command was added successfully, return 0 when command is added for all devices, otherwise
86      *     -1.
87      * @throws ConfigurationException if command could not be parsed
88      * @see IConfigurationFactory#createConfigurationFromArgs(String[])
89      */
addCommand(String[] args)90     public Pair<Boolean, Integer> addCommand(String[] args) throws ConfigurationException;
91 
92     /**
93      * Adds all commands from given file to the scheduler
94      *
95      * @param cmdFile the filesystem path of comand file
96      * @param extraArgs a {@link List} of {@link String} arguments to append to each command parsed
97      *            from file. Can be empty but should not be null.
98      * @throws ConfigurationException if command file could not be parsed
99      * @see CommandFileParser
100      */
addCommandFile(String cmdFile, List<String> extraArgs)101     public void addCommandFile(String cmdFile, List<String> extraArgs)
102             throws ConfigurationException;
103 
104     /**
105      * Directly allocates a device and executes a command without adding it to the command queue.
106      *
107      * @param listener the {@link ICommandScheduler.IScheduledInvocationListener} to be informed
108      * @param args the command arguments
109      * @return The invocation id of the scheduled command.
110      * @throws ConfigurationException if command was invalid
111      * @throws NoDeviceException if there is no device to use
112      */
execCommand(IScheduledInvocationListener listener, String[] args)113     public long execCommand(IScheduledInvocationListener listener, String[] args)
114             throws ConfigurationException, NoDeviceException;
115 
116     /**
117      * Directly execute command on already allocated devices.
118      *
119      * @param listener the {@link ICommandScheduler.IScheduledInvocationListener} to be informed
120      * @param devices the {@link List<ITestDevice>} to use
121      * @param args the command arguments
122      * @return The invocation id of the scheduled command.
123      * @throws ConfigurationException if command was invalid
124      */
execCommand( IScheduledInvocationListener listener, List<ITestDevice> devices, String[] args)125     public long execCommand(
126             IScheduledInvocationListener listener, List<ITestDevice> devices, String[] args)
127             throws ConfigurationException;
128 
129     /**
130      * Directly execute command on already allocated device.
131      *
132      * @param listener the {@link ICommandScheduler.IScheduledInvocationListener} to be informed
133      * @param device the {@link ITestDevice} to use
134      * @param args the command arguments
135      * @return The invocation id of the scheduled command.
136      * @throws ConfigurationException if command was invalid
137      */
execCommand( IScheduledInvocationListener listener, ITestDevice device, String[] args)138     public long execCommand(
139             IScheduledInvocationListener listener, ITestDevice device, String[] args)
140             throws ConfigurationException;
141 
142     /**
143      * Directly allocates a device and executes a command without adding it to the command queue
144      * using an already existing {@link IInvocationContext}.
145      *
146      * @param context an existing {@link IInvocationContext}.
147      * @param listener the {@link ICommandScheduler.IScheduledInvocationListener} to be informed
148      * @param args the command arguments
149      * @throws ConfigurationException if command was invalid
150      * @throws NoDeviceException if there is no device to use
151      */
execCommand( IInvocationContext context, IScheduledInvocationListener listener, String[] args)152     public long execCommand(
153             IInvocationContext context, IScheduledInvocationListener listener, String[] args)
154             throws ConfigurationException, NoDeviceException;
155 
156     /**
157      * Remove all commands from scheduler
158      */
removeAllCommands()159     public void removeAllCommands();
160 
161     /**
162      * Attempt to gracefully shutdown the command scheduler.
163      *
164      * <p>Clears commands waiting to be tested, and requests that all invocations in progress shut
165      * down gracefully.
166      *
167      * <p>After shutdown is called, the scheduler main loop will wait for all invocations in
168      * progress to complete before exiting completely.
169      */
shutdown()170     default void shutdown() {
171         shutdown(false);
172     }
173 
174     /**
175      * Stops scheduling and accepting new tests but does not stop Tradefed. This is meant to enable
176      * a two steps shutdown where first we drain all the running tests, then terminate Tradefed
177      * process.
178      */
stopScheduling()179     default void stopScheduling() {
180         // Empty
181     }
182 
183     /**
184      * Attempt to gracefully shutdown the command scheduler.
185      *
186      * @param notifyStop if true, notifies invocations of TF shutdown.
187      */
shutdown(boolean notifyStop)188     public void shutdown(boolean notifyStop);
189 
190     /**
191      * Similar to {@link #shutdown()}, but will instead wait for all commands to be executed
192      * before exiting.
193      * <p/>
194      * Note that if any commands are in loop mode, the scheduler will never exit.
195      */
shutdownOnEmpty()196     public void shutdownOnEmpty();
197 
198     /** Attempt to forcefully shutdown the command scheduler. Same as shutdownHard(true). */
shutdownHard()199     public void shutdownHard();
200 
201     /**
202      * Attempt to forcefully shutdown the command scheduler.
203      *
204      * <p>Similar to {@link #shutdown()}, but will also optionally kill the adb connection, in an
205      * attempt to 'inspire' invocations in progress to complete quicker.
206      */
shutdownHard(boolean killAdb)207     public void shutdownHard(boolean killAdb);
208 
209     /**
210      * Start the {@link ICommandScheduler}.
211      * <p/>
212      * Must be called before calling other methods.
213      * <p/>
214      * Will run until {@link #shutdown()} is called.
215      *
216      * see {@link Thread#start()}.
217      */
start()218     public void start();
219 
220     /**
221      * Waits for scheduler to complete.
222      *
223      * @see Thread#join()
224      */
join()225     public void join() throws InterruptedException;
226 
227     /**
228      * Waits for scheduler to complete or timeout after the duration specified in milliseconds.
229      *
230      * @see Thread#join(long)
231      */
join(long millis)232     public void join(long millis) throws InterruptedException;
233 
234     /**
235      * Waits for scheduler to start running, including waiting for handover from old TF to complete
236      * if applicable.
237      */
await()238     public void await() throws InterruptedException;
239 
240     /**
241      * Displays a list of current invocations.
242      *
243      * @param printWriter the {@link PrintWriter} to output to.
244      */
displayInvocationsInfo(PrintWriter printWriter)245     public void displayInvocationsInfo(PrintWriter printWriter);
246 
247     /**
248      * Stop a running invocation.
249      *
250      * @return true if the invocation was stopped, false otherwise
251      * @throws UnsupportedOperationException if the implementation doesn't support this
252      */
stopInvocation(ITestInvocation invocation)253     public boolean stopInvocation(ITestInvocation invocation) throws UnsupportedOperationException;
254 
255     /**
256      * Stop a running invocation by specifying it's id.
257      *
258      * @return true if the invocation was stopped, false otherwise
259      * @throws UnsupportedOperationException if the implementation doesn't support this
260      */
stopInvocation(int invocationId)261     public default boolean stopInvocation(int invocationId) throws UnsupportedOperationException {
262         return stopInvocation(invocationId, null);
263     }
264 
265     /**
266      * Stop a running invocation by specifying it's id.
267      *
268      * @param invocationId the tracking id of the invocation.
269      * @param cause the cause for stopping the invocation.
270      * @return true if the invocation was stopped, false otherwise
271      * @throws UnsupportedOperationException if the implementation doesn't support this
272      */
stopInvocation(int invocationId, String cause)273     public boolean stopInvocation(int invocationId, String cause)
274             throws UnsupportedOperationException;
275 
276     /**
277      * Return the information on an invocation bu specifying the invocation id.
278      *
279      * @param invocationId the tracking id of the invocation.
280      * @return A {@link String} containing information about the invocation.
281      */
getInvocationInfo(int invocationId)282     public String getInvocationInfo(int invocationId);
283 
284     /**
285      * Output a list of current commands.
286      *
287      * @param printWriter the {@link PrintWriter} to output to.
288      * @param regex the regular expression to which commands should be matched in order to be
289      * printed.  If null, then all commands will be printed.
290      */
displayCommandsInfo(PrintWriter printWriter, String regex)291     public void displayCommandsInfo(PrintWriter printWriter, String regex);
292 
293     /**
294      * Dump the expanded xml file for the command with all
295      * {@link com.android.tradefed.config.Option} values specified for all current commands.
296      *
297      * @param printWriter the {@link PrintWriter} to output the status to.
298      * @param regex the regular expression to which commands should be matched in order for the
299      * xml file to be dumped.  If null, then all commands will be dumped.
300      */
dumpCommandsXml(PrintWriter printWriter, String regex)301     public void dumpCommandsXml(PrintWriter printWriter, String regex);
302 
303     /**
304      * Output detailed debug info on state of command execution queue.
305      *
306      * @param printWriter
307      */
displayCommandQueue(PrintWriter printWriter)308     public void displayCommandQueue(PrintWriter printWriter);
309 
310     /**
311      * Get the appropriate {@link CommandFileWatcher} for this scheduler
312      */
getCommandFileWatcher()313     public CommandFileWatcher getCommandFileWatcher();
314 
315     /**
316      * Return true if we need to shutdown the scheduler on a command errors
317      */
shouldShutdownOnCmdfileError()318     public boolean shouldShutdownOnCmdfileError();
319 
320     /**
321      * Return the error code of the last invocation that ran.
322      * Return 0 (no error), if no invocation has ran yet.
323      */
getLastInvocationExitCode()324     public ExitCode getLastInvocationExitCode();
325 
326     /**
327      * Return the {@link Throwable} from the last invocation that ran.
328      * Return null, if no throwable is available.
329      */
getLastInvocationThrowable()330     public Throwable getLastInvocationThrowable();
331 
332     /** Returns the number of Commands in ready state in the queue. */
getReadyCommandCount()333     public int getReadyCommandCount();
334 
335     /** Returns the number of Commands in executing state. */
getExecutingCommandCount()336     public int getExecutingCommandCount();
337 
338     /** Set the client to report harness data */
setClearcutClient(ClearcutClient client)339     public void setClearcutClient(ClearcutClient client);
340 
341     /** Returns true if the device is used by an active invocation thread. */
isDeviceInInvocationThread(ITestDevice device)342     public boolean isDeviceInInvocationThread(ITestDevice device);
343 }
344