1 /* 2 * Copyright (C) 2008 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.cts; 18 19 import java.io.BufferedReader; 20 import java.io.IOException; 21 import java.util.ArrayList; 22 import java.util.Collections; 23 import java.util.HashMap; 24 import java.util.List; 25 26 /** 27 * Interact with user to select from optional items. 28 * 29 */ 30 abstract public class Selector { 31 public static final String PACKAGE_SELECTOR = "packageSelector"; 32 public static final String SUITE_SELECTOR = "suiteSelector"; 33 public static final String CASE_SELECTOR = "caseSelector"; 34 public static final String TEST_SELECTOR = "testSelector"; 35 36 public static final String PACKAGE_HDR = "[Choose package] "; 37 public static final String PACKAGE_TAIL = 38 ": select[Y], reject[n], or choose suite in it[m]? [Y/n/m] "; 39 40 public static final String SUITE_HDR = "[Choose suite] "; 41 public static final String SUITE_TAIL = 42 ": select[Y], reject[n], or choose case in it[m]? [Y/n/m] "; 43 44 public static final String CASE_HDR = "[Choose case] "; 45 public static final String CASE_TAIL = 46 ": select[Y], reject[n], or choose method in it[m]? [Y/n/m] "; 47 48 public static final String TEST_HDR = "[Choose test] "; 49 public static final String TEST_TAIL = "?: [Y/n] "; 50 51 /** 52 * Define user's possible selections. 53 * 54 */ 55 public enum Selection { 56 ACCEPT, REJECT, MORE 57 } 58 59 public List<String> mRecords; 60 61 public String mHdr; 62 public String mTail; 63 public String mType; 64 65 public BufferedReader mBufferedReader; 66 Selector(String type, List<String> records)67 public Selector(String type, List<String> records) { 68 mRecords = records; 69 Collections.sort(mRecords); 70 mBufferedReader = null; 71 mType = type; 72 73 if (type.equals(PACKAGE_SELECTOR)) { 74 mHdr = PACKAGE_HDR; 75 mTail = PACKAGE_TAIL; 76 } else if (type.equals(SUITE_SELECTOR)) { 77 mHdr = SUITE_HDR; 78 mTail = SUITE_TAIL; 79 } else if (type.equals(CASE_SELECTOR)) { 80 mHdr = CASE_HDR; 81 mTail = CASE_TAIL; 82 } else if (type.equals(TEST_SELECTOR)) { 83 mHdr = TEST_HDR; 84 mTail = TEST_TAIL; 85 } 86 } 87 88 /** 89 * Set the input stream of BufferedReader type. 90 * 91 * @param in The input stream. 92 */ setInputStream(BufferedReader in)93 public void setInputStream(BufferedReader in) { 94 mBufferedReader = in; 95 } 96 97 /** 98 * Read a specific line from the input stream. 99 * 100 * @param prompt The prompt displayed on the console to notify the user. 101 * @return The string the user typed in over the console. 102 */ readLine(String prompt)103 public String readLine(String prompt) throws IOException { 104 String str = null; 105 if (mBufferedReader != null) { 106 CUIOutputStream.print(prompt); 107 str = mBufferedReader.readLine().trim(); 108 } 109 110 return str; 111 } 112 113 /** 114 * Interact with the user to decide what are included and what 115 * others are not. 116 * 117 * @param name The specific name. 118 * @return The selection by the user. 119 */ doAccept(final String name)120 public Selection doAccept(final String name) throws IOException { 121 Selection selection = Selection.REJECT; 122 123 if (mType.equals(TEST_SELECTOR)) { 124 String prompt = mHdr + "Include " + name + mTail; 125 String answer = readLine(prompt); 126 while (!answer.matches("[yn]?")) { 127 CUIOutputStream.println( 128 "Invalid input. Please chose 'y' or 'n' (default is 'y')"); 129 answer = readLine(prompt); 130 } 131 132 if (ConsoleUi.isConfirmation(answer, true)) { 133 selection = Selection.ACCEPT; 134 } 135 } else { 136 String prompt = mHdr + name + mTail; 137 String answer = readLine(prompt); 138 while (!answer.matches("[ynm]?")) { 139 CUIOutputStream.println( 140 "Invalid input. Please chose 'y', 'n', or 'm' (default is 'y')"); 141 answer = readLine(prompt); 142 } 143 144 if (ConsoleUi.isConfirmation(answer, true)) { 145 selection = Selection.ACCEPT; 146 } else if (0 == "m".compareToIgnoreCase(answer)) { 147 selection = Selection.MORE; 148 } 149 } 150 151 return selection; 152 } 153 154 /** 155 * Check if the specified name has been selected against the selected list. 156 * 157 * @param selectedList The selected list. 158 * @param name The specified name to be checked. 159 * @return If selected, return true; else, return false. 160 */ isSelected(ArrayList<String> selectedList, String name)161 public boolean isSelected(ArrayList<String> selectedList, String name) { 162 for (String str : selectedList) { 163 if (name.equals(str) || isSubName(str, name)) { 164 return true; 165 } 166 } 167 return false; 168 } 169 170 /** 171 * Check whether a package name is a sub-package name of parent name. 172 * 173 * @param parent The parent package name. 174 * @param name The package name. 175 * @return True if it's a sub-package name of parent. 176 */ isSubName(String parent, String name)177 private boolean isSubName(String parent, String name) { 178 return name.startsWith(parent + "."); 179 } 180 } 181 182 /** 183 * Building the specific plan by following user's selection. 184 */ 185 class PlanBuilder extends Selector{ 186 private SuiteSelector mSuiteSelector; 187 PlanBuilder(List<String> records)188 public PlanBuilder(List<String> records) { 189 super(PACKAGE_SELECTOR, records); 190 } 191 192 /** 193 * Interact with user to select over packages. 194 * 195 * @return The selected result with excluded lists. 196 */ doSelect()197 public HashMap<String, ArrayList<String>> doSelect() throws IOException { 198 HashMap<String, ArrayList<String>> packages = new HashMap<String, ArrayList<String>>(); 199 for (String javaPkgName : mRecords) { 200 Selection select = doAccept(javaPkgName); 201 TestPackage testPackage = 202 HostConfig.getInstance().getTestPackage(javaPkgName); 203 if (select == Selection.ACCEPT) { 204 packages.put(javaPkgName, null); 205 } else if (select == Selection.MORE) { 206 List<String> suiteNames = testPackage.getAllTestSuiteNames(); 207 mSuiteSelector = new SuiteSelector(suiteNames, testPackage); 208 209 if (mBufferedReader != null) { 210 mSuiteSelector.setInputStream(mBufferedReader); 211 } 212 213 ArrayList<String> excludedSuites = new ArrayList<String>(); 214 ArrayList<String> excludedCases = new ArrayList<String>(); 215 mSuiteSelector.doSelect(excludedSuites, excludedCases); 216 if (suiteNames.size() == excludedSuites.size()) { 217 Log.i("package=" + javaPkgName + " has been removed all."); 218 } else { 219 excludedSuites.addAll(excludedCases); 220 packages.put(javaPkgName, excludedSuites); 221 } 222 } 223 } 224 225 if (packages.size() == 0) { 226 return null; 227 } else { 228 return packages; 229 } 230 } 231 232 /** 233 * Suite selector. 234 * 235 */ 236 class SuiteSelector extends Selector { 237 private TestCaseSelector mCaseSelector; 238 private TestPackage mTestPackage; 239 SuiteSelector(List<String> suites, TestPackage testPackage)240 public SuiteSelector(List<String> suites, TestPackage testPackage) { 241 super(SUITE_SELECTOR, suites); 242 mTestPackage = testPackage; 243 } 244 245 /** 246 * Interact with user to select over suites. 247 * 248 * @param excludedTestSuites The fully excluded test suite list. 249 * @param excludedTestCases The excluded test case list. 250 */ doSelect(ArrayList<String> excludedTestSuites, ArrayList<String> excludedTestCases)251 public void doSelect(ArrayList<String> excludedTestSuites, 252 ArrayList<String> excludedTestCases) throws IOException { 253 ArrayList<String> selectedList = new ArrayList<String>(); 254 for (String suiteName : mRecords) { 255 if (!isSelected(selectedList, suiteName)) { 256 Selection select = doAccept(suiteName); 257 if (select == Selection.REJECT) { 258 excludedTestSuites.add(suiteName); 259 } else if (select == Selection.MORE) { 260 List<String> testCaseNames = 261 mTestPackage.getAllTestCaseNames(suiteName); 262 mCaseSelector = new TestCaseSelector(testCaseNames, mTestPackage); 263 264 if (mBufferedReader != null) { 265 mCaseSelector.setInputStream(mBufferedReader); 266 } 267 268 ArrayList<String> notIncludedTestCases = new ArrayList<String>(); 269 ArrayList<String> notIncludedTests = new ArrayList<String>(); 270 mCaseSelector.doSelect(notIncludedTestCases, notIncludedTests); 271 if (testCaseNames.size() == notIncludedTestCases.size()) { 272 Log.i("suite=" + suiteName + " has been removed all"); 273 excludedTestSuites.add(suiteName); 274 } else { 275 excludedTestCases.addAll(notIncludedTestCases); 276 excludedTestCases.addAll(notIncludedTests); 277 } 278 } 279 selectedList.add(suiteName); 280 } 281 } 282 } 283 } 284 285 /** 286 * TestCase selector. 287 */ 288 class TestCaseSelector extends Selector { 289 private TestSelector mTestSelector; 290 private TestPackage mTestPackage; 291 TestCaseSelector(List<String> testCases, TestPackage testPackage)292 public TestCaseSelector(List<String> testCases, TestPackage testPackage) { 293 super(CASE_SELECTOR, testCases); 294 mTestPackage = testPackage; 295 } 296 297 /** 298 * Interact with user to select over test cases. 299 * 300 * @param excludedTestCases The fully excluded test case list. 301 * @param excludedTests The excluded test list. 302 */ doSelect(ArrayList<String> excludedTestCases, ArrayList<String> excludedTests)303 public void doSelect(ArrayList<String> excludedTestCases, 304 ArrayList<String> excludedTests) throws IOException { 305 ArrayList<String> selectedList = new ArrayList<String>(); 306 for (String testCaseName : mRecords) { 307 if (!isSelected(selectedList, testCaseName)) { 308 Selection select = doAccept(testCaseName); 309 if (select == Selection.REJECT) { 310 excludedTestCases.add(testCaseName); 311 } else if (select == Selection.MORE) { 312 List<String> testNames = mTestPackage.getAllTestNames(testCaseName); 313 mTestSelector = new TestSelector(testNames); 314 315 if (mBufferedReader != null) { 316 mTestSelector.setInputStream(mBufferedReader); 317 } 318 319 ArrayList<String> notIncludedTests = mTestSelector.doSelect(); 320 if (notIncludedTests.size() == testNames.size()) { 321 Log.i("testCase=" + testCaseName + " has been removed all"); 322 excludedTestCases.add(testCaseName); 323 } else { 324 excludedTests.addAll(notIncludedTests); 325 } 326 } 327 selectedList.add(testCaseName); 328 } 329 } 330 } 331 } 332 333 /** 334 * Test selector. 335 * 336 */ 337 class TestSelector extends Selector { TestSelector(List<String> records)338 public TestSelector(List<String> records) { 339 super(TEST_SELECTOR, records); 340 } 341 342 /** 343 * Interact with user to select over tests. 344 * 345 * @return The selected result with excluded lists. 346 */ doSelect()347 public ArrayList<String> doSelect() throws IOException { 348 ArrayList<String> records = new ArrayList<String>(); 349 for (String test : mRecords) { 350 Selection select = doAccept(test); 351 if (select == Selection.REJECT) { 352 records.add(test); 353 } 354 } 355 356 return records; 357 } 358 } 359 } 360