def test_alive(self):
        primary = ha_tools.get_primary()
        secondary = ha_tools.get_random_secondary()
        primary_cx = connected(
            MongoClient(
                primary,
                serverSelectionTimeoutMS=self.server_selection_timeout)),
        secondary_cx = connected(
            MongoClient(
                secondary,
                serverSelectionTimeoutMS=self.server_selection_timeout))
        rsc = connected(
            MongoClient(
                self.seed,
                replicaSet=self.name,
                serverSelectionTimeoutMS=self.server_selection_timeout))

        self.assertTrue(primary_cx.alive())
        self.assertTrue(secondary_cx.alive())
        self.assertTrue(rsc.alive())

        ha_tools.kill_primary()
        time.sleep(0.5)

        self.assertFalse(primary_cx.alive())
        self.assertTrue(secondary_cx.alive())
        self.assertFalse(rsc.alive())

        ha_tools.kill_members([secondary], 2)
        time.sleep(0.5)

        self.assertFalse(primary_cx.alive())
        self.assertFalse(secondary_cx.alive())
        self.assertFalse(rsc.alive())
    def test_mongo_client(self):
        pair = client_context.pair
        m = rs_or_single_client(w=0)
        coll = m.pymongo_test.write_concern_test
        coll.drop()
        doc = {"_id": ObjectId()}
        coll.insert_one(doc)
        self.assertTrue(coll.insert_one(doc))
        coll = coll.with_options(write_concern=WriteConcern(w=1))
        self.assertRaises(OperationFailure, coll.insert_one, doc)

        m = rs_or_single_client()
        coll = m.pymongo_test.write_concern_test
        new_coll = coll.with_options(write_concern=WriteConcern(w=0))
        self.assertTrue(new_coll.insert_one(doc))
        self.assertRaises(OperationFailure, coll.insert_one, doc)

        m = rs_or_single_client("mongodb://%s/" % (pair,),
                                replicaSet=client_context.replica_set_name)

        coll = m.pymongo_test.write_concern_test
        self.assertRaises(OperationFailure, coll.insert_one, doc)
        m = rs_or_single_client("mongodb://%s/?w=0" % (pair,),
                                replicaSet=client_context.replica_set_name)

        coll = m.pymongo_test.write_concern_test
        coll.insert_one(doc)

        # Equality tests
        direct = connected(single_client(w=0))
        direct2 = connected(single_client("mongodb://%s/?w=0" % (pair,),
                                          **self.credentials))
        self.assertEqual(direct, direct2)
        self.assertFalse(direct != direct2)
Beispiel #3
0
    def test_mongo_client(self):
        pair = client_context.pair
        m = rs_or_single_client(w=0)
        coll = m.pymongo_test.write_concern_test
        coll.drop()
        doc = {"_id": ObjectId()}
        coll.insert_one(doc)
        self.assertTrue(coll.insert_one(doc))
        coll = coll.with_options(write_concern=WriteConcern(w=1))
        self.assertRaises(OperationFailure, coll.insert_one, doc)

        m = rs_or_single_client()
        coll = m.pymongo_test.write_concern_test
        new_coll = coll.with_options(write_concern=WriteConcern(w=0))
        self.assertTrue(new_coll.insert_one(doc))
        self.assertRaises(OperationFailure, coll.insert_one, doc)

        m = rs_or_single_client("mongodb://%s/" % (pair, ),
                                replicaSet=client_context.replica_set_name)

        coll = m.pymongo_test.write_concern_test
        self.assertRaises(OperationFailure, coll.insert_one, doc)
        m = rs_or_single_client("mongodb://%s/?w=0" % (pair, ),
                                replicaSet=client_context.replica_set_name)

        coll = m.pymongo_test.write_concern_test
        coll.insert_one(doc)

        # Equality tests
        direct = connected(single_client(w=0))
        direct2 = connected(
            single_client("mongodb://%s/?w=0" % (pair, ), **self.credentials))
        self.assertEqual(direct, direct2)
        self.assertFalse(direct != direct2)
    def test_ssl_pem_passphrase(self):
        # Expects the server to be running with server.pem and ca.pem
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        vi = sys.version_info
        if vi[0] == 2 and vi < (2, 7, 9) or vi[0] == 3 and vi < (3, 3):
            self.assertRaises(
                ConfigurationError,
                MongoClient,
                'localhost',
                ssl=True,
                ssl_certfile=CLIENT_ENCRYPTED_PEM,
                ssl_pem_passphrase="clientpassword",
                ssl_ca_certs=CA_PEM,
                serverSelectionTimeoutMS=100)
        else:
            connected(MongoClient('localhost',
                                  ssl=True,
                                  ssl_certfile=CLIENT_ENCRYPTED_PEM,
                                  ssl_pem_passphrase="clientpassword",
                                  ssl_ca_certs=CA_PEM,
                                  serverSelectionTimeoutMS=100,
                                  **self.credentials))

            uri_fmt = ("mongodb://localhost/?ssl=true"
                       "&ssl_certfile=%s&ssl_pem_passphrase=clientpassword"
                       "&ssl_ca_certs=%s&serverSelectionTimeoutMS=100")
            connected(MongoClient(uri_fmt % (CLIENT_ENCRYPTED_PEM, CA_PEM),
                                  **self.credentials))
    def test_local_threshold(self):
        client = connected(self.mock_client(localThresholdMS=30))
        self.assertEqual(30, client.local_threshold_ms)
        wait_until(lambda: len(client.nodes) == 3, 'connect to all mongoses')
        topology = client._topology

        # All are within a 30-ms latency window, see self.mock_client().
        self.assertEqual(set([('a', 1), ('b', 2), ('c', 3)]),
                         writable_addresses(topology))

        # No error
        client.admin.command('ismaster')

        client = connected(self.mock_client(localThresholdMS=0))
        self.assertEqual(0, client.local_threshold_ms)
        # No error
        client.db.command('ismaster')
        # Our chosen mongos goes down.
        client.kill_host('%s:%s' % next(iter(client.nodes)))
        try:
            client.db.command('ismaster')
        except:
            pass

        # We eventually connect to a new mongos.
        def connect_to_new_mongos():
            try:
                return client.db.command('ismaster')
            except AutoReconnect:
                pass

        wait_until(connect_to_new_mongos, 'connect to a new mongos')
Beispiel #6
0
    def test_ssl_pem_passphrase(self):
        # Expects the server to be running with server.pem and ca.pem
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        if not hasattr(ssl, 'SSLContext') and not _ssl.IS_PYOPENSSL:
            self.assertRaises(ConfigurationError,
                              MongoClient,
                              'localhost',
                              ssl=True,
                              ssl_certfile=CLIENT_ENCRYPTED_PEM,
                              ssl_pem_passphrase="qwerty",
                              ssl_ca_certs=CA_PEM,
                              serverSelectionTimeoutMS=100)
        else:
            connected(
                MongoClient('localhost',
                            ssl=True,
                            ssl_certfile=CLIENT_ENCRYPTED_PEM,
                            ssl_pem_passphrase="qwerty",
                            ssl_ca_certs=CA_PEM,
                            serverSelectionTimeoutMS=5000,
                            **self.credentials))

            uri_fmt = ("mongodb://localhost/?ssl=true"
                       "&ssl_certfile=%s&ssl_pem_passphrase=qwerty"
                       "&ssl_ca_certs=%s&serverSelectionTimeoutMS=5000")
            connected(
                MongoClient(uri_fmt % (CLIENT_ENCRYPTED_PEM, CA_PEM),
                            **self.credentials))
    def test_local_threshold(self):
        client = connected(self.mock_client(localThresholdMS=30))
        self.assertEqual(30, client.local_threshold_ms)
        wait_until(lambda: len(client.nodes) == 3, 'connect to all mongoses')
        topology = client._topology

        # All are within a 30-ms latency window, see self.mock_client().
        self.assertEqual(set([('a', 1), ('b', 2), ('c', 3)]),
                         writable_addresses(topology))

        # No error
        client.db.collection.find_one()

        client = connected(self.mock_client(localThresholdMS=0))
        self.assertEqual(0, client.local_threshold_ms)
        # No error
        client.db.collection.find_one()
        # Our chosen mongos goes down.
        client.kill_host('%s:%s' % next(iter(client.nodes)))
        try:
            client.db.collection.find_one()
        except:
            pass
        # No error
        client.db.collection.find_one()
    def test_local_threshold(self):
        client = connected(self.mock_client(localThresholdMS=30))
        self.assertEqual(30, client.local_threshold_ms)
        wait_until(lambda: len(client.nodes) == 3, 'connect to all mongoses')
        topology = client._topology

        # All are within a 30-ms latency window, see self.mock_client().
        self.assertEqual(set([('a', 1), ('b', 2), ('c', 3)]),
                         writable_addresses(topology))

        # No error
        client.db.collection.find_one()

        client = connected(self.mock_client(localThresholdMS=0))
        self.assertEqual(0, client.local_threshold_ms)
        # No error
        client.db.collection.find_one()
        # Our chosen mongos goes down.
        client.kill_host('%s:%s' % next(iter(client.nodes)))
        try:
            client.db.collection.find_one()
        except:
            pass
        # No error
        client.db.collection.find_one()
