This file is indexed.

/usr/lib/python2.7/dist-packages/rosunit/pyunit.py is in python-rosunit 1.14.2-1.

This file is owned by root:root, with mode 0o644.

The actual contents of the file can be viewed below.

  1
  2
  3
  4
  5
  6
  7
  8
  9
 10
 11
 12
 13
 14
 15
 16
 17
 18
 19
 20
 21
 22
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
# Software License Agreement (BSD License)
#
# Copyright (c) 2008, Willow Garage, Inc.
# All rights reserved.
#
# Redistribution and use in source and binary forms, with or without
# modification, are permitted provided that the following conditions
# are met:
#
#  * Redistributions of source code must retain the above copyright
#    notice, this list of conditions and the following disclaimer.
#  * Redistributions in binary form must reproduce the above
#    copyright notice, this list of conditions and the following
#    disclaimer in the documentation and/or other materials provided
#    with the distribution.
#  * Neither the name of Willow Garage, Inc. nor the names of its
#    contributors may be used to endorse or promote products derived
#    from this software without specific prior written permission.
#
# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
# FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
# COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
# INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
# BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES;
# LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER
# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
# LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN
# ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
# POSSIBILITY OF SUCH DAMAGE.
#
# Revision $Id$

"""
Wrapper for running Python unittest within rosunit/rostest framework.
"""
from __future__ import with_statement, print_function

import sys

from .core import create_xml_runner, XML_OUTPUT_FLAG
from .baretest import print_unittest_summary

def unitrun(package, test_name, test, sysargs=None, coverage_packages=None):
    """
    Wrapper routine from running python unitttests with
    JUnit-compatible XML output.  This is meant for unittests that do
    not not need a running ROS graph (i.e. offline tests only).

    This enables JUnit-compatible test reporting so that
    test results can be reported to higher-level tools.

    WARNING: unitrun() will trigger a sys.exit() on test failure in
    order to properly exit with an error code. This routine is meant
    to be used as a main() routine, not as a library.
    
    @param package: name of ROS package that is running the test
    @type  package: str
    @param test: a test case instance or a name resolving to a test case or suite
    @type  test: unittest.TestCase, or string
    @param coverage_packages: list of Python package to compute coverage results for. Defaults to package
    @type  coverage_packages: [str]
    @param sysargs: (optional) alternate sys.argv
    @type  sysargs: [str]
    """
    if sysargs is None:
        # lazy-init sys args
        import sys
        sysargs = sys.argv

    import unittest
    
    if coverage_packages is None:
        coverage_packages = [package]
        
    #parse sysargs
    result_file = None
    for arg in sysargs:
        if arg.startswith(XML_OUTPUT_FLAG):
            result_file = arg[len(XML_OUTPUT_FLAG):]
    text_mode = '--text' in sysargs

    coverage_mode = '--cov' in sysargs or '--covhtml' in sysargs
    if coverage_mode:
        start_coverage(coverage_packages)

    # create and run unittest suite with our xmllrunner wrapper
    suite = None
    if isinstance(test, str):
        suite = unittest.TestLoader().loadTestsFromName(test)
    else:
        # some callers pass a TestCase type (instead of an instance)
        suite = unittest.TestLoader().loadTestsFromTestCase(test)

    if text_mode:
        result = unittest.TextTestRunner(verbosity=2).run(suite)
    else:
        result = create_xml_runner(package, test_name, result_file).run(suite)
    if coverage_mode:
        cov_html_dir = 'covhtml' if '--covhtml' in sysargs else None
        stop_coverage(coverage_packages, html=cov_html_dir)

    # test over, summarize results and exit appropriately
    print_unittest_summary(result)
    
    if not result.wasSuccessful():
        import sys
        sys.exit(1)

# coverage instance
_cov = None
def start_coverage(packages):
    global _cov
    try:
        import coverage
        try:
            _cov = coverage.coverage()
            # load previous results as we need to accumulate
            _cov.load()
            _cov.start()
        except coverage.CoverageException:
            print("WARNING: you have an older version of python-coverage that is not support. Please update to the version provided by 'easy_install coverage'", file=sys.stderr)
    except ImportError as e:
        print("""WARNING: cannot import python-coverage, coverage tests will not run.
To install coverage, run 'easy_install coverage'""", file=sys.stderr)

def stop_coverage(packages, html=None):
    """
    @param packages: list of packages to generate coverage reports for
    @type  packages: [str]
    @param html: (optional) if not None, directory to generate html report to
    @type  html: str
    """
    if _cov is None:
        return
    import sys, os
    try:
        _cov.stop()
        # accumulate results
        _cov.save()
        
        # - update our own .coverage-modules file list for
        #   coverage-html tool. The reason we read and rewrite instead
        #   of append is that this does a uniqueness check to keep the
        #   file from growing unbounded
        if os.path.exists('.coverage-modules'):
            with open('.coverage-modules','r') as f:
                all_packages = set([x for x in f.read().split('\n') if x.strip()] + packages)
        else:
            all_packages = set(packages)
        with open('.coverage-modules','w') as f:
            f.write('\n'.join(all_packages)+'\n')
            
        try:
            # list of all modules for html report
            all_mods = []

            # iterate over packages to generate per-package console reports
            for package in packages:
                pkg = __import__(package)
                m = [v for v in sys.modules.values() if v and v.__name__.startswith(package)]
                all_mods.extend(m)

                # generate overall report and per module analysis
                _cov.report(m, show_missing=0)
                for mod in m:
                    res = _cov.analysis(mod)
                    print("\n%s:\nMissing lines: %s"%(res[0], res[3]))
                    
            if html:
                
                print("="*80+"\ngenerating html coverage report to %s\n"%html+"="*80)
                _cov.html_report(all_mods, directory=html)
        except ImportError as e:
            print("WARNING: cannot import '%s', will not generate coverage report"%package, file=sys.stderr)
    except ImportError as e:
        print("""WARNING: cannot import python-coverage, coverage tests will not run.
To install coverage, run 'easy_install coverage'""", file=sys.stderr)