10d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya#!/usr/bin/env python
20d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya"""
30d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    An LTP [execution and] parsing wrapper.
40d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
50d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    Used as a second layer for ease-of-use with users as many developers
60d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    complain about complexity involved with trying to use LTP in my
70d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    organization -_-.
80d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
98967f960f820f449162101a02ee5747f195a8a57Ngie Cooper    Copyright (C) 2009-2012, Ngie Cooper
100d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
110d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    This program is free software; you can redistribute it and/or modify
120d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    it under the terms of the GNU General Public License as published by
130d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    the Free Software Foundation; either version 2 of the License, or
140d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    (at your option) any later version.
150d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
160d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    This program is distributed in the hope that it will be useful,
170d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    but WITHOUT ANY WARRANTY; without even the implied warranty of
180d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
190d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    GNU General Public License for more details.
200d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
210d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    You should have received a copy of the GNU General Public License along
220d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    with this program; if not, write to the Free Software Foundation, Inc.,
230d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
240d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya"""
250d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
26fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper
270d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneyafrom optparse import OptionGroup, OptionParser
28fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooperimport os
29fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooperimport re
30fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooperimport sys
31fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper
320d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
330d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneyaclass ResultsParseException(Exception):
340d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    """ Extended class for parsing LTP results. """
350d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
36fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper
370d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneyadef parse_ltp_results(exec_log, output_log, verbose=0):
38fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper    """Function for parsing LTP results.
390d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
400d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    1. The exec log is the log with the results in summary form.
410d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
420d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    And now a note from our sponsors about exec logs...
430d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
440d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    startup='Thu Oct  1 06:42:07 2009'
450d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    tag=abort01 stime=1254379327 dur=2 exit=exited stat=0 core=no cu=0 cs=16
460d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    tag=accept01 stime=1254379329 dur=0 exit=exited stat=0 core=no cu=1 cs=0
470d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    tag=access01 stime=1254379329 dur=0 exit=exited stat=0 core=no cu=0 cs=0
480d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    tag=access02 stime=1254379329 dur=0 exit=exited stat=0 core=no cu=0 cs=0
490d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    tag=access03 stime=1254379329 dur=1 exit=exited stat=0 core=no cu=0 cs=1
500d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
510d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    [...]
520d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
530d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    a. tag is the test tag name.
540d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    b. stime is the system time at the start of the exec.
550d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    c. dur is the total duration of the test.
560d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    d. exit tells you what the result was. Valid values are:
570d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya       - exited
580d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya       - signaled
590d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya       - stopped
600d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya       - unknown
610d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya       See run_child in pan.c.
620d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    e. stat is the exit status.
630d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    f. core answers the question: `did I dump core?'.
640d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    g. cu is the cutime (cumulative user time).
650d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    h. cs is the cstime (cumulative system time).
660d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
670d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    2. The output log is the log with all of the terse results.
680d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    3. verbose tells us whether or not we need to include the passed results.
690d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    """
700d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
710d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    if not os.access(exec_log, os.R_OK):
720d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        raise ResultsParseException("Exec log - %s - specified doesn't exist"
730d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                    % exec_log)
740d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    elif 1 < verbose and not os.access(output_log, os.R_OK):
750d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        # Need the output log for context to the end user.
760d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        raise ResultsParseException("Output log - %s - specified doesn't exist"
77fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper                                    % output_log)
780d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
790d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    context = None
800d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
81fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper    failed = []
820d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    passed = 0
830d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
840d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    if 2 <= verbose:
85fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper        passed = []
860d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
87fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper    target_vals = ('exited', '0', 'no')
880d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
890d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    fd = open(exec_log, 'r')
900d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
910d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    try:
920d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        content = fd.read()
930d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        matches = re.finditer('tag=(?P<tag>\w+).+exit=(?P<exit>\w+) '
940d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                              'stat=(?P<stat>\d+) core=(?P<core>\w+)', content)
950d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    finally:
960ab3aacfd035ca96ba0f5fd8aef77bbf5f08ee41Garrett Cooper        content = None
970d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        fd.close()
980d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
990d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    if not matches:
1000d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        raise ResultsParseException("No parseable results were found in the "
101fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper                                    "exec log - `%s'." % exec_log)
1020d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1030d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    for match in matches:
1040d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1050d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        if ((match.group('exit'), match.group('stat'), match.group('core')) !=
1060d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya             target_vals):
1070d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            failed.append(match.group('tag'))
1080d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        elif 2 <= verbose:
1090d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            passed.append(match.group('tag'))
1100d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        else:
1110d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            passed += 1
1120d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1130d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    # Save memory on large files because lists can eat up a fair amount of
1140d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    # memory.
1150d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    matches = None
1160d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1170d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    if 1 <= verbose:
1180d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
119fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper        context = {}
1200d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1210d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        search_tags = failed[:]
1220d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1230d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        if 2 <= verbose:
1240d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            search_tags += passed
1250d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1260d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        search_tags.sort()
1270d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1280d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        fd = open(output_log, 'r')
1290d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1300d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        try:
1310d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1320ab3aacfd035ca96ba0f5fd8aef77bbf5f08ee41Garrett Cooper            line_iterator = getattr(fd, 'xreadlines', getattr(fd, 'readlines'))
1330d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1340d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            end_output = '<<<execution_status>>>'
1350d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            output_start = '<<<test_output>>>'
1360d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1370d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            tag_re = re.compile('tag=(\w+)')
1380d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1390d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            grab_output = False
1400d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1410d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            local_context = ''
1420d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1430d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            search_tag = None
1440d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
145bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya            try:
146bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya
147bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                while True:
148bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya
149bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                    line = line_iterator.next()
1500d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
151bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                    if line.startswith(end_output):
1520d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
153bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                        if search_tag:
154bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                            context[search_tag] = local_context
1550d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
156bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                        grab_output = False
157bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                        local_context = ''
158bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                        search_tag = None
1590d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
160bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                    if not search_tag:
1610d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
162bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                        while True:
1630d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
164bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                            line = line_iterator.next()
1650d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
166bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                            match = tag_re.match(line)
1670d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
168bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                            if match and match.group(1) in search_tags:
169bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                                search_tag = match.group(1)
170bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                                break
1710d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
172bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                    elif line.startswith(output_start):
173bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                        grab_output = True
174bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                    elif grab_output:
175bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                        local_context += line
1760d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
177bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya            except StopIteration:
178bbfbd512abb9592bb22480a38793cf1b99d512d2yaberauneya                pass
1790d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1800d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            for k in context.keys():
1810d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                if k not in search_tags:
1820d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                    raise ResultsParseException('Leftover token in search '
1830d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                                'keys: %s' % k)
1840d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1850ab3aacfd035ca96ba0f5fd8aef77bbf5f08ee41Garrett Cooper        except Exception as exc:
1860d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            # XXX (garrcoop): change from Exception to soft error and print
1870d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            # out warning with logging module.
1880d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            raise ResultsParseException('Encountered exception reading output '
1890d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                        'for context: %s' % str(exc))
1900ab3aacfd035ca96ba0f5fd8aef77bbf5f08ee41Garrett Cooper        finally:
1910ab3aacfd035ca96ba0f5fd8aef77bbf5f08ee41Garrett Cooper            fd.close()
1920d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1930d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    return failed, passed, context
1940d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
195fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper
1960d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneyadef determine_context(output_log, testsuite, test_set, context):
197fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper    """Return a set of context values mapping test_set -> context."""
1980d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
1990d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    test_set_context = {}
2000d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
2010d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    for test in test_set:
2020d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
2030d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        if test in context:
2040d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            test_context = context[test]
2050d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            del context[test]
2060d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        else:
2070d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            test_context = ('Could not determine context for %s; please see '
2080d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                            'output log - %s' % (test, output_log))
2090d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
2100d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        test_set_context['%s : %s' % (testsuite, test)] = test_context
2110d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
2120d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    return test_set_context
2130d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
214fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper
2150d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneyadef print_context(output_dest, header, testsuite_context):
216fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper    """Print out testsuite_context to output_dest, heading it up with
217fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper       header.
2180d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    """
219fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper
2200d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    output_dest.write('\n'.join(['', '=' * 40, header, '-' * 40, '']))
2210d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
2220d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    for test, context in testsuite_context.items():
2230d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        output_dest.write('<output test="%s">\n%s\n</output>\n' %
2240d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                          (test, context.strip()))
2250d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
226fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper
2270d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneyadef main():
228fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper    """main"""
2290d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
2300d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    parser = OptionParser(prog=os.path.basename(sys.argv[0]),
2310d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                          usage='usage: %prog [options] test ...',
2327324c3ab6ebdf26f5c8252b776ba2be77ade7011Garrett Cooper                          version='0.0.2')
2330d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
2340d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    ltpdir = os.getenv('LTPROOT', '@prefix@')
2350d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
2360d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    parser.add_option('-l', '--ltp-dir', dest='ltp_dir',
2370d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                      default=ltpdir, help='LTP directory [default: %default]')
2380d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    parser.add_option('-L', '--log-dir', dest='log_dir',
2390d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                      default=None,
2400d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                      help=('directory for [storing and] retrieving logs '
2410d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                            '[default: %s/output]' % ltpdir),
2420d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                      metavar='DIR')
2430d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    parser.add_option('-p', '--postprocess-only', dest='postprocess_only',
2440d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                      default=False, action='store_true',
2450d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                      help=("Don't execute runltp; just postprocess logs "
2460d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                            "[default: %default]."))
2470d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    parser.add_option('-o', '--output-file', dest='output_file',
2480d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                      default=None,
2490d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                      help='File to output results')
2500d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    parser.add_option('-r', '--runltp-opts', dest='runltp_opts',
2510d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                      default='',
2520d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                      help=('options to pass directly to runltp (will '
2530d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                            'suppress -q).'))
2540d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
2550d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    group = OptionGroup(parser, 'Logging',
2560d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        'If --summary-mode is 0, then the summary output is '
2570d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        'suppressed. '
2580d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        'If --summary-mode is 1 [the default], then summary '
2590d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        'output will be displayed for test execution'
2600d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        'If --summary-mode is 2, then summary output will be '
2610d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        'provided on a per-test suite basis. If only '
2620d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        'one test suite is specified, this has the same net '
2630d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        "effect as `--summary-mode 1'"
2640d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        'If --verbose is specified once, prints out failed '
2650d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        'test information with additional context. '
2660d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        'If --verbose is specified twice, prints out the '
2670d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        'failed and passed test context, as well as the '
2680d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        'summary.')
2690d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
2700d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    parser.add_option('-s', '--summary-mode', dest='summary_mode', default=1,
2710d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                      type='int',
2720d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                      help='See Logging.')
2730d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
2740d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    parser.add_option('-v', '--verbose', dest='verbose', default=0,
2750d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                      action='count',
2760d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                      help=('Increases context verbosity from tests. See '
2770d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                            'Verbosity for more details.'))
2780d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    parser.add_option_group(group)
2790d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
2800d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    group = OptionGroup(parser, 'Copyright',
281fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper                        '%(prog)s version %(version)s, Copyright (C) '
2828967f960f820f449162101a02ee5747f195a8a57Ngie Cooper                        '2009-2012, Ngie Cooper %(prog)s comes with '
283fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper                        'ABSOLUTELY NO WARRANTY; '
2840d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        'This is free software, and you are welcome to '
2850d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        'redistribute it under certain conditions (See the '
2860d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        'license tort in %(file)s for more details).'
2870d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        % { 'file'    : os.path.abspath(__file__),
2880d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                            'prog'    : parser.prog,
2890d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                            'version' : parser.version })
2900d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
2910d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    parser.add_option_group(group)
2920d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
2930d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    opts, args = parser.parse_args()
2940d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
295fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper    # Remove -q from the opts string, as long as it's a standalone option.
2960d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    runltp_opts = re.sub('^((?<!\S)+\-q\s+|\-q|\s+\-q(?!\S))$', '',
2970d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                         opts.runltp_opts)
2980d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
2990d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    if not opts.log_dir:
300fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper        opts.log_dir = os.path.join(opts.ltp_dir, 'output')
3010d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3020d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    if not opts.summary_mode and not opts.verbose:
3030d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        parser.error('You cannot suppress summary output and disable '
3040d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                     'verbosity.')
3050d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    elif opts.summary_mode not in range(3):
3060d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        parser.error('--summary-mode must be a value between 0 and 2.')
3070d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3080d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    if len(args) == 0:
3096607608d8d11449aae09fb5db155b4a2109d612fGarrett Cooper        # Default to scenarios also used by runltp.
310e7c107b20c87f7ae7792bb031529ecc8a431fffdDaniel Sangorrin        fd = open(os.path.join(ltpdir, 'scenario_groups/default'), 'r')
3117324c3ab6ebdf26f5c8252b776ba2be77ade7011Garrett Cooper        try:
312fdefef3202f679884edff85b86139ea6dda3813fCyril Hrubis            args = [l.strip() for l in fd.readlines()]
3137324c3ab6ebdf26f5c8252b776ba2be77ade7011Garrett Cooper        finally:
3147324c3ab6ebdf26f5c8252b776ba2be77ade7011Garrett Cooper            fd.close()
3150d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3160d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    if opts.output_file:
3170d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3180d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        output_dir = os.path.dirname(opts.output_file)
3190d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3200d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        if output_dir:
3210d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            # Not cwd; let's check to make sure that the directory does or
3220d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            # does not exist.
3230d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3240d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            if not os.path.exists(output_dir):
3250d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                # We need to make the directory.
3260d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                os.makedirs(os.path.dirname(opts.output_file))
3270d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            elif not os.path.isdir(os.path.abspath(output_dir)):
3280d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                # Path exists, but isn't a file. Oops!
3290d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                parser.error('Dirname for path specified - %s - is not valid'
3300d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                             % output_dir)
3310d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3320d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        else:
3330d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            # Current path (cwd)
3340d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            opts.output_file = os.path.join(os.getcwd(), opts.output_file)
3350d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3360d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        output_dest = open(opts.output_file, 'w')
3370d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3380d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    else:
3390d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3400d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        output_dest = sys.stdout
3410d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3420d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    try:
3430d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3440d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        failed_context = {}
3450d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        passed_context = {}
3460d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3470d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        failed_count = 0
3480d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        passed_count = 0
3490d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3500d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        if opts.summary_mode == 2 and len(args) == 1:
3510d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            opts.summary_mode = 1
3520d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3530d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        for testsuite in args:
3540d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3550d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            # Iterate over the provided test list
3560d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3570d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            context = {}
3580d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            exec_log = os.path.join(opts.log_dir, '%s-exec.log' % testsuite)
3590d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            output_log = os.path.join(opts.log_dir, ('%s-output.log'
3600d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                                     % testsuite))
3610d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3620d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            failed_subset = {}
3630d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3640d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            runtest_file = os.path.join(opts.ltp_dir, 'runtest', testsuite)
3650d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3660d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            if not opts.postprocess_only:
3670d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
368fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper                for log in [exec_log, output_log]:
3690d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                    if os.path.isfile(log):
3700d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                        os.remove(log)
3710d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3720d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                if not os.access(runtest_file, os.R_OK):
3730d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                    output_dest.write("%s doesn't exist; skipping "
3740d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                      "test\n" % runtest_file)
3750d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                    continue
3760d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
377fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper                os.system(' '.join([os.path.join(opts.ltp_dir, 'runltp'),
378fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper                                    runltp_opts, '-f', testsuite,
379fbd580ebd9e77308a49603efe91ac563d4dbef1aGarrett Cooper                                    '-l', exec_log, '-o', output_log]))
3800d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3810d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            try:
3820d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3830d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                failed_subset, passed_css, context = \
3840d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                    parse_ltp_results(exec_log, output_log,
3850d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                  verbose=opts.verbose)
3860d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3870ab3aacfd035ca96ba0f5fd8aef77bbf5f08ee41Garrett Cooper            except ResultsParseException as rpe:
3880d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                output_dest.write('Error encountered when parsing results for '
3890d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                  'test - %s: %s\n' % (testsuite, str(rpe)))
3900d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                continue
3910d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3920d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            failed_count += len(failed_subset)
3930d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3940d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            failed_subset_context = {}
3950d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            passed_subset_context = {}
3960d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
3970d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            if opts.verbose:
3980d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                failed_subset_context = determine_context(output_log,
3990d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                                          testsuite,
4000d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                                          failed_subset,
4010d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                                          context)
4020d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            if type(passed_css) == list:
4030d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4040d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                passed_count += len(passed_css)
4050d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4060d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                if opts.verbose == 2:
4070d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                    passed_subset_context = determine_context(output_log,
4080d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                                              testsuite,
4090d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                                              passed_css,
4100d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                                              context)
4110d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4120d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            else:
4130d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4140d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                passed_count += passed_css
4150d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4160d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            if opts.summary_mode == 1:
4170d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4180d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                failed_context.update(failed_subset_context)
4190d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                passed_context.update(passed_subset_context)
4200d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4210d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            else:
4220d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4230d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                if 1 <= opts.verbose:
4240d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                    # Print out failed testcases.
4250d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                    print_context(output_dest,
4260d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                  'FAILED TESTCASES for %s' % testsuite,
4270d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                  failed_subset_context)
4280d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4290d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                if opts.verbose == 2:
4300d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                    # Print out passed testcases with context.
4310d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                    print_context(output_dest,
4320d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                  'PASSED TESTCASES for %s' % testsuite,
4330d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                                  passed_subset_context)
4340d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4350d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                if opts.summary_mode == 2:
4360d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                    output_dest.write("""
4370d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya========================================
4380d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneyaSUMMARY for: %s
4390d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya----------------------------------------
4400d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneyaPASS - %d
4410d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneyaFAIL - %d
4420d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya----------------------------------------
4430d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya""" % (testsuite, passed_count, len(failed_subset)))
4440d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4450d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        if opts.summary_mode == 1:
4460d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4470d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            # Print out overall results.
4480d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4490d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            if 1 <= opts.verbose:
4500d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                # Print out failed testcases with context.
4510d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                print_context(output_dest, "FAILED TESTCASES", failed_context)
4520d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4530d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            if opts.verbose == 2:
4540d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                # Print out passed testcases with context.
4550d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya                print_context(output_dest, "PASSED TESTCASES", passed_context)
4560d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4570d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            output_dest.write("""
4580d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya========================================
4590d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneyaSUMMARY for tests:
4600d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya%s
4610d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya----------------------------------------
4620d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneyaPASS - %d
4630d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneyaFAIL - %d
4640d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya----------------------------------------
4650d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya""" % (' '.join(args), passed_count, failed_count))
4660d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4670d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    finally:
4680d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4690d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya        if output_dest != sys.stdout:
4700d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4710d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya            output_dest.close()
4720d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya
4730d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneyaif __name__ == '__main__':
4740d39b83926e9ea4b58cb44ffd2f9476088a3ca33yaberauneya    main()
475