Beispiel #9
0
    def test_ssl_pem_passphrase(self):
        # Expects the server to be running with server.pem and ca.pem
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        if not CERT_SSL:
            raise SkipTest("No mongod available over SSL with certs")

        vi = sys.version_info
        if vi[0] == 2 and vi < (2, 7, 9) or vi[0] == 3 and vi < (3, 3):
            self.assertRaises(ConfigurationError,
                              MongoClient,
                              'server',
                              ssl=True,
                              ssl_certfile=CLIENT_ENCRYPTED_PEM,
                              ssl_pem_passphrase="clientpassword",
                              ssl_ca_certs=CA_PEM,
                              serverSelectionTimeoutMS=100)
        else:
            connected(
                MongoClient('server',
                            ssl=True,
                            ssl_certfile=CLIENT_ENCRYPTED_PEM,
                            ssl_pem_passphrase="clientpassword",
                            ssl_ca_certs=CA_PEM,
                            serverSelectionTimeoutMS=100))

            uri_fmt = ("mongodb://server/?ssl=true"
                       "&ssl_certfile=%s&ssl_pem_passphrase=clientpassword"
                       "&ssl_ca_certs=%s&serverSelectionTimeoutMS=100")
            connected(MongoClient(uri_fmt % (CLIENT_ENCRYPTED_PEM, CA_PEM)))
    def test_alive(self):
        primary = ha_tools.get_primary()
        secondary = ha_tools.get_random_secondary()
        primary_cx = connected(
            MongoClient(
                primary,
                serverSelectionTimeoutMS=self.server_selection_timeout)),
        secondary_cx = connected(
            MongoClient(
                secondary,
                serverSelectionTimeoutMS=self.server_selection_timeout))
        rsc = connected(
            MongoClient(
                self.seed,
                replicaSet=self.name,
                serverSelectionTimeoutMS=self.server_selection_timeout))

        self.assertTrue(primary_cx.alive())
        self.assertTrue(secondary_cx.alive())
        self.assertTrue(rsc.alive())

        ha_tools.kill_primary()
        time.sleep(0.5)

        self.assertFalse(primary_cx.alive())
        self.assertTrue(secondary_cx.alive())
        self.assertFalse(rsc.alive())

        ha_tools.kill_members([secondary], 2)
        time.sleep(0.5)

        self.assertFalse(primary_cx.alive())
        self.assertFalse(secondary_cx.alive())
        self.assertFalse(rsc.alive())
    def test_ssl_pem_passphrase(self):
        # Expects the server to be running with server.pem and ca.pem
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        if not CERT_SSL:
            raise SkipTest("No mongod available over SSL with certs")

        vi = sys.version_info
        if vi[0] == 2 and vi < (2, 7, 9) or vi[0] == 3 and vi < (3, 3):
            self.assertRaises(
                ConfigurationError,
                MongoClient,
                'server',
                ssl=True,
                ssl_certfile=CLIENT_ENCRYPTED_PEM,
                ssl_pem_passphrase="clientpassword",
                ssl_ca_certs=CA_PEM,
                serverSelectionTimeoutMS=100)
        else:
            connected(MongoClient('server',
                                  ssl=True,
                                  ssl_certfile=CLIENT_ENCRYPTED_PEM,
                                  ssl_pem_passphrase="clientpassword",
                                  ssl_ca_certs=CA_PEM,
                                  serverSelectionTimeoutMS=100))

            uri_fmt = ("mongodb://server/?ssl=true"
                       "&ssl_certfile=%s&ssl_pem_passphrase=clientpassword"
                       "&ssl_ca_certs=%s&serverSelectionTimeoutMS=100")
            connected(MongoClient(uri_fmt % (CLIENT_ENCRYPTED_PEM, CA_PEM)))
    def test_ssl_pem_passphrase(self):
        # Expects the server to be running with server.pem and ca.pem
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        vi = sys.version_info
        if vi[0] == 2 and vi < (2, 7, 9) or vi[0] == 3 and vi < (3, 3):
            self.assertRaises(
                ConfigurationError,
                MongoClient,
                'localhost',
                ssl=True,
                ssl_certfile=CLIENT_ENCRYPTED_PEM,
                ssl_pem_passphrase="clientpassword",
                ssl_ca_certs=CA_PEM,
                serverSelectionTimeoutMS=100)
        else:
            connected(MongoClient('localhost',
                                  ssl=True,
                                  ssl_certfile=CLIENT_ENCRYPTED_PEM,
                                  ssl_pem_passphrase="clientpassword",
                                  ssl_ca_certs=CA_PEM,
                                  serverSelectionTimeoutMS=100,
                                  **self.credentials))

            uri_fmt = ("mongodb://localhost/?ssl=true"
                       "&ssl_certfile=%s&ssl_pem_passphrase=clientpassword"
                       "&ssl_ca_certs=%s&serverSelectionTimeoutMS=100")
            connected(MongoClient(uri_fmt % (CLIENT_ENCRYPTED_PEM, CA_PEM),
                                  **self.credentials))
    def test_local_threshold(self):
        client = connected(self.mock_client(localThresholdMS=30))
        self.assertEqual(30, client.local_threshold_ms)
        wait_until(lambda: len(client.nodes) == 3, 'connect to all mongoses')
        topology = client._topology

        # All are within a 30-ms latency window, see self.mock_client().
        self.assertEqual(set([('a', 1), ('b', 2), ('c', 3)]),
                         writable_addresses(topology))

        # No error
        client.admin.command('ismaster')

        client = connected(self.mock_client(localThresholdMS=0))
        self.assertEqual(0, client.local_threshold_ms)
        # No error
        client.db.command('ismaster')
        # Our chosen mongos goes down.
        client.kill_host('%s:%s' % next(iter(client.nodes)))
        try:
            client.db.command('ismaster')
        except:
            pass

        # We eventually connect to a new mongos.
        def connect_to_new_mongos():
            try:
                return client.db.command('ismaster')
            except AutoReconnect:
                pass
        wait_until(connect_to_new_mongos, 'connect to a new mongos')
    def test_atexit_hook(self):
        client = single_client(client_context.host, client_context.port)
        executor = one(client._topology._servers.values())._monitor._executor
        connected(client)

        # The executor stores a weakref to itself in _EXECUTORS.
        ref = one([r for r in _EXECUTORS.copy() if r() is executor])

        del executor
        del client

        wait_until(partial(unregistered, ref), 'unregister executor',
                   timeout=5)
    def test_ssl_crlfile_support(self):
        if not hasattr(ssl, 'VERIFY_CRL_CHECK_LEAF'):
            self.assertRaises(
                ConfigurationError,
                MongoClient,
                'localhost',
                ssl=True,
                ssl_ca_certs=CA_PEM,
                ssl_crlfile=CRL_PEM,
                serverSelectionTimeoutMS=100)
        else:
            connected(MongoClient('localhost',
                                  ssl=True,
                                  ssl_ca_certs=CA_PEM,
                                  serverSelectionTimeoutMS=100,
                                  **self.credentials))

            with self.assertRaises(ConnectionFailure):
                connected(MongoClient('localhost',
                                      ssl=True,
                                      ssl_ca_certs=CA_PEM,
                                      ssl_crlfile=CRL_PEM,
                                      serverSelectionTimeoutMS=100,
                                      **self.credentials))

            uri_fmt = ("mongodb://localhost/?ssl=true&"
                       "ssl_ca_certs=%s&serverSelectionTimeoutMS=100")
            connected(MongoClient(uri_fmt % (CA_PEM,),
                                  **self.credentials))

            uri_fmt = ("mongodb://localhost/?ssl=true&ssl_crlfile=%s"
                       "&ssl_ca_certs=%s&serverSelectionTimeoutMS=100")
            with self.assertRaises(ConnectionFailure):
                connected(MongoClient(uri_fmt % (CRL_PEM, CA_PEM),
                                      **self.credentials))
    def test_atexit_hook(self):
        client = single_client(client_context.host, client_context.port)
        executor = one(client._topology._servers.values())._monitor._executor
        connected(client)

        # The executor stores a weakref to itself in _EXECUTORS.
        ref = one([r for r in _EXECUTORS.copy() if r() is executor])

        del executor
        del client

        wait_until(partial(unregistered, ref),
                   'unregister executor',
                   timeout=5)
    def test_ssl_crlfile_support(self):
        if not hasattr(ssl, 'VERIFY_CRL_CHECK_LEAF'):
            self.assertRaises(
                ConfigurationError,
                MongoClient,
                'localhost',
                ssl=True,
                ssl_ca_certs=CA_PEM,
                ssl_crlfile=CRL_PEM,
                serverSelectionTimeoutMS=100)
        else:
            connected(MongoClient('localhost',
                                  ssl=True,
                                  ssl_ca_certs=CA_PEM,
                                  serverSelectionTimeoutMS=100,
                                  **self.credentials))

            with self.assertRaises(ConnectionFailure):
                connected(MongoClient('localhost',
                                      ssl=True,
                                      ssl_ca_certs=CA_PEM,
                                      ssl_crlfile=CRL_PEM,
                                      serverSelectionTimeoutMS=100,
                                      **self.credentials))

            uri_fmt = ("mongodb://localhost/?ssl=true&"
                       "ssl_ca_certs=%s&serverSelectionTimeoutMS=100")
            connected(MongoClient(uri_fmt % (CA_PEM,),
                                  **self.credentials))

            uri_fmt = ("mongodb://localhost/?ssl=true&ssl_crlfile=%s"
                       "&ssl_ca_certs=%s&serverSelectionTimeoutMS=100")
            with self.assertRaises(ConnectionFailure):
                connected(MongoClient(uri_fmt % (CRL_PEM, CA_PEM),
                                      **self.credentials))
    def test_auth_from_uri(self):
        self.client.admin.add_user("admin", "pass", roles=["root"])
        self.addCleanup(self.client.admin.remove_user, "admin")
        self.addCleanup(remove_all_users, self.client.pymongo_test)

        self.client.pymongo_test.add_user("user", "pass", roles=["userAdmin", "readWrite"])

        with self.assertRaises(OperationFailure):
            connected(rs_or_single_client("mongodb://*****:*****@%s:%d" % (host, port)))

        # No error.
        connected(rs_or_single_client_noauth("mongodb://*****:*****@%s:%d" % (host, port)))

        # Wrong database.
        uri = "mongodb://*****:*****@%s:%d/pymongo_test" % (host, port)
        with self.assertRaises(OperationFailure):
            connected(rs_or_single_client(uri))

        # No error.
        connected(rs_or_single_client_noauth("mongodb://*****:*****@%s:%d/pymongo_test" % (host, port)))

        # Auth with lazy connection.
        rs_or_single_client(
            "mongodb://*****:*****@%s:%d/pymongo_test" % (host, port), connect=False
        ).pymongo_test.test.find_one()

        # Wrong password.
        bad_client = rs_or_single_client("mongodb://*****:*****@%s:%d/pymongo_test" % (host, port), connect=False)

        self.assertRaises(OperationFailure, bad_client.pymongo_test.test.find_one)
    def test_auth_network_error(self):
        # Make sure there's no semaphore leak if we get a network error
        # when authenticating a new socket with cached credentials.

        # Get a client with one socket so we detect if it's leaked.
        c = connected(rs_or_single_client(maxPoolSize=1,
                                          waitQueueTimeoutMS=1))

        # Simulate an authenticate() call on a different socket.
        credentials = auth._build_credentials_tuple(
            'DEFAULT', 'admin', db_user, db_pwd, {})

        c._cache_credentials('test', credentials, connect=False)

        # Cause a network error on the actual socket.
        pool = get_pool(c)
        socket_info = one(pool.sockets)
        socket_info.sock.close()

        # SocketInfo.check_auth logs in with the new credential, but gets a
        # socket.error. Should be reraised as AutoReconnect.
        self.assertRaises(AutoReconnect, c.test.collection.find_one)

        # No semaphore leak, the pool is allowed to make a new socket.
        c.test.collection.find_one()
    def test_failover(self):
        nthreads = 10
        client = connected(self.mock_client(localThresholdMS=0.001))
        wait_until(lambda: len(client.nodes) == 3, 'connect to all mongoses')

        # Our chosen mongos goes down.
        client.kill_host('a:1')

        # Trigger failover to higher-latency nodes. AutoReconnect should be
        # raised at most once in each thread.
        passed = []

        def f():
            try:
                client.db.command('ismaster')
            except AutoReconnect:
                # Second attempt succeeds.
                client.db.command('ismaster')

            passed.append(True)

        threads = [threading.Thread(target=f) for _ in range(nthreads)]
        for t in threads:
            t.start()

        for t in threads:
            t.join()

        self.assertEqual(nthreads, len(passed))

        # Down host removed from list.
        self.assertEqual(2, len(client.nodes))
    def test_failover(self):
        nthreads = 10
        client = connected(self.mock_client(localThresholdMS=0.001))
        wait_until(lambda: len(client.nodes) == 3, 'connect to all mongoses')

        # Our chosen mongos goes down.
        client.kill_host('a:1')

        # Trigger failover to higher-latency nodes. AutoReconnect should be
        # raised at most once in each thread.
        passed = []

        def f():
            try:
                client.db.command('ismaster')
            except AutoReconnect:
                # Second attempt succeeds.
                client.db.command('ismaster')

            passed.append(True)

        threads = [threading.Thread(target=f) for _ in range(nthreads)]
        for t in threads:
            t.start()

        for t in threads:
            t.join()

        self.assertEqual(nthreads, len(passed))

        # Down host removed from list.
        self.assertEqual(2, len(client.nodes))
    def test_load_balancing(self):
        # Although the server selection JSON tests already prove that
        # select_servers works for sharded topologies, here we do an end-to-end
        # test of discovering servers' round trip times and configuring
        # localThresholdMS.
        client = connected(self.mock_client())
        wait_until(lambda: len(client.nodes) == 3, 'connect to all mongoses')

        # Prohibited for topology type Sharded.
        with self.assertRaises(InvalidOperation):
            client.address

        topology = client._topology
        self.assertEqual(TOPOLOGY_TYPE.Sharded,
                         topology.description.topology_type)

        # a and b are within the 15-ms latency window, see self.mock_client().
        self.assertEqual(set([('a', 1), ('b', 2)]),
                         writable_addresses(topology))

        client.mock_rtts['a:1'] = 0.040

        # Discover only b is within latency window.
        wait_until(lambda: set([('b', 2)]) == writable_addresses(topology),
                   'discover server "a" is too far')
    def test_load_balancing(self):
        # Although the server selection JSON tests already prove that
        # select_servers works for sharded topologies, here we do an end-to-end
        # test of discovering servers' round trip times and configuring
        # localThresholdMS.
        client = connected(self.mock_client())
        wait_until(lambda: len(client.nodes) == 3, 'connect to all mongoses')

        # Prohibited for topology type Sharded.
        with self.assertRaises(InvalidOperation):
            client.address

        topology = client._topology
        self.assertEqual(TOPOLOGY_TYPE.Sharded,
                         topology.description.topology_type)

        # a and b are within the 15-ms latency window, see self.mock_client().
        self.assertEqual(set([('a', 1), ('b', 2)]),
                         writable_addresses(topology))

        client.mock_rtts['a:1'] = 0.045

        # Discover only b is within latency window.
        wait_until(lambda: set([('b', 2)]) == writable_addresses(topology),
                   'discover server "a" is too far')
    def test_auth_network_error(self):
        # Make sure there's no semaphore leak if we get a network error
        # when authenticating a new socket with cached credentials.

        # Get a client with one socket so we detect if it's leaked.
        c = connected(rs_or_single_client(maxPoolSize=1,
                                          waitQueueTimeoutMS=1))

        # Simulate an authenticate() call on a different socket.
        credentials = auth._build_credentials_tuple(
            'DEFAULT', 'admin', db_user, db_pwd, {})

        c._cache_credentials('test', credentials, connect=False)

        # Cause a network error on the actual socket.
        pool = get_pool(c)
        socket_info = one(pool.sockets)
        socket_info.sock.close()

        # SocketInfo.check_auth logs in with the new credential, but gets a
        # socket.error. Should be reraised as AutoReconnect.
        self.assertRaises(AutoReconnect, c.test.collection.find_one)

        # No semaphore leak, the pool is allowed to make a new socket.
        c.test.collection.find_one()
    def test_local_threshold(self):
        client = connected(self.mock_client(localThresholdMS=30))
        wait_until(lambda: len(client.nodes) == 3, 'connect to all mongoses')
        topology = client._topology

        # All are within a 30-ms latency window, see self.mock_client().
        self.assertEqual(set([('a', 1), ('b', 2), ('c', 3)]),
                         writable_addresses(topology))
    def test_local_threshold(self):
        client = connected(self.mock_client(localThresholdMS=30))
        wait_until(lambda: len(client.nodes) == 3, 'connect to all mongoses')
        topology = client._topology

        # All are within a 30-ms latency window, see self.mock_client().
        self.assertEqual(set([('a', 1), ('b', 2), ('c', 3)]),
                         writable_addresses(topology))
