Home | History | Annotate | Download | only in command
      1 /*
      2  * Copyright (C) 2011 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 package com.android.cts.tradefed.command;
     17 
     18 import com.android.cts.tradefed.build.CtsBuildHelper;
     19 import com.android.cts.tradefed.build.CtsBuildProvider;
     20 import com.android.cts.tradefed.result.ITestResultRepo;
     21 import com.android.cts.tradefed.result.ITestSummary;
     22 import com.android.cts.tradefed.result.PlanCreator;
     23 import com.android.cts.tradefed.result.TestResultRepo;
     24 import com.android.cts.tradefed.testtype.ITestPackageRepo;
     25 import com.android.cts.tradefed.testtype.TestPackageRepo;
     26 import com.android.tradefed.command.Console;
     27 import com.android.tradefed.config.ArgsOptionParser;
     28 import com.android.tradefed.config.ConfigurationException;
     29 import com.android.tradefed.util.FileUtil;
     30 import com.android.tradefed.util.RegexTrie;
     31 import com.android.tradefed.util.TableFormatter;
     32 
     33 import java.io.File;
     34 import java.io.FileNotFoundException;
     35 import java.io.FilenameFilter;
     36 import java.io.PrintWriter;
     37 import java.util.ArrayList;
     38 import java.util.Arrays;
     39 import java.util.List;
     40 import java.util.Map;
     41 
     42 /**
     43  * Specialization of trade federation console that adds CTS commands to list plans and packages.
     44  */
     45 public class CtsConsole extends Console {
     46 
     47     protected static final String ADD_PATTERN = "a(?:dd)?";
     48 
     49     private CtsBuildHelper mCtsBuild = null;
     50 
     51     CtsConsole() {
     52         super();
     53     }
     54 
     55     @Override
     56     public void run() {
     57         printLine(String.format("Android CTS %s", CtsBuildProvider.CTS_BUILD_VERSION));
     58         super.run();
     59     }
     60 
     61     /**
     62      * Adds the 'list packages' and 'list plans' commands
     63      */
     64     @Override
     65     protected void setCustomCommands(RegexTrie<Runnable> trie, List<String> genericHelp,
     66             Map<String, String> commandHelp) {
     67         trie.put(new Runnable() {
     68             @Override
     69             public void run() {
     70                 CtsBuildHelper ctsBuild = getCtsBuild();
     71                 if (ctsBuild != null) {
     72                     listPlans(ctsBuild);
     73                 }
     74             }
     75         }, LIST_PATTERN, "p(?:lans)?");
     76         trie.put(new Runnable() {
     77             @Override
     78             public void run() {
     79                 CtsBuildHelper ctsBuild = getCtsBuild();
     80                 if (ctsBuild != null) {
     81                     listPackages(ctsBuild);
     82                 }
     83             }
     84         }, LIST_PATTERN, "packages");
     85         trie.put(new Runnable() {
     86             @Override
     87             public void run() {
     88                 CtsBuildHelper ctsBuild = getCtsBuild();
     89                 if (ctsBuild != null) {
     90                     listResults(ctsBuild);
     91                 }
     92             }
     93         }, LIST_PATTERN, "r(?:esults)?");
     94 
     95         // find existing help for 'LIST_PATTERN' commands, and append these commands help
     96         String listHelp = commandHelp.get(LIST_PATTERN);
     97         if (listHelp == null) {
     98             // no help? Unexpected, but soldier on
     99             listHelp = new String();
    100         }
    101         String combinedHelp = listHelp +
    102                 "\tp[lans]\t\tList all CTS test plans" + LINE_SEPARATOR +
    103                 "\tpackages\tList all CTS packages" + LINE_SEPARATOR +
    104                 "\tr[esults]\tList all CTS results" + LINE_SEPARATOR;
    105         commandHelp.put(LIST_PATTERN, combinedHelp);
    106 
    107         ArgRunnable<CaptureList> addDerivedCommand = new ArgRunnable<CaptureList>() {
    108             @Override
    109             public void run(CaptureList args) {
    110                 // Skip 2 tokens to get past addPattern and "derivedplan"
    111                 String[] flatArgs = new String[args.size() - 2];
    112                 for (int i = 2; i < args.size(); i++) {
    113                     flatArgs[i - 2] = args.get(i).get(0);
    114                 }
    115                 CtsBuildHelper ctsBuild = getCtsBuild();
    116                 if (ctsBuild != null) {
    117                     addDerivedPlan(ctsBuild, flatArgs);
    118                 }
    119             }
    120         };
    121         trie.put(addDerivedCommand, ADD_PATTERN, "d(?:erivedplan?)", null);
    122         commandHelp.put(ADD_PATTERN, String.format(
    123                 "%s help:" + LINE_SEPARATOR +
    124                 "\tderivedplan      Add a derived plan" + LINE_SEPARATOR,
    125                 ADD_PATTERN));
    126     }
    127 
    128     @Override
    129     protected String getConsolePrompt() {
    130         return "cts-tf > ";
    131     }
    132 
    133     @Override
    134     protected String getGenericHelpString(List<String> genericHelp) {
    135         StringBuilder helpBuilder = new StringBuilder();
    136         helpBuilder.append("CTS-tradefed host version ");
    137         helpBuilder.append(CtsBuildProvider.CTS_BUILD_VERSION);
    138         helpBuilder.append("\n\n");
    139         helpBuilder.append("CTS-tradefed is the test harness for running the Android ");
    140         helpBuilder.append("Compatibility Suite, built on top of the tradefed framework.\n\n");
    141         helpBuilder.append("Available commands and options\n");
    142         helpBuilder.append("Host:\n");
    143         helpBuilder.append("  help: show this message\n");
    144         helpBuilder.append("  help all: show the complete tradefed help\n");
    145         helpBuilder.append("  exit: gracefully exit the cts console, waiting till all ");
    146         helpBuilder.append("invocations are complete\n");
    147         helpBuilder.append("Run:\n");
    148         helpBuilder.append("  run cts --plan test_plan_name: run a test plan\n");
    149         helpBuilder.append("  run cts --package/-p : run a CTS test package\n");
    150         helpBuilder.append("  run cts --class/-c [--method/-m] : run a specific test class and/or");
    151         helpBuilder.append("method\n");
    152         helpBuilder.append("  run cts --continue-session session_ID: run all not executed ");
    153         helpBuilder.append("tests from a previous CTS session\n");
    154         helpBuilder.append("  run cts [options] --serial/s device_ID: run CTS on specified ");
    155         helpBuilder.append("device\n");
    156         helpBuilder.append("  run cts [options] --shards number_of_shards: shard a CTS run into ");
    157         helpBuilder.append("given number of independent chunks, to run on multiple devices in");
    158         helpBuilder.append("parallel\n");
    159         helpBuilder.append("  run cts --help/--help-all: get more help on running CTS\n");
    160         helpBuilder.append("List:\n");
    161         helpBuilder.append("  l/list d/devices: list connected devices and their state\n");
    162         helpBuilder.append("  l/list packages: list CTS test packages\n");
    163         helpBuilder.append("  l/list p/plans: list CTS test plans\n");
    164         helpBuilder.append("  l/list i/invocations: list invocations aka CTS test runs currently");
    165         helpBuilder.append("in progress\n");
    166         helpBuilder.append("  l/list c/commands: list commands: aka CTS test run commands ");
    167         helpBuilder.append("currently in the queue waiting to be allocated devices\n");
    168         helpBuilder.append("  l/list r/results: list CTS results currently present in the ");
    169         helpBuilder.append("repository\n");
    170         helpBuilder.append("Add:\n");
    171         helpBuilder.append("  add derivedplan --plan plane_name --session/-s session_id -r ");
    172         helpBuilder.append("[pass/fail/notExecuted/timeout]: derive a plan from the given ");
    173         helpBuilder.append("session\n");
    174         helpBuilder.append("Dump:\n");
    175         helpBuilder.append("  d/dump l/logs: dump the tradefed logs for all running invocations\n");
    176         return helpBuilder.toString();
    177     }
    178 
    179     private void listPlans(CtsBuildHelper ctsBuild) {
    180         FilenameFilter xmlFilter = new FilenameFilter() {
    181             @Override
    182             public boolean accept(File dir, String name) {
    183                 return name.endsWith(".xml");
    184             }
    185         };
    186         for (File planFile : ctsBuild.getTestPlansDir().listFiles(xmlFilter)) {
    187             printLine(FileUtil.getBaseName(planFile.getName()));
    188         }
    189     }
    190 
    191     private void listPackages(CtsBuildHelper ctsBuild) {
    192         ITestPackageRepo testCaseRepo = new TestPackageRepo(ctsBuild.getTestCasesDir(), false);
    193         for (String packageUri : testCaseRepo.getPackageNames()) {
    194             printLine(packageUri);
    195         }
    196     }
    197 
    198     private void listResults(CtsBuildHelper ctsBuild) {
    199         TableFormatter tableFormatter = new TableFormatter();
    200         List<List<String>> table = new ArrayList<List<String>>();
    201         table.add(Arrays.asList("Session","Pass", "Fail","Not Executed","Start time","Plan name",
    202                 "Device serial(s)"));
    203         ITestResultRepo testResultRepo = new TestResultRepo(ctsBuild.getResultsDir());
    204         for (ITestSummary result : testResultRepo.getSummaries()) {
    205             table.add(Arrays.asList(Integer.toString(result.getId()),
    206                     Integer.toString(result.getNumPassed()),
    207                     Integer.toString(result.getNumFailed()),
    208                     Integer.toString(result.getNumIncomplete()),
    209                     result.getTimestamp(),
    210                     result.getTestPlan(),
    211                     result.getDeviceSerials()));
    212         }
    213         tableFormatter.displayTable(table, new PrintWriter(System.out, true));
    214     }
    215 
    216     private void addDerivedPlan(CtsBuildHelper ctsBuild, String[] flatArgs) {
    217         PlanCreator creator = new PlanCreator();
    218         try {
    219             ArgsOptionParser optionParser = new ArgsOptionParser(creator);
    220             optionParser.parse(Arrays.asList(flatArgs));
    221             creator.createAndSerializeDerivedPlan(ctsBuild);
    222         } catch (ConfigurationException e) {
    223             printLine("Error: " + e.getMessage());
    224             printLine(ArgsOptionParser.getOptionHelp(false, creator));
    225         }
    226     }
    227 
    228     private CtsBuildHelper getCtsBuild() {
    229         if (mCtsBuild == null) {
    230             String ctsInstallPath = System.getProperty("CTS_ROOT");
    231             if (ctsInstallPath != null) {
    232                 mCtsBuild = new CtsBuildHelper(new File(ctsInstallPath));
    233                 try {
    234                     mCtsBuild.validateStructure();
    235                 } catch (FileNotFoundException e) {
    236                     printLine(String.format("Invalid cts install: %s", e.getMessage()));
    237                     mCtsBuild = null;
    238                 }
    239             } else {
    240                 printLine("Could not find CTS install location: CTS_ROOT env variable not set");
    241             }
    242         }
    243         return mCtsBuild;
    244     }
    245 
    246     public static void main(String[] args) throws InterruptedException {
    247         Console console = new CtsConsole();
    248         Console.startConsole(console, args);
    249     }
    250 }
    251