This file is indexed.

/usr/lib/python3/dist-packages/behave/formatter/rerun.py is in python3-behave 1.2.5-2.

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
# -*- coding: utf-8 -*-
"""
Provides a formatter that simplifies to rerun the failing scenarios
of the last test run. It writes a text file with the file locations of
the failing scenarios, like:

    # -- file:rerun.features
    # RERUN: Failing scenarios during last test run.
    features/alice.feature:10
    features/alice.feature:42
    features/bob.feature:67

To rerun the failing scenarios, use:

    behave @rerun_failing.features

Normally, you put the RerunFormatter into the behave configuration file:

    # -- file:behave.ini
    [behave]
    format   = rerun
    outfiles = rerun_failing.features
"""


from behave.formatter.base import Formatter
from datetime import datetime
from os.path import relpath
import os


# -----------------------------------------------------------------------------
# CLASS: RerunFormatter
# -----------------------------------------------------------------------------
class RerunFormatter(Formatter):
    """
    Provides formatter class that emits a summary which scenarios failed
    during the last test run. This output can be used to rerun the tests
    with the failed scenarios.
    """
    name = "rerun"
    description = "Emits scenario file locations of failing scenarios"

    show_timestamp = False
    show_failed_scenarios_descriptions = False

    def __init__(self, stream_opener, config):
        super(RerunFormatter, self).__init__(stream_opener, config)
        self.failed_scenarios = []
        self.current_feature = None

    def reset(self):
        self.failed_scenarios = []
        self.current_feature = None

    # -- FORMATTER API:
    def feature(self, feature):
        self.current_feature = feature

    def eof(self):
        """Called at end of a feature."""
        if self.current_feature and self.current_feature.status == "failed":
            # -- COLLECT SCENARIO FAILURES:
            for scenario in self.current_feature.walk_scenarios():
                if scenario.status == "failed":
                    self.failed_scenarios.append(scenario)

        # -- RESET:
        self.current_feature = None
        assert self.current_feature is None

    def close(self):
        """Called at end of test run."""
        stream_name = self.stream_opener.name
        if self.failed_scenarios:
            # -- ENSURE: Output stream is open.
            self.stream = self.open()
            self.report_scenario_failures()
        elif stream_name and os.path.exists(stream_name):
            # -- ON SUCCESS: Remove last rerun file with its failures.
            os.remove(self.stream_opener.name)

        # -- FINALLY:
        self.close_stream()

    # -- SPECIFIC-API:
    def report_scenario_failures(self):
        assert self.failed_scenarios
        # -- SECTION: Banner
        message = "# -- RERUN: %d failing scenarios during last test run.\n"
        self.stream.write(message % len(self.failed_scenarios))
        if self.show_timestamp:
            now = datetime.now().replace(microsecond=0)
            self.stream.write("# NOW: %s\n"% now.isoformat(" "))

        # -- SECTION: Textual summary in comments.
        if self.show_failed_scenarios_descriptions:
            current_feature = None
            for index, scenario in enumerate(self.failed_scenarios):
                if current_feature != scenario.filename:
                    if current_feature is not None:
                        self.stream.write("#\n")
                    current_feature = scenario.filename
                    short_filename = relpath(scenario.filename, os.getcwd())
                    self.stream.write("# %s\n" % short_filename)
                self.stream.write("#  %4d:  %s\n" % \
                                  (scenario.line, scenario.name))
            self.stream.write("\n")

        # -- SECTION: Scenario file locations, ala: "alice.feature:10"
        for scenario in self.failed_scenarios:
            self.stream.write("%s\n" % scenario.location)
        self.stream.write("\n")