This file is indexed.

/usr/lib/python2.7/dist-packages/sptest/output.py is in python-sptest 0.2.1-3.

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
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
# Copyright (C) 2008 Stephan Peijnik
#
# This file is part of sptest.
#
#  sptest is free software: you can redistribute it and/or modify     
#  it under the terms of the GNU General Public License as published by      
#  the Free Software Foundation, either version 3 of the License, or         
#  (at your option) any later version.                                       
#                                                                              
#  sptest is distributed in the hope that it will be useful,          
#  but WITHOUT ANY WARRANTY; without even the implied warranty of            
#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the             
#  GNU General Public License for more details.                             
#                                                                              
#  You should have received a copy of the GNU General Public License       
#  along with sptest.  If not, see <http://www.gnu.org/licenses/>.

import sys
import traceback

from datetime import datetime

## Used internally for checking whether xml.dom is available.
HAVE_XML = False

try:
    from xml.dom import getDOMImplementation
    HAVE_XML = True
except ImportError:
    pass

## Output class interface.
class IOutput(object):
    ## Constructor.
    # @param result TestResult object.
    # @param args Non-keyword arguments.
    # @param kwargs Keyword-arguments.
    def __init__(self, result, *args, **kwargs):
        ## TestResult object pointer.
        self.result = result

    ## Handler stub.
    # Called when the current module has changed.
    # @param module New module's name.
    def new_module(self, module):
        raise NotImplementedError()

    ## Handler stub.
    # Called when the current TestCase has changed.
    # @param module Module's name.
    # @param case New TestCase's name.
    def new_case(self, module, case):
        raise NotImplementedError()
    
    ## Handler stub.
    # Called when a test is started.
    # @param module Module's name.
    # @param case TestCase's name.
    # @param testname Test's name.
    def test_started(self, module, case, testname):
        raise NotImplementedError()

    ## Handler stub.
    # Called when a test's result is success.
    # @param module Module's name.
    # @param case TestCase's name.
    # @param testname Test's name.
    def test_success(self, module, case, testname):
        raise NotImplementedError()

    ## Handler stub.
    # Called when a test's result is failure.
    # @param module Module's name.
    # @param case TestCase's name.
    # @param testname Test's name.
    # @param error Tuple of error type, error info and error traceback.
    def test_failure(self, module, case, testname, error):
        raise NotImplementedError()

    ## Handler stub.
    # Called when a test's result is error.
    # @param module Module's name.
    # @param case TestCase's name.
    # @param testname Test's name.
    # @param error Tuple of error type, error info and error traceback. 
    def test_error(self, module, case, testname, error):
        raise NotImplementedError()

    ## Handler stub.
    # Called when all tests have finished.
    def done(self):
        raise NotImplementedError()

    ## Handler stub.
    # Called before prepare_func is called.
    def prepare(self):
        raise NotImplementedError()

    ## Handler stub.
    # Called before cleanup_func is called.
    def cleanup(self):
        raise NotImplementedError()

    ## Handler stub.
    # Called after cleanup_func has been called.
    def after_cleanup(self):
        raise NotImplementedError()

    ## Handler stub.
    # Called before executing the first test.
    def run(self):
        raise NotImplementedError()

