def __init__(self):
     """Create a client and grab essential information from the server."""
     self.connection_attempts = []
     self.connected = False
     self.w = None
     self.nodes = set()
     self.replica_set_name = None
     self.cmd_line = None
     self.server_status = None
     self.version = Version(-1)  # Needs to be comparable with Version
     self.auth_enabled = False
     self.test_commands_enabled = False
     self.server_parameters = None
     self.is_mongos = False
     self.mongoses = []
     self.is_rs = False
     self.has_ipv6 = False
     self.tls = False
     self.ssl_certfile = False
     self.server_is_resolvable = is_server_resolvable()
     self.default_client_options = {}
     self.sessions_enabled = False
     self.client = None
     self.conn_lock = threading.Lock()
     self.is_data_lake = False
     if COMPRESSORS:
         self.default_client_options["compressors"] = COMPRESSORS
     if MONGODB_API_VERSION:
         server_api = ServerApi(MONGODB_API_VERSION)
         self.default_client_options["server_api"] = server_api
Exemplo n.º 2
0
    def __init__(self):
        """Create a client and grab essential information from the server."""
        self.connection_attempts = []
        self.connected = False
        self.ismaster = {}
        self.w = None
        self.nodes = set()
        self.replica_set_name = None
        self.cmd_line = None
        self.version = Version(-1)  # Needs to be comparable with Version
        self.auth_enabled = False
        self.test_commands_enabled = False
        self.is_mongos = False
        self.is_rs = False
        self.has_ipv6 = False
        self.ssl = False
        self.ssl_cert_none = False
        self.ssl_certfile = False
        self.server_is_resolvable = is_server_resolvable()
        self.default_client_options = {}
        self.sessions_enabled = False
        self.client = None
        self.conn_lock = threading.Lock()

        if COMPRESSORS:
            self.default_client_options["compressors"] = COMPRESSORS
Exemplo n.º 3
0
 def require_version_max(self, *ver):
     """Run a test only if the server version is at most ``version``."""
     other_version = Version(*ver)
     return self.require(
         lambda: self.version <= other_version,
         "Server version must be at most %s" % str(other_version),
     )
Exemplo n.º 4
0
    def setUpClass(cls):
        super(MotorTransactionTest, cls).setUpClass()
        if not env.sessions_enabled:
            raise SkipTest("Sessions not supported")

        if not env.is_replica_set:
            raise SkipTest("Requires a replica set")

        if env.version < Version(3, 7):
            raise SkipTest("Requires MongoDB 3.7+")
def is_run_on_requirement_satisfied(requirement):
    topology_satisfied = True
    req_topologies = requirement.get('topologies')
    if req_topologies:
        topology_satisfied = client_context.is_topology_type(req_topologies)

    server_version = Version(*client_context.version[:3])

    min_version_satisfied = True
    req_min_server_version = requirement.get('minServerVersion')
    if req_min_server_version:
        min_version_satisfied = Version.from_string(
            req_min_server_version) <= server_version

    max_version_satisfied = True
    req_max_server_version = requirement.get('maxServerVersion')
    if req_max_server_version:
        max_version_satisfied = Version.from_string(
            req_max_server_version) >= server_version

    serverless = requirement.get('serverless')
    if serverless == "require":
        serverless_satisfied = client_context.serverless
    elif serverless == "forbid":
        serverless_satisfied = not client_context.serverless
    else:  # unset or "allow"
        serverless_satisfied = True

    params_satisfied = True
    params = requirement.get('serverParameters')
    if params:
        for param, val in params.items():
            if param not in client_context.server_parameters:
                params_satisfied = False
            elif client_context.server_parameters[param] != val:
                params_satisfied = False

    auth_satisfied = True
    req_auth = requirement.get('auth')
    if req_auth is not None:
        if req_auth:
            auth_satisfied = client_context.auth_enabled
        else:
            auth_satisfied = not client_context.auth_enabled

    return (topology_satisfied and min_version_satisfied
            and max_version_satisfied and serverless_satisfied
            and params_satisfied and auth_satisfied)
