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