## Fancy command line interface output (coloured).
class FancyCLIOutput(IOutput):
    ## Stub, does nothing.
    # @param module Module's name.
    def new_module(self, module):
        pass

    ## Handles a new test case.
    # @param module Module's name.
    # @param case TestCase's name.
    def new_case(self, module, case):
        # Only do this if it is not the first test case.
        if self.result.last_case != None:
            # move cursor up
            print '\x1b[%dF' % (self.result.tests_run_in_case+2)
            csi = ''
                
            if self.result.failures_in_case:
                csi = '\x1b[31;01m'
            elif self.result.errors_in_case:
                csi = '\x1b[33;01m'
            else:
                csi = '\x1b[32;01m'
                
            print '%s[%s.%s]\x1b[0m' % (csi, self.result.last_module,
                                            self.result.last_case)

            # move cursor back down
            print '\x1b[%dE' % (self.result.tests_run_in_case)

            
        if module and case:
            print '\x1b[34;01m[%s.%s]\x1b[0m' % (module, case)

    ## Handles starting of a test.
    # @param module Module's name.
    # @param case TestCase's name.
    # @param testname Test's name.
    def test_started(self, module, case, testname):
        print '\x1b[34;01m [R] %s...\x1b[0m\r' % (testname),
        sys.stdout.flush()

    ## Handles result of a test being success.
    # @param module Module's name.
    # @param case TestCase's name.
    # @param testname Test's name.
    def test_success(self, module, case, testname):
        print '\x1b[32;01m [S] %s   \x1b[0m' % (testname)

    ## Handles result of a test being failure.
    # @param module Module's name.
    # @param case TestCase's name.
    # @param testname Test's name.
    # @param errobj Tuple of error type, error info and error traceback.
    def test_failure(self, module, case, testname, errobj):
        print '\x1b[31;01m [F] %s   \x1b[0m' % (testname)

    ## Handles result of a test being error.
    # @param module Module's name.
    # @param case TestCase's name.
    # @param testname Test's name.
    # @param errobj Tuple of error type, error info and error traceback. 
    def test_error(self, module, case, testname, errobj):
        print '\x1b[33;01m [E] %s   \x1b[0m' % (testname)

    ## Handles all tests having finished.
    def done(self):
        self.new_case(None, None)

    ## Prints summary after cleanup.
    def after_cleanup(self):
        print '\x1b[01m>> Summary\x1b[0m'

        success_cnt = self.result.tests_success
        error_cnt = self.result.tests_error
        failure_cnt = self.result.tests_failure

        one_pc = 100/float(self.result.test_count)

        success_pc = one_pc*self.result.tests_success
        error_pc = one_pc*self.result.tests_error
        failure_pc = one_pc*self.result.tests_failure

        print '\x1b[32;01m success : %d [%.1f%%]\x1b[0m' % (success_cnt,
                                                            success_pc)
        print '\x1b[33;01m error   : %d [%.1f%%]\x1b[0m' % (error_cnt,
                                                            error_pc)
        print '\x1b[31;01m failure : %d [%.1f%%]\x1b[0m' % (failure_cnt,
                                                            failure_pc)
        ## Shared function for printing errors and failures.
        def print_details(d_list, d_csi, d_desc):
            print '\x1b[01m>> %s details\x1b[0m' % (d_desc)
            for (module, case, testname), (errtype, errstr, errtb) in d_list:
                print '%s [%s.%s] %s:\x1b[0m' % (d_csi, module, case,
                                                 testname)
                print '  - type      : %s' % (str(errtype))
                print '  - info      : %s' % (errstr)
                print '  - traceback :'
                tbinfo = traceback.extract_tb(errtb)
                for line in traceback.format_list(tbinfo):
                    # Ignore unittest-specific traceback info (useless).
                    if '/unittest.py' in line:
                        continue
                    print '    - %s' % (line)
                print ''

        if error_cnt > 0:
            print_details(self.result.errors, '\x1b[33;01m', 'Error')

        if failure_cnt > 0:
            print_details(self.result.failures, '\x1b[31;01m', 'Failure')

        print '\x1b[01m>> Done\x1b[0m'

    ## Prints info that tests are being prepared.
    def prepare(self):
        print '\x1b[01m>> Preparation\x1b[0m'

    ## Prints info that tests are being run.
    def run(self):
        print '\x1b[01m>> Tests\x1b[0m'

    ## Prints info that cleanup is being done.
    def cleanup(self):
        print '\x1b[1F\x1b[01m>> Cleanup\x1b[0m'

