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