1924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot#!/usr/bin/python2.4
2924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot#
3924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot#
4924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot# Copyright 2009, The Android Open Source Project
5924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot#
6924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot# Licensed under the Apache License, Version 2.0 (the "License");
7924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot# you may not use this file except in compliance with the License.
8924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot# You may obtain a copy of the License at
9924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot#
10924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot#     http://www.apache.org/licenses/LICENSE-2.0
11924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot#
12924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot# Unless required by applicable law or agreed to in writing, software
13924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot# distributed under the License is distributed on an "AS IS" BASIS,
14924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
15924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot# See the License for the specific language governing permissions and
16924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot# limitations under the License.
17924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
18924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot"""Utility to parse suite info from xml."""
19924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
20924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot# Python imports
21924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabotimport xml.dom.minidom
22924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabotimport xml.parsers
23924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
24924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot# local imports
25924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabotimport errors
26924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabotimport logger
27924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabotimport host_test
28924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabotimport instrumentation_test
29924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabotimport native_test
30924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
31924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
32924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabotclass XmlSuiteParser(object):
33924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  """Parses XML attributes common to all TestSuite's."""
34924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
35924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  # common attributes
36924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  _NAME_ATTR = 'name'
37924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  _BUILD_ATTR = 'build_path'
38924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  _CONTINUOUS_ATTR = 'continuous'
394a5d9f1ba755394e0e2547210c3b99b6e1b935ccBrett Chabot  _SUITE_ATTR = 'suite'
40924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  _DESCRIPTION_ATTR = 'description'
41924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  _EXTRA_BUILD_ARGS_ATTR = 'extra_build_args'
428dc9eb8ba63229e4fd9b97383b82e3c8f76ee89cBrett Chabot  _FULL_MAKE_ATTR = 'full_make'
43924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
44924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  def Parse(self, element):
45924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    """Populates common suite attributes from given suite xml element.
46924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
47924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    Args:
48924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot      element: xml node to parse
49924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    Raises:
50924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot      ParseError if a required attribute is missing.
51924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    Returns:
52924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot      parsed test suite or None
53924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    """
54924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    parser = None
55924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    if element.nodeName == InstrumentationParser.TAG_NAME:
56924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot      parser = InstrumentationParser()
57924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    elif element.nodeName == NativeParser.TAG_NAME:
58924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot      parser = NativeParser()
59924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    elif element.nodeName == HostParser.TAG_NAME:
60924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot      parser = HostParser()
61924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    else:
62924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot      logger.Log('Unrecognized tag %s found' % element.nodeName)
63924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot      return None
64924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    test_suite = parser.Parse(element)
65924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    return test_suite
66924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
67924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  def _ParseCommonAttributes(self, suite_element, test_suite):
68924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    test_suite.SetName(self._ParseAttribute(suite_element, self._NAME_ATTR,
69924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot                                            True))
70924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    test_suite.SetBuildPath(self._ParseAttribute(suite_element,
71924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot                                                 self._BUILD_ATTR, True))
72924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    test_suite.SetContinuous(self._ParseAttribute(suite_element,
73924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot                                                  self._CONTINUOUS_ATTR,
74924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot                                                  False, default_value=False))
754a5d9f1ba755394e0e2547210c3b99b6e1b935ccBrett Chabot    test_suite.SetSuite(self._ParseAttribute(suite_element, self._SUITE_ATTR, False,
764a5d9f1ba755394e0e2547210c3b99b6e1b935ccBrett Chabot                                           default_value=None))
77924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    test_suite.SetDescription(self._ParseAttribute(suite_element,
78924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot                                                   self._DESCRIPTION_ATTR,
79924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot                                                   False,
80924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot                                                   default_value=''))
81924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    test_suite.SetExtraBuildArgs(self._ParseAttribute(
82924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot        suite_element, self._EXTRA_BUILD_ARGS_ATTR, False, default_value=''))
838dc9eb8ba63229e4fd9b97383b82e3c8f76ee89cBrett Chabot    test_suite.SetIsFullMake(self._ParseAttribute(
848dc9eb8ba63229e4fd9b97383b82e3c8f76ee89cBrett Chabot        suite_element, self._FULL_MAKE_ATTR, False, default_value=False))
858dc9eb8ba63229e4fd9b97383b82e3c8f76ee89cBrett Chabot
86924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
87924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  def _ParseAttribute(self, suite_element, attribute_name, mandatory,
88924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot                      default_value=None):
89924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    if suite_element.hasAttribute(attribute_name):
90924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot      value = suite_element.getAttribute(attribute_name)
91924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    elif mandatory:
92924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot      error_msg = ('Could not find attribute %s in %s' %
93924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot                   (attribute_name, self.TAG_NAME))
94924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot      raise errors.ParseError(msg=error_msg)
95924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    else:
96924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot      value = default_value
97924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    return value
98924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
99924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
100924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabotclass InstrumentationParser(XmlSuiteParser):
101924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  """Parses instrumentation suite attributes from xml."""
102924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
103924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  # for legacy reasons, the xml tag name for java (device) tests is 'test'
104924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  TAG_NAME = 'test'
105924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
106924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  _PKG_ATTR = 'package'
107924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  _RUNNER_ATTR = 'runner'
108924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  _CLASS_ATTR = 'class'
109924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  _TARGET_ATTR = 'coverage_target'
110924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
111924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  def Parse(self, suite_element):
112924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    """Creates suite and populate with data from xml element."""
113924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    suite = instrumentation_test.InstrumentationTestSuite()
114924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    XmlSuiteParser._ParseCommonAttributes(self, suite_element, suite)
115924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    suite.SetPackageName(self._ParseAttribute(suite_element, self._PKG_ATTR,
116924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot                                              True))
117924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    suite.SetRunnerName(self._ParseAttribute(
118924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot        suite_element, self._RUNNER_ATTR, False,
119924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot        instrumentation_test.InstrumentationTestSuite.DEFAULT_RUNNER))
120924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    suite.SetClassName(self._ParseAttribute(suite_element, self._CLASS_ATTR,
121924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot                                            False))
122924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    suite.SetTargetName(self._ParseAttribute(suite_element, self._TARGET_ATTR,
123924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot                                             False))
124924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    return suite
125924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
126924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
127924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabotclass NativeParser(XmlSuiteParser):
128924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  """Parses native suite attributes from xml."""
129924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
130924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  TAG_NAME = 'test-native'
131924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
132924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  def Parse(self, suite_element):
133924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    """Creates suite and populate with data from xml element."""
134924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    suite = native_test.NativeTestSuite()
135924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    XmlSuiteParser._ParseCommonAttributes(self, suite_element, suite)
136924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    return suite
137924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
138924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
139924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabotclass HostParser(XmlSuiteParser):
140924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  """Parses host suite attributes from xml."""
141924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
142924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  TAG_NAME = 'test-host'
143924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
144924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  _CLASS_ATTR = 'class'
145924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  # TODO: consider obsoleting in favor of parsing the Android.mk to find the
146924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  # jar name
147924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  _JAR_ATTR = 'jar_name'
148924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot
149924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot  def Parse(self, suite_element):
150924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    """Creates suite and populate with data from xml element."""
151924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    suite = host_test.HostTestSuite()
152924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    XmlSuiteParser._ParseCommonAttributes(self, suite_element, suite)
153924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    suite.SetClassName(self._ParseAttribute(suite_element, self._CLASS_ATTR,
154924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot                                            True))
155924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    suite.SetJarName(self._ParseAttribute(suite_element, self._JAR_ATTR, True))
156924c0898792f4e14eb87a91a8e30d7138fb68be0Brett Chabot    return suite
157