1 /* 2 * Copyright (C) 2018 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.apicoverage; 18 19 20 import com.android.cts.apicoverage.TestSuiteProto.*; 21 import com.android.tradefed.testtype.IRemoteTest; 22 23 import junit.framework.Test; 24 25 import org.jf.dexlib2.AccessFlags; 26 import org.jf.dexlib2.DexFileFactory; 27 import org.jf.dexlib2.Opcodes; 28 import org.jf.dexlib2.iface.Annotation; 29 import org.jf.dexlib2.iface.AnnotationElement; 30 import org.jf.dexlib2.iface.ClassDef; 31 import org.jf.dexlib2.iface.DexFile; 32 import org.jf.dexlib2.iface.Method; 33 import org.junit.runners.Suite.SuiteClasses; 34 import org.junit.runner.RunWith; 35 36 import java.lang.reflect.Modifier; 37 import java.io.File; 38 import java.io.FileInputStream; 39 import java.io.FileOutputStream; 40 import java.io.FileWriter; 41 import java.io.IOException; 42 import java.io.PrintWriter; 43 import java.nio.file.Paths; 44 import java.security.NoSuchAlgorithmException; 45 import java.net.URL; 46 import java.net.URLClassLoader; 47 import java.util.ArrayList; 48 import java.util.Collection; 49 import java.util.Enumeration; 50 import java.util.List; 51 import java.util.Set; 52 import java.util.jar.JarEntry; 53 import java.util.jar.JarFile; 54 55 class TestCaseReport { 56 // JUNIT3 Test suffix 57 private static final String TEST_TAG = "Test;"; 58 // Some may ends with Tests e.g. cts/tests/tests/accounts/src/android/accounts/cts/AbstractAuthenticatorTests.java 59 private static final String TESTS_TAG = "Tests;"; 60 private static final String TEST_PREFIX_TAG = "test"; 61 private static final String DEPRECATED_ANNOTATION_TAG = "Ljava/lang/Deprecated;"; 62 private static final String RUN_WITH_ANNOTATION_TAG = 63 "Lorg/junit/runner/RunWith;"; 64 private static final String TEST_ANNOTATION_TAG = 65 "Lorg/junit/Test;"; 66 private static final String SUPPRESS_ANNOTATION_TAG = "/Suppress;"; 67 private static final String PARAMETERS_TAG = 68 "Lorg/junit/runners/Parameterized$Parameters"; 69 private static final String ANDROID_JUNIT4_TEST_TAG = 70 "AndroidJUnit4.class"; 71 private static final String PARAMETERIZED_TAG = 72 "Parameterized.class"; 73 74 // configuration option 75 private static final String NOT_SHARDABLE_TAG = "not-shardable"; 76 // test class option 77 private static final String RUNTIME_HIT_TAG = "runtime-hint"; 78 // com.android.tradefed.testtype.AndroidJUnitTest option 79 private static final String PACKAGE_TAG = "package"; 80 // com.android.compatibility.common.tradefed.testtype.JarHostTest option 81 private static final String JAR_TAG = "jar"; 82 // com.android.tradefed.testtype.GTest option 83 private static final String NATIVE_TEST_DEVICE_PATH_TAG = "native-test-device-path"; 84 private static final String MODULE_TAG = "module-name"; 85 86 private static final String SUITE_API_INSTALLER_TAG = "com.android.tradefed.targetprep.suite.SuiteApkInstaller"; 87 private static final String HOST_TEST_CLASS_TAG = 88 "com.android.compatibility.common.tradefed.testtype.JarHostTest"; 89 // com.android.tradefed.targetprep.suite.SuiteApkInstaller option 90 private static final String TEST_FILE_NAME_TAG = "test-file-name"; 91 // com.android.compatibility.common.tradefed.targetprep.FilePusher option 92 private static final String PUSH_TAG = "push"; 93 94 // test class 95 private static final String ANDROID_JUNIT_TEST_TAG = "com.android.tradefed.testtype.AndroidJUnitTest"; 96 private static final String DEQP_TEST_TAG = "com.drawelements.deqp.runner.DeqpTestRunner"; 97 private static final String GTEST_TAG = "com.android.tradefed.testtype.GTest"; 98 private static final String LIBCORE_TEST_TAG = "com.android.compatibility.testtype.LibcoreTest"; 99 private static final String DALVIK_TEST_TAG = "com.android.compatibility.testtype.DalvikTest"; 100 101 102 // Target File Extensions 103 private static final String CONFIG_EXT_TAG = ".config"; 104 private static final String CONFIG_REGEX = ".config$"; 105 private static final String JAR_EXT_TAG = ".jar"; 106 private static final String APK_EXT_TAG = ".apk"; 107 private static final String SO_EXT_TAG = ".so"; 108 109 // [module].[class]#[method] 110 public static final String TESTCASE_NAME_FORMAT = "%s.%s#%s"; 111 printUsage()112 private static void printUsage() { 113 System.out.println("Usage: test-suite-content-report [OPTION]..."); 114 System.out.println(); 115 System.out.println("Generates test test list protocal buffer message."); 116 System.out.println(); 117 System.out.println( 118 "$ANDROID_HOST_OUT/bin/test-suite-content-report " 119 + "-i out/host/linux-x86/cts/android-cts/testcases " 120 + "-c ./cts-content.pb" 121 + "-o ./cts-list.pb"); 122 System.out.println(); 123 System.out.println("Options:"); 124 System.out.println(" -i PATH path to the Test Suite Folder"); 125 System.out.println(" -c FILE input file of Test Content Protocal Buffer"); 126 System.out.println(" -o FILE output file of Test Case List Protocal Buffer"); 127 System.out.println(); 128 System.exit(1); 129 } 130 131 /** Get the argument or print out the usage and exit. */ getExpectedArg(String[] args, int index)132 private static String getExpectedArg(String[] args, int index) { 133 if (index < args.length) { 134 return args[index]; 135 } else { 136 printUsage(); 137 return null; // Never will happen because print Usage will call exit(1) 138 } 139 } 140 hasAnnotation(Set<? extends Annotation> annotations, String tag)141 private static boolean hasAnnotation(Set<? extends Annotation> annotations, String tag) { 142 for (Annotation annotation : annotations) { 143 if (annotation.getType().equals(tag)) { 144 return true; 145 } 146 } 147 return false; 148 } 149 hasAnnotationSuffix(Set<? extends Annotation> annotations, String tag)150 private static boolean hasAnnotationSuffix(Set<? extends Annotation> annotations, String tag) { 151 for (Annotation annotation : annotations) { 152 if (annotation.getType().endsWith(tag)) { 153 return true; 154 } 155 } 156 return false; 157 } 158 chkTestType(ClassDef classDef)159 private static TestSuite.Package.Class.ClassType chkTestType(ClassDef classDef) { 160 // Only care about Public Class 161 if ((classDef.getAccessFlags() & AccessFlags.PUBLIC.getValue()) == 0) { 162 return TestSuite.Package.Class.ClassType.UNKNOWN; 163 } 164 165 for (Annotation annotation : classDef.getAnnotations()) { 166 if (annotation.getType().equals(DEPRECATED_ANNOTATION_TAG)) { 167 return TestSuite.Package.Class.ClassType.UNKNOWN; 168 } 169 if (annotation.getType().equals(RUN_WITH_ANNOTATION_TAG)) { 170 for (AnnotationElement annotationEle : annotation.getElements()) { 171 String aName = annotationEle.getName(); 172 if (aName.equals(ANDROID_JUNIT4_TEST_TAG)) { 173 return TestSuite.Package.Class.ClassType.JUNIT4; 174 } else if (aName.equals(PARAMETERIZED_TAG)) { 175 return TestSuite.Package.Class.ClassType.PARAMETERIZED; 176 } 177 } 178 return TestSuite.Package.Class.ClassType.JUNIT4; 179 } 180 } 181 182 if (classDef.getType().endsWith(TEST_TAG) || classDef.getType().endsWith(TESTS_TAG)) { 183 return TestSuite.Package.Class.ClassType.JUNIT3; 184 } else { 185 return TestSuite.Package.Class.ClassType.UNKNOWN; 186 } 187 } 188 isTargetClass(List<String> pkgList, String className)189 private static boolean isTargetClass(List<String> pkgList, String className) { 190 boolean found = false; 191 for (String pkg : pkgList) { 192 if (className.startsWith(pkg)) { 193 found = true; 194 break; 195 } 196 } 197 return found; 198 } 199 200 // Get test case list from an APK parseApkTestCase(List<String> apkList, List<String> classList, String tsPath, int api)201 private static TestSuite.Package.Builder parseApkTestCase(List<String> apkList, 202 List<String> classList, String tsPath, int api) 203 throws Exception { 204 205 TestSuite.Package.Builder tsPkgBuilder = TestSuite.Package.newBuilder(); 206 for (String apkName : apkList) { 207 DexFile dexFile = null; 208 String apkPath = Paths.get(tsPath, apkName).toString(); 209 try { 210 dexFile = DexFileFactory.loadDexFile(apkPath, Opcodes.forApi(api)); 211 } catch (IOException | DexFileFactory.DexFileNotFoundException ex) { 212 System.err.println("Unable to load dex file: " + apkPath); 213 // ex.printStackTrace(); 214 continue; 215 } 216 217 tsPkgBuilder.setName(apkName); 218 for (ClassDef classDef : dexFile.getClasses()) { 219 // adjust the format Lclass/y; 220 String className = classDef.getType().replace('/','.'); 221 // remove L...; 222 if (className.length() > 2) { 223 className = className.substring(1, className.length() - 1); 224 } 225 226 TestSuite.Package.Class.ClassType cType; 227 cType = chkTestType(classDef); 228 if (TestSuite.Package.Class.ClassType.JUNIT3 == cType) { 229 TestSuite.Package.Class.Builder tClassBuilder = 230 TestSuite.Package.Class.newBuilder(); 231 tClassBuilder.setClassType(cType); 232 tClassBuilder.setApk(apkName); 233 tClassBuilder.setName(className); 234 235 for (Method method : classDef.getMethods()) { 236 if ((method.getAccessFlags() & AccessFlags.PUBLIC.getValue()) != 0) { 237 String mName = method.getName(); 238 if (hasAnnotationSuffix( 239 method.getAnnotations(), SUPPRESS_ANNOTATION_TAG)) { 240 System.err.printf("%s#%s with Suppress:\n", className, mName); 241 System.err.println(method.getAnnotations()); 242 } else if (mName.startsWith(TEST_PREFIX_TAG)) { 243 TestSuite.Package.Class.Method.Builder methodBuilder = 244 TestSuite.Package.Class.Method.newBuilder(); 245 methodBuilder.setName(mName); 246 tClassBuilder.addMethods(methodBuilder); 247 } 248 } 249 } 250 tsPkgBuilder.addClasses(tClassBuilder); 251 } else if (TestSuite.Package.Class.ClassType.JUNIT4 == cType) { 252 TestSuite.Package.Class.Builder tClassBuilder = 253 TestSuite.Package.Class.newBuilder(); 254 tClassBuilder.setClassType(cType); 255 tClassBuilder.setApk(apkName); 256 tClassBuilder.setName(className); 257 258 for (Method method : classDef.getMethods()) { 259 if (hasAnnotation(method.getAnnotations(), TEST_ANNOTATION_TAG)) { 260 String mName = method.getName(); 261 TestSuite.Package.Class.Method.Builder methodBuilder = 262 TestSuite.Package.Class.Method.newBuilder(); 263 methodBuilder.setName(mName); 264 tClassBuilder.addMethods(methodBuilder); 265 } 266 } 267 tsPkgBuilder.addClasses(tClassBuilder); 268 } else if (TestSuite.Package.Class.ClassType.PARAMETERIZED == cType) { 269 TestSuite.Package.Class.Builder tClassBuilder = 270 TestSuite.Package.Class.newBuilder(); 271 tClassBuilder.setClassType(cType); 272 tClassBuilder.setApk(apkName); 273 tClassBuilder.setName(className); 274 275 for (Method method : classDef.getMethods()) { 276 if (hasAnnotation(method.getAnnotations(), TEST_ANNOTATION_TAG)) { 277 String mName = method.getName(); 278 TestSuite.Package.Class.Method.Builder methodBuilder = 279 TestSuite.Package.Class.Method.newBuilder(); 280 methodBuilder.setName(mName); 281 tClassBuilder.addMethods(methodBuilder); 282 } 283 } 284 tsPkgBuilder.addClasses(tClassBuilder); 285 } 286 } 287 } 288 return tsPkgBuilder; 289 } 290 getJarTestClasses(File jarTestFile, String tfPath)291 private static Collection<Class<?>> getJarTestClasses(File jarTestFile, String tfPath) 292 throws IllegalArgumentException { 293 List<Class<?>> classes = new ArrayList<>(); 294 295 try (JarFile jarFile = new JarFile(jarTestFile)) { 296 Enumeration<JarEntry> e = jarFile.entries(); 297 298 URL[] urls = { 299 new URL(String.format("jar:file:%s!/", jarTestFile.getAbsolutePath())), 300 new URL(String.format("jar:file:%s!/", tfPath)) 301 }; 302 URLClassLoader cl = 303 URLClassLoader.newInstance(urls, JarTestFinder.class.getClassLoader()); 304 305 while (e.hasMoreElements()) { 306 JarEntry je = e.nextElement(); 307 if (je.isDirectory() 308 || !je.getName().endsWith(".class") 309 || je.getName().contains("$") 310 || je.getName().contains("junit/")) { 311 continue; 312 } 313 String className = getClassName(je.getName()); 314 315 /*if (!className.endsWith("Test")) { 316 continue; 317 }*/ 318 try { 319 Class<?> cls = cl.loadClass(className); 320 321 if (IRemoteTest.class.isAssignableFrom(cls) 322 || Test.class.isAssignableFrom(cls)) { 323 classes.add(cls); 324 } else if (!Modifier.isAbstract(cls.getModifiers()) 325 && hasJUnit4Annotation(cls)) { 326 classes.add(cls); 327 } 328 } catch (ClassNotFoundException | Error x) { 329 System.err.println( 330 String.format( 331 "Cannot find test class %s from %s", 332 className, jarTestFile.getName())); 333 x.printStackTrace(); 334 } 335 } 336 } catch (IOException e) { 337 e.printStackTrace(); 338 } 339 return classes; 340 } 341 342 /** Helper to determine if we are dealing with a Test class with Junit4 annotations. */ hasJUnit4Annotation(Class<?> classObj)343 protected static boolean hasJUnit4Annotation(Class<?> classObj) { 344 if (classObj.isAnnotationPresent(SuiteClasses.class)) { 345 return true; 346 } 347 if (classObj.isAnnotationPresent(RunWith.class)) { 348 return true; 349 } 350 /*for (Method m : classObj.getMethods()) { 351 if (m.isAnnotationPresent(org.junit.Test.class)) { 352 return true; 353 } 354 }*/ 355 return false; 356 } 357 getClassName(String name)358 private static String getClassName(String name) { 359 // -6 because of .class 360 return name.substring(0, name.length() - 6).replace('/', '.'); 361 } 362 parseJarTestCase( List<String> jarList, String tsPath, String tfPath)363 private static TestSuite.Package.Builder parseJarTestCase( 364 List<String> jarList, String tsPath, String tfPath) throws Exception { 365 366 TestSuite.Package.Builder tsPkgBuilder = TestSuite.Package.newBuilder(); 367 for (String jarName : jarList) { 368 tsPkgBuilder.setName(jarName); 369 Collection<Class<?>> classes = 370 getJarTestClasses(Paths.get(tsPath, jarName).toFile(), tfPath); 371 for (Class<?> c : classes) { 372 TestSuite.Package.Class.Builder tClassBuilder = 373 TestSuite.Package.Class.newBuilder(); 374 tClassBuilder.setClassType(TestSuite.Package.Class.ClassType.JAVAHOST); 375 tClassBuilder.setApk(jarName); 376 tClassBuilder.setName(c.getName()); 377 378 System.err.printf("class: %s\n", c.getName()); 379 for (java.lang.reflect.Method m : c.getMethods()) { 380 int mdf = m.getModifiers(); 381 if (Modifier.isPublic(mdf) || Modifier.isProtected(mdf)) { 382 if (m.getName().startsWith(TEST_PREFIX_TAG)) { 383 System.err.printf("test: %s\n", m.getName()); 384 TestSuite.Package.Class.Method.Builder methodBuilder = 385 TestSuite.Package.Class.Method.newBuilder(); 386 methodBuilder.setName(m.getName()); 387 tClassBuilder.addMethods(methodBuilder); 388 } 389 } 390 } 391 tsPkgBuilder.addClasses(tClassBuilder); 392 } 393 } 394 return tsPkgBuilder; 395 } 396 397 // Iterates though all test suite content and prints them. listTestCases(TestSuiteContent tsContent, String tsPath, String tfPath)398 static TestSuite.Builder listTestCases(TestSuiteContent tsContent, String tsPath, String tfPath) 399 throws Exception { 400 TestSuite.Builder tsBuilder = TestSuite.newBuilder(); 401 402 int i = 1; 403 for (Entry entry: tsContent.getFileEntriesList()) { 404 if (Entry.EntryType.CONFIG == entry.getType()) { 405 TestSuite.Package.Type pType = null; 406 ConfigMetadata config = entry.getFileMetadata().getConfigMetadata(); 407 408 // getting package/class list from Test Module Configuration 409 ArrayList<String> testClassList = new ArrayList<String> (); 410 ArrayList<String> hostTestJarList = new ArrayList<String>(); 411 List<Option> optList; 412 List<ConfigMetadata.TestClass> testClassesList = config.getTestClassesList(); 413 for (ConfigMetadata.TestClass tClass : testClassesList) { 414 boolean isHostTest = false; 415 boolean isAndroidJunitTest = false; 416 optList = tClass.getOptionsList(); 417 if (HOST_TEST_CLASS_TAG.equals(tClass.getTestClass())) { 418 isHostTest = true; 419 pType = TestSuite.Package.Type.JAVAHOST; 420 } else if (ANDROID_JUNIT_TEST_TAG.equals(tClass.getTestClass())) { 421 isAndroidJunitTest = true; 422 } else if (GTEST_TAG.equals(tClass.getTestClass())) { 423 pType = TestSuite.Package.Type.GTEST; 424 } else if (DEQP_TEST_TAG.equals(tClass.getTestClass())) { 425 pType = TestSuite.Package.Type.DEQP; 426 } else if (LIBCORE_TEST_TAG.equals(tClass.getTestClass())) { 427 pType = TestSuite.Package.Type.LIBCORE; 428 } else if (DALVIK_TEST_TAG.equals(tClass.getTestClass())) { 429 // cts/tests/jdwp/AndroidTest.xml 430 pType = TestSuite.Package.Type.DALVIK; 431 } else { 432 System.err.printf( 433 "Unknown Test Type: %s %s\n", 434 entry.getName(), tClass.getTestClass()); 435 } 436 437 for (Option opt : optList) { 438 if (isAndroidJunitTest && PACKAGE_TAG.equalsIgnoreCase(opt.getName())) { 439 testClassList.add(opt.getValue()); 440 } else if (isHostTest && JAR_TAG.equalsIgnoreCase(opt.getName())) { 441 hostTestJarList.add(opt.getValue()); 442 } 443 } 444 } 445 446 // getting apk list from Test Module Configuration 447 ArrayList<String> testApkList = new ArrayList<String> (); 448 List<ConfigMetadata.TargetPreparer> tPrepList = config.getTargetPreparersList(); 449 for (ConfigMetadata.TargetPreparer tPrep : tPrepList) { 450 optList = tPrep.getOptionsList(); 451 for (Option opt : optList) { 452 if (TEST_FILE_NAME_TAG.equalsIgnoreCase(opt.getName())) { 453 testApkList.add(opt.getValue()); 454 } 455 } 456 } 457 458 TestSuite.Package.Builder tsPkgBuilder; 459 460 if (pType == TestSuite.Package.Type.JAVAHOST) { 461 tsPkgBuilder = parseJarTestCase(hostTestJarList, tsPath, tfPath); 462 } else { 463 tsPkgBuilder = parseApkTestCase(testApkList, testClassList, tsPath, 27); 464 } 465 466 tsPkgBuilder.setName(entry.getName().replaceAll(CONFIG_REGEX, "")); 467 if (null != pType) { 468 tsPkgBuilder.setType(pType); 469 } 470 471 tsBuilder.addPackages(tsPkgBuilder); 472 } 473 } 474 return tsBuilder; 475 } 476 isKnownFailure(String tsName, List<String> knownFailures)477 private static boolean isKnownFailure(String tsName, List<String> knownFailures) { 478 for (String kf : knownFailures) { 479 if (tsName.startsWith(kf)) { 480 return true; 481 } 482 } 483 return false; 484 } 485 486 // Iterates though all test suite content and prints them. printTestSuite(TestSuite ts, List<String> knownFailures)487 static void printTestSuite(TestSuite ts, List<String> knownFailures) { 488 //Header 489 System.out.println("Module,Class,Test,no,Apk,Type"); 490 int i = 1; 491 for (TestSuite.Package pkg : ts.getPackagesList()) { 492 for (TestSuite.Package.Class cls : pkg.getClassesList()) { 493 for (TestSuite.Package.Class.Method mtd : cls.getMethodsList()) { 494 String testCaseName = 495 String.format( 496 TESTCASE_NAME_FORMAT, 497 pkg.getName(), 498 cls.getName(), 499 mtd.getName()); 500 // Filter out known failures 501 if (!isKnownFailure(testCaseName, knownFailures)) { 502 System.out.printf( 503 "%s,%s,%s,%d,%s,%s\n", 504 pkg.getName(), 505 cls.getName(), 506 mtd.getName(), 507 i++, 508 cls.getApk(), 509 cls.getClassType()); 510 } 511 } 512 } 513 } 514 } 515 516 // Iterates though all test suite content and prints them. printTestSuiteSummary(TestSuite ts, String fName, List<String> knownFailures)517 static void printTestSuiteSummary(TestSuite ts, String fName, List<String> knownFailures) 518 throws IOException { 519 FileWriter fWriter = new FileWriter(fName); 520 PrintWriter pWriter = new PrintWriter(fWriter); 521 522 //Header 523 pWriter.print("Module,Test#,no,Type,Class#\n"); 524 525 int i = 0; 526 for (TestSuite.Package pkg : ts.getPackagesList()) { 527 int classCnt = 0; 528 int methodCnt = 0; 529 for (TestSuite.Package.Class cls : pkg.getClassesList()) { 530 for (TestSuite.Package.Class.Method mtd : cls.getMethodsList()) { 531 String testCaseName = 532 String.format( 533 TESTCASE_NAME_FORMAT, 534 pkg.getName(), 535 cls.getName(), 536 mtd.getName()); 537 // Filter out known failures 538 if (!isKnownFailure(testCaseName, knownFailures)) { 539 methodCnt++; 540 } 541 } 542 classCnt++; 543 } 544 pWriter.printf( 545 "%s,%s,%d,%s,%d\n", pkg.getName(), methodCnt, i++, pkg.getType(), classCnt); 546 } 547 548 pWriter.close(); 549 } 550 main(String[] args)551 public static void main(String[] args) 552 throws IOException, NoSuchAlgorithmException, Exception { 553 String tsContentFilePath = "./tsContentMessage.pb"; 554 String outputTestCaseListFilePath = "./tsTestCaseList.pb"; 555 String outputSummaryFilePath = "./tsSummary.csv"; 556 String tsPath = ""; 557 String tradFedJarPath = ""; 558 559 for (int i = 0; i < args.length; i++) { 560 if (args[i].startsWith("-")) { 561 if ("-o".equals(args[i])) { 562 outputTestCaseListFilePath = getExpectedArg(args, ++i); 563 } else if ("-c".equals(args[i])) { 564 tsContentFilePath = getExpectedArg(args, ++i); 565 } else if ("-s".equals(args[i])) { 566 outputSummaryFilePath = getExpectedArg(args, ++i); 567 } else if ("-t".equals(args[i])) { 568 tradFedJarPath = getExpectedArg(args, ++i); 569 } else if ("-i".equals(args[i])) { 570 tsPath = getExpectedArg(args, ++i); 571 File file = new File(tsPath); 572 // Only acception a folder 573 if (!file.isDirectory()) { 574 printUsage(); 575 } 576 } else { 577 printUsage(); 578 } 579 } 580 } 581 582 // Read message from the file and print them out 583 TestSuiteContent tsContent = 584 TestSuiteContent.parseFrom(new FileInputStream(tsContentFilePath)); 585 586 TestSuite ts = listTestCases(tsContent, tsPath, tradFedJarPath).build(); 587 588 // Write test case list message to disk. 589 FileOutputStream output = new FileOutputStream(outputTestCaseListFilePath); 590 try { 591 ts.writeTo(output); 592 } finally { 593 output.close(); 594 } 595 596 // Read message from the file and print them out 597 TestSuite ts1 = TestSuite.parseFrom(new FileInputStream(outputTestCaseListFilePath)); 598 printTestSuite(ts1, tsContent.getKnownFailuresList()); 599 printTestSuiteSummary(ts1, outputSummaryFilePath, tsContent.getKnownFailuresList()); 600 } 601 } 602