Exemplo n.º 6
0
    def test_RetryableWriteError_error_label(self):
        listener = OvertCommandListener()
        client = rs_or_single_client(
            retryWrites=True, event_listeners=[listener])

        # Ensure collection exists.
        client.pymongo_test.testcoll.insert_one({})

        with self.fail_point(self.fail_insert):
            with self.assertRaises(WriteConcernError) as cm:
                client.pymongo_test.testcoll.insert_one({})
            self.assertTrue(cm.exception.has_error_label(
                'RetryableWriteError'))

        if client_context.version >= Version(4, 4):
            # In MongoDB 4.4+ we rely on the server returning the error label.
            self.assertIn(
                'RetryableWriteError',
                listener.results['succeeded'][-1].reply['errorLabels'])
Exemplo n.º 7
0
 def require_version_min(self, *ver):
     """Run a test only if the server version is at least ``version``."""
     other_version = Version(*ver)
     return self._require(
         self.version >= other_version,
         "Server version must be at least %s" % str(other_version))
Exemplo n.º 8
0
    def __init__(self):
        """Create a client and grab essential information from the server."""
        self.connected = False
        self.ismaster = {}
        self.w = None
        self.nodes = set()
        self.replica_set_name = None
        self.cmd_line = None
        self.version = Version(-1)  # Needs to be comparable with Version
        self.auth_enabled = False
        self.test_commands_enabled = False
        self.is_mongos = False
        self.is_rs = False
        self.has_ipv6 = False
        self.ssl = False
        self.ssl_cert_none = False
        self.ssl_certfile = False
        self.server_is_resolvable = is_server_resolvable()
        self.ssl_client_options = {}
        self.sessions_enabled = False
        self.client = _connect(host, port)

        if HAVE_SSL and not self.client:
            # Is MongoDB configured for SSL?
            self.client = _connect(host, port, **_SSL_OPTIONS)
            if self.client:
                self.ssl = True
                self.ssl_client_options = _SSL_OPTIONS
                self.ssl_certfile = True
                if _SSL_OPTIONS.get('ssl_cert_reqs') == ssl.CERT_NONE:
                    self.ssl_cert_none = True

        if self.client:
            self.connected = True

            try:
                self.cmd_line = self.client.admin.command('getCmdLineOpts')
            except pymongo.errors.OperationFailure as e:
                msg = e.details.get('errmsg', '')
                if e.code == 13 or 'unauthorized' in msg or 'login' in msg:
                    # Unauthorized.
                    self.auth_enabled = True
                else:
                    raise
            else:
                self.auth_enabled = self._server_started_with_auth()

            if self.auth_enabled:
                # See if db_user already exists.
                if not self._check_user_provided():
                    self.client.admin.add_user(db_user, db_pwd, roles=['root'])

                self.client = _connect(host,
                                       port,
                                       username=db_user,
                                       password=db_pwd,
                                       replicaSet=self.replica_set_name,
                                       **self.ssl_client_options)

                # May not have this if OperationFailure was raised earlier.
                self.cmd_line = self.client.admin.command('getCmdLineOpts')

            self.ismaster = ismaster = self.client.admin.command('isMaster')
            self.sessions_enabled = 'logicalSessionTimeoutMinutes' in ismaster

            if 'setName' in ismaster:
                self.replica_set_name = ismaster['setName']
                self.is_rs = True
                if self.auth_enabled:
                    # It doesn't matter which member we use as the seed here.
                    self.client = pymongo.MongoClient(
                        host,
                        port,
                        username=db_user,
                        password=db_pwd,
                        replicaSet=self.replica_set_name,
                        **self.ssl_client_options)
                else:
                    self.client = pymongo.MongoClient(
                        host,
                        port,
                        replicaSet=self.replica_set_name,
                        **self.ssl_client_options)

                # Get the authoritative ismaster result from the primary.
                self.ismaster = self.client.admin.command('ismaster')
                nodes = [
                    partition_node(node.lower())
                    for node in self.ismaster.get('hosts', [])
                ]
                nodes.extend([
                    partition_node(node.lower())
                    for node in self.ismaster.get('passives', [])
                ])
                nodes.extend([
                    partition_node(node.lower())
                    for node in self.ismaster.get('arbiters', [])
                ])
                self.nodes = set(nodes)
            else:
                self.ismaster = ismaster
                self.nodes = set([(host, port)])
            self.w = len(self.ismaster.get("hosts", [])) or 1
            self.version = Version.from_client(self.client)

            if 'enableTestCommands=1' in self.cmd_line['argv']:
                self.test_commands_enabled = True
            elif 'parsed' in self.cmd_line:
                params = self.cmd_line['parsed'].get('setParameter', [])
                if 'enableTestCommands=1' in params:
                    self.test_commands_enabled = True
                else:
                    params = self.cmd_line['parsed'].get('setParameter', {})
                    if params.get('enableTestCommands') == '1':
                        self.test_commands_enabled = True

            self.is_mongos = (self.ismaster.get('msg') == 'isdbgrid')
            self.has_ipv6 = self._server_started_with_ipv6()
    def __init__(self):
        """Create a client and grab essential information from the server."""
        self.connected = False
        self.ismaster = {}
        self.w = None
        self.nodes = set()
        self.replica_set_name = None
        self.rs_client = None
        self.cmd_line = None
        self.version = Version(-1)  # Needs to be comparable with Version
        self.auth_enabled = False
        self.test_commands_enabled = False
        self.is_mongos = False
        self.is_rs = False
        self.has_ipv6 = False

        try:
            client = pymongo.MongoClient(host,
                                         port,
                                         serverSelectionTimeoutMS=100)
            client.admin.command('ismaster')  # Can we connect?

            # If so, then reset client to defaults.
            self.client = pymongo.MongoClient(host, port)

        except pymongo.errors.ConnectionFailure:
            self.client = self.rs_or_standalone_client = None
        else:
            self.connected = True
            self.ismaster = self.client.admin.command('ismaster')
            self.w = len(self.ismaster.get("hosts", [])) or 1
            self.nodes = set([(host, port)])
            self.replica_set_name = self.ismaster.get('setName', '')
            self.rs_client = None
            self.version = Version.from_client(self.client)
            if self.replica_set_name:
                self.is_rs = True
                self.rs_client = pymongo.MongoClient(
                    pair, replicaSet=self.replica_set_name)

                nodes = [
                    partition_node(node.lower())
                    for node in self.ismaster.get('hosts', [])
                ]
                nodes.extend([
                    partition_node(node.lower())
                    for node in self.ismaster.get('passives', [])
                ])
                nodes.extend([
                    partition_node(node.lower())
                    for node in self.ismaster.get('arbiters', [])
                ])
                self.nodes = set(nodes)

            self.rs_or_standalone_client = self.rs_client or self.client

            try:
                self.cmd_line = self.client.admin.command('getCmdLineOpts')
            except pymongo.errors.OperationFailure as e:
                msg = e.details.get('errmsg', '')
                if e.code == 13 or 'unauthorized' in msg or 'login' in msg:
                    # Unauthorized.
                    self.auth_enabled = True
                else:
                    raise
            else:
                self.auth_enabled = self._server_started_with_auth()

            if self.auth_enabled:
                # See if db_user already exists.
                self.user_provided = self._check_user_provided()
                if not self.user_provided:
                    roles = {}
                    if self.version.at_least(2, 5, 3, -1):
                        roles = {'roles': ['root']}
                    self.client.admin.add_user(db_user, db_pwd, **roles)
                    self.client.admin.authenticate(db_user, db_pwd)

                if self.rs_client:
                    self.rs_client.admin.authenticate(db_user, db_pwd)

                # May not have this if OperationFailure was raised earlier.
                self.cmd_line = self.client.admin.command('getCmdLineOpts')

            if 'enableTestCommands=1' in self.cmd_line['argv']:
                self.test_commands_enabled = True
            elif 'parsed' in self.cmd_line:
                params = self.cmd_line['parsed'].get('setParameter', [])
                if 'enableTestCommands=1' in params:
                    self.test_commands_enabled = True

            self.is_mongos = (self.ismaster.get('msg') == 'isdbgrid')
            self.has_ipv6 = self._server_started_with_ipv6()
