Quellcodebibliothek Statistik Leitseite products/Sources/formale Sprachen/C/Firefox/testing/mochitest/   (Browser von der Mozilla Stiftung Version 136.0.1©)  Datei vom 10.2.2025 mit Größe 11 kB image not shown  

SSL bisection.py   Sprache: Python

 
import math

import mozinfo


class Bisect(object):
    "Class for creating, bisecting and summarizing for --bisect-chunk option."

    def __init__(self, harness):
        super(Bisect, self).__init__()
        self.summary = []
        self.contents = {}
        self.repeat = 10
        self.failcount = 0
        self.max_failures = 3

    def setup(self, tests):
        """This method is used to initialize various variables that are required
        for test bisection"""
        status = 0
        self.contents.clear()
        # We need totalTests key in contents for sanity check
        self.contents["totalTests"] = tests
        self.contents["tests"] = tests
        self.contents["loop"] = 0
        return status

    def reset(self, expectedError, result):
        """This method is used to initialize self.expectedError and self.result
        for each loop in runtests."""
        self.expectedError = expectedError
        self.result = result

    def get_tests_for_bisection(self, options, tests):
        """Make a list of tests for bisection from a given list of tests"""
        bisectlist = []
        for test in tests:
            bisectlist.append(test)
            if test.endswith(options.bisectChunk):
                break

        return bisectlist

    def pre_test(self, options, tests, status):
        """This method is used to call other methods for setting up variables and
        getting the list of tests for bisection."""
        if options.bisectChunk == "default":
            return tests
        # The second condition in 'if' is required to verify that the failing
        # test is the last one.
        elif "loop" not in self.contents or not self.contents["tests"][-1].endswith(
            options.bisectChunk
        ):
            tests = self.get_tests_for_bisection(options, tests)
            status = self.setup(tests)

        return self.next_chunk_binary(options, status)

    def post_test(self, options, expectedError, result):
        """This method is used to call other methods to summarize results and check whether a
        sanity check is done or not."""
        self.reset(expectedError, result)
        status = self.summarize_chunk(options)
        # Check whether sanity check has to be done. Also it is necessary to check whether
        # options.bisectChunk is present in self.expectedError as we do not want to run
        # if it is "default".
        if status == -1 and options.bisectChunk in self.expectedError:
            # In case we have a debug build, we don't want to run a sanity
            # check, will take too much time.
            if mozinfo.info["debug"]:
                return status

            testBleedThrough = self.contents["testsToRun"][0]
            tests = self.contents["totalTests"]
            tests.remove(testBleedThrough)
            # To make sure that the failing test is dependent on some other
            # test.
            if options.bisectChunk in testBleedThrough:
                return status

            status = self.setup(tests)
            self.summary.append("Sanity Check:")

        return status

    def next_chunk_reverse(self, options, status):
        "This method is used to bisect the tests in a reverse search fashion."

        # Base Cases.
        if self.contents["loop"] <= 1:
            self.contents["testsToRun"] = self.contents["tests"]
            if self.contents["loop"] == 1:
                self.contents["testsToRun"] = [self.contents["tests"][-1]]
            self.contents["loop"] += 1
            return self.contents["testsToRun"]

        if "result" in self.contents:
            if self.contents["result"] == "PASS":
                chunkSize = self.contents["end"] - self.contents["start"]
                self.contents["end"] = self.contents["start"] - 1
                self.contents["start"] = self.contents["end"] - chunkSize

            # self.contents['result'] will be expected error only if it fails.
            elif self.contents["result"] == "FAIL":
                self.contents["tests"] = self.contents["testsToRun"]
                status = 1  # for initializing

        # initialize
        if status:
            totalTests = len(self.contents["tests"])
            chunkSize = int(math.ceil(totalTests / 10.0))
            self.contents["start"] = totalTests - chunkSize - 1
            self.contents["end"] = totalTests - 2

        start = self.contents["start"]
        end = self.contents["end"] + 1
        self.contents["testsToRun"] = self.contents["tests"][start:end]
        self.contents["testsToRun"].append(self.contents["tests"][-1])
        self.contents["loop"] += 1

        return self.contents["testsToRun"]

    def next_chunk_binary(self, options, status):
        "This method is used to bisect the tests in a binary search fashion."

        # Base cases.
        if self.contents["loop"] <= 1:
            self.contents["testsToRun"] = self.contents["tests"]
            if self.contents["loop"] == 1:
                self.contents["testsToRun"] = [self.contents["tests"][-1]]
            self.contents["loop"] += 1
            return self.contents["testsToRun"]

        # Initialize the contents dict.
        if status:
            totalTests = len(self.contents["tests"])
            self.contents["start"] = 0
            self.contents["end"] = totalTests - 2

        # pylint --py3k W1619
        mid = (self.contents["start"] + self.contents["end"]) / 2
        if "result" in self.contents:
            if self.contents["result"] == "PASS":
                self.contents["end"] = mid

            elif self.contents["result"] == "FAIL":
                self.contents["start"] = mid + 1

        mid = (self.contents["start"] + self.contents["end"]) / 2
        start = mid + 1
        end = self.contents["end"] + 1
        self.contents["testsToRun"] = self.contents["tests"][start:end]
        if not self.contents["testsToRun"]:
            self.contents["testsToRun"].append(self.contents["tests"][mid])
        self.contents["testsToRun"].append(self.contents["tests"][-1])
        self.contents["loop"] += 1

        return self.contents["testsToRun"]

    def summarize_chunk(self, options):
        "This method is used summarize the results after the list of tests is run."
        if options.bisectChunk == "default":
            # if no expectedError that means all the tests have successfully
            # passed.
            if len(self.expectedError) == 0:
                return -1
            options.bisectChunk = self.expectedError.keys()[0]
            self.summary.append("\tFound Error in test: %s" % options.bisectChunk)
            return 0

        # If options.bisectChunk is not in self.result then we need to move to
        # the next run.
        if options.bisectChunk not in self.result:
            return -1

        self.summary.append("\tPass %d:" % self.contents["loop"])
        if len(self.contents["testsToRun"]) > 1:
            self.summary.append(
                "\t\t%d test files(start,end,failing). [%s, %s, %s]"
                % (
                    len(self.contents["testsToRun"]),
                    self.contents["testsToRun"][0],
                    self.contents["testsToRun"][-2],
                    self.contents["testsToRun"][-1],
                )
            )
        else:
            self.summary.append("\t\t1 test file [%s]" % self.contents["testsToRun"][0])
            return self.check_for_intermittent(options)

        if self.result[options.bisectChunk] == "PASS":
            self.summary.append("\t\tno failures found.")
            if self.contents["loop"] == 1:
                status = -1
            else:
                self.contents["result"] = "PASS"
                status = 0

        elif self.result[options.bisectChunk] == "FAIL":
            if "expectedError" not in self.contents:
                self.summary.append("\t\t%s failed." % self.contents["testsToRun"][-1])
                self.contents["expectedError"] = self.expectedError[options.bisectChunk]
                status = 0

            elif (
                self.expectedError[options.bisectChunk]
                == self.contents["expectedError"]
            ):
                self.summary.append(
                    "\t\t%s failed with expected error."
                    % self.contents["testsToRun"][-1]
                )
                self.contents["result"] = "FAIL"
                status = 0

                # This code checks for test-bleedthrough. Should work for any
                # algorithm.
                numberOfTests = len(self.contents["testsToRun"])
                if numberOfTests < 3:
                    # This means that only 2 tests are run. Since the last test
                    # is the failing test itself therefore the bleedthrough
                    # test is the first test
                    self.summary.append(
                        "TEST-UNEXPECTED-FAIL | %s | Bleedthrough detected, this test is the "
                        "root cause for many of the above failures"
                        % self.contents["testsToRun"][0]
                    )
                    status = -1
            else:
                self.summary.append(
                    "\t\t%s failed with different error."
                    % self.contents["testsToRun"][-1]
                )
                status = -1

        return status

    def check_for_intermittent(self, options):
        "This method is used to check whether a test is an intermittent."
        if self.result[options.bisectChunk] == "PASS":
            self.summary.append(
                "\t\tThe test %s passed." % self.contents["testsToRun"][0]
            )
            if self.repeat > 0:
                # loop is set to 1 to again run the single test.
                self.contents["loop"] = 1
                self.repeat -= 1
                return 0
            else:
                if self.failcount > 0:
                    # -1 is being returned as the test is intermittent, so no need to bisect
                    # further.
                    return -1
                # If the test does not fail even once, then proceed to next chunk for bisection.
                # loop is set to 2 to proceed on bisection.
                self.contents["loop"] = 2
                return 1
        elif self.result[options.bisectChunk] == "FAIL":
            self.summary.append(
                "\t\tThe test %s failed." % self.contents["testsToRun"][0]
            )
            self.failcount += 1
            self.contents["loop"] = 1
            self.repeat -= 1
            # self.max_failures is the maximum number of times a test is allowed
            # to fail to be called an intermittent. If a test fails more than
            # limit set, it is a perma-fail.
            if self.failcount < self.max_failures:
                if self.repeat == 0:
                    # -1 is being returned as the test is intermittent, so no need to bisect
                    # further.
                    return -1
                return 0
            else:
                self.summary.append(
                    "TEST-UNEXPECTED-FAIL | %s | Bleedthrough detected, this test is the "
                    "root cause for many of the above failures"
                    % self.contents["testsToRun"][0]
                )
                return -1

    def print_summary(self):
        "This method is used to print the recorded summary."
        print("Bisection summary:")
        for line in self.summary:
            print(line)

91%


¤ Dauer der Verarbeitung: 0.51 Sekunden  (vorverarbeitet)  ¤

*© Formatika GbR, Deutschland






Wurzel

Suchen

Beweissystem der NASA

Beweissystem Isabelle

NIST Cobol Testsuite

Cephes Mathematical Library

Wiener Entwicklungsmethode

Haftungshinweis

Die Informationen auf dieser Webseite wurden nach bestem Wissen sorgfältig zusammengestellt. Es wird jedoch weder Vollständigkeit, noch Richtigkeit, noch Qualität der bereit gestellten Informationen zugesichert.

Bemerkung:

Die farbliche Syntaxdarstellung ist noch experimentell.