## XML Output handler class.
class _XMLOutput(IOutput):
    ## Constructor.
    # @param result TestResult object.
    # @param output_file File to write XML output to.
    # @param args Non-keyword arguments.
    # @param kwargs Keyword arguments.
    def __init__(self, result, output_file=None, *args, **kwargs):
        IOutput.__init__(self, result, *args, **kwargs)

        ## Output file object.
        self.fp = None
        ## XML element of current module.
        self.current_module = None
        ## XML element of current TestCase.
        self.current_case = None
        ## XML document.
        self.doc = None
        ## XML root element.
        self.xml_root = None
        
        if output_file:
            try:
                self.fp = open(output_file, 'w')
            except IOError, e:
                sys.stderr.write('Could not open %s for writing: %s' \
                                 % (output_file, e))
                sys.stderr.flush()
                sys.exit(1)
        else:
            self.fp = sys.stderr
    ## Handles a new test module.
    # @param module Module's name.
    def new_module(self, module):
        module_elem = self.doc.createElement('module')
        module_elem.setAttribute('name', module)
        self.xml_root.appendChild(module_elem)
        self.current_module = module_elem

    ## Handles a new test case.
    # @param module Module's name.
    # @param case TestCase's name.
    def new_case(self, module, case):
        case_elem = self.doc.createElement('case')
        case_elem.setAttribute('name', case)
        self.current_module.appendChild(case_elem)
        self.current_case = case_elem

    ## Stub, does nothing.
    # @param module Module's name.
    # @param case TestCase's name.
    # @param testname Test's name.
    def test_started(self, module, case, testname):
        pass

    ## Creates a 'test' XML element.
    # @param testname Test's name.
    # @param status Test's status.
    # @returns 'test' XML element.
    def _create_test_element(self, testname, status):
        test = self.doc.createElement('test')
        test.setAttribute('name', testname)
        test.setAttribute('status', status)
        self.current_case.appendChild(test)
        return test
    
    ## Creates XML elements for tests that failed/had an error.
    # @param elem_name Element name (error or failure).
    # @param test_elem Test XML element.
    # @param errobj Tuple of error type, error info and error traceback.
    def _test_element_add_error_or_failure(self, elem_name, test_elem, errobj):
        errtype, errstr, errtb = errobj
        elem = self.doc.createElement(elem_name)
        elem.setAttribute('type', str(errtype))
        elem.setAttribute('info', str(errstr))

        tbinfo = traceback.extract_tb(errtb)
        tbelem = self.doc.createElement('traceback')
        elem.appendChild(tbelem)
        for fname, lineno, funcname, text in tbinfo:
            if '/unittest.py' in fname:
                continue
            
            entryelem = self.doc.createElement('entry')
            entryelem.setAttribute('filename', fname)
            entryelem.setAttribute('linenumber', str(lineno))
            entryelem.setAttribute('function', funcname)
            textnode = self.doc.createTextNode(text)
            entryelem.appendChild(textnode)
            tbelem.appendChild(entryelem)
            
        test_elem.appendChild(elem)

    ## Handles result of a test being success.
    # @param module Module's name.
    # @param case TestCase's name.
    # @param testname Test's name.
    def test_success(self, module, case, testname):
        self._create_test_element(testname, 'success')

    ## Handles result of a test being failure.
    # @param module Module's name.
    # @param case TestCase's name.
    # @param testname Test's name.
    # @param errobj Tuple of error type, error info and error traceback.
    def test_failure(self, module, case, testname, errobj):
        test = self._create_test_element(testname, 'failure')
        self._test_element_add_error_or_failure('failure', test, errobj)

    ## Handles result of a test being error.
    # @param module Module's name.
    # @param case TestCase's name.
    # @param testname Test's name.
    # @param errobj Tuple of error type, error info and error traceback.
    def test_error(self, module, case, testname, errobj):
        test = self._create_test_element(testname, 'error')
        self._test_element_add_error_or_failure('error', test, errobj)

    ## Prints info that tests are being prepared and prepares XML document.
    def prepare(self):
        xmldoc = getDOMImplementation()
        self.doc = xmldoc.createDocument('', 'unittest', '')
        self.xml_root = self.doc.firstChild
        self.doc.appendChild(self.xml_root)
        self.xml_root.setAttribute('started', str(datetime.now()))
        self.current_module = None
        self.current_case = None
        print '>> Preparation'

    ## Stub, does nothing.
    def done(self):
        pass

    ## Prints info that cleanup is being done.
    def cleanup(self):
        print '>> Cleanup'

    ## Finished generation of XML document and writes it to file/stderr.
    def after_cleanup(self):
        self.xml_root.setAttribute('finished', str(datetime.now()))
        self.fp.write(self.doc.toprettyxml())
        self.fp.flush()
        if self.fp != sys.stderr:
            print '>> Written results to %s.' % (self.fp.name)
            self.fp.close()

    ## Prints info that tests are being run.
    def run(self):
        print '>> Tests'

## Set to _XMLOutput after checking that xml.dom is available (via HAVE_XML).
XMLOutput = IOutput

if HAVE_XML:
    XMLOutput = _XMLOutput