Beispiel #27
0
    def test_connect_with_internal_ips(self):
        # Client is passed an IP it can reach, 'a:1', but the RS config
        # only contains unreachable IPs like 'internal-ip'. PYTHON-608.
        with self.assertRaises(AutoReconnect) as context:
            connected(
                MockClient(standalones=[],
                           members=['a:1'],
                           mongoses=[],
                           ismaster_hosts=['internal-ip:27017'],
                           host='a:1',
                           replicaSet='rs',
                           serverSelectionTimeoutMS=100))

        self.assertEqual(
            "Could not reach any servers in [('internal-ip', 27017)]."
            " Replica set is configured with internal hostnames or IPs?",
            str(context.exception))
    def test_connect_with_internal_ips(self):
        # Client is passed an IP it can reach, 'a:1', but the RS config
        # only contains unreachable IPs like 'internal-ip'. PYTHON-608.
        with self.assertRaises(AutoReconnect) as context:
            connected(MockClient(
                standalones=[],
                members=['a:1'],
                mongoses=[],
                ismaster_hosts=['internal-ip:27017'],
                host='a:1',
                replicaSet='rs',
                serverSelectionTimeoutMS=100))

        self.assertEqual(
            "Could not reach any servers in [('internal-ip', 27017)]."
            " Replica set is configured with internal hostnames or IPs?",
            str(context.exception))
