1 #!/usr/bin/python2.4 2 # 3 # 4 # Copyright 2009, The Android Open Source Project 5 # 6 # Licensed under the Apache License, Version 2.0 (the "License"); 7 # you may not use this file except in compliance with the License. 8 # You may obtain a copy of the License at 9 # 10 # http://www.apache.org/licenses/LICENSE-2.0 11 # 12 # Unless required by applicable law or agreed to in writing, software 13 # distributed under the License is distributed on an "AS IS" BASIS, 14 # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 15 # See the License for the specific language governing permissions and 16 # limitations under the License. 17 18 """Utility to parse suite info from xml.""" 19 20 # Python imports 21 import xml.dom.minidom 22 import xml.parsers 23 24 # local imports 25 import errors 26 import logger 27 import host_test 28 import instrumentation_test 29 import native_test 30 31 32 class XmlSuiteParser(object): 33 """Parses XML attributes common to all TestSuite's.""" 34 35 # common attributes 36 _NAME_ATTR = 'name' 37 _BUILD_ATTR = 'build_path' 38 _CONTINUOUS_ATTR = 'continuous' 39 _SUITE_ATTR = 'suite' 40 _DESCRIPTION_ATTR = 'description' 41 _EXTRA_BUILD_ARGS_ATTR = 'extra_build_args' 42 _FULL_MAKE_ATTR = 'full_make' 43 44 def Parse(self, element): 45 """Populates common suite attributes from given suite xml element. 46 47 Args: 48 element: xml node to parse 49 Raises: 50 ParseError if a required attribute is missing. 51 Returns: 52 parsed test suite or None 53 """ 54 parser = None 55 if element.nodeName == InstrumentationParser.TAG_NAME: 56 parser = InstrumentationParser() 57 elif element.nodeName == NativeParser.TAG_NAME: 58 parser = NativeParser() 59 elif element.nodeName == HostParser.TAG_NAME: 60 parser = HostParser() 61 else: 62 logger.Log('Unrecognized tag %s found' % element.nodeName) 63 return None 64 test_suite = parser.Parse(element) 65 return test_suite 66 67 def _ParseCommonAttributes(self, suite_element, test_suite): 68 test_suite.SetName(self._ParseAttribute(suite_element, self._NAME_ATTR, 69 True)) 70 test_suite.SetBuildPath(self._ParseAttribute(suite_element, 71 self._BUILD_ATTR, True)) 72 test_suite.SetContinuous(self._ParseAttribute(suite_element, 73 self._CONTINUOUS_ATTR, 74 False, default_value=False)) 75 test_suite.SetSuite(self._ParseAttribute(suite_element, self._SUITE_ATTR, False, 76 default_value=None)) 77 test_suite.SetDescription(self._ParseAttribute(suite_element, 78 self._DESCRIPTION_ATTR, 79 False, 80 default_value='')) 81 test_suite.SetExtraBuildArgs(self._ParseAttribute( 82 suite_element, self._EXTRA_BUILD_ARGS_ATTR, False, default_value='')) 83 test_suite.SetIsFullMake(self._ParseAttribute( 84 suite_element, self._FULL_MAKE_ATTR, False, default_value=False)) 85 86 87 def _ParseAttribute(self, suite_element, attribute_name, mandatory, 88 default_value=None): 89 if suite_element.hasAttribute(attribute_name): 90 value = suite_element.getAttribute(attribute_name) 91 elif mandatory: 92 error_msg = ('Could not find attribute %s in %s' % 93 (attribute_name, self.TAG_NAME)) 94 raise errors.ParseError(msg=error_msg) 95 else: 96 value = default_value 97 return value 98 99 100 class InstrumentationParser(XmlSuiteParser): 101 """Parses instrumentation suite attributes from xml.""" 102 103 # for legacy reasons, the xml tag name for java (device) tests is 'test' 104 TAG_NAME = 'test' 105 106 _PKG_ATTR = 'package' 107 _RUNNER_ATTR = 'runner' 108 _CLASS_ATTR = 'class' 109 _TARGET_ATTR = 'coverage_target' 110 111 def Parse(self, suite_element): 112 """Creates suite and populate with data from xml element.""" 113 suite = instrumentation_test.InstrumentationTestSuite() 114 XmlSuiteParser._ParseCommonAttributes(self, suite_element, suite) 115 suite.SetPackageName(self._ParseAttribute(suite_element, self._PKG_ATTR, 116 True)) 117 suite.SetRunnerName(self._ParseAttribute( 118 suite_element, self._RUNNER_ATTR, False, 119 instrumentation_test.InstrumentationTestSuite.DEFAULT_RUNNER)) 120 suite.SetClassName(self._ParseAttribute(suite_element, self._CLASS_ATTR, 121 False)) 122 suite.SetTargetName(self._ParseAttribute(suite_element, self._TARGET_ATTR, 123 False)) 124 return suite 125 126 127 class NativeParser(XmlSuiteParser): 128 """Parses native suite attributes from xml.""" 129 130 TAG_NAME = 'test-native' 131 132 def Parse(self, suite_element): 133 """Creates suite and populate with data from xml element.""" 134 suite = native_test.NativeTestSuite() 135 XmlSuiteParser._ParseCommonAttributes(self, suite_element, suite) 136 return suite 137 138 139 class HostParser(XmlSuiteParser): 140 """Parses host suite attributes from xml.""" 141 142 TAG_NAME = 'test-host' 143 144 _CLASS_ATTR = 'class' 145 # TODO: consider obsoleting in favor of parsing the Android.mk to find the 146 # jar name 147 _JAR_ATTR = 'jar_name' 148 149 def Parse(self, suite_element): 150 """Creates suite and populate with data from xml element.""" 151 suite = host_test.HostTestSuite() 152 XmlSuiteParser._ParseCommonAttributes(self, suite_element, suite) 153 suite.SetClassName(self._ParseAttribute(suite_element, self._CLASS_ATTR, 154 True)) 155 suite.SetJarName(self._ParseAttribute(suite_element, self._JAR_ATTR, True)) 156 return suite 157