#!/usr/bin/python2.4
#
#
# Copyright 2008, The Android Open Source Project
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
"""Parser for test definition xml files."""
# Python imports
import xml.dom.minidom
import xml.parsers
# local imports
import errors
import logger
import xml_suite_helper
class TestDefinitions(object):
"""Accessor for a test definitions xml file data.
See test_defs.xsd for expected format.
"""
def __init__(self):
# dictionary of test name to tests
self._testname_map = {}
def __iter__(self):
ordered_list = []
for k in sorted(self._testname_map):
ordered_list.append(self._testname_map[k])
return iter(ordered_list)
def Parse(self, file_path):
"""Parse the test suite data from from given file path.
Args:
file_path: absolute file path to parse
Raises:
ParseError if file_path cannot be parsed
"""
try:
doc = xml.dom.minidom.parse(file_path)
self._ParseDoc(doc)
except IOError:
logger.Log("test file %s does not exist" % file_path)
raise errors.ParseError
except xml.parsers.expat.ExpatError:
logger.Log("Error Parsing xml file: %s " % file_path)
raise errors.ParseError
except errors.ParseError, e:
logger.Log("Error Parsing xml file: %s Reason: %s" % (file_path, e.msg))
raise e
def ParseString(self, xml_string):
"""Alternate parse method that accepts a string of the xml data."""
doc = xml.dom.minidom.parseString(xml_string)
# TODO: catch exceptions and raise ParseError
return self._ParseDoc(doc)
def _ParseDoc(self, doc):
root_element = self._GetRootElement(doc)
suite_parser = xml_suite_helper.XmlSuiteParser()
for element in root_element.childNodes:
if element.nodeType != xml.dom.Node.ELEMENT_NODE:
continue
test_suite = suite_parser.Parse(element)
if test_suite:
self._AddTest(test_suite)
def _GetRootElement(self, doc):
root_elements = doc.getElementsByTagName("test-definitions")
if len(root_elements) != 1:
error_msg = "expected 1 and only one test-definitions tag"
raise errors.ParseError(msg=error_msg)
return root_elements[0]
def _AddTest(self, test):
"""Adds a test to this TestManifest.
If a test already exists with the same name, it overrides it.
Args:
test: TestSuite to add
"""
if self.GetTest(test.GetName()) is not None:
logger.SilentLog("Overriding test definition %s" % test.GetName())
self._testname_map[test.GetName()] = test
def GetTests(self):
return self._testname_map.values()
def GetContinuousTests(self):
con_tests = []
for test in self.GetTests():
if test.IsContinuous():
con_tests.append(test)
return con_tests
def GetTestsInSuite(self, suite):
"""Return list of tests in given suite."""
return [t for t in self.GetTests() if t.GetSuite() == suite]
def GetTest(self, name):
return self._testname_map.get(name, None)
def Parse(file_path):
"""Parses out a TestDefinitions from given path to xml file.
Args:
file_path: string absolute file path
Returns:
a TestDefinitions object containing data parsed from file_path
Raises:
ParseError if xml format is not recognized
"""
tests_result = TestDefinitions()
tests_result.Parse(file_path)
return tests_result