Beispiel #29
0
    def test_validation_with_system_ca_certs(self):
        # Expects the server to be running with server.pem and ca.pem.
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        #   --sslWeakCertificateValidation
        #
        if sys.platform == "win32":
            raise SkipTest("Can't test system ca certs on Windows.")

        if sys.version_info < (2, 7, 9):
            raise SkipTest("Can't load system CA certificates.")

        if (ssl.OPENSSL_VERSION.lower().startswith('libressl')
                and sys.platform == 'darwin' and not _ssl.IS_PYOPENSSL):
            raise SkipTest(
                "LibreSSL on OSX doesn't support setting CA certificates "
                "using SSL_CERT_FILE environment variable.")

        # Tell OpenSSL where CA certificates live.
        os.environ['SSL_CERT_FILE'] = CA_PEM
        try:
            with self.assertRaises(ConnectionFailure):
                # Server cert is verified but hostname matching fails
                connected(
                    MongoClient('server',
                                ssl=True,
                                serverSelectionTimeoutMS=100,
                                **self.credentials))

            # Server cert is verified. Disable hostname matching.
            connected(
                MongoClient('server',
                            ssl=True,
                            ssl_match_hostname=False,
                            serverSelectionTimeoutMS=100,
                            **self.credentials))

            # Server cert and hostname are verified.
            connected(
                MongoClient('localhost',
                            ssl=True,
                            serverSelectionTimeoutMS=100,
                            **self.credentials))

            # Server cert and hostname are verified.
            connected(
                MongoClient(
                    'mongodb://localhost/?ssl=true&serverSelectionTimeoutMS=100',
                    **self.credentials))
        finally:
            os.environ.pop('SSL_CERT_FILE')
Beispiel #30
0
def get_client():
    # Attempt a direct connection to each node until one succeeds. Using a
    # non-PRIMARY read preference allows us to use the node even if it's a
    # secondary.
    for i, node in enumerate(nodes.keys()):
        try:
            return connected(
                pymongo.MongoClient(
                    node, read_preference=ReadPreference.PRIMARY_PREFERRED))
        except pymongo.errors.ConnectionFailure:
            if i == len(nodes) - 1:
                raise
