# Path: stestr/bisect_tests.py
# def bisect_tests(self, spurious_failures):
# 
#     test_conflicts = {}
#     if not spurious_failures:
#         raise ValueError('No failures provided to bisect the cause of')
#     for spurious_failure in spurious_failures:
#         candidate_causes = self._prior_tests(self.latest_run,
#                                              spurious_failure)
#         bottom = 0
#         top = len(candidate_causes)
#         width = top - bottom
#         while width:
#             check_width = int(math.ceil(width / 2.0))
#             test_ids = candidate_causes[
#                 bottom:bottom + check_width] + [spurious_failure]
#             cmd = self.conf.get_run_command(
#                 test_ids, group_regex=self.group_regex,
#                 repo_type=self.repo_type, repo_url=self.repo_url,
#                 serial=self.serial, concurrency=self.concurrency,
#                 test_path=self.test_path, top_dir=self.top_dir)
#             self.run_func(cmd, False,
#                           pretty_out=False,
#                           repo_type=self.repo_type,
#                           repo_url=self.repo_url)
#             # check that the test we're probing still failed - still
#             # awkward.
#             found_fail = []
# 
#             def find_fail(test_dict):
#                 if test_dict['id'] == spurious_failure:
#                     found_fail.append(True)
# 
#             checker = testtools.StreamToDict(find_fail)
#             checker.startTestRun()
#             try:
#                 self.repo.get_failing().get_test().run(checker)
#             finally:
#                 checker.stopTestRun()
#             if found_fail:
#                 # Our conflict is in bottom - clamp the range down.
#                 top = bottom + check_width
#                 if width == 1:
#                     # found the cause
#                     test_conflicts[
#                         spurious_failure] = candidate_causes[bottom]
#                     width = 0
#                 else:
#                     width = top - bottom
#             else:
#                 # Conflict in the range we did not run: discard bottom.
#                 bottom = bottom + check_width
#                 if width == 1:
#                     # there will be no more to check, so we didn't
#                     # reproduce the failure.
#                     width = 0
#                 else:
#                     width = top - bottom
#         if spurious_failure not in test_conflicts:
#             # Could not determine cause
#             test_conflicts[spurious_failure] = 'unknown - no conflicts'
#     if test_conflicts:
#         table = [('failing test', 'caused by test')]
#         for failure in sorted(test_conflicts):
#             causes = test_conflicts[failure]
#             table.append((failure, causes))
#         output.output_table(table)
#         return 3
#     return 0
# 
# Path: stestr/repository/abstract.py
# class AbstractRepositoryFactory:
# class AbstractRepository:
# class AbstractTestRun:
# class RepositoryNotFound(Exception):
#     def initialise(self, url):
#     def open(self, url):
#     def count(self):
#     def get_failing(self):
#     def get_run_ids(self):
#     def remove_run_id(self, run_id):
#     def get_inserter(self, partial=False, run_id=None, metadata=None):
#     def _get_inserter(self, partial=False, run_id=None, metadata=None):
#     def get_latest_run(self):
#     def get_test_run(self, run_id):
#     def get_test_times(self, test_ids):
#     def _get_test_times(self, test_ids):
#     def latest_id(self):
#     def get_test_ids(self, run_id):
#         def gather(test_dict):
#     def find_metadata(self, metadata):
#     def get_id(self):
#     def get_subunit_stream(self):
#     def get_test(self):
#     def get_metadata(self):
#     def __init__(self, url):
# 
# Path: stestr/tests/base.py
# class TestCase(testtools.TestCase):
#     def setUp(self):


import io
import operator
import subunit
import testtools
from unittest import mock
from stestr import bisect_tests
from stestr.repository import abstract
from stestr.tests import base
        run = FakeFailedTestRunWithTags()
        prior_tests = bisector._prior_tests(run, 'test_c')
        self.assertEqual(['test_a'], prior_tests)

    @mock.patch('stestr.output.output_table')
    def test_bisect_tests_isolated_failure(self, table_mock):
        run = FakeFailedTestRunWithTags()
        self.conf_mock.get_run_command = mock.MagicMock()

        def get_failures(*args, **kwargs):
            return FakeNoFailing()

        self.repo_mock.get_failing = get_failures
        bisector = bisect_tests.IsolationAnalyzer(
            run, self.conf_mock, self.run_func_mock, self.repo_mock)
        return_code = bisector.bisect_tests(['test_c'])
        expected_issue = [('failing test', 'caused by test'),
                          ('test_c', 'unknown - no conflicts')]
        table_mock.assert_called_once_with(expected_issue)
        self.assertEqual(3, return_code)

    @mock.patch('stestr.output.output_table')
    def test_bisect_tests_not_isolated_failure(self, table_mock):
        run = FakeFailedTestRunWithTags()
        self.conf_mock.get_run_command = mock.MagicMock()

        def get_failures(*args, **kwargs):
            return FakeFailingWithTags()

        self.repo_mock.get_failing = get_failures