Exemplo n.º 10
0
    def __init__(self):
        """Create a client and grab essential information from the server."""
        # Seed host. This may be updated further down.
        self.host, self.port = host, port
        self.connected = False
        self.ismaster = {}
        self.w = None
        self.nodes = set()
        self.replica_set_name = None
        self.rs_client = None
        self.cmd_line = None
        self.version = Version(-1)  # Needs to be comparable with Version
        self.auth_enabled = False
        self.test_commands_enabled = False
        self.is_mongos = False
        self.is_rs = False
        self.has_ipv6 = False
        self.ssl_cert_none = False
        self.ssl_certfile = False
        self.server_is_resolvable = is_server_resolvable()

        self.client = self.rs_or_standalone_client = None

        def connect(**kwargs):
            try:
                client = pymongo.MongoClient(self.host,
                                             self.port,
                                             serverSelectionTimeoutMS=100,
                                             **kwargs)
                client.admin.command('ismaster')  # Can we connect?
                # If connected, then return client with default timeout
                return pymongo.MongoClient(self.host, self.port, **kwargs)
            except pymongo.errors.ConnectionFailure:
                return None

        self.client = connect()

        if HAVE_SSL and not self.client:
            # Is MongoDB configured for SSL?
            self.client = connect(ssl=True, ssl_cert_reqs=ssl.CERT_NONE)
            if self.client:
                self.ssl_cert_none = True

            # Can client connect with certfile?
            client = connect(
                ssl=True,
                ssl_cert_reqs=ssl.CERT_NONE,
                ssl_certfile=CLIENT_PEM,
            )
            if client:
                self.ssl_certfile = True
                self.client = client

        if self.client:
            self.connected = True
            self.ismaster = self.client.admin.command('ismaster')
            self.w = len(self.ismaster.get("hosts", [])) or 1
            self.nodes = set([(self.host, self.port)])
            self.replica_set_name = self.ismaster.get('setName', '')
            self.rs_client = None
            self.version = Version.from_client(self.client)
            if self.replica_set_name:
                self.is_rs = True
                self.rs_client = pymongo.MongoClient(
                    self.ismaster['primary'], replicaSet=self.replica_set_name)
                # Force connection
                self.rs_client.admin.command('ismaster')
                self.host, self.port = self.rs_client.primary
                self.client = connect()

                nodes = [
                    partition_node(node.lower())
                    for node in self.ismaster.get('hosts', [])
                ]
                nodes.extend([
                    partition_node(node.lower())
                    for node in self.ismaster.get('passives', [])
                ])
                nodes.extend([
                    partition_node(node.lower())
                    for node in self.ismaster.get('arbiters', [])
                ])
                self.nodes = set(nodes)

            self.rs_or_standalone_client = self.rs_client or self.client

            try:
                self.cmd_line = self.client.admin.command('getCmdLineOpts')
            except pymongo.errors.OperationFailure as e:
                msg = e.details.get('errmsg', '')
                if e.code == 13 or 'unauthorized' in msg or 'login' in msg:
                    # Unauthorized.
                    self.auth_enabled = True
                else:
                    raise
            else:
                self.auth_enabled = self._server_started_with_auth()

            if self.auth_enabled:
                # See if db_user already exists.
                self.user_provided = self._check_user_provided()
                if not self.user_provided:
                    roles = {}
                    if self.version.at_least(2, 5, 3, -1):
                        roles = {'roles': ['root']}
                    self.client.admin.add_user(db_user, db_pwd, **roles)
                    self.client.admin.authenticate(db_user, db_pwd)

                if self.rs_client:
                    self.rs_client.admin.authenticate(db_user, db_pwd)

                # May not have this if OperationFailure was raised earlier.
                self.cmd_line = self.client.admin.command('getCmdLineOpts')

            if 'enableTestCommands=1' in self.cmd_line['argv']:
                self.test_commands_enabled = True
            elif 'parsed' in self.cmd_line:
                params = self.cmd_line['parsed'].get('setParameter', [])
                if 'enableTestCommands=1' in params:
                    self.test_commands_enabled = True

            self.is_mongos = (self.ismaster.get('msg') == 'isdbgrid')
            self.has_ipv6 = self._server_started_with_ipv6()

        # Do this after we connect so we know who the primary is.
        self.pair = "%s:%d" % (self.host, self.port)
