1 /*
2  * Copyright (C) 2011 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 package com.android.cts.xmlgenerator;
17 
18 import org.w3c.dom.Document;
19 import org.w3c.dom.Element;
20 import org.w3c.dom.NodeList;
21 
22 import vogar.ExpectationStore;
23 import vogar.ModeId;
24 
25 import java.io.File;
26 import java.util.Arrays;
27 import java.util.HashMap;
28 import java.util.HashSet;
29 import java.util.Map;
30 import java.util.Set;
31 
32 import javax.xml.parsers.DocumentBuilderFactory;
33 
34 /** Class that outputs a test package xml. */
35 public class CtsXmlGenerator {
36 
usage(String[] args)37     private static void usage(String[] args) {
38         System.err.println("Arguments: " + Arrays.asList(args));
39         System.err.println("Usage: cts-xml-generator -p PACKAGE_NAME -n NAME [-t TEST_TYPE]"
40                 + " [-j JAR_PATH] [-i INSTRUMENTATION] [-m MANIFEST_FILE] [-e EXPECTATION_FILE]"
41                 + " [-b UNSUPPORTED_ABI_FILE] [-a ARCHITECTURE] [-o OUTPUT_FILE]"
42                 + " [-s APP_NAME_SPACE] [-x ADDITIONAL_ATTRIBUTE_KEY->VALUE]");
43         System.exit(1);
44     }
45 
main(String[] args)46     public static void main(String[] args) throws Exception {
47         String appPackageName = null;
48         String name = null;
49         String outputPath = null;
50         Set<File> expectationFiles = new HashSet<File>();
51         Set<File> abiFiles = new HashSet<File>();
52         String architecture = null;
53         File manifestFile = null;
54         String instrumentation = null;
55         String testType = null;
56         String jarPath = null;
57         String appNameSpace = null;
58         String targetNameSpace = null;
59         Map<String, String> additionalAttributes = new HashMap<String, String>();
60 
61         for (int i = 0; i < args.length; i++) {
62             if ("-p".equals(args[i])) {
63                 appPackageName = getArg(args, ++i, "Missing value for test package");
64             } else if ("-n".equals(args[i])) {
65                 name = getArg(args, ++i, "Missing value for executable name");
66             } else if ("-t".equals(args[i])) {
67                 testType = getArg(args, ++i, "Missing value for test type");
68             } else if ("-j".equals(args[i])) {
69                 jarPath = getArg(args, ++i, "Missing value for jar path");
70             } else if ("-m".equals(args[i])) {
71                 manifestFile = new File(getArg(args, ++i, "Missing value for manifest"));
72             } else if ("-i".equals(args[i])) {
73                 instrumentation = getArg(args, ++i, "Missing value for instrumentation");
74             } else if ("-e".equals(args[i])) {
75                 expectationFiles.add(new File(getArg(args, ++i,
76                         "Missing value for expectation store")));
77             } else if ("-b".equals(args[i])) {
78                 abiFiles.add(new File(getArg(args, ++i, "Missing value for abi store")));
79             } else if ("-a".equals(args[i])) {
80                 architecture = getArg(args, ++i, "Missing value for architecture");
81             } else if ("-o".equals(args[i])) {
82                 outputPath = getArg(args, ++i, "Missing value for output file");
83             } else if ("-s".equals(args[i])) {
84                 appNameSpace =  getArg(args, ++i, "Missing value for app name space");
85             } else if ("-r".equals(args[i])) {
86                 targetNameSpace =  getArg(args, ++i, "Missing value for target name space");
87             } else if ("-x".equals(args[i])) {
88                 String value = getArg(args, ++i, "Missing value for additional attribute");
89                 String[] tokens = value.split("->");
90                 if (tokens.length != 2) {
91                     System.err.println(
92                             "For specifying additional attributes; use the format KEY->VALUE");
93                     usage(args);
94                 }
95                 if (additionalAttributes.containsKey(tokens[0])) {
96                     System.err.println(String.format(
97                             "Additional attribute %s has already been specified", tokens[0]));
98                     usage(args);
99                 }
100                 additionalAttributes.put(tokens[0], tokens[1]);
101             } else {
102                 System.err.println("Unsupported flag: " + args[i]);
103                 usage(args);
104             }
105         }
106 
107         String runner = null;
108 
109         if (manifestFile != null) {
110             Document manifest = DocumentBuilderFactory.newInstance().newDocumentBuilder()
111                     .parse(manifestFile);
112             Element documentElement = manifest.getDocumentElement();
113             appNameSpace = documentElement.getAttribute("package");
114             runner = getElementAttribute(documentElement, "instrumentation",
115                     "android:name");
116             targetNameSpace = getElementAttribute(documentElement, "instrumentation",
117                     "android:targetPackage");
118         }
119 
120         if (appPackageName == null) {
121             System.out.println("Package name is required");
122             usage(args);
123         } else if (name == null) {
124             System.out.println("Executable name is required");
125             usage(args);
126         }
127 
128         ExpectationStore failuresStore = ExpectationStore.parse(expectationFiles, ModeId.DEVICE);
129         ExpectationStore abiStore = ExpectationStore.parse(abiFiles, ModeId.DEVICE);
130         XmlGenerator generator = new XmlGenerator(failuresStore, abiStore, architecture,
131                 appNameSpace, appPackageName, name, runner, instrumentation, targetNameSpace,
132                 jarPath, testType, outputPath, additionalAttributes);
133         generator.writePackageXml();
134     }
135 
getArg(String[] args, int index, String message)136     private static String getArg(String[] args, int index, String message) {
137         if (index < args.length) {
138             return args[index];
139         } else {
140             System.err.println(message);
141             usage(args);
142             return null;
143         }
144     }
145 
getElementAttribute(Element parentElement, String elementName, String attributeName)146     private static String getElementAttribute(Element parentElement, String elementName,
147             String attributeName) {
148         NodeList nodeList = parentElement.getElementsByTagName(elementName);
149         if (nodeList.getLength() > 0) {
150              Element element = (Element) nodeList.item(0);
151              return element.getAttribute(attributeName);
152         }
153         return null;
154     }
155 }
156