Home | History | Annotate | Download | only in hosttest
      1 /*
      2  * Copyright (C) 2009 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.hosttest;
     18 
     19 import java.util.ArrayList;
     20 import java.util.List;
     21 
     22 import junit.framework.Test;
     23 import junit.framework.TestResult;
     24 import junit.textui.TestRunner;
     25 
     26 import com.android.ddmlib.AndroidDebugBridge;
     27 import com.android.ddmlib.IDevice;
     28 import com.android.ddmlib.Log;
     29 import com.android.ddmlib.AndroidDebugBridge.IDeviceChangeListener;
     30 
     31 /**
     32  * Command line interface for running DeviceTest tests.
     33  *
     34  * Extends junit.textui.TestRunner to handle optional -s (device serial) and -p (test data)
     35  * arguments, and then pass their values to the instantiated DeviceTests.
     36  *
     37  * Provided test class must be a DeviceTest.
     38  *
     39  * @see junit.textui.TestRunner for more information on command line syntax.
     40  */
     41 public class DeviceTestRunner extends TestRunner {
     42 
     43     private static final String LOG_TAG = "DeviceTestRunner";
     44     private String mDeviceSerial = null;
     45     private IDevice mDevice = null;
     46     private String mTestDataPath = null;
     47 
     48     private DeviceTestRunner() {
     49     }
     50 
     51     /**
     52      * Starts the test run.
     53      * Extracts out DeviceTestCase specific command line arguments, then passes control to parent
     54      * TestRunner.
     55      * @param args command line arguments
     56      * @return {@link TestResult}
     57      */
     58     @Override
     59     public TestResult start(String[] args) throws Exception {
     60         // holds unprocessed arguments to pass to parent
     61         List<String> parentArgs = new ArrayList<String>();
     62         for (int i=0; i < args.length; i++) {
     63             if (args[i].equals("-s")) {
     64                 i++;
     65                 mDeviceSerial = extractArg(args, i);
     66             } else if (args[i].equals("-p")) {
     67                 i++;
     68                 mTestDataPath = extractArg(args, i);
     69             } else {
     70                 // unrecognized arg, must be for parent
     71                 parentArgs.add(args[i]);
     72             }
     73         }
     74         DeviceConnector connector = new DeviceConnector();
     75         mDevice = connector.connectToDevice(mDeviceSerial);
     76         return super.start(parentArgs.toArray(new String[parentArgs.size()]));
     77     }
     78 
     79     private String extractArg(String[] args, int index) {
     80         if (args.length <= index) {
     81             printUsage();
     82             throw new IllegalArgumentException("Error: not enough arguments");
     83         }
     84         return args[index];
     85     }
     86 
     87 
     88     /**
     89      * Main entry point.
     90      *
     91      * Establishes connection to provided adb device and runs tests
     92      *
     93      * @param args expects:
     94      *     test class to run
     95      *     optionally, device serial number. If unspecified, will connect to first device found
     96      *     optionally, file system path to test data files
     97      */
     98     public static void main(String[] args) {
     99         DeviceTestRunner aTestRunner = new DeviceTestRunner();
    100         try {
    101             TestResult r = aTestRunner.start(args);
    102             if (!r.wasSuccessful())
    103                 System.exit(FAILURE_EXIT);
    104             System.exit(SUCCESS_EXIT);
    105         } catch(Exception e) {
    106             System.err.println(e.getMessage());
    107             System.exit(EXCEPTION_EXIT);
    108         }
    109     }
    110 
    111     private static void printUsage() {
    112         System.out.println("Usage: DeviceTestRunner <test_class> [-s device_serial] " +
    113                 "[-p test_data_path]");
    114     }
    115 
    116     /**
    117      * Override parent to set DeviceTest data
    118      */
    119     @Override
    120     public TestResult doRun(Test test, boolean wait) {
    121         if (test instanceof DeviceTest) {
    122             DeviceTest deviceTest = (DeviceTest)test;
    123             deviceTest.setDevice(mDevice);
    124             deviceTest.setTestAppPath(mTestDataPath);
    125         } else {
    126             Log.w(LOG_TAG, String.format("%s test class is not a DeviceTest.",
    127                     test.getClass().getName()));
    128         }
    129         return super.doRun(test, wait);
    130     }
    131 
    132     /**
    133      * Override parent to create DeviceTestSuite wrapper, instead of TestSuite
    134      */
    135     @SuppressWarnings("unchecked")
    136     @Override
    137     protected TestResult runSingleMethod(String testCase, String method, boolean wait)
    138     throws Exception {
    139         Class testClass = loadSuiteClass(testCase);
    140         Test test = DeviceTestSuite.createTest(testClass, method);
    141         return doRun(test, wait);
    142     }
    143 }
    144