summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorZituo Jin <zituo.jin@mongodb.com>2022-01-06 01:03:46 +0000
committerEvergreen Agent <no-reply@evergreen.mongodb.com>2022-01-06 01:32:15 +0000
commitf6ee04d23017664482146e6f1db067c691767cc7 (patch)
tree2a82041b24cdba01173a1720e0cc0bfeeebf5100
parent8703ef72272bcb912f7f3763040e8db100913422 (diff)
downloadmongo-f6ee04d23017664482146e6f1db067c691767cc7.tar.gz
SERVER-62256 Remove bisect from mongo repo
-rw-r--r--buildscripts/resmokelib/bisect/__init__.py322
-rw-r--r--buildscripts/resmokelib/bisect/run_user_script.sh5
-rw-r--r--buildscripts/resmokelib/bisect/setup_test_env.sh7
-rw-r--r--buildscripts/resmokelib/bisect/teardown_test_env.sh3
-rw-r--r--buildscripts/resmokelib/cli.py4
-rw-r--r--buildscripts/resmokelib/parser.py2
-rw-r--r--buildscripts/tests/resmokelib/bisect/__init__.py1
-rw-r--r--buildscripts/tests/resmokelib/bisect/test_bisect.py59
8 files changed, 3 insertions, 400 deletions
diff --git a/buildscripts/resmokelib/bisect/__init__.py b/buildscripts/resmokelib/bisect/__init__.py
deleted file mode 100644
index e3cedcc1175..00000000000
--- a/buildscripts/resmokelib/bisect/__init__.py
+++ /dev/null
@@ -1,322 +0,0 @@
-"""Interactions with the resmoke bisect command."""
-import logging
-import os
-import subprocess
-import sys
-from datetime import datetime, timedelta, timezone
-
-import structlog
-from buildscripts.resmokelib.plugin import PluginInterface, Subcommand
-from buildscripts.resmokelib.utils import evergreen_conn
-
-LOGGER = structlog.getLogger(__name__)
-
-_HELP = """
-Perform an evergreen-aware git-bisect to find the 'last passing version' and 'first failing version'
-of mongo, with respect to a user provided shell script.
-"""
-
-_USAGE = """
-The 'bisect' command lets a user specify a '--branch', '--variant' & '--lookback' period on which to
-perform a bisect. The user also provides a shell test '--script' which exits with status code 0 to
-indicate a successful test. The command performs the following steps:
-
-(1) Get all versions for the given '--branch', '--variant' & '--lookback' period from Evergreen.
-(2) Filter the versions for versions that Evergreen has binaries and artifacts for.
-(3) Find the 'middle' version.
-(4) Setup a test environment.
- - The 'build/resmoke-bisect' directory will have a sub directory --
- 'build/resmoke-bisect/{version_id}' containing the git repo for this version.
- - The 'binaries' & 'artifacts' will also be downloaded to the directory named
- 'build/resmoke-bisect/{version_id}'.
- - Create a virtual environment at 'build/resmoke-bisect/bisect_venv' and
- install packages for this version.
-(5) Activate 'bisect_venv' & run the user provided shell script from within the
-'build/resmoke-bisect/{version_id}' directory.
-(6) Teardown the test environment.
-(7) Repeat steps (3)-(6) on the left half, if (5) failed, or right half, if (5) succeeded.
-
-This command will print the "Last Known Passing Version" & "First Known Failing Version".
-
-NOTE: This 'bisect' command assumes a perfect partition between passing & failing versions.
-ie: [Pass, Pass, Pass, Fail, Fail, Fail]
-If there is not a perfect partition, try modifying the '--lookback' period or shell '--script'.
-"""
-
-_COMMAND = "bisect"
-
-BISECT_DIR = os.path.dirname(os.path.abspath(__file__))
-SETUP_TEST_ENV_SH = os.path.join(BISECT_DIR, "setup_test_env.sh")
-TEARDOWN_TEST_ENV_SH = os.path.join(BISECT_DIR, "teardown_test_env.sh")
-RUN_USER_SCRIPT_SH = os.path.join(BISECT_DIR, "run_user_script.sh")
-RESMOKE_FILEPATH = os.path.join(os.path.dirname(os.path.dirname(BISECT_DIR)), "resmoke.py")
-
-
-def setup_logging(debug=False):
- """Enable logging."""
- log_level = logging.DEBUG if debug else logging.INFO
- logging.basicConfig(
- format="[%(asctime)s - %(name)s - %(levelname)s] %(message)s",
- level=log_level,
- stream=sys.stdout,
- )
- structlog.configure(logger_factory=structlog.stdlib.LoggerFactory())
-
-
-class Bisect(Subcommand): # pylint: disable=invalid-name
- """Main class for the Bisect subcommand."""
-
- def __init__(
- self,
- branch,
- lookback,
- variant,
- script,
- python_installation,
- evergreen_config=None,
- debug=None,
- ):
- """Initialize."""
- setup_logging(debug)
- self.branch = branch
- self.lookback = lookback
- self.variant = variant
- self.script = script
- self.python_installation = python_installation
- self.evergreen_config = evergreen_config
- self.evg_api = evergreen_conn.get_evergreen_api(evergreen_config)
-
- @staticmethod
- def _teardown_test_env(version):
- """Remove any directories added during testing process."""
- try:
- subprocess.run(["bash", TEARDOWN_TEST_ENV_SH], check=True)
- except subprocess.CalledProcessError as err:
- LOGGER.error("Could not teardown test environment for bisect.", version=version)
- raise err
- LOGGER.info("Completed teardown of test environment for bisect.", version=version)
-
- def _setup_test_env(self, version):
- """Set up a test environment for the given version."""
- try:
- subprocess.run(
- [
- "bash",
- SETUP_TEST_ENV_SH,
- self.python_installation,
- RESMOKE_FILEPATH,
- self.evergreen_config if self.evergreen_config else "",
- self.variant,
- version,
- ],
- check=True,
- )
- except subprocess.CalledProcessError:
- LOGGER.error("Could not setup test environment for bisect -- retrying.",
- version=version)
- try:
- subprocess.run(
- [
- "bash",
- SETUP_TEST_ENV_SH,
- self.python_installation,
- RESMOKE_FILEPATH,
- self.evergreen_config if self.evergreen_config else "",
- self.variant,
- version,
- ],
- check=True,
- )
- except subprocess.CalledProcessError as err:
- LOGGER.error("Could not setup test environment for bisect.", version=version)
- raise err
- LOGGER.info("Completed setup of test environment for bisect.", version=version)
-
- def _run_user_script(self, version):
- """Run the user script in a virtual environment."""
- return subprocess.run(["bash", RUN_USER_SCRIPT_SH, version, self.script],
- check=False).returncode
-
- def _test_version_with_script(self, version):
- """Test the given version with the user provided script."""
- self._setup_test_env(version)
- success = self._run_user_script(version)
- self._teardown_test_env(version)
- return success == 0
-
- def bisect(self, versions):
- """Bisect to find latest passing version assuming ordered by oldest to latest version."""
- if len(versions) == 0:
- return None
- midpoint = len(versions) // 2
- success = self._test_version_with_script(versions[midpoint])
- # if success, keep checking right
- if success:
- LOGGER.info(
- "Version passed user script.",
- version=versions[midpoint],
- )
- return self.bisect(versions[midpoint + 1:]) or versions[midpoint]
- # if fail, keep checking left
- else:
- LOGGER.info("Version failed user script.", version=versions[midpoint])
- return self.bisect(versions[0:midpoint])
-
- def find_versions_with_binaries(self):
- """
- Find versions that have binaries for the user provided variant in the lookback period.
-
- :return: List of versions that have binaries ordered from earliest to latest.
- """
- versions_with_binaries = []
- for version in self.evg_api.versions_by_project_time_window(
- project_id=f'mongodb-mongo-{"" if self.branch == "master" else "v"}{self.branch}',
- before=datetime.now(timezone.utc),
- after=datetime.now(timezone.utc) - timedelta(self.lookback),
- ):
- urls = evergreen_conn.get_compile_artifact_urls(self.evg_api, version, self.variant,
- ignore_failed_push=True)
- if urls.get("Artifacts") and urls.get("Binaries"):
- versions_with_binaries.append(version.revision)
-
- versions_with_binaries.reverse()
- return versions_with_binaries
-
- def execute(self):
- """
- Perform bisect for the provided branch, variant & lookback period based on result of script.
-
- Print the last passing version and first failing version.
- """
- versions_with_binaries = self.find_versions_with_binaries()
-
- # No versions found
- if not versions_with_binaries:
- LOGGER.info(
- "No versions with binaries found for given branch, variant & lookback period.",
- branch=self.branch,
- variant=self.variant,
- lookback=self.lookback,
- )
- exit(0)
-
- LOGGER.info("Performing bisect on the following versions: ",
- versions=versions_with_binaries)
-
- last_passing_version = self.bisect(versions_with_binaries)
- first_failing_version = None
-
- # All versions failed
- if last_passing_version is None:
- first_failing_version = versions_with_binaries[0]
- LOGGER.info("All versions in lookback period failed.")
-
- # All versions passed
- elif last_passing_version == versions_with_binaries[-1]:
- LOGGER.info("All versions in lookback period passed.")
-
- else:
- first_failing_version = versions_with_binaries[
- versions_with_binaries.index(last_passing_version) + 1]
-
- print(f"Last Known Passing Version: {last_passing_version}")
- print(f"First Known Failing Version: {first_failing_version}")
-
-
-class BisectPlugin(PluginInterface):
- """Interact with Resmoke bisect."""
-
- @classmethod
- def _add_args_to_parser(cls, parser):
- parser.add_argument(
- "--lookback",
- "-l",
- action="store",
- type=int,
- default=365,
- help="Maximum number of days to look back for versions to test.",
- )
- parser.add_argument(
- "--branch",
- "-b",
- action="store",
- type=str,
- required=True,
- help="The branch for which versions are being tested. [REQUIRED]",
- )
- parser.add_argument(
- "--variant",
- "-v",
- action="store",
- type=str,
- required=True,
- help="The variant for which versions are being tested. [REQUIRED]",
- )
- parser.add_argument(
- "--script",
- "-s",
- action="store",
- type=str,
- required=True,
- help="Location of the shell test script to run on the versions. [REQUIRED]",
- )
- parser.add_argument(
- "--python-installation",
- "-p",
- action="store",
- type=str,
- dest="python_installation",
- default="/opt/mongodbtoolchain/v3/bin/python3",
- required=False,
- help="Location of a python installation to use for shell commands. If not specified, "
- "it will use '/opt/mongodbtoolchain/v3/bin/python3' -- assuming this is being run on "
- "an Evergreen host. If this is being run from within a virtual env you can use "
- "'python' or 'python3'.",
- )
- parser.add_argument(
- "-ec",
- "--evergreenConfig",
- dest="evergreen_config",
- help="Location of evergreen configuration file. If not specified it will look "
- f"for it in the following locations: {evergreen_conn.EVERGREEN_CONFIG_LOCATIONS}",
- )
- parser.add_argument(
- "-d",
- "--debug",
- dest="debug",
- action="store_true",
- default=False,
- help="Set DEBUG logging level.",
- )
-
- def add_subcommand(self, subparsers):
- """
- Add 'bisect' subcommand.
-
- :param subparsers: argparse parser to add to.
- """
- parser = subparsers.add_parser(_COMMAND, usage=_USAGE, help=_HELP)
- self._add_args_to_parser(parser)
-
- def parse(self, subcommand, parser, parsed_args, **kwargs):
- """
- Return bisect if command is one we recognize.
-
- :param subcommand: equivalent to parsed_args.command
- :param parser: parser used
- :param parsed_args: output of parsing
- :param kwargs: additional args
- :return: None or a Subcommand
- """
- if subcommand != _COMMAND:
- return None
- args = parsed_args
- return Bisect(
- branch=args.branch,
- lookback=args.lookback,
- evergreen_config=args.evergreen_config,
- variant=args.variant,
- script=args.script,
- debug=args.debug,
- python_installation=args.python_installation,
- )
diff --git a/buildscripts/resmokelib/bisect/run_user_script.sh b/buildscripts/resmokelib/bisect/run_user_script.sh
deleted file mode 100644
index 3061aad9fb6..00000000000
--- a/buildscripts/resmokelib/bisect/run_user_script.sh
+++ /dev/null
@@ -1,5 +0,0 @@
-set -e
-source build/resmoke-bisect/bisect_venv/bin/activate
-cd build/resmoke-bisect/"$1"
-bash "$2"
-deactivate
diff --git a/buildscripts/resmokelib/bisect/setup_test_env.sh b/buildscripts/resmokelib/bisect/setup_test_env.sh
deleted file mode 100644
index 94b64e393df..00000000000
--- a/buildscripts/resmokelib/bisect/setup_test_env.sh
+++ /dev/null
@@ -1,7 +0,0 @@
-set -e
-"$1" "$2" setup-multiversion -ec "$3" -db -da -i build/resmoke-bisect -l build/resmoke-bisect/"$5" -v "$4" "$5"
-"$1" -m venv build/resmoke-bisect/bisect_venv
-source build/resmoke-bisect/bisect_venv/bin/activate
-"$1" -m pip install --upgrade pip
-"$1" -m pip install -r etc/pip/dev-requirements.txt
-deactivate
diff --git a/buildscripts/resmokelib/bisect/teardown_test_env.sh b/buildscripts/resmokelib/bisect/teardown_test_env.sh
deleted file mode 100644
index 31f43475ff6..00000000000
--- a/buildscripts/resmokelib/bisect/teardown_test_env.sh
+++ /dev/null
@@ -1,3 +0,0 @@
-set -e
-rm -rf build/resmoke-bisect
-rm -rf build/tmp
diff --git a/buildscripts/resmokelib/cli.py b/buildscripts/resmokelib/cli.py
index 6218412ea53..6743e62043b 100644
--- a/buildscripts/resmokelib/cli.py
+++ b/buildscripts/resmokelib/cli.py
@@ -17,5 +17,7 @@ def main(argv):
argv[1:], start_time=__start_time,
usage="Resmoke is MongoDB's correctness testing orchestrator.\n"
"For more information, see the help message for each subcommand.\n"
- "For example: resmoke.py run -h\n")
+ "For example: resmoke.py run -h\n"
+ "Note: bisect subcommand has been moved to db-contrib-tool (https://github.com/10gen/db-contrib-tool#readme).\n"
+ )
subcommand.execute()
diff --git a/buildscripts/resmokelib/parser.py b/buildscripts/resmokelib/parser.py
index 9442634edca..92452c68225 100644
--- a/buildscripts/resmokelib/parser.py
+++ b/buildscripts/resmokelib/parser.py
@@ -11,7 +11,6 @@ from buildscripts.resmokelib.run import RunPlugin
from buildscripts.resmokelib.setup_multiversion import SetupMultiversionPlugin
from buildscripts.resmokelib.symbolizer import SymbolizerPlugin
from buildscripts.resmokelib.undodb import UndoDbPlugin
-from buildscripts.resmokelib.bisect import BisectPlugin
_PLUGINS = [
RunPlugin(),
@@ -20,7 +19,6 @@ _PLUGINS = [
SetupMultiversionPlugin(),
PowercyclePlugin(),
SymbolizerPlugin(),
- BisectPlugin(),
GenerateFCVConstantsPlugin(),
]
diff --git a/buildscripts/tests/resmokelib/bisect/__init__.py b/buildscripts/tests/resmokelib/bisect/__init__.py
deleted file mode 100644
index 4b7a2bb941b..00000000000
--- a/buildscripts/tests/resmokelib/bisect/__init__.py
+++ /dev/null
@@ -1 +0,0 @@
-"""Empty."""
diff --git a/buildscripts/tests/resmokelib/bisect/test_bisect.py b/buildscripts/tests/resmokelib/bisect/test_bisect.py
deleted file mode 100644
index b3dab40b2ec..00000000000
--- a/buildscripts/tests/resmokelib/bisect/test_bisect.py
+++ /dev/null
@@ -1,59 +0,0 @@
-"""Unit tests for buildscripts/resmokelib/bisect."""
-# pylint: disable=missing-docstring
-# pylint: disable=no-self-use
-# pylint: disable=protected-access
-import unittest
-from os.path import exists
-
-import buildscripts.resmokelib.bisect as under_test
-
-
-def mock_run_test_script(arg):
- return "success" in arg
-
-
-class TestBisectBase(unittest.TestCase):
- def setUp(self):
- mock_bisect = under_test.Bisect(
- branch="mongodb-mongo-master",
- lookback=10,
- evergreen_config=None,
- variant="enterprise-macos",
- script="/file/path/to/test/shell/script",
- debug=None,
- python_installation="python",
- )
- mock_bisect._test_version_with_script = mock_run_test_script
- self.bisect = mock_bisect
-
-
-class TestBisect(TestBisectBase):
- def test_bisect_standard(self):
- versions = ["success1", "success2", "success3", "fail1", "fail2", "fail3"]
- self.assertEqual("success3", self.bisect.bisect(versions))
-
- def test_bisect_empty(self):
- versions = []
- self.assertEqual(None, self.bisect.bisect(versions))
-
- def test_bisect_all_success(self):
- versions = ["success1", "success2", "success3", "success4"]
- self.assertEqual("success4", self.bisect.bisect(versions))
-
- def test_bisect_all_fail(self):
- versions = ["fail1", "fail2", "fail3"]
- self.assertEqual(None, self.bisect.bisect(versions))
-
-
-class TestFilePaths(unittest.TestCase):
- def test_setup_test_env_filepath(self):
- assert exists(under_test.SETUP_TEST_ENV_SH)
-
- def test_teardown_test_env_filepath(self):
- assert exists(under_test.TEARDOWN_TEST_ENV_SH)
-
- def test_run_user_script_filepath(self):
- assert exists(under_test.RUN_USER_SCRIPT_SH)
-
- def test_resmoke_filepath(self):
- assert exists(under_test.RESMOKE_FILEPATH)