Files
mongo/buildscripts/resmokelib/testing/testcases/fixture.py

Ignoring revisions in .git-blame-ignore-revs. Click here to bypass and see the normal blame view.

132 lines
5.5 KiB
Python
Raw Normal View History

"""The unittest.TestCase instances for setting up and tearing down fixtures."""
from pymongo import ReadPreference
from buildscripts.resmokelib import errors
from buildscripts.resmokelib.testing.fixtures import interface as fixture_interface
from buildscripts.resmokelib.testing.fixtures.external import ExternalFixture
from buildscripts.resmokelib.testing.fixtures.replicaset import ReplicaSetFixture
from buildscripts.resmokelib.testing.testcases import interface
from buildscripts.resmokelib.utils import registry
from buildscripts.resmokelib.utils.sharded_cluster_util import (
refresh_logical_session_cache_with_retry,
)
class FixtureTestCase(interface.TestCase):
"""Base class for the fixture test cases."""
REGISTERED_NAME = registry.LEAVE_UNREGISTERED
def __init__(self, logger, job_name, phase):
"""Initialize the FixtureTestCase."""
interface.TestCase.__init__(
self, logger, "Fixture test", "{}_fixture_{}".format(job_name, phase), dynamic=True
)
self.job_name = job_name
class FixtureSetupTestCase(FixtureTestCase):
"""TestCase for setting up a fixture."""
REGISTERED_NAME = registry.LEAVE_UNREGISTERED
PHASE = "setup"
def __init__(self, logger, fixture, job_name, times_set_up):
"""Initialize the FixtureSetupTestCase."""
specific_phase = "{phase}_{times_set_up}".format(
phase=self.PHASE, times_set_up=times_set_up
)
FixtureTestCase.__init__(self, logger, job_name, specific_phase)
self.fixture = fixture
def run_test(self):
"""Set up the fixture and wait for it to be ready."""
try:
self.return_code = 2
self.logger.info("Starting the setup of %s.", self.fixture)
self.fixture.setup()
self.logger.info("Waiting for %s to be ready.", self.fixture)
self.fixture.await_ready()
if (
not isinstance(self.fixture, (fixture_interface.NoOpFixture, ExternalFixture))
# Replica set with --configsvr cannot run refresh unless it is part of a sharded cluster.
and not (
isinstance(self.fixture, ReplicaSetFixture)
and "configsvr" in self.fixture.mongod_options
)
):
mongo_client = self.fixture.mongo_client(ReadPreference.PRIMARY)
# Read from the CSRS primary to gossip the most recent configTime to the mongos.
# This ensures that the latest state of the sessions collection can be seen
# by the router, when performing the LogicalSessionCache refresh.
mongo_client.admin["system.version"].find({})
# Perform the LogicalSessionCache refresh.
refresh_logical_session_cache_with_retry(mongo_client)
self.logger.info("Finished the setup of %s.", self.fixture)
self.return_code = 0
except errors.ServerFailure as err:
self.logger.error("An error occurred during the setup of %s: %s", self.fixture, err)
raise
except:
self.logger.exception("An error occurred during the setup of %s.", self.fixture)
raise
class FixtureTeardownTestCase(FixtureTestCase):
"""TestCase for tearing down a fixture."""
REGISTERED_NAME = registry.LEAVE_UNREGISTERED
PHASE = "teardown"
def __init__(self, logger, fixture, job_name):
"""Initialize the FixtureTeardownTestCase."""
FixtureTestCase.__init__(self, logger, job_name, self.PHASE)
self.fixture = fixture
def run_test(self):
"""Tear down the fixture."""
try:
self.return_code = 2
self.logger.info("Starting the teardown of %s.", self.fixture)
self.fixture.teardown(finished=True)
self.logger.info("Finished the teardown of %s.", self.fixture)
self.return_code = 0
except errors.ServerFailure as err:
self.logger.error("An error occurred during the teardown of %s: %s", self.fixture, err)
raise
except:
self.logger.exception("An error occurred during the teardown of %s.", self.fixture)
raise
class FixtureAbortTestCase(FixtureTestCase):
"""TestCase for killing a fixture. Intended for use before archiving a failed test."""
REGISTERED_NAME = registry.LEAVE_UNREGISTERED
PHASE = "abort"
def __init__(self, logger, fixture, job_name, times_set_up):
"""Initialize the FixtureAbortTestCase."""
specific_phase = "{phase}_{times_set_up}".format(
phase=self.PHASE, times_set_up=times_set_up
)
FixtureTestCase.__init__(self, logger, job_name, specific_phase)
self.fixture = fixture
def run_test(self):
"""Tear down the fixture."""
try:
self.return_code = 2 # Test return code of 2 is used for fixture failures.
self.logger.info("Aborting the fixture %s due to test failure.", self.fixture)
self.fixture.teardown(finished=False, mode=fixture_interface.TeardownMode.ABORT)
self.logger.info("Finished aborting %s.", self.fixture)
self.return_code = 0
except errors.ServerFailure:
# If the server wasn't already running, we can't exactly fail to abort it.
self.logger.info("Finished aborting %s.", self.fixture)
self.return_code = 0
except:
self.logger.exception("An error occurred while aborting %s.", self.fixture)
raise