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