Beispiel #31
0
    def test_cert_ssl_validation_hostname_matching(self):
        # Expects the server to be running with server.pem and ca.pem
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        #
        response = self.client.admin.command('ismaster')

        with self.assertRaises(ConnectionFailure):
            connected(
                MongoClient('server',
                            ssl=True,
                            ssl_certfile=CLIENT_PEM,
                            ssl_cert_reqs=ssl.CERT_REQUIRED,
                            ssl_ca_certs=CA_PEM,
                            serverSelectionTimeoutMS=100,
                            **self.credentials))

        connected(
            MongoClient('server',
                        ssl=True,
                        ssl_certfile=CLIENT_PEM,
                        ssl_cert_reqs=ssl.CERT_REQUIRED,
                        ssl_ca_certs=CA_PEM,
                        ssl_match_hostname=False,
                        serverSelectionTimeoutMS=100,
                        **self.credentials))

        if 'setName' in response:
            with self.assertRaises(ConnectionFailure):
                connected(
                    MongoClient('server',
                                replicaSet=response['setName'],
                                ssl=True,
                                ssl_certfile=CLIENT_PEM,
                                ssl_cert_reqs=ssl.CERT_REQUIRED,
                                ssl_ca_certs=CA_PEM,
                                serverSelectionTimeoutMS=100,
                                **self.credentials))

            connected(
                MongoClient('server',
                            replicaSet=response['setName'],
                            ssl=True,
                            ssl_certfile=CLIENT_PEM,
                            ssl_cert_reqs=ssl.CERT_REQUIRED,
                            ssl_ca_certs=CA_PEM,
                            ssl_match_hostname=False,
                            serverSelectionTimeoutMS=100,
                            **self.credentials))
    def test_validation_with_system_ca_certs(self):
        # Expects the server to be running with the server.pem, ca.pem
        # and crl.pem provided in mongodb and the server tests eg:
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        #   --sslCRLFile=/path/to/pymongo/test/certificates/crl.pem
        #   --sslWeakCertificateValidation
        #
        # Also requires an /etc/hosts entry where "server" is resolvable
        if not CERT_SSL:
            raise SkipTest("No mongod available over SSL with certs")

        if not SERVER_IS_RESOLVABLE:
            raise SkipTest("No hosts entry for 'server'. Cannot validate "
                           "hostname in the certificate")

        if sys.platform == "win32":
            raise SkipTest("Can't test system ca certs on Windows.")

        if sys.version_info < (2, 7, 9):
            raise SkipTest("Can't load system CA certificates.")


        # Tell OpenSSL where CA certificates live.
        os.environ['SSL_CERT_FILE'] = CA_PEM
        try:
            with self.assertRaises(ConnectionFailure):
                # Server cert is verified but hostname matching fails
                connected(MongoClient(pair,
                                      ssl=True,
                                      serverSelectionTimeoutMS=100))

            # Server cert is verified. Disable hostname matching.
            connected(MongoClient(pair,
                                  ssl=True,
                                  ssl_match_hostname=False,
                                  serverSelectionTimeoutMS=100))

            # Server cert and hostname are verified.
            connected(MongoClient('server',
                                  ssl=True,
                                  serverSelectionTimeoutMS=100))

            # Server cert and hostname are verified.
            connected(
                MongoClient(
                    'mongodb://server/?ssl=true&serverSelectionTimeoutMS=100'))
        finally:
            os.environ.pop('SSL_CERT_FILE')
Beispiel #33
0
    def test_cert_ssl_validation_hostname_matching(self):
        # Expects the server to be running with the server.pem, ca.pem
        # and crl.pem provided in mongodb and the server tests eg:
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        #   --sslCRLFile=/path/to/pymongo/test/certificates/crl.pem
        if not CERT_SSL:
            raise SkipTest("No mongod available over SSL with certs")

        response = ssl_client.admin.command('ismaster')

        with self.assertRaises(ConnectionFailure):
            connected(
                MongoClient(pair,
                            ssl=True,
                            ssl_certfile=CLIENT_PEM,
                            ssl_cert_reqs=ssl.CERT_REQUIRED,
                            ssl_ca_certs=CA_PEM,
                            serverSelectionTimeoutMS=100))

        connected(
            MongoClient(pair,
                        ssl=True,
                        ssl_certfile=CLIENT_PEM,
                        ssl_cert_reqs=ssl.CERT_REQUIRED,
                        ssl_ca_certs=CA_PEM,
                        ssl_match_hostname=False,
                        serverSelectionTimeoutMS=100))

        if 'setName' in response:
            with self.assertRaises(ConnectionFailure):
                connected(
                    MongoClient(pair,
                                replicaSet=response['setName'],
                                ssl=True,
                                ssl_certfile=CLIENT_PEM,
                                ssl_cert_reqs=ssl.CERT_REQUIRED,
                                ssl_ca_certs=CA_PEM,
                                serverSelectionTimeoutMS=100))

            connected(
                MongoClient(pair,
                            replicaSet=response['setName'],
                            ssl=True,
                            ssl_certfile=CLIENT_PEM,
                            ssl_cert_reqs=ssl.CERT_REQUIRED,
                            ssl_ca_certs=CA_PEM,
                            ssl_match_hostname=False,
                            serverSelectionTimeoutMS=100))
def get_client():
    # Attempt a direct connection to each node until one succeeds. Using a
    # non-PRIMARY read preference allows us to use the node even if it's a
    # secondary.
    for i, node in enumerate(nodes.keys()):
        try:
            return connected(
                pymongo.MongoClient(
                    node,
                    read_preference=ReadPreference.PRIMARY_PREFERRED))
        except pymongo.errors.ConnectionFailure:
            if i == len(nodes) - 1:
                raise
Beispiel #35
0
    def test_exhaust_network_error(self):
        # When doing an exhaust query, the socket stays checked out on success
        # but must be checked in on error to avoid semaphore leaks.
        client = rs_or_single_client(maxPoolSize=1)
        collection = client.pymongo_test.test
        pool = get_pool(client)
        pool._check_interval_seconds = None  # Never check.

        # Ensure a socket.
        connected(client)

        # Cause a network error.
        sock_info = one(pool.sockets)
        sock_info.sock.close()
        cursor = collection.find(cursor_type=CursorType.EXHAUST)
        with self.assertRaises(ConnectionFailure):
            next(cursor)

        self.assertTrue(sock_info.closed)

        # The semaphore was decremented despite the error.
        self.assertTrue(pool._socket_semaphore.acquire(blocking=False))
    def test_reconnect(self):
        nthreads = 10
        client = connected(self.mock_client())

        # connected() ensures we've contacted at least one mongos. Wait for
        # all of them.
        wait_until(lambda: len(client.nodes) == 3, 'connect to all mongoses')

        # Trigger reconnect.
        client.close()
        do_simple_op(client, nthreads)

        wait_until(lambda: len(client.nodes) == 3, 'reconnect to all mongoses')
    def test_exhaust_network_error(self):
        # When doing an exhaust query, the socket stays checked out on success
        # but must be checked in on error to avoid semaphore leaks.
        client = rs_or_single_client(maxPoolSize=1)
        collection = client.pymongo_test.test
        pool = get_pool(client)
        pool._check_interval_seconds = None  # Never check.

        # Ensure a socket.
        connected(client)

        # Cause a network error.
        sock_info = one(pool.sockets)
        sock_info.sock.close()
        cursor = collection.find(cursor_type=CursorType.EXHAUST)
        with self.assertRaises(ConnectionFailure):
            next(cursor)

        self.assertTrue(sock_info.closed)

        # The semaphore was decremented despite the error.
        self.assertTrue(pool._socket_semaphore.acquire(blocking=False))
Beispiel #38
0
    def test_validation_with_system_ca_certs(self):
        # Expects the server to be running with the server.pem, ca.pem
        # and crl.pem provided in mongodb and the server tests eg:
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        #   --sslCRLFile=/path/to/pymongo/test/certificates/crl.pem
        #   --sslWeakCertificateValidation
        #
        # Also requires an /etc/hosts entry where "server" is resolvable
        if not CERT_SSL:
            raise SkipTest("No mongod available over SSL with certs")

        if not SERVER_IS_RESOLVABLE:
            raise SkipTest("No hosts entry for 'server'. Cannot validate "
                           "hostname in the certificate")

        if sys.platform == "win32":
            raise SkipTest("Can't test system ca certs on Windows.")

        if sys.version_info < (2, 7, 9):
            raise SkipTest("Can't load system CA certificates.")

        # Tell OpenSSL where CA certificates live.
        os.environ['SSL_CERT_FILE'] = CA_PEM
        try:
            with self.assertRaises(ConnectionFailure):
                # Server cert is verified but hostname matching fails
                connected(
                    MongoClient(pair, ssl=True, serverSelectionTimeoutMS=100))

            # Server cert is verified. Disable hostname matching.
            connected(
                MongoClient(pair,
                            ssl=True,
                            ssl_match_hostname=False,
                            serverSelectionTimeoutMS=100))

            # Server cert and hostname are verified.
            connected(
                MongoClient('server', ssl=True, serverSelectionTimeoutMS=100))

            # Server cert and hostname are verified.
            connected(
                MongoClient(
                    'mongodb://server/?ssl=true&serverSelectionTimeoutMS=100'))
        finally:
            os.environ.pop('SSL_CERT_FILE')
    def test_reconnect(self):
        nthreads = 10
        client = connected(self.mock_client())

        # connected() ensures we've contacted at least one mongos. Wait for
        # all of them.
        wait_until(lambda: len(client.nodes) == 3, 'connect to all mongoses')

        # Trigger reconnect.
        client.close()
        do_simple_op(client, nthreads)

        wait_until(lambda: len(client.nodes) == 3,
                   'reconnect to all mongoses')
    def test_socket_timeout_ms_validation(self):
        c = rs_or_single_client(socketTimeoutMS=10 * 1000)
        self.assertEqual(10, get_pool(c).opts.socket_timeout)

        c = connected(rs_or_single_client(socketTimeoutMS=None))
        self.assertEqual(None, get_pool(c).opts.socket_timeout)

        self.assertRaises(ValueError, rs_or_single_client, socketTimeoutMS=0)

        self.assertRaises(ValueError, rs_or_single_client, socketTimeoutMS=-1)

        self.assertRaises(ValueError, rs_or_single_client, socketTimeoutMS=1e10)

        self.assertRaises(ValueError, rs_or_single_client, socketTimeoutMS="foo")