# Path: stestr/bisect_tests.py
# def bisect_tests(self, spurious_failures):
# 
#     test_conflicts = {}
#     if not spurious_failures:
#         raise ValueError('No failures provided to bisect the cause of')
#     for spurious_failure in spurious_failures:
#         candidate_causes = self._prior_tests(self.latest_run,
#                                              spurious_failure)
#         bottom = 0
#         top = len(candidate_causes)
#         width = top - bottom
#         while width:
#             check_width = int(math.ceil(width / 2.0))
#             test_ids = candidate_causes[
#                 bottom:bottom + check_width] + [spurious_failure]
#             cmd = self.conf.get_run_command(
#                 test_ids, group_regex=self.group_regex,
#                 repo_type=self.repo_type, repo_url=self.repo_url,
#                 serial=self.serial, concurrency=self.concurrency,
#                 test_path=self.test_path, top_dir=self.top_dir)
#             self.run_func(cmd, False,
#                           pretty_out=False,
#                           repo_type=self.repo_type,
#                           repo_url=self.repo_url)
#             # check that the test we're probing still failed - still
#             # awkward.
#             found_fail = []
# 
#             def find_fail(test_dict):
#                 if test_dict['id'] == spurious_failure:
#                     found_fail.append(True)
# 
#             checker = testtools.StreamToDict(find_fail)
#             checker.startTestRun()
#             try:
#                 self.repo.get_failing().get_test().run(checker)
#             finally:
#                 checker.stopTestRun()
#             if found_fail:
#                 # Our conflict is in bottom - clamp the range down.
#                 top = bottom + check_width
#                 if width == 1:
#                     # found the cause
#                     test_conflicts[
#                         spurious_failure] = candidate_causes[bottom]
#                     width = 0
#                 else:
#                     width = top - bottom
#             else:
#                 # Conflict in the range we did not run: discard bottom.
#                 bottom = bottom + check_width
#                 if width == 1:
#                     # there will be no more to check, so we didn't
#                     # reproduce the failure.
#                     width = 0
#                 else:
#                     width = top - bottom
#         if spurious_failure not in test_conflicts:
#             # Could not determine cause
#             test_conflicts[spurious_failure] = 'unknown - no conflicts'
#     if test_conflicts:
#         table = [('failing test', 'caused by test')]
#         for failure in sorted(test_conflicts):
#             causes = test_conflicts[failure]
#             table.append((failure, causes))
#         output.output_table(table)
#         return 3
#     return 0
# 
# Path: stestr/repository/abstract.py
# class AbstractRepositoryFactory:
# class AbstractRepository:
# class AbstractTestRun:
# class RepositoryNotFound(Exception):
#     def initialise(self, url):
#     def open(self, url):
#     def count(self):
#     def get_failing(self):
#     def get_run_ids(self):
#     def remove_run_id(self, run_id):
#     def get_inserter(self, partial=False, run_id=None, metadata=None):
#     def _get_inserter(self, partial=False, run_id=None, metadata=None):
#     def get_latest_run(self):
#     def get_test_run(self, run_id):
#     def get_test_times(self, test_ids):
#     def _get_test_times(self, test_ids):
#     def latest_id(self):
#     def get_test_ids(self, run_id):
#         def gather(test_dict):
#     def find_metadata(self, metadata):
#     def get_id(self):
#     def get_subunit_stream(self):
#     def get_test(self):
#     def get_metadata(self):
#     def __init__(self, url):
# 
# Path: stestr/tests/base.py
# class TestCase(testtools.TestCase):
#     def setUp(self):


# Path: stestr/tests/test_bisect_tests.py
import io
import operator
import subunit
import testtools
from unittest import mock
from stestr import bisect_tests
from stestr.repository import abstract
from stestr.tests import base

        run = FakeFailedTestRunWithTags()
        prior_tests = bisector._prior_tests(run, 'test_c')
        self.assertEqual(['test_a'], prior_tests)

    @mock.patch('stestr.output.output_table')
    def test_bisect_tests_isolated_failure(self, table_mock):
        run = FakeFailedTestRunWithTags()
        self.conf_mock.get_run_command = mock.MagicMock()

        def get_failures(*args, **kwargs):
            return FakeNoFailing()

        self.repo_mock.get_failing = get_failures
        bisector = bisect_tests.IsolationAnalyzer(
            run, self.conf_mock, self.run_func_mock, self.repo_mock)
        return_code = bisector.bisect_tests(['test_c'])
        expected_issue = [('failing test', 'caused by test'),
                          ('test_c', 'unknown - no conflicts')]
        table_mock.assert_called_once_with(expected_issue)
        self.assertEqual(3, return_code)

    @mock.patch('stestr.output.output_table')
    def test_bisect_tests_not_isolated_failure(self, table_mock):
        run = FakeFailedTestRunWithTags()
        self.conf_mock.get_run_command = mock.MagicMock()

        def get_failures(*args, **kwargs):
            return FakeFailingWithTags()

        self.repo_mock.get_failing = get_failures

        bisector = bisect_tests.IsolationAnalyzer(