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 DeviceTestRunner()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 start(String[] args)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 extractArg(String[] args, int index)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 */ main(String[] args)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 printUsage()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 doRun(Test test, boolean wait)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 runSingleMethod(String testCase, String method, boolean wait)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