• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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
21import xml.dom.minidom
22import xml.parsers
23
24# local imports
25import errors
26import logger
27import host_test
28import instrumentation_test
29import native_test
30
31
32class 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  _CTS_ATTR = 'cts'
40  _DESCRIPTION_ATTR = 'description'
41  _EXTRA_BUILD_ARGS_ATTR = 'extra_build_args'
42
43  def Parse(self, element):
44    """Populates common suite attributes from given suite xml element.
45
46    Args:
47      element: xml node to parse
48    Raises:
49      ParseError if a required attribute is missing.
50    Returns:
51      parsed test suite or None
52    """
53    parser = None
54    if element.nodeName == InstrumentationParser.TAG_NAME:
55      parser = InstrumentationParser()
56    elif element.nodeName == NativeParser.TAG_NAME:
57      parser = NativeParser()
58    elif element.nodeName == HostParser.TAG_NAME:
59      parser = HostParser()
60    else:
61      logger.Log('Unrecognized tag %s found' % element.nodeName)
62      return None
63    test_suite = parser.Parse(element)
64    return test_suite
65
66  def _ParseCommonAttributes(self, suite_element, test_suite):
67    test_suite.SetName(self._ParseAttribute(suite_element, self._NAME_ATTR,
68                                            True))
69    test_suite.SetBuildPath(self._ParseAttribute(suite_element,
70                                                 self._BUILD_ATTR, True))
71    test_suite.SetContinuous(self._ParseAttribute(suite_element,
72                                                  self._CONTINUOUS_ATTR,
73                                                  False, default_value=False))
74    test_suite.SetCts(self._ParseAttribute(suite_element, self._CTS_ATTR, False,
75                                           default_value=False))
76    test_suite.SetDescription(self._ParseAttribute(suite_element,
77                                                   self._DESCRIPTION_ATTR,
78                                                   False,
79                                                   default_value=''))
80    test_suite.SetExtraBuildArgs(self._ParseAttribute(
81        suite_element, self._EXTRA_BUILD_ARGS_ATTR, False, default_value=''))
82
83  def _ParseAttribute(self, suite_element, attribute_name, mandatory,
84                      default_value=None):
85    if suite_element.hasAttribute(attribute_name):
86      value = suite_element.getAttribute(attribute_name)
87    elif mandatory:
88      error_msg = ('Could not find attribute %s in %s' %
89                   (attribute_name, self.TAG_NAME))
90      raise errors.ParseError(msg=error_msg)
91    else:
92      value = default_value
93    return value
94
95
96class InstrumentationParser(XmlSuiteParser):
97  """Parses instrumentation suite attributes from xml."""
98
99  # for legacy reasons, the xml tag name for java (device) tests is 'test'
100  TAG_NAME = 'test'
101
102  _PKG_ATTR = 'package'
103  _RUNNER_ATTR = 'runner'
104  _CLASS_ATTR = 'class'
105  _TARGET_ATTR = 'coverage_target'
106
107  def Parse(self, suite_element):
108    """Creates suite and populate with data from xml element."""
109    suite = instrumentation_test.InstrumentationTestSuite()
110    XmlSuiteParser._ParseCommonAttributes(self, suite_element, suite)
111    suite.SetPackageName(self._ParseAttribute(suite_element, self._PKG_ATTR,
112                                              True))
113    suite.SetRunnerName(self._ParseAttribute(
114        suite_element, self._RUNNER_ATTR, False,
115        instrumentation_test.InstrumentationTestSuite.DEFAULT_RUNNER))
116    suite.SetClassName(self._ParseAttribute(suite_element, self._CLASS_ATTR,
117                                            False))
118    suite.SetTargetName(self._ParseAttribute(suite_element, self._TARGET_ATTR,
119                                             False))
120    return suite
121
122
123class NativeParser(XmlSuiteParser):
124  """Parses native suite attributes from xml."""
125
126  TAG_NAME = 'test-native'
127
128  def Parse(self, suite_element):
129    """Creates suite and populate with data from xml element."""
130    suite = native_test.NativeTestSuite()
131    XmlSuiteParser._ParseCommonAttributes(self, suite_element, suite)
132    return suite
133
134
135class HostParser(XmlSuiteParser):
136  """Parses host suite attributes from xml."""
137
138  TAG_NAME = 'test-host'
139
140  _CLASS_ATTR = 'class'
141  # TODO: consider obsoleting in favor of parsing the Android.mk to find the
142  # jar name
143  _JAR_ATTR = 'jar_name'
144
145  def Parse(self, suite_element):
146    """Creates suite and populate with data from xml element."""
147    suite = host_test.HostTestSuite()
148    XmlSuiteParser._ParseCommonAttributes(self, suite_element, suite)
149    suite.SetClassName(self._ParseAttribute(suite_element, self._CLASS_ATTR,
150                                            True))
151    suite.SetJarName(self._ParseAttribute(suite_element, self._JAR_ATTR, True))
152    return suite
153