Exemplo n.º 11
0
    def __init__(self):
        """Create a client and grab essential information from the server."""
        # Seed host. This may be updated further down.
        self.host, self.port = host, port
        self.connected = False
        self.ismaster = {}
        self.w = None
        self.nodes = set()
        self.replica_set_name = None
        self.cmd_line = None
        self.version = Version(-1)  # Needs to be comparable with Version
        self.auth_enabled = False
        self.test_commands_enabled = False
        self.is_mongos = False
        self.is_rs = False
        self.has_ipv6 = False
        self.ssl = False
        self.ssl_cert_none = False
        self.ssl_certfile = False
        self.server_is_resolvable = is_server_resolvable()
        self.ssl_client_options = {}
        self.client = _connect(self.host, self.port)

        if HAVE_SSL and not self.client:
            # Is MongoDB configured for SSL?
            self.client = _connect(self.host, self.port, **_SSL_OPTIONS)
            if self.client:
                self.ssl = True
                self.ssl_client_options = _SSL_OPTIONS
                self.ssl_certfile = True
                if _SSL_OPTIONS.get('ssl_cert_reqs') == ssl.CERT_NONE:
                    self.ssl_cert_none = True

        if self.client:
            self.connected = True
            self.ismaster = self.client.admin.command('ismaster')
            self.w = len(self.ismaster.get("hosts", [])) or 1
            self.nodes = set([(self.host, self.port)])
            self.replica_set_name = self.ismaster.get('setName', '')
            self.version = Version.from_client(self.client)
            if self.replica_set_name:
                self.is_rs = True
                self.client = pymongo.MongoClient(
                    self.ismaster['primary'],
                    replicaSet=self.replica_set_name,
                    **self.ssl_client_options)
                # Force connection
                self.client.admin.command('ismaster')
                self.host, self.port = self.client.primary

                nodes = [partition_node(node.lower())
                         for node in self.ismaster.get('hosts', [])]
                nodes.extend([partition_node(node.lower())
                              for node in self.ismaster.get('passives', [])])
                nodes.extend([partition_node(node.lower())
                              for node in self.ismaster.get('arbiters', [])])
                self.nodes = set(nodes)

            try:
                self.cmd_line = self.client.admin.command('getCmdLineOpts')
            except pymongo.errors.OperationFailure as e:
                msg = e.details.get('errmsg', '')
                if e.code == 13 or 'unauthorized' in msg or 'login' in msg:
                    # Unauthorized.
                    self.auth_enabled = True
                else:
                    raise
            else:
                self.auth_enabled = self._server_started_with_auth()

            if self.auth_enabled:
                # See if db_user already exists.
                self.user_provided = self._check_user_provided()
                if not self.user_provided:
                    roles = {}
                    if self.version.at_least(2, 5, 3, -1):
                        roles = {'roles': ['root']}
                    self.client.admin.add_user(db_user, db_pwd, **roles)
                    self.client.admin.authenticate(db_user, db_pwd)

                # May not have this if OperationFailure was raised earlier.
                self.cmd_line = self.client.admin.command('getCmdLineOpts')

            if 'enableTestCommands=1' in self.cmd_line['argv']:
                self.test_commands_enabled = True
            elif 'parsed' in self.cmd_line:
                params = self.cmd_line['parsed'].get('setParameter', [])
                if 'enableTestCommands=1' in params:
                    self.test_commands_enabled = True
                else:
                    params = self.cmd_line['parsed'].get('setParameter', {})
                    if params.get('enableTestCommands') == '1':
                        self.test_commands_enabled = True

            self.is_mongos = (self.ismaster.get('msg') == 'isdbgrid')
            self.has_ipv6 = self._server_started_with_ipv6()