Beispiel #41
0
    def test_cert_ssl_validation_hostname_matching(self):
        # Expects the server to be running with the server.pem, ca.pem
        # and crl.pem provided in mongodb and the server tests eg:
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        #   --sslCRLFile=/path/to/pymongo/test/certificates/crl.pem
        if not CERT_SSL:
            raise SkipTest("No mongod available over SSL with certs")

        response = ssl_client.admin.command('ismaster')

        with self.assertRaises(ConnectionFailure):
            connected(MongoClient(pair,
                                  ssl=True,
                                  ssl_certfile=CLIENT_PEM,
                                  ssl_cert_reqs=ssl.CERT_REQUIRED,
                                  ssl_ca_certs=CA_PEM,
                                  serverSelectionTimeoutMS=100))

        connected(MongoClient(pair,
                              ssl=True,
                              ssl_certfile=CLIENT_PEM,
                              ssl_cert_reqs=ssl.CERT_REQUIRED,
                              ssl_ca_certs=CA_PEM,
                              ssl_match_hostname=False,
                              serverSelectionTimeoutMS=100))


        if 'setName' in response:
            with self.assertRaises(ConnectionFailure):
                connected(MongoClient(pair,
                                      replicaSet=response['setName'],
                                      ssl=True,
                                      ssl_certfile=CLIENT_PEM,
                                      ssl_cert_reqs=ssl.CERT_REQUIRED,
                                      ssl_ca_certs=CA_PEM,
                                      serverSelectionTimeoutMS=100))

            connected(MongoClient(pair,
                                  replicaSet=response['setName'],
                                  ssl=True,
                                  ssl_certfile=CLIENT_PEM,
                                  ssl_cert_reqs=ssl.CERT_REQUIRED,
                                  ssl_ca_certs=CA_PEM,
                                  ssl_match_hostname=False,
                                  serverSelectionTimeoutMS=100))
 def test_zero_latency(self):
     ping_times = set()
     # Generate unique ping times.
     while len(ping_times) < len(self.client.nodes):
         ping_times.add(random.random())
     for ping_time, host in zip(ping_times, self.client.nodes):
         ServerDescription._host_to_round_trip_time[host] = ping_time
     try:
         client = connected(
             rs_client(readPreference='nearest', localThresholdMS=0))
         wait_until(lambda: client.nodes == self.client.nodes,
                    "discovered all nodes")
         host = self.read_from_which_host(client)
         for _ in range(5):
             self.assertEqual(host, self.read_from_which_host(client))
     finally:
         ServerDescription._host_to_round_trip_time.clear()
    def test_validation_with_system_ca_certs(self):
        # Expects the server to be running with server.pem and ca.pem.
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        #   --sslWeakCertificateValidation
        #
        if sys.platform == "win32":
            raise SkipTest("Can't test system ca certs on Windows.")

        if sys.version_info < (2, 7, 9):
            raise SkipTest("Can't load system CA certificates.")

        # Tell OpenSSL where CA certificates live.
        os.environ['SSL_CERT_FILE'] = CA_PEM
        try:
            with self.assertRaises(ConnectionFailure):
                # Server cert is verified but hostname matching fails
                connected(MongoClient('server',
                                      ssl=True,
                                      serverSelectionTimeoutMS=100,
                                      **self.credentials))

            # Server cert is verified. Disable hostname matching.
            connected(MongoClient('server',
                                  ssl=True,
                                  ssl_match_hostname=False,
                                  serverSelectionTimeoutMS=100,
                                  **self.credentials))

            # Server cert and hostname are verified.
            connected(MongoClient('localhost',
                                  ssl=True,
                                  serverSelectionTimeoutMS=100,
                                  **self.credentials))

            # Server cert and hostname are verified.
            connected(
                MongoClient(
                    'mongodb://localhost/?ssl=true&serverSelectionTimeoutMS=100',
                    **self.credentials))
        finally:
            os.environ.pop('SSL_CERT_FILE')
Beispiel #44
0
    def test_validation_with_system_ca_certs(self):
        # Expects the server to be running with server.pem and ca.pem.
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        #   --sslWeakCertificateValidation
        #
        if sys.platform == "win32":
            raise SkipTest("Can't test system ca certs on Windows.")

        if sys.version_info < (2, 7, 9):
            raise SkipTest("Can't load system CA certificates.")

        # Tell OpenSSL where CA certificates live.
        os.environ['SSL_CERT_FILE'] = CA_PEM
        try:
            with self.assertRaises(ConnectionFailure):
                # Server cert is verified but hostname matching fails
                connected(
                    MongoClient('server',
                                ssl=True,
                                serverSelectionTimeoutMS=100))

            # Server cert is verified. Disable hostname matching.
            connected(
                MongoClient('server',
                            ssl=True,
                            ssl_match_hostname=False,
                            serverSelectionTimeoutMS=100))

            # Server cert and hostname are verified.
            connected(
                MongoClient('localhost',
                            ssl=True,
                            serverSelectionTimeoutMS=100))

            # Server cert and hostname are verified.
            connected(
                MongoClient(
                    'mongodb://localhost/?ssl=true&serverSelectionTimeoutMS=100'
                ))
        finally:
            os.environ.pop('SSL_CERT_FILE')
 def test_zero_latency(self):
     ping_times = set()
     # Generate unique ping times.
     while len(ping_times) < len(self.client.nodes):
         ping_times.add(random.random())
     for ping_time, host in zip(ping_times, self.client.nodes):
         ServerDescription._host_to_round_trip_time[host] = ping_time
     try:
         client = connected(
             rs_client(readPreference='nearest', localThresholdMS=0))
         wait_until(
             lambda: client.nodes == self.client.nodes,
             "discovered all nodes")
         host = self.read_from_which_host(client)
         for _ in range(5):
             self.assertEqual(host, self.read_from_which_host(client))
     finally:
         ServerDescription._host_to_round_trip_time.clear()
