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