Home | History | Annotate | Download | only in coverage
      1 #!/usr/bin/python2.4
      2 #
      3 #
      4 # Copyright 2008, 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 import xml.dom.minidom
     18 import xml.parsers
     19 import os
     20 
     21 
     22 import coverage_target
     23 import logger
     24 import errors
     25 
     26 class CoverageTargets:
     27   """Accessor for the code coverage target xml file
     28   Expects the following format:
     29   <targets>
     30     <target
     31       name=""
     32       type="JAVA_LIBRARIES|APPS"
     33       build_path=""
     34 
     35       [<src path=""/>] (0..*)  - These are relative to build_path. If missing,
     36                                  assumes 'src'
     37     >/target>
     38 
     39     TODO: add more format checking
     40   """
     41 
     42   _TARGET_TAG_NAME = 'coverage_target'
     43   _NAME_ATTR = 'name'
     44   _TYPE_ATTR = 'type'
     45   _BUILD_ATTR = 'build_path'
     46   _SRC_TAG = 'src'
     47   _PATH_ATTR = 'path'
     48 
     49   def __init__(self, ):
     50     self._target_map= {}
     51 
     52   def __iter__(self):
     53     return iter(self._target_map.values())
     54 
     55   def Parse(self, file_path):
     56     """Parse the coverage target data from from given file path, and add it to
     57        the current object
     58        Args:
     59          file_path: absolute file path to parse
     60        Raises:
     61          errors.ParseError if file_path cannot be parsed
     62     """
     63     try:
     64       doc = xml.dom.minidom.parse(file_path)
     65     except IOError:
     66       # Error: The results file does not exist
     67       logger.Log('Results file %s does not exist' % file_path)
     68       raise errors.ParseError
     69     except xml.parsers.expat.ExpatError:
     70       logger.Log('Error Parsing xml file: %s ' %  file_path)
     71       raise errors.ParseError
     72 
     73     target_elements = doc.getElementsByTagName(self._TARGET_TAG_NAME)
     74 
     75     for target_element in target_elements:
     76       target = coverage_target.CoverageTarget()
     77       self._ParseCoverageTarget(target, target_element)
     78       self._AddTarget(target)
     79 
     80   def _AddTarget(self, target):
     81     self._target_map[target.GetName()] = target
     82 
     83   def GetBuildTargets(self):
     84     """ returns list of target names """
     85     build_targets = []
     86     for target in self:
     87       build_targets.append(target.GetName())
     88     return build_targets
     89 
     90   def GetTargets(self):
     91     """ returns list of CoverageTarget"""
     92     return self._target_map.values()
     93 
     94   def GetTarget(self, name):
     95     """ returns CoverageTarget for given name. None if not found """
     96     try:
     97       return self._target_map[name]
     98     except KeyError:
     99       return None
    100 
    101   def _ParseCoverageTarget(self, target, target_element):
    102     """Parse coverage data from XML.
    103 
    104     Args:
    105       target: the Coverage object to populate
    106       target_element: the XML element to get data from
    107     """
    108     target.SetName(target_element.getAttribute(self._NAME_ATTR))
    109     target.SetType(target_element.getAttribute(self._TYPE_ATTR))
    110     target.SetBuildPath(target_element.getAttribute(self._BUILD_ATTR))
    111     self._paths = []
    112     self._ParsePaths(target, target_element)
    113 
    114   def _ParsePaths(self, target, target_element):
    115     src_elements = target_element.getElementsByTagName(self._SRC_TAG)
    116     if len(src_elements) <= 0:
    117       # no src tags specified. Assume build_path + src
    118       target.AddPath(os.path.join(target.GetBuildPath(), "src"))
    119     for src_element in src_elements:
    120       rel_path = src_element.getAttribute(self._PATH_ATTR)
    121       target.AddPath(os.path.join(target.GetBuildPath(), rel_path))
    122 
    123 
    124 def Parse(xml_file_path):
    125   """parses out a file_path class from given path to xml"""
    126   targets = CoverageTargets()
    127   targets.Parse(xml_file_path)
    128   return targets
    129