Make coverage work without test defs.
Change-Id: I946df038e97dc5c2f40a4610d4076e13ab6bde37
diff --git a/testrunner/coverage/coverage_targets.py b/testrunner/coverage/coverage_targets.py
new file mode 100644
index 0000000..a627671
--- /dev/null
+++ b/testrunner/coverage/coverage_targets.py
@@ -0,0 +1,128 @@
+#!/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.
+import xml.dom.minidom
+import xml.parsers
+import os
+
+
+import coverage_target
+import logger
+import errors
+
+class CoverageTargets:
+ """Accessor for the code coverage target xml file
+ Expects the following format:
+ <targets>
+ <target
+ name=""
+ type="JAVA_LIBRARIES|APPS"
+ build_path=""
+
+ [<src path=""/>] (0..*) - These are relative to build_path. If missing,
+ assumes 'src'
+ >/target>
+
+ TODO: add more format checking
+ """
+
+ _TARGET_TAG_NAME = 'coverage_target'
+ _NAME_ATTR = 'name'
+ _TYPE_ATTR = 'type'
+ _BUILD_ATTR = 'build_path'
+ _SRC_TAG = 'src'
+ _PATH_ATTR = 'path'
+
+ def __init__(self, ):
+ self._target_map= {}
+
+ def __iter__(self):
+ return iter(self._target_map.values()
+
+ def Parse(self, file_path):
+ """Parse the coverage target data from from given file path, and add it to
+ the current object
+ Args:
+ file_path: absolute file path to parse
+ Raises:
+ errors.ParseError if file_path cannot be parsed
+ """
+ try:
+ doc = xml.dom.minidom.parse(file_path)
+ except IOError:
+ # Error: The results file does not exist
+ logger.Log('Results 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
+
+ target_elements = doc.getElementsByTagName(self._TARGET_TAG_NAME)
+
+ for target_element in target_elements:
+ target = coverage_target.CoverageTarget()
+ self._ParseCoverageTarget(target, target_element)
+ self._AddTarget(target)
+
+ def _AddTarget(self, target):
+ self._target_map[target.GetName()] = target
+
+ def GetBuildTargets(self):
+ """ returns list of target names """
+ build_targets = []
+ for target in self:
+ build_targets.append(target.GetName())
+ return build_targets
+
+ def GetTargets(self):
+ """ returns list of CoverageTarget"""
+ return self._target_map.values()
+
+ def GetTarget(self, name):
+ """ returns CoverageTarget for given name. None if not found """
+ try:
+ return self._target_map[name]
+ except KeyError:
+ return None
+
+ def _ParseCoverageTarget(self, target, target_element):
+ """Parse coverage data from XML.
+
+ Args:
+ target: the Coverage object to populate
+ target_element: the XML element to get data from
+ """
+ target.SetName(target_element.getAttribute(self._NAME_ATTR))
+ target.SetType(target_element.getAttribute(self._TYPE_ATTR))
+ target.SetBuildPath(target_element.getAttribute(self._BUILD_ATTR))
+ self._paths = []
+ self._ParsePaths(target, target_element)
+
+ def _ParsePaths(self, target, target_element):
+ src_elements = target_element.getElementsByTagName(self._SRC_TAG)
+ if len(src_elements) <= 0:
+ # no src tags specified. Assume build_path + src
+ target.AddPath(os.path.join(target.GetBuildPath(), "src"))
+ for src_element in src_elements:
+ rel_path = src_element.getAttribute(self._PATH_ATTR)
+ target.AddPath(os.path.join(target.GetBuildPath(), rel_path))
+
+
+def Parse(xml_file_path):
+ """parses out a file_path class from given path to xml"""
+ targets = CoverageTargets()
+ targets.Parse(xml_file_path)
+ return targets