/* * Copyright (C) 2008 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.android.cts; import com.android.cts.TestHost.ActionType; import com.android.cts.TestHost.MODE; import org.xml.sax.SAXException; import java.io.BufferedReader; import java.io.File; import java.io.FileNotFoundException; import java.io.IOException; import java.io.InputStreamReader; import java.security.NoSuchAlgorithmException; import java.util.ArrayList; import java.util.Collection; import java.util.HashMap; import java.util.List; import javax.xml.parsers.ParserConfigurationException; import javax.xml.transform.TransformerException; import javax.xml.transform.TransformerFactoryConfigurationError; /** * Main console of CTS providing user with the interface to interact.
* Using CommandParser to parse command line argument and process. * */ public class ConsoleUi { private static final String OS_NAME_LINUX = "Linux"; private static final String LS_PLAN_SEPARATOR = "================================="; private static final String CMD_TYPE_LEADING_SPACE = " "; private static final String CMD_OPT_LEADING_SPACE = " "; private static final String CREATE_SESSION = "create a new session"; private static final String CHOOSE_SESSION = "choose a session"; private TestHost mHost; private boolean mKeepRunning; private BufferedReader mCommandInput; // private static ConsoleInputStream sConsoleReader; private CommandHistory mCommandHistory = new CommandHistory(); private String mOsName = "none"; // Define test case name pattern static final String CASE_NAME_PATTERN_STR = "((\\S+\\.)+\\S+)\\.(\\S+):(\\S+)"; private static HashMap mResultCodeMap; static { mResultCodeMap = new HashMap(); mResultCodeMap.put(CtsTestResult.STR_PASS, CtsTestResult.CODE_PASS); mResultCodeMap.put(CtsTestResult.STR_FAIL, CtsTestResult.CODE_FAIL); mResultCodeMap.put(CtsTestResult.STR_ERROR, CtsTestResult.CODE_ERROR); mResultCodeMap.put(CtsTestResult.STR_NOT_EXECUTED, CtsTestResult.CODE_NOT_EXECUTED); mResultCodeMap.put(CtsTestResult.STR_TIMEOUT, CtsTestResult.CODE_TIMEOUT); } public ConsoleUi(TestHost host) { mHost = host; mCommandInput = new BufferedReader(new InputStreamReader(System.in)); mKeepRunning = true; initInputStream(); } /** * Start the console user interface. * */ public void startUi() { while (mKeepRunning) { try { String cmdLine = readLine(CUIOutputStream.CTS_PROMPT_SIGN); CommandParser cp = CommandParser.parse(cmdLine); processCommand(cp); mCommandHistory.addCommand(cp, cmdLine); } catch (CommandNotFoundException e) { // avoid displaying help message for empty // command by pressing ENTER over console directly } catch (Exception e) { Log.e("Got exception while processing command.", e); showHelp(); } } } /** * Initialize the CommandProcessor. */ private void initInputStream() { // mOsName = System.getProperty("os.name"); if (mOsName.equals(OS_NAME_LINUX)) { // sConsoleReader = new ConsoleInputStream(new FileInputStream( // FileDescriptor.in), mCommandHistory); // sConsoleReader.setup(); } else { mCommandInput = new BufferedReader(new InputStreamReader(System.in)); } } /** * Read a message line from console. * * @param prompt The notification message print out to console before reading. * @return The string user typed in. */ private String readLine(String prompt) throws IOException { String cmdLine = null; if (mOsName.equals(OS_NAME_LINUX)) { // cmdLine = sConsoleReader.readLine(prompt).trim(); } else { CUIOutputStream.print(prompt); cmdLine = mCommandInput.readLine().trim(); } return cmdLine; } /** * Display the help message. */ private void showHelp() { CUIOutputStream.println("Usage: command options"); CUIOutputStream.println("Avaiable commands and options:"); showHostCmdHelp(); showPlanCmdHelp(); showPackageCmdHelp(); showResultCmdHelp(); showHistoryCmdHelp(); showDeviceCmdHelp(); } /** * Display the help message related to history commands. */ private void showHistoryCmdHelp() { final String cmdStr = CTSCommand.HISTORY + "/" + CTSCommand.H; CUIOutputStream.println(CMD_TYPE_LEADING_SPACE + "History:"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + cmdStr + ": list all commands in command history"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + cmdStr + " count: list the latest count records in command history"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + cmdStr + " " + CTSCommand.OPTION_E + " num: run the command designated by 'num' in command history"); } /** * Display the help message related to result commands. */ private void showResultCmdHelp() { final String cmdStr = CTSCommand.LIST + " " + CTSCommand.OPTION_R + "/" + CTSCommand.OPTION_RESULT; final String sessionStr = CTSCommand.OPTION_S + "/" + CTSCommand.OPTION_SESSION; final String resultsStr = " [" + CtsTestResult.STR_PASS + "/" + CtsTestResult.STR_FAIL + "/" + CtsTestResult.STR_NOT_EXECUTED + "/" + CtsTestResult.STR_TIMEOUT + "] "; CUIOutputStream.println(CMD_TYPE_LEADING_SPACE + "Result:"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + cmdStr + ": list all result of sessions"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + cmdStr + " " + sessionStr + " session_id: list detail case result of a specified session"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + cmdStr + resultsStr + sessionStr + " session_id: list detail cases of a specified" + " session by the specified result."); } /** * Display the help message related to package commands. */ private void showPackageCmdHelp() { final String cmdStr = CTSCommand.LIST + " " + CTSCommand.OPTION_P + "/" + CTSCommand.OPTION_PACKAGE; final String pkgStr = CTSCommand.OPTION_P + "/" + CTSCommand.OPTION_PACKAGE; CUIOutputStream.println(CMD_TYPE_LEADING_SPACE + "Package:"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + cmdStr + ": list available packages"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + cmdStr + " package_name: " + "list contents of the package with specified name"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + CTSCommand.ADD + " " + pkgStr + " root: add packages from root to repository"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + CTSCommand.REMOVE + " " + pkgStr + " package_name/all: " + "remove a package or all packages from repository"); } /** * Display the help message related to plan commands. */ private void showPlanCmdHelp() { final String lsPlanStr = CTSCommand.LIST + " " + CTSCommand.OPTION_PLAN; final String addPlanStr = CTSCommand.ADD + " " + CTSCommand.OPTION_PLAN; final String rmPlanStr = CTSCommand.REMOVE + " " + CTSCommand.OPTION_PLAN; final String addDerivedPlanStr = CTSCommand.ADD + " " + CTSCommand.OPTION_DERIVED_PLAN; CUIOutputStream.println(CMD_TYPE_LEADING_SPACE + "Plan:"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + lsPlanStr + ": list available plans"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + lsPlanStr + " plan_name: list contents of the plan with specified name"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + addPlanStr + " plan_name: add a new plan with specified name"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + addDerivedPlanStr + " plan_name " + CTSCommand.OPTION_S + "/" + CTSCommand.OPTION_SESSION + " session_id " + CTSCommand.OPTION_R + "/" + CTSCommand.OPTION_RESULT + " result_type" + ": derive a plan from the given session"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + rmPlanStr + " plan_name/all: remove a plan or all plans from repository"); showStartSessionHelp(); } /** * Display the help message related to start session command. */ private void showStartSessionHelp() { final String cmdStr = CTSCommand.START + " " + CTSCommand.OPTION_PLAN; final String testStr = CTSCommand.OPTION_T + "/" + CTSCommand.OPTION_TEST; final String deviceStr = CTSCommand.OPTION_D + "/" + CTSCommand.OPTION_DEVICE; final String pkgStr = CTSCommand.OPTION_P + "/" + CTSCommand.OPTION_PACKAGE; CUIOutputStream.println(CMD_OPT_LEADING_SPACE + cmdStr + " test_plan_name: run a test plan"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + cmdStr + " test_plan_name " + deviceStr + " device_ID" + ": run a test plan using the specified device"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + cmdStr + " test_plan_name " + testStr + " test_name" + ": run a specific test"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + cmdStr + " test_plan_name " + pkgStr + " java_package_name" + ": run a specific java package"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + cmdStr + " test_plan_name " + testStr + " test_name " + deviceStr + " device_ID" + ": run a specific test using the specified device"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + cmdStr + " test_plan_name " + pkgStr + " java_package_name " + deviceStr + " device_ID" + ": run a specific java package using the specified device"); } /** * Display the help message related to host commands. */ private void showHostCmdHelp() { CUIOutputStream.println(CMD_TYPE_LEADING_SPACE + "Host:"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + CTSCommand.HELP + ": show this message"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + CTSCommand.EXIT + ": exit cts command line"); } /** * Display the help message related to device commands. */ private void showDeviceCmdHelp() { final String deviceStr = CTSCommand.OPTION_D + "/" + CTSCommand.OPTION_DEVICE; CUIOutputStream.println(CMD_TYPE_LEADING_SPACE + "Device:"); CUIOutputStream.println(CMD_OPT_LEADING_SPACE + CTSCommand.LIST + " " + deviceStr + ": list available devices"); } /** * Process the command from user's input. * * @param cp Command container. */ public void processCommand(final CommandParser cp) throws Exception { String action = cp.getAction(); if (action.equals(CTSCommand.EXIT)) { if (cp.getArgSize() != 1) { showHelp(); return; } Log.d("exit cts host"); mKeepRunning = false; mHost.tearDown(); } else if (action.equals(CTSCommand.HELP)) { showHelp(); } else if (mCommandHistory.isHistoryCommand(action)) { processHistoryCommands(cp); } else if (action.equals(CTSCommand.ADD)) { processAddCommand(cp); } else if (action.equals(CTSCommand.START)) { processStartCommand(cp); } else if (action.equals(CTSCommand.REMOVE)) { processRmCommand(cp); } else if (action.equals(CTSCommand.LIST)) { processListCommand(cp); } else { showHelp(); } } /** * Process start command. * * @param cp Command container. */ private void processStartCommand(CommandParser cp) throws SAXException, ParserConfigurationException { if (cp.containsKey(CTSCommand.OPTION_PLAN)) { processStartSessionCommand(cp); } else if (cp.containsKey(CTSCommand.OPTION_P) || cp.containsKey(CTSCommand.OPTION_PACKAGE)) { processStartPackageCommand(cp); } else { showHelp(); } } /** * Process start package command. * * * @param cp Command container. */ private void processStartPackageCommand(CommandParser cp) { try { String pathName = cp.getValue(CTSCommand.OPTION_PACKAGE); mHost.startZippedPackage(pathName); } catch (DeviceDisconnectedException e) { Log.e("Device " + e.getMessage() + " disconnected", e); } catch (Exception e) { Log.e("Met exception during running zipped package.", e); } } /** * Validate the command parameters used to activate CTS. * * @param cp Command container. * @return If command parameters are valid, return true; else, return false. */ public boolean validateCommandParams(CommandParser cp) { if (cp == null) { return false; } if (cp.getAction() == null) { return true; } else if (isValidCommandOption(cp, CTSCommand.START, CTSCommand.OPTION_PLAN)) { return true; } else if (isValidCommandOption(cp, CTSCommand.START, CTSCommand.OPTION_PACKAGE)) { return true; } else if (isValidCommandOption(cp, CTSCommand.START, CTSCommand.OPTION_P)) { return true; } else { return false; } } /** * Check if the command option is valid. * * @param cp CommandParser which contains the command and options. * @param command Command the user typed in. * @param option Option the user typed in. * @return If command option valid, return true; else, return false. */ private static boolean isValidCommandOption(CommandParser cp, String command, String option) { return (cp.getAction().equals(command)) && (cp.containsKey(option)) && (cp.getValue(option) != null) && (cp.getValue(option).length() != 0); } /** * Process start session command. * * @param cp container which contained start command options and values * Process the list commands. */ private void processStartSessionCommand(CommandParser cp) throws SAXException, ParserConfigurationException { if (mHost.getDeviceList().length == 0) { Log.e("No device connected", null); return; } String testPlanPath = null; String deviceId = null; String testName = null; String javaPkgName = null; String testPlanName = mHost.getPlanName(cp.getValue(CTSCommand.OPTION_PLAN)); try { if (cp.getActionValues().size() != 0 || cp.getOptionSize() < 1 || cp.getOptionSize() > 3) { showStartSessionHelp(); return; } testPlanName = mHost.getPlanName(cp .getValue(CTSCommand.OPTION_PLAN)); testPlanPath = HostConfig.getInstance().getPlanRepository() .getPlanPath(testPlanName); if (testPlanPath == null) { CUIOutputStream.println("Plan " + testPlanName + " is not in repository, please create it!"); return; } ActionType actionType = ActionType.START_NEW_SESSION; if (cp.containsKey(CTSCommand.OPTION_TEST)) { testName = cp.getValue(CTSCommand.OPTION_TEST); if (-1 == testName.indexOf(Test.METHOD_SEPARATOR)) { Log.e("Test full name must be in the form of:" + " java_package_name.class_name#method_name.", null); return; } actionType = ActionType.RUN_SINGLE_TEST; } else if (cp.containsKey(CTSCommand.OPTION_PACKAGE)) { javaPkgName = cp.getValue(CTSCommand.OPTION_PACKAGE); actionType = ActionType.RUN_SINGLE_JAVA_PACKAGE; } TestSession ts = null; ArrayList sessionList = mHost.getSessionList(testPlanName); if ((sessionList != null) && (sessionList.size() > 0)) { if ((testName == null) || (testName.length() == 0)) { String mode = chooseMode(sessionList); if (CREATE_SESSION.equals(mode)) { ts = TestHost.createSession(testPlanName); } } if (ts == null) { ts = chooseTestSession(sessionList); deviceId = ts.getDeviceId(); if ((actionType != ActionType.RUN_SINGLE_TEST) && (actionType != ActionType.RUN_SINGLE_JAVA_PACKAGE)) { actionType = ActionType.RESUME_SESSION; } } } if (cp.containsKey(CTSCommand.OPTION_DEVICE)) { deviceId = cp.getValue(CTSCommand.OPTION_DEVICE); String[] deviceIdList = deviceId.trim().split(","); if (deviceIdList.length > 1) { Log.e("Just allow choosing one device ID.", null); return; } } if (deviceId == null) { TestDevice td = mHost.getFirstAvailableDevice(); if (td == null) { // no devices attached CUIOutputStream.println("No idle devices found."); return; } deviceId = td.getSerialNumber(); } if (!checkDeviceExists(mHost.getDeviceList(), deviceId)) { CUIOutputStream.println("Can't find specified device id. Is it attached?"); return; } if (ts == null) { ts = TestHost.createSession(testPlanName); } mHost.startSession(ts, deviceId, testName, javaPkgName, actionType); } catch (IOException e) { Log.e("Can't create test session", e); } catch (DeviceNotAvailableException e) { CUIOutputStream.println("Test plan(" + testPlanName + ") " + e.getMessage()); showStartSessionHelp(); } catch (TestNotFoundException e) { CUIOutputStream.println(e.getMessage()); } catch (TestPlanNotFoundException e) { CUIOutputStream.println("Can't find test plan " + testPlanName); } catch (IllegalTestNameException e) { CUIOutputStream.println("Illegal case name: " + testName); } catch (DeviceDisconnectedException e) { Log.e("Device " + e.getMessage() + " disconnected ", null); } catch (NoSuchAlgorithmException e) { Log.e("Fail to initialise SHA-1 algorithm", e); } catch (InvalidApkPathException e) { Log.e(e.getMessage(), null); } catch (InvalidNameSpaceException e) { Log.e(e.getMessage(), null); } } /** * Choose test session among the available test session list. * * @param sessionList The available test session list. * @return The test session chosen. */ private TestSession chooseTestSession(ArrayList sessionList) throws IOException { if ((sessionList == null) || (sessionList.size() == 0)) { return null; } if (sessionList.size() == 1) { return sessionList.get(0); } int index = 0; String notification = "Please choose a session from the existed session(s):\n"; for (TestSession session : sessionList) { notification += " " + session.getId() + " [" + index + "] \n"; index ++; } return sessionList.get(getUserInputId(notification, 0, index)); } /** * Choose between creating a new session and choosing a session among available ones. * * @param sessionList The available test session list. * @return If choose to create a new session, return CREATE_SESSION; * else return CHOOSE_SESSION. */ private String chooseMode(ArrayList sessionList) throws IOException { if (TestHost.sMode == MODE.RUN || (sessionList == null) || (sessionList.size() == 0)) { // do not prompt if the test run was started from command line mode, or when // there are no existing sessions return CREATE_SESSION; } String planName = sessionList.get(0).getSessionLog().getTestPlanName(); String notification = "There are " + sessionList.size() + " existing session(s) for plan " + planName + ".\n" + "Create a new session or choose an existing one?\n" + " Create a new session [0]\n" + " Choose a session [1]\n"; int indexSelected = getUserInputId(notification, 0, 2); if (indexSelected == 0) { return CREATE_SESSION; } else { return CHOOSE_SESSION; } } /** * Validate the specified device ID against the available device array. * * @param availableDevices The available device array. * @param specifiedId The specified device ID list. * @return true if the id is valid */ public boolean checkDeviceExists(TestDevice[] availableDevices, String specifiedId) { for (TestDevice dev : availableDevices) { if (specifiedId.equals(dev.getSerialNumber())) { return true; } } return false; } /** * Get device ID from the device ID string against the available devices. * * @param availableDevices The available devices. * @param idStr The device ID string. * @return The device ID. */ public int getDeviceId(TestDevice[] availableDevices, String idStr) { for (int i = 0; i < availableDevices.length; i++) { TestDevice dev = availableDevices[i]; if (idStr.equals(dev.getSerialNumber())) { return i; } } return -1; } /** * Get the ID input by the against the specified range. * * @param notification The notification message to notify the user. * @param startIndex The start index. * @param endIndex The end index. * @return The selected index of the ID the user chosen. */ private int getUserInputId(String notification, int startIndex, int endIndex) throws IOException { int indexSelected = 0; boolean success = false; while (!success) { String answer = readLine(notification); try { indexSelected = Integer.parseInt(answer); if ((indexSelected >= 0) && (indexSelected < endIndex)) { success = true; } else { CUIOutputStream.println("" + indexSelected + " is out of range [0," + (endIndex -1 ) + "]."); } } catch (NumberFormatException e) { CUIOutputStream.println("Invalid nuber is typed in."); } } return indexSelected; } /** * Check if the specified device ID is valid. * * @param numOfAvailableDevices The number of available devices. * @param specifiedId The specified device ID. * @return If the specified ID contained in available ID list, * return true; else, return false. */ public boolean isValidDeviceId(int numOfAvailableDevices, int specifiedId) { if (specifiedId < 0 || specifiedId >= numOfAvailableDevices) { return false; } return true; } /** * Process list commands. *
    *
  • Syntax 1: * ls --device *
  • Syntax 2: * ls --plan [ plan-name ] *
  • Syntax 3: * ls --package [ package-name ] *
  • Syntax 4: * ls --result * [ pass/fail/notExecuted/timeout ] * [ --session session_id ] *
* * @param cp Command container. */ private void processListCommand(CommandParser cp) throws SAXException, IOException, ParserConfigurationException { if (cp.containsKey(CTSCommand.OPTION_DEVICE)) { if (cp.getActionValues().size() != 0 || cp.getOptionSize() != 1) { showDeviceCmdHelp(); return; } if (cp.getValue(CTSCommand.OPTION_DEVICE).equals("")) { listDevices(); } else { showDeviceCmdHelp(); } } else if (cp.containsKey(CTSCommand.OPTION_PLAN)) { if (cp.getActionValues().size() != 0 || cp.getOptionSize() != 1) { showPlanCmdHelp(); return; } String planValue = cp.getValue(CTSCommand.OPTION_PLAN); if (planValue.equals("")) { listPlans(); } else { listSinglePlan(mHost.getPlanName(planValue)); } } else if (cp.containsKey(CTSCommand.OPTION_RESULT)) { if (cp.getActionValues().size() != 0 || (cp.getOptionSize() < 1 || cp.getOptionSize() > 2)) { showResultCmdHelp(); return; } String resultValue = cp.getValue(CTSCommand.OPTION_RESULT); String sessionId = cp.getValue(CTSCommand.OPTION_SESSION); Integer resultCode = null; if (sessionId != null) { if (resultValue.length() != 0 && !mResultCodeMap.containsKey(resultValue)) { showResultCmdHelp(); } else { resultCode = mResultCodeMap.get(resultValue); listSessionResult(sessionId, resultCode); } } else if (resultValue.length() == 0) { listResults(); } else { showHelp(); } } else if (cp.containsKey(CTSCommand.OPTION_PACKAGE)) { if (cp.getActionValues().size() != 0 || cp.getOptionSize() != 1) { showPackageCmdHelp(); return; } listPackages(cp); } else { showHelp(); } } /** * Process the removing commands. *
    *
  • Syntax 1: * rm --plan [ plan-name ] [ all ] *
  • Syntax 2: * rm --package [ package-name ] [ all ] *
* * @param cp Command container. */ private void processRmCommand(CommandParser cp) throws IOException { if (cp.containsKey(CTSCommand.OPTION_PLAN)) { if (cp.getActionValues().size() != 0 || cp.getOptionSize() != 1) { showPlanCmdHelp(); return; } String planName = mHost.getPlanName(cp.getValue(CTSCommand.OPTION_PLAN)); if (HostConfig.ALL.equals(planName)) { String prompt = "Remove all of the plans?([y/N])"; String answer = readLine(prompt).trim(); if (!isConfirmation(answer, false)) { return; } } mHost.removePlans(planName); } else if (cp.containsKey(CTSCommand.OPTION_PACKAGE)) { if (cp.getActionValues().size() != 0 || cp.getOptionSize() != 1) { showPackageCmdHelp(); return; } String packageName = cp.getValue(CTSCommand.OPTION_PACKAGE); if (HostConfig.ALL.equals(packageName)) { String prompt = "Remove all of the packages?([y/N])"; String answer = readLine(prompt).trim(); if (!isConfirmation(answer, false)) { return; } } mHost.removePackages(packageName); } else { showHelp(); } } /** * Check if the answer is confirmation. * * @param answer The answer user typed in. * @param defaultResult If true, default to yes; else, default to no. * @return If confirmation, return true; else, return false. */ public static boolean isConfirmation(String answer, boolean defaultResult) { if ("".equals(answer)) { return defaultResult; } return ("y".equals(answer.toLowerCase()) || "yes".equals(answer.toLowerCase())); } /** * Process the add commands. *
    *
  • Syntax 1: * add --plan plan-name *
  • Syntax 2: * add --package package-name *
* * @param cp Command container. */ private void processAddCommand(CommandParser cp) { if (cp.containsKey(CTSCommand.OPTION_PLAN)) { if (isValidAddPlanArguments(cp)) { createPlan(cp, CTSCommand.OPTION_PLAN); } else { showPlanCmdHelp(); } } else if (cp.containsKey(CTSCommand.OPTION_DERIVED_PLAN)) { if (isValidDerivedPlanArguments(cp)) { createPlan(cp, CTSCommand.OPTION_DERIVED_PLAN); } else { showPlanCmdHelp(); } } else if (cp.containsKey(CTSCommand.OPTION_PACKAGE)) { try { addPackage(cp); } catch (IOException e) { Log.e("Can't add package", e); } catch (IndexOutOfBoundsException e) { Log.e("Can't add package", e); } catch (NoSuchAlgorithmException e) { Log.e("Can't add package", e); } } else { showHelp(); } } /** * Check if it's valid arguments for adding plan. * * @param cp The command processor. * @return if valid, return true; else, return false. */ private boolean isValidAddPlanArguments(CommandParser cp) { return (cp.getArgSize() == 3) && (cp.getActionValues().size() == 0) && (cp.getOptionSize() == 1); } /** * Check if it's valid arguments for deriving plan. * * @param cp The command processor. * @return if valid, return true; else, return false. */ private boolean isValidDerivedPlanArguments(CommandParser cp) { //argument size: it's at least 3, as "add --plan plan_name" //action values: no option contains more than one value //option size: it's at least 1, as "add --plan plan_name" return (cp.getArgSize() >= 3) && (cp.getActionValues().size() == 0) && (cp.getOptionSize() >= 1); } /** * Process the history commands. *
    *
  • Syntax: * history [ -e ] [ number] *
* * @param cp Command container. */ private void processHistoryCommands(final CommandParser cp) throws Exception { try { if ((cp.getOptionSize() == 0) && (cp.getActionValues().size() == 0)) { mCommandHistory.show(mCommandHistory.size()); } else if (cp.containsKey(CTSCommand.OPTION_E) && (cp.getActionValues().size() == 0)) { int cmdNum = 0; cmdNum = Integer.parseInt(cp.getValue(CTSCommand.OPTION_E)); if (cmdNum >= 0 && cmdNum < mCommandHistory.size()) { String cmdLine = mCommandHistory.get(cmdNum); CommandParser cpH = CommandParser.parse(cmdLine); CUIOutputStream.printPrompt(); CUIOutputStream.println(cmdLine);// print(CTS_PROMPT_SIGN // + cmdLine); processCommand(cpH); mCommandHistory.addCommand(cpH, cmdLine); } else { if (mCommandHistory.size() > 0) { Log.e("Command index " + cmdNum + " is out of command history range [0," + (mCommandHistory.size() - 1) + "].", null); } else { Log.e("No command exists in command history.", null); } } } else if ((cp.getOptionSize() == 0) && (cp.getActionValues().size() == 1)) { int cmdCount = Integer.parseInt(cp.getActionValues().iterator() .next()); if (cmdCount < 0 || cmdCount > mCommandHistory.size()) { cmdCount = mCommandHistory.size(); } mCommandHistory.show(cmdCount); } else { showHistoryCmdHelp(); } } catch (NumberFormatException e) { showHistoryCmdHelp(); } } /** * List a single plan by the plan name given. * * @param name The plan name. */ private void listSinglePlan(String name) throws SAXException, IOException, ParserConfigurationException { String planName = null; for (String str : mHost.getPlanRepository().getAllPlanNames()) { if (str.startsWith(name)) { planName = str; break; } } if (planName == null) { Log.e("No plan named " + name + " in repository!", null); return; } String planPath = mHost.getPlanRepository().getPlanPath(planName); ArrayList removedPkgList = new ArrayList(); Collection pkgNames = TestPlan.getEntries(planPath, removedPkgList); if (removedPkgList.size() != 0) { CUIOutputStream.println("The following package(s) contained in plan " + planName + " have been removed:"); for (String pkgName : removedPkgList) { CUIOutputStream.println(" " + pkgName); } } if (pkgNames.size() > 0) { CUIOutputStream.println("Packages of plan " + planName + " (" + pkgNames.size() + " in total):"); CUIOutputStream.println(LS_PLAN_SEPARATOR); for (String pkgName : pkgNames) { CUIOutputStream.println(pkgName); } } } /** * Create test plan via the test session and result type given. * * @param name The test plan name. * @param ts The test session. * @param resultType The result type. */ private void createPlanFromSession(final String name, TestSession ts, final String resultType) throws FileNotFoundException, IOException, ParserConfigurationException, TransformerFactoryConfigurationError, TransformerException { HashMap> selectedResult = new HashMap>(); ArrayList packageNames = new ArrayList(); for (TestPackage pkg : ts.getSessionLog().getTestPackages()) { String pkgName = pkg.getAppPackageName(); ArrayList excludedList = pkg.getExcludedList(resultType); if (excludedList != null) { packageNames.add(pkgName); selectedResult.put(pkgName, excludedList); } } if ((selectedResult != null) && (selectedResult.size() > 0)) { TestSessionBuilder.getInstance().serialize(name, packageNames, selectedResult); } else { if (resultType == null) { Log.i("All tests of session " + ts.getId() + " have passed execution. The plan is not created!"); } else { Log.i("No " + resultType + " tests of session " + ts.getId() + ". The plan is not created!"); } } } /** * Add a derived plan from a given session. * * @param cp Command container. * @param name The plan name. * @param packageNames The package name list. */ private void addDerivedPlan(final CommandParser cp, final String name, ArrayList packageNames) { try { String sessionId = null; String resultType = null; int id = TestSession.getLastSessionId(); if (cp.containsKey(CTSCommand.OPTION_SESSION)) { sessionId = cp.getValue(CTSCommand.OPTION_SESSION); id = Integer.parseInt(sessionId); } TestSession ts = mHost.getSession(id); if (ts == null) { Log.e("The session ID of " + id + " doesn't exist.", null); return; } if (cp.containsKey(CTSCommand.OPTION_RESULT)) { resultType = cp.getValue(CTSCommand.OPTION_RESULT); if (!CtsTestResult.isValidResultType(resultType)) { Log.e("The following result type is invalid: " + resultType, null); return; } } createPlanFromSession(name, ts, resultType); } catch (Exception e) { Log.e("Got exception while trying to add a plan!", e); return; } } /** * Add a plan by the plan name given. * * @param cp Command container. * @param name The plan name. * @param packageNames The package name list. */ private void addPlan(final CommandParser cp, final String name, ArrayList packageNames) { try { PlanBuilder planBuilder = new PlanBuilder(packageNames); if (mOsName.equals(OS_NAME_LINUX)) { // planBuilder.setInputStream(sConsoleReader); } else { planBuilder.setInputStream(mCommandInput); } HashMap> selectedResult = planBuilder.doSelect(); if (selectedResult != null) { TestSessionBuilder.getInstance().serialize(name, packageNames, selectedResult); } else { Log.i("Selected nothing for the plan of " + name + ". The plan is not created!"); } } catch (Exception e) { Log.e("Got exception while trying to add a plan!", e); return; } } /** * Create a plan. * * @param cp Command container. * @param type the action type. */ private void createPlan(final CommandParser cp, final String type) { String name = null; if (CTSCommand.OPTION_PLAN.equals(type)) { name = cp.getValue(CTSCommand.OPTION_PLAN); } else if (CTSCommand.OPTION_DERIVED_PLAN.equals(type)) { name = cp.getValue(CTSCommand.OPTION_DERIVED_PLAN); } else { return; } if (HostUtils.isFileExist(HostConfig.getInstance().getPlanRepository() .getPlanPath(name)) == true) { Log.e("Plan " + name + " already exist, please use another name!", null); return; } try { if ((name != null) && (!name.matches("\\w+"))) { CUIOutputStream.println("Only letter of the alphabet, number and '_'" + " are available for test plan name"); return; } ArrayList packageNames = HostConfig.getInstance().getCaseRepository().getPackageNames(); Collection testPackages = HostConfig.getInstance().getTestPackages(); if (testPackages.size() == 0) { CUIOutputStream.println("No package found in repository, please add package first!"); return; } if (CTSCommand.OPTION_PLAN.equals(type)) { addPlan(cp, name, packageNames); } else if (CTSCommand.OPTION_DERIVED_PLAN.equals(type)) { addDerivedPlan(cp, name, packageNames); } } catch (Exception e) { Log.e("Got exception while trying to add a plan!", e); return; } } /** * List all of the plans in the plan repository. */ private void listPlans() { ArrayList plans = mHost.getPlanRepository().getAllPlanNames(); if (plans.size() == 0) { CUIOutputStream.println("No plan created!"); } else { CUIOutputStream.println("List of plans (" + plans.size() + " in total):"); for (String name : plans) { CUIOutputStream.println(name); } } } /** * List detailed case result of specified session. The result can be * filtered, if resultType isn't null, by the specified resultType. * * @param idStr the session id. * @param resultType the type of result, [pass, fail, notExecuted, timeout, null]. */ private void listSessionResult(final String idStr, final Integer resultType) { if (!idStr.matches("\\d+")) { showResultCmdHelp(); return; } int sessionId = Integer.parseInt(idStr); TestSession ts = mHost.getSession(sessionId); if (null == ts) { Log.e("Can't find specified session", null); return; } TestSessionLog log = ts.getSessionLog(); CUIOutputStream.println("Result of session " + ts.getId()); CUIOutputStream.println("Result\t\tCase name"); CUIOutputStream .println("=============================================================="); for (Test test : log.getAllResults()) { CtsTestResult result = test.getResult(); if ((resultType != null) && (result.getResultCode() != resultType.intValue())) { continue; } CUIOutputStream.println(result.getResultString() + "\t\t" + test.getFullName()); } } /** * List all of the test results. */ private void listResults() { Collection sessions = mHost.getSessions(); if (sessions.isEmpty()) { CUIOutputStream.println("There aren't any test results!"); } else { CUIOutputStream.println("List of all results: "); CUIOutputStream.println("Session\t\tTest result\t\t\t\tStart time\t\tEnd time\t" + "\tTest plan name\t"); CUIOutputStream.println("\t\tPass\tFail\tTimeout\tNotExecuted"); for (TestSession session : sessions) { TestSessionLog log = session.getSessionLog(); int passNum = log.getTestList( CtsTestResult.CODE_PASS).size(); int failNum = log.getTestList( CtsTestResult.CODE_FAIL).size(); int notExecutedNum = log.getTestList( CtsTestResult.CODE_NOT_EXECUTED).size(); int timeOutNum = log.getTestList( CtsTestResult.CODE_TIMEOUT).size(); String resStr = Long.toString(passNum) + "\t" + failNum; resStr += "\t" + timeOutNum; resStr += "\t" + notExecutedNum; String startTimeStr = HostUtils.getFormattedTimeString(log.getStartTime().getTime(), " ", ".", ":"); String endTimeStr = HostUtils.getFormattedTimeString(log.getEndTime().getTime(), " ", ".", ":"); CUIOutputStream.println(Long.toString(session.getId()) + "\t\t" + resStr + "\t\t" + startTimeStr + "\t" + endTimeStr + "\t" + log.getTestPlanName()); } } } /** * Add a package by the path and package name. * * @param cp Command container. */ private void addPackage(final CommandParser cp) throws IOException, IndexOutOfBoundsException, NoSuchAlgorithmException { if (cp.getActionValues().size() != 0 || cp.getOptionSize() != 1) { showPackageCmdHelp(); return; } String pathName = cp.getValue(CTSCommand.OPTION_PACKAGE); mHost.addPackage(pathName); } /** * List current package in the case repository. * * @param cp Command container */ private void listPackages(final CommandParser cp) { // walk through the case root path // and list available packages String expectPackage = cp.getValue(CTSCommand.OPTION_PACKAGE); String caseRoot = mHost.getCaseRepository().getRoot(); if (caseRoot == null) { Log.e("Case repository is null", null); return; } File root = new File(caseRoot); if (!root.isDirectory()) { Log.e("Case repository must be a directory!", null); return; } Collection testPackages = HostConfig.getInstance().getTestPackages(); if (testPackages.size() == 0) { CUIOutputStream .println("No package available under case repository!"); } else { if (expectPackage.equals("")) { CUIOutputStream.println("Available packages (" + testPackages.size() + " in total):"); for (TestPackage pkg : testPackages) { CUIOutputStream.println(pkg.getAppPackageName()); } } else { List> list = mHost.getCaseRepository() .listAvailablePackage(expectPackage); ArrayList packageList = list.get(0); ArrayList suiteList = list.get(1); ArrayList caseList = list.get(2); ArrayList testList = list.get(3); if ((packageList.size() == 0) && (suiteList.size() == 0) && (caseList.size() == 0) && (testList.size() == 0)) { CUIOutputStream .println("Not available test package, suite, cases or tests: " + expectPackage); } else { if (packageList.size() != 0) { CUIOutputStream.println( "Test packages (" + packageList.size() + " in total):"); for (String packageName : packageList) { CUIOutputStream.println(packageName); } } if (suiteList.size() != 0) { CUIOutputStream.println( "Test suites (" + suiteList.size() + " in total):"); for (String suiteName : suiteList) { CUIOutputStream.println(suiteName); } } if (caseList.size() != 0) { CUIOutputStream.println("Test cases (" + caseList.size() + " in total):"); for (String caseName : caseList) { CUIOutputStream.println(caseName); } } if (testList.size() != 0) { CUIOutputStream.println("Tests (" + testList.size() + " in total):"); for (String testName : testList) { CUIOutputStream.println(testName); } } } } } } /** * List all of the devices connected. */ private void listDevices() { String[] deviceNames = mHost.listDevices(); if (deviceNames.length == 0) { CUIOutputStream.println("No device connected."); return; } CUIOutputStream.println("Id\t\tDevice Name\t\tStatus"); for (int i = 0; i < deviceNames.length; i++) { CUIOutputStream.println(i + "\t\t" + deviceNames[i]); } } }