Beispiel #46
0
    def test_cert_ssl_validation_hostname_matching(self):
        # Expects the server to be running with server.pem and ca.pem
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        #
        response = self.client.admin.command('ismaster')

        with self.assertRaises(ConnectionFailure):
            connected(MongoClient('server',
                                  ssl=True,
                                  ssl_certfile=CLIENT_PEM,
                                  ssl_cert_reqs=ssl.CERT_REQUIRED,
                                  ssl_ca_certs=CA_PEM,
                                  serverSelectionTimeoutMS=100))

        connected(MongoClient('server',
                              ssl=True,
                              ssl_certfile=CLIENT_PEM,
                              ssl_cert_reqs=ssl.CERT_REQUIRED,
                              ssl_ca_certs=CA_PEM,
                              ssl_match_hostname=False,
                              serverSelectionTimeoutMS=100))

        if 'setName' in response:
            with self.assertRaises(ConnectionFailure):
                connected(MongoClient('server',
                                      replicaSet=response['setName'],
                                      ssl=True,
                                      ssl_certfile=CLIENT_PEM,
                                      ssl_cert_reqs=ssl.CERT_REQUIRED,
                                      ssl_ca_certs=CA_PEM,
                                      serverSelectionTimeoutMS=100))

            connected(MongoClient('server',
                                  replicaSet=response['setName'],
                                  ssl=True,
                                  ssl_certfile=CLIENT_PEM,
                                  ssl_cert_reqs=ssl.CERT_REQUIRED,
                                  ssl_ca_certs=CA_PEM,
                                  ssl_match_hostname=False,
                                  serverSelectionTimeoutMS=100))
Beispiel #47
0
    def test_socket_timeout_ms_validation(self):
        c = rs_or_single_client(socketTimeoutMS=10 * 1000)
        self.assertEqual(10, get_pool(c).opts.socket_timeout)

        c = connected(rs_or_single_client(socketTimeoutMS=None))
        self.assertEqual(None, get_pool(c).opts.socket_timeout)

        self.assertRaises(ValueError, rs_or_single_client, socketTimeoutMS=0)

        self.assertRaises(ValueError, rs_or_single_client, socketTimeoutMS=-1)

        self.assertRaises(ValueError,
                          rs_or_single_client,
                          socketTimeoutMS=1e10)

        self.assertRaises(ValueError,
                          rs_or_single_client,
                          socketTimeoutMS='foo')
    def test_exhaust_query_server_error(self):
        # When doing an exhaust query, the socket stays checked out on success
        # but must be checked in on error to avoid semaphore leaks.
        client = connected(rs_or_single_client(maxPoolSize=1))

        collection = client.pymongo_test.test
        pool = get_pool(client)
        sock_info = one(pool.sockets)

        # This will cause OperationFailure in all mongo versions since
        # the value for $orderby must be a document.
        cursor = collection.find(SON([("$query", {}), ("$orderby", True)]), cursor_type=CursorType.EXHAUST)

        self.assertRaises(OperationFailure, cursor.next)
        self.assertFalse(sock_info.closed)

        # The socket was checked in and the semaphore was decremented.
        self.assertIn(sock_info, pool.sockets)
        self.assertTrue(pool._socket_semaphore.acquire(blocking=False))
Beispiel #49
0
    def test_auth_from_uri(self):
        self.client.admin.add_user("admin", "pass", roles=["root"])
        self.addCleanup(self.client.admin.remove_user, 'admin')
        self.addCleanup(remove_all_users, self.client.pymongo_test)

        self.client.pymongo_test.add_user("user",
                                          "pass",
                                          roles=['userAdmin', 'readWrite'])

        with self.assertRaises(OperationFailure):
            connected(rs_or_single_client("mongodb://*****:*****@%s:%d" %
                                          (host, port)))

        # No error.
        connected(
            rs_or_single_client_noauth("mongodb://*****:*****@%s:%d" %
                                       (host, port)))

        # Wrong database.
        uri = "mongodb://*****:*****@%s:%d/pymongo_test" % (host, port)
        with self.assertRaises(OperationFailure):
            connected(rs_or_single_client(uri))

        # No error.
        connected(
            rs_or_single_client_noauth(
                "mongodb://*****:*****@%s:%d/pymongo_test" % (host, port)))

        # Auth with lazy connection.
        rs_or_single_client("mongodb://*****:*****@%s:%d/pymongo_test" %
                            (host, port),
                            connect=False).pymongo_test.test.find_one()

        # Wrong password.
        bad_client = rs_or_single_client(
            "mongodb://*****:*****@%s:%d/pymongo_test" % (host, port),
            connect=False)

        self.assertRaises(OperationFailure,
                          bad_client.pymongo_test.test.find_one)
Beispiel #50
0
    def test_ssl_crlfile_support(self):
        # Expects the server to be running with server.pem and ca.pem
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        if not CERT_SSL:
            raise SkipTest("No mongod available over SSL with certs")

        if not hasattr(ssl, 'VERIFY_CRL_CHECK_LEAF'):
            self.assertRaises(ConfigurationError,
                              MongoClient,
                              'server',
                              ssl=True,
                              ssl_ca_certs=CA_PEM,
                              ssl_crlfile=CRL_PEM,
                              serverSelectionTimeoutMS=100)
        else:
            connected(
                MongoClient('server',
                            ssl=True,
                            ssl_ca_certs=CA_PEM,
                            serverSelectionTimeoutMS=100))

            with self.assertRaises(ConnectionFailure):
                connected(
                    MongoClient('server',
                                ssl=True,
                                ssl_ca_certs=CA_PEM,
                                ssl_crlfile=CRL_PEM,
                                serverSelectionTimeoutMS=100))

            uri_fmt = ("mongodb://server/?ssl=true&"
                       "ssl_ca_certs=%s&serverSelectionTimeoutMS=100")
            connected(MongoClient(uri_fmt % (CA_PEM, )))

            uri_fmt = ("mongodb://server/?ssl=true&ssl_crlfile=%s"
                       "&ssl_ca_certs=%s&serverSelectionTimeoutMS=100")
            with self.assertRaises(ConnectionFailure):
                connected(MongoClient(uri_fmt % (CRL_PEM, CA_PEM)))
Beispiel #51
0
 def test_zero_latency(self):
     if (client_context.version >= (3, 7, 2) and client_context.auth_enabled
             and client_context.is_rs):
         raise SkipTest("Disabled due to SERVER-32845")
     ping_times = set()
     # Generate unique ping times.
     while len(ping_times) < len(self.client.nodes):
         ping_times.add(random.random())
     for ping_time, host in zip(ping_times, self.client.nodes):
         ServerDescription._host_to_round_trip_time[host] = ping_time
     try:
         client = connected(
             rs_client(readPreference='nearest', localThresholdMS=0))
         wait_until(lambda: client.nodes == self.client.nodes,
                    "discovered all nodes")
         host = self.read_from_which_host(client)
         for _ in range(5):
             self.assertEqual(host, self.read_from_which_host(client))
     finally:
         ServerDescription._host_to_round_trip_time.clear()
Beispiel #52
0
    def test_exhaust_query_server_error(self):
        # When doing an exhaust query, the socket stays checked out on success
        # but must be checked in on error to avoid semaphore leaks.
        client = connected(rs_or_single_client(maxPoolSize=1))

        collection = client.pymongo_test.test
        pool = get_pool(client)
        sock_info = one(pool.sockets)

        # This will cause OperationFailure in all mongo versions since
        # the value for $orderby must be a document.
        cursor = collection.find(SON([('$query', {}), ('$orderby', True)]),
                                 cursor_type=CursorType.EXHAUST)

        self.assertRaises(OperationFailure, cursor.next)
        self.assertFalse(sock_info.closed)

        # The socket was checked in and the semaphore was decremented.
        self.assertIn(sock_info, pool.sockets)
        self.assertTrue(pool._socket_semaphore.acquire(blocking=False))
    def test_ssl_crlfile_support(self):
        # Expects the server to be running with server.pem and ca.pem
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        if not CERT_SSL:
            raise SkipTest("No mongod available over SSL with certs")

        if not hasattr(ssl, 'VERIFY_CRL_CHECK_LEAF'):
            self.assertRaises(
                ConfigurationError,
                MongoClient,
                'server',
                ssl=True,
                ssl_ca_certs=CA_PEM,
                ssl_crlfile=CRL_PEM,
                serverSelectionTimeoutMS=100)
        else:
            connected(MongoClient('server',
                                  ssl=True,
                                  ssl_ca_certs=CA_PEM,
                                  serverSelectionTimeoutMS=100))

            with self.assertRaises(ConnectionFailure):
                connected(MongoClient('server',
                                      ssl=True,
                                      ssl_ca_certs=CA_PEM,
                                      ssl_crlfile=CRL_PEM,
                                      serverSelectionTimeoutMS=100))

            uri_fmt = ("mongodb://server/?ssl=true&"
                       "ssl_ca_certs=%s&serverSelectionTimeoutMS=100")
            connected(MongoClient(uri_fmt % (CA_PEM,)))

            uri_fmt = ("mongodb://server/?ssl=true&ssl_crlfile=%s"
                       "&ssl_ca_certs=%s&serverSelectionTimeoutMS=100")
            with self.assertRaises(ConnectionFailure):
                connected(MongoClient(uri_fmt % (CRL_PEM, CA_PEM)))
Beispiel #54
0
    def test_constants(self):
        # Set bad defaults.
        MongoClient.HOST = "somedomainthatdoesntexist.org"
        MongoClient.PORT = 123456789
        with self.assertRaises(AutoReconnect):
            connected(MongoClient(serverSelectionTimeoutMS=10))

        # Override the defaults. No error.
        connected(MongoClient(host, port))

        # Set good defaults.
        MongoClient.HOST = host
        MongoClient.PORT = port

        # No error.
        connected(MongoClient())
    def test_constants(self):
        # Set bad defaults.
        MongoClient.HOST = "somedomainthatdoesntexist.org"
        MongoClient.PORT = 123456789
        with self.assertRaises(AutoReconnect):
            connected(MongoClient(serverSelectionTimeoutMS=10))

        # Override the defaults. No error.
        connected(MongoClient(host, port))

        # Set good defaults.
        MongoClient.HOST = host
        MongoClient.PORT = port

        # No error.
        connected(MongoClient())
    def test_validation_with_system_ca_certs(self):
        # Expects the server to be running with server.pem and ca.pem.
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        #   --sslWeakCertificateValidation
        #
        self.patch_system_certs(CA_PEM)
        with self.assertRaises(ConnectionFailure):
            # Server cert is verified but hostname matching fails
            connected(
                MongoClient('server',
                            ssl=True,
                            serverSelectionTimeoutMS=100,
                            **self.credentials))

        # Server cert is verified. Disable hostname matching.
        connected(
            MongoClient('server',
                        ssl=True,
                        tlsAllowInvalidHostnames=True,
                        serverSelectionTimeoutMS=100,
                        **self.credentials))

        # Server cert and hostname are verified.
        connected(
            MongoClient('localhost',
                        ssl=True,
                        serverSelectionTimeoutMS=100,
                        **self.credentials))

        # Server cert and hostname are verified.
        connected(
            MongoClient(
                'mongodb://localhost/?ssl=true&serverSelectionTimeoutMS=100',
                **self.credentials))
Beispiel #57
0
    def test_mongodb_x509_auth(self):
        # Expects the server to be running with the server.pem, ca.pem
        # and crl.pem provided in mongodb and the server tests as well as
        # --auth
        #
        #   --sslPEMKeyFile=/path/to/pymongo/test/certificates/server.pem
        #   --sslCAFile=/path/to/pymongo/test/certificates/ca.pem
        #   --sslCRLFile=/path/to/pymongo/test/certificates/crl.pem
        #   --auth
        if not CERT_SSL:
            raise SkipTest("No mongod available over SSL with certs")

        if not Version.from_client(ssl_client).at_least(2, 5, 3, -1):
            raise SkipTest("MONGODB-X509 tests require MongoDB 2.5.3 or newer")
        if not server_started_with_auth(ssl_client):
            raise SkipTest('Authentication is not enabled on server')

        self.addCleanup(ssl_client['$external'].logout)
        self.addCleanup(remove_all_users, ssl_client['$external'])

        # Give admin all necessary privileges.
        ssl_client['$external'].add_user(MONGODB_X509_USERNAME, roles=[
            {'role': 'readWriteAnyDatabase', 'db': 'admin'},
            {'role': 'userAdminAnyDatabase', 'db': 'admin'}])

        coll = ssl_client.pymongo_test.test
        self.assertRaises(OperationFailure, coll.count)
        self.assertTrue(ssl_client.admin.authenticate(
            MONGODB_X509_USERNAME, mechanism='MONGODB-X509'))
        coll.drop()
        uri = ('mongodb://%s@%s:%d/?authMechanism='
               'MONGODB-X509' % (
                   quote_plus(MONGODB_X509_USERNAME), host, port))
        # SSL options aren't supported in the URI...
        self.assertTrue(MongoClient(uri,
                                    ssl=True, ssl_certfile=CLIENT_PEM))

        # Should require a username
        uri = ('mongodb://%s:%d/?authMechanism=MONGODB-X509' % (host,
                                                                port))
        client_bad = MongoClient(uri, ssl=True, ssl_certfile=CLIENT_PEM)
        self.assertRaises(OperationFailure,
                          client_bad.pymongo_test.test.delete_one, {})

        # Auth should fail if username and certificate do not match
        uri = ('mongodb://%s@%s:%d/?authMechanism='
               'MONGODB-X509' % (
                   quote_plus("not the username"), host, port))

        bad_client = MongoClient(uri, ssl=True, ssl_certfile=CLIENT_PEM)
        with self.assertRaises(OperationFailure):
            bad_client.pymongo_test.test.find_one()

        self.assertRaises(OperationFailure, ssl_client.admin.authenticate,
                          "not the username",
                          mechanism="MONGODB-X509")

        # Invalid certificate (using CA certificate as client certificate)
        uri = ('mongodb://%s@%s:%d/?authMechanism='
               'MONGODB-X509' % (
                   quote_plus(MONGODB_X509_USERNAME), host, port))
        # These tests will raise SSLError (>= 3.2) or ConnectionFailure
        # (2.x) depending on where OpenSSL first sees the PEM file.
        try:
            connected(MongoClient(uri, ssl=True, ssl_certfile=CA_PEM,
                                  serverSelectionTimeoutMS=100))
        except (ssl.SSLError, ConnectionFailure):
            pass
        else:
            self.fail("Invalid certificate accepted.")

        try:
            connected(MongoClient(pair, ssl=True, ssl_certfile=CA_PEM,
                                  serverSelectionTimeoutMS=100))
        except (ssl.SSLError, ConnectionFailure):
            pass
        else:
            self.fail("Invalid certificate accepted.")
Beispiel #58
0
        except socket.error:
            return False
    finally:
        socket.setdefaulttimeout(socket_timeout)

# Shared ssl-enabled client for the tests
ssl_client = None

if HAVE_SSL:
    import ssl

    # Check this all once instead of before every test method below.

    # Is MongoDB configured for SSL?
    try:
        connected(MongoClient(host, port, ssl=True,
                              serverSelectionTimeoutMS=100))

        SIMPLE_SSL = True
    except ConnectionFailure:
        pass

    # Is MongoDB configured with server.pem, ca.pem, and crl.pem from
    # mongodb jstests/lib?
    try:
        ssl_client = connected(MongoClient(
            host, port, ssl=True, ssl_certfile=CLIENT_PEM,
            serverSelectionTimeoutMS=100))

        CERT_SSL = True
    except ConnectionFailure:
        pass
    def test_equality(self):
        c = connected(rs_or_single_client())
        self.assertEqual(client_context.rs_or_standalone_client, c)

        # Explicitly test inequality
        self.assertFalse(client_context.rs_or_standalone_client != c)
 def test_host_w_port(self):
     with self.assertRaises(ValueError):
         connected(MongoClient("%s:1234567" % host, connectTimeoutMS=1,
                               serverSelectionTimeoutMS=10))