• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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