def test_actionable_error_message(self): if client_context.storage_engine != 'mmapv1': raise SkipTest('This cluster is not running MMAPv1') expected_msg = ("This MongoDB deployment does not support retryable " "writes. Please add retryWrites=false to your " "connection string.") for method, args, kwargs in retryable_single_statement_ops( self.db.retryable_write_test): with self.assertRaisesRegex(OperationFailure, expected_msg): method(*args, **kwargs)
def test_fetch_next_delete(self): if sys.version_info < (3, 4): raise SkipTest("requires Python 3.4") if 'PyPy' in sys.version: raise SkipTest('PyPy') client, server = self.client_server(auto_ismaster={'ismaster': True}) cursor = client.test.collection.find() # With Tornado, simply accessing fetch_next starts the fetch. cursor.fetch_next request = yield self.run_thread(server.receives, OpQuery) request.replies({'_id': 1}, cursor_id=123) # Decref'ing the cursor eventually closes it on the server. del cursor # Clear Runner's reference. This is Tornado 3 substitute for gen.moment. yield gen.Task(self.io_loop.add_callback) yield self.run_thread(server.receives, OpKillCursors(cursor_ids=[123]))
def test_gssapi_threaded(self): client = MongoClient(GSSAPI_HOST, GSSAPI_PORT, username=GSSAPI_PRINCIPAL, password=GSSAPI_PASS, authMechanism='GSSAPI', authMechanismProperties=self.mech_properties) # Authentication succeeded? client.server_info() db = client[GSSAPI_DB] # Need one document in the collection. AutoAuthenticateThread does # collection.find_one with a 1-second delay, forcing it to check out # multiple sockets from the pool concurrently, proving that # auto-authentication works with GSSAPI. collection = db.test if collection.count() == 0: try: collection.drop() collection.insert_one({'_id': 1}) except OperationFailure: raise SkipTest("User must be able to write.") threads = [] for _ in range(4): threads.append(AutoAuthenticateThread(collection)) for thread in threads: thread.start() for thread in threads: thread.join() self.assertTrue(thread.success) set_name = client.admin.command('ismaster').get('setName') if set_name: client = MongoClient(GSSAPI_HOST, GSSAPI_PORT, username=GSSAPI_PRINCIPAL, password=GSSAPI_PASS, authMechanism='GSSAPI', authMechanismProperties=self.mech_properties, replicaSet=set_name) # Succeeded? client.server_info() threads = [] for _ in range(4): threads.append(AutoAuthenticateThread(collection)) for thread in threads: thread.start() for thread in threads: thread.join() self.assertTrue(thread.success)
def test_aggregation_cursor_exc_info(self): if not (yield at_least(self.cx, (2, 6))): raise SkipTest("Requires MongoDB >= 2.6") if sys.version_info < (3, ): raise SkipTest("Requires Python 3") yield self._make_test_data(200) cursor = self.db.test.aggregate(self.pipeline) yield cursor.to_list(length=10) yield self.db.test.drop() try: yield cursor.to_list(length=None) except OperationFailure: _, _, tb = sys.exc_info() # The call tree should include PyMongo code we ran on a thread. formatted = '\n'.join(traceback.format_tb(tb)) self.assertTrue('_unpack_response' in formatted or '_check_command_response' in formatted)
def setUp(self): # Before 2.7.7, SCRAM-SHA-1 had to be enabled from the command line. if client_context.version < Version(2, 7, 7): cmd_line = client_context.cmd_line if 'SCRAM-SHA-1' not in cmd_line.get( 'parsed', {}).get('setParameter', {}).get('authenticationMechanisms', ''): raise SkipTest('SCRAM-SHA-1 mechanism not enabled') client_context.create_user( 'pymongo_test', 'user', 'pass', roles=['userAdmin', 'readWrite'])
def test_cert_ssl_validation_optional(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 # # 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") client = MongoClient('server', ssl=True, ssl_certfile=CLIENT_PEM, ssl_cert_reqs=ssl.CERT_OPTIONAL, ssl_ca_certs=CA_PEM) response = client.admin.command('ismaster') if 'setName' in response: if response['primary'].split(":")[0] != 'server': raise SkipTest("No hosts in the replicaset for 'server'. " "Cannot validate hostname in the certificate") client = MongoClient('server', replicaSet=response['setName'], w=len(response['hosts']), ssl=True, ssl_certfile=CLIENT_PEM, ssl_cert_reqs=ssl.CERT_OPTIONAL, ssl_ca_certs=CA_PEM) db = client.pymongo_ssl_test db.test.drop() db.test.insert_one({'ssl': True}) self.assertTrue(db.test.find_one()['ssl']) client.drop_database('pymongo_ssl_test')
async def test_cert_ssl_validation_hostname_fail(self): if not test.env.mongod_validates_client_cert: raise SkipTest("No mongod available over SSL with certs") if test.env.auth: raise SkipTest("can't test with auth") client = motor.MotorClient( env.host, env.port, tlsCertificateKeyFile=CLIENT_PEM, tlsCAFile=CA_PEM, io_loop=self.io_loop, ) response = await client.admin.command("ismaster") with self.assertRaises(ConnectionFailure): # Create client with hostname 'server', not 'localhost', # which is what the server cert presents. client = motor.MotorClient( test.env.fake_hostname_uri, serverSelectionTimeoutMS=100, tlsCertificateKeyFile=CLIENT_PEM, tlsCAFile=CA_PEM, io_loop=self.io_loop, ) await client.db.collection.find_one() if "setName" in response: with self.assertRaises(ConnectionFailure): client = motor.MotorClient( test.env.fake_hostname_uri, serverSelectionTimeoutMS=100, replicaSet=response["setName"], tlsCertificateKeyFile=CLIENT_PEM, tlsCAFile=CA_PEM, io_loop=self.io_loop, ) await client.db.collection.find_one()
def test_timeout(self): if tornado_version < (4, 0, 0, 0): raise SkipTest("MOTOR-73") server = self.server(auto_ismaster=True) client = motor.MotorClient(server.uri, socketTimeoutMS=100) with self.assertRaises(pymongo.errors.AutoReconnect) as context: yield client.motor_test.test_collection.find_one() self.assertIn('timed out', str(context.exception)) client.close()
async def test_cert_ssl(self): if not test.env.mongod_validates_client_cert: raise SkipTest("No mongod available over SSL with certs") if test.env.auth: raise SkipTest("can't test with auth") client = motor.MotorClient( env.host, env.port, tlsCertificateKeyFile=CLIENT_PEM, tlsCAFile=CA_PEM, io_loop=self.io_loop, ) await client.db.collection.find_one() response = await client.admin.command("ismaster") if "setName" in response: client = self.motor_rsc(tlsCertificateKeyFile=CLIENT_PEM, tlsCAFile=CA_PEM) await client.db.collection.find_one()
def test_save_with_invalid_key(self): if client_context.version.at_least(3, 5, 8): raise SkipTest("MongoDB >= 3.5.8 allows dotted fields in updates") # Tests legacy save. self.db.drop_collection("test") self.assertTrue(self.db.test.insert({"hello": "world"})) doc = self.db.test.find_one() doc['a.b'] = 'c' expected = InvalidDocument if client_context.version.at_least(2, 5, 4, -1): expected = OperationFailure self.assertRaises(expected, self.db.test.save, doc)
def test_cert_ssl_validation_optional(self): # Expects the server to be running with the server.pem, ca.pem # and crl.pem provided in mongodb and the server tests e.g.: # # --sslPEMKeyFile=jstests/libs/server.pem # --sslCAFile=jstests/libs/ca.pem # --sslCRLFile=jstests/libs/crl.pem # # Also requires an /etc/hosts entry where "server" is resolvable. if not test.env.mongod_validates_client_cert: raise SkipTest("No mongod available over SSL with certs") if not test.env.server_is_resolvable: raise SkipTest("No hosts entry for 'server'. Cannot validate " "hostname in the certificate") if test.env.auth: raise SkipTest("can't test with auth") client = motor.MotorClient(test.env.fake_hostname_uri, ssl_certfile=CLIENT_PEM, ssl_cert_reqs=ssl.CERT_OPTIONAL, ssl_ca_certs=CA_PEM, io_loop=self.io_loop) response = yield client.admin.command('ismaster') if 'setName' in response: if response['primary'].split(":")[0] != 'server': raise SkipTest("No hosts in the replicaset for 'server'. " "Cannot validate hostname in the certificate") client = motor.MotorReplicaSetClient( test.env.fake_hostname_uri, replicaSet=response['setName'], ssl_certfile=CLIENT_PEM, ssl_cert_reqs=ssl.CERT_OPTIONAL, ssl_ca_certs=CA_PEM, io_loop=self.io_loop) yield client.db.collection.find_one()
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(client_context.pair, ssl=True, serverSelectionTimeoutMS=100)) # Server cert is verified. Disable hostname matching. connected( MongoClient(client_context.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_comment(self): if server_started_with_auth(self.db.client): raise SkipTest("SERVER-4754 - This test uses profiling.") def run_with_profiling(func): self.db.set_profiling_level(OFF) self.db.system.profile.drop() self.db.set_profiling_level(ALL) func() self.db.set_profiling_level(OFF) def find(): list(self.db.test.find().comment('foo')) op = self.db.system.profile.find({ 'ns': 'pymongo_test.test', 'op': 'query', 'query.$comment': 'foo' }) self.assertEqual(op.count(), 1) run_with_profiling(find) def count(): self.db.test.find().comment('foo').count() op = self.db.system.profile.find({ 'ns': 'pymongo_test.$cmd', 'op': 'command', 'command.count': 'test', 'command.$comment': 'foo' }) self.assertEqual(op.count(), 1) run_with_profiling(count) def distinct(): self.db.test.find().comment('foo').distinct('type') op = self.db.system.profile.find({ 'ns': 'pymongo_test.$cmd', 'op': 'command', 'command.distinct': 'test', 'command.$comment': 'foo' }) self.assertEqual(op.count(), 1) run_with_profiling(distinct) self.db.test.insert_many([{}, {}]) cursor = self.db.test.find() next(cursor) self.assertRaises(InvalidOperation, cursor.comment, 'hello') self.db.system.profile.drop()
def test_aggregation_cursor(self): if not (yield at_least(self.cx, (2, 6))): raise SkipTest("Requires MongoDB >= 2.6") db = self.db # A small collection which returns only an initial batch, # and a larger one that requires a getMore. for collection_size in (10, 1000): expected_sum = yield self._make_test_data(collection_size) cursor = db.test.aggregate(self.pipeline) docs = yield cursor.to_list(collection_size) self.assertAllDocs(expected_sum, docs)
def test_cursor_del(self): if sys.version_info < (3, 4): raise SkipTest("requires Python 3.4") if 'PyPy' in sys.version: raise SkipTest("PyPy") client, server = self.client_server(auto_ismaster=True) cursor = client.test.collection.find() future = cursor.fetch_next request = yield self.run_thread(server.receives, OpQuery) request.replies({'_id': 1}, cursor_id=123) yield future # Complete the first fetch. # Dereference the cursor. del cursor # Let the event loop iterate once more to clear its references to # callbacks, allowing the cursor to be freed. yield gen.sleep(0.1) yield self.run_thread(server.receives, OpKillCursors)
def test_command_cursor_attrs(self): if not (yield at_least(self.cx, (2, 6))): raise SkipTest("Requires MongoDB >= 2.6") motor_agg_cursor_only = set( ['collection', 'start', 'args', 'kwargs', 'pipeline']).union(motor_cursor_only) pymongo_cursor = env.sync_cx.test.test.aggregate([], cursor={}) motor_cursor = self.cx.test.test.aggregate([]) self.assertEqual( attrs(pymongo_cursor) - pymongo_cursor_only, attrs(motor_cursor) - motor_agg_cursor_only)
def test_certifi_support(self): if hasattr(ssl, "SSLContext"): # SSLSocket doesn't provide ca_certs attribute on pythons # with SSLContext and SSLContext provides no information # about ca_certs. raise SkipTest("Can't test when SSLContext available.") if not ssl_support.HAVE_CERTIFI: raise SkipTest("Need certifi to test certifi support.") have_wincertstore = ssl_support.HAVE_WINCERTSTORE # Force the test on Windows, regardless of environment. ssl_support.HAVE_WINCERTSTORE = False try: ctx = get_ssl_context(None, None, None, CA_PEM, ssl.CERT_REQUIRED, None) ssl_sock = ctx.wrap_socket(socket.socket()) self.assertEqual(ssl_sock.ca_certs, CA_PEM) ctx = get_ssl_context(None, None, None, None, None, None) ssl_sock = ctx.wrap_socket(socket.socket()) self.assertEqual(ssl_sock.ca_certs, ssl_support.certifi.where()) finally: ssl_support.HAVE_WINCERTSTORE = have_wincertstore
async def test_gridout_open_exc_info(self): if sys.version_info < (3, ): raise SkipTest("Requires Python 3") g = motor.MotorGridOut(self.db.fs, "_id that doesn't exist") try: await g.open() except NoFile: _, _, tb = sys.exc_info() # The call tree should include PyMongo code we ran on a thread. formatted = '\n'.join(traceback.format_tb(tb)) self.assertTrue('_ensure_file' in formatted)
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_supported_single_statement_unsupported_cluster(self): if client_context.is_rs or client_context.is_mongos: raise SkipTest('This cluster supports retryable writes') for method, args, kwargs in retryable_single_statement_ops( self.db.retryable_write_test): msg = '%s(*%r, **%r)' % (method.__name__, args, kwargs) self.listener.results.clear() method(*args, **kwargs) for event in self.listener.results['started']: self.assertNotIn( 'txnNumber', event.command, '%s sent txnNumber with %s' % (msg, event.command_name))
def test_cert_ssl_uri_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 # # 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") uri_fmt = ("mongodb://server/?ssl=true&ssl_certfile=%s&ssl_cert_reqs" "=%s&ssl_ca_certs=%s&ssl_match_hostname=true") client = MongoClient(uri_fmt % (CLIENT_PEM, 'CERT_REQUIRED', CA_PEM)) db = client.pymongo_ssl_test db.test.drop() db.test.insert_one({'ssl': True}) self.assertTrue(db.test.find_one()['ssl']) client.drop_database('pymongo_ssl_test')
def test_pickle_backwards_compatability(self): # For a full discussion see http://bugs.python.org/issue6137 if sys.version.startswith('3.0'): raise SkipTest("Python 3.0.x can't unpickle " "objects pickled in Python 2.x.") # This string was generated by pickling a SON object in pymongo # version 2.1.1 pickled_with_2_1_1 = b( "ccopy_reg\n_reconstructor\np0\n(cbson.son\nSON\np1\n" "c__builtin__\ndict\np2\n(dp3\ntp4\nRp5\n(dp6\n" "S'_SON__keys'\np7\n(lp8\nsb.") son_2_1_1 = pickle.loads(pickled_with_2_1_1) self.assertEqual(son_2_1_1, SON([]))
def test_comment(self): if client_context.auth_enabled: raise SkipTest("SERVER-4754 - This test uses profiling.") # MongoDB 3.1.5 changed the ns for commands. regex = {'$regex': 'pymongo_test.(\$cmd|test)'} if client_context.version.at_least(3, 5, 8, -1): query_key = "command.comment" elif client_context.version.at_least(3, 1, 8, -1): query_key = "query.comment" else: query_key = "query.$comment" self.client.drop_database(self.db) self.db.set_profiling_level(ALL) try: list(self.db.test.find().comment('foo')) op = self.db.system.profile.find({ 'ns': 'pymongo_test.test', 'op': 'query', query_key: 'foo' }) self.assertEqual(op.count(), 1) self.db.test.find().comment('foo').count() op = self.db.system.profile.find({ 'ns': regex, 'op': 'command', 'command.count': 'test', 'command.$comment': 'foo' }) self.assertEqual(op.count(), 1) self.db.test.find().comment('foo').distinct('type') op = self.db.system.profile.find({ 'ns': regex, 'op': 'command', 'command.distinct': 'test', 'command.$comment': 'foo' }) self.assertEqual(op.count(), 1) finally: self.db.set_profiling_level(OFF) self.db.system.profile.drop() self.db.test.insert_many([{}, {}]) cursor = self.db.test.find() next(cursor) self.assertRaises(InvalidOperation, cursor.comment, 'hello')
def test_cert_ssl_validation_hostname_fail(self): if not test.env.mongod_validates_client_cert: raise SkipTest("No mongod available over SSL with certs") if test.env.auth: raise SkipTest("can't test with auth") client = motor.MotorClient(env.host, env.port, ssl_certfile=CLIENT_PEM, ssl_ca_certs=CA_PEM, io_loop=self.io_loop) response = yield client.admin.command('ismaster') with self.assertRaises(ConnectionFailure): # Create client with hostname 'server', not 'localhost', # which is what the server cert presents. client = motor.MotorClient(test.env.fake_hostname_uri, serverSelectionTimeoutMS=100, ssl_certfile=CLIENT_PEM, ssl_cert_reqs=ssl.CERT_REQUIRED, ssl_ca_certs=CA_PEM, io_loop=self.io_loop) yield client.db.collection.find_one() if 'setName' in response: with self.assertRaises(ConnectionFailure): client = motor.MotorClient(test.env.fake_hostname_uri, serverSelectionTimeoutMS=100, replicaSet=response['setName'], ssl_certfile=CLIENT_PEM, ssl_cert_reqs=ssl.CERT_REQUIRED, ssl_ca_certs=CA_PEM, io_loop=self.io_loop) yield client.db.collection.find_one()
def test_cert_ssl_validation(self): # Expects the server to be running with the server.pem, ca.pem # and crl.pem provided in mongodb and the server tests e.g.: # # --sslPEMKeyFile=jstests/libs/server.pem # --sslCAFile=jstests/libs/ca.pem # --sslCRLFile=jstests/libs/crl.pem # # Also requires an /etc/hosts entry where "server" is resolvable. if not test.mongod_validates_client_cert: 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") client = motor.MotorClient('server', ssl_certfile=CLIENT_PEM, ssl_cert_reqs=ssl.CERT_REQUIRED, ssl_ca_certs=CA_PEM) yield client.db.collection.find_one() response = yield client.admin.command('ismaster') if 'setName' in response: if response['primary'].split(":")[0] != 'server': raise SkipTest("No hosts in the replicaset for 'server'. " "Cannot validate hostname in the certificate") client = motor.MotorReplicaSetClient( 'server', replicaSet=response['setName'], ssl_certfile=CLIENT_PEM, ssl_cert_reqs=ssl.CERT_REQUIRED, ssl_ca_certs=CA_PEM) yield client.db.collection.find_one()
def test_unix_socket(self): if env.mongod_started_with_ssl: raise SkipTest("Server started with SSL") mongodb_socket = '/tmp/mongodb-%d.sock' % env.port if not os.access(mongodb_socket, os.R_OK): raise SkipTest("Socket file is not accessible") encoded_socket = '%2Ftmp%2Fmongodb-' + str(env.port) + '.sock' uri = 'mongodb://%s' % encoded_socket client = self.motor_client(uri) if test.env.auth: yield client.admin.authenticate(db_user, db_password) yield client.motor_test.test.insert_one({"dummy": "object"}) # Confirm it fails with a missing socket. client = motor.MotorClient("mongodb://%2Ftmp%2Fnon-existent.sock", io_loop=self.io_loop, serverSelectionTimeoutMS=100) with self.assertRaises(ConnectionFailure): yield client.admin.command('ismaster')
def test_abc(self): try: from abc import ABC except ImportError: # Python < 3.4. raise SkipTest() class C(ABC): db = self.db collection = self.collection subcollection = self.collection.subcollection # MOTOR-104, TypeError: Can't instantiate abstract class C with abstract # methods collection, db, subcollection. C()
def test_from_datetime(self): if 'PyPy 1.8.0' in sys.version: # See https://bugs.pypy.org/issue1092 raise SkipTest("datetime.timedelta is broken in pypy 1.8.0") d = datetime.datetime.utcnow() d = d - datetime.timedelta(microseconds=d.microsecond) oid = ObjectId.from_datetime(d) self.assertEqual(d, oid.generation_time.replace(tzinfo=None)) self.assertEqual("0" * 16, str(oid)[8:]) aware = datetime.datetime(1993, 4, 4, 2, tzinfo=FixedOffset(555, "SomeZone")) as_utc = (aware - aware.utcoffset()).replace(tzinfo=utc) oid = ObjectId.from_datetime(aware) self.assertEqual(as_utc, oid.generation_time)
def test_no_ssl_module(self): # Test that ConfigurationError is raised if the ssl # module isn't available. if HAVE_SSL: raise SkipTest( "The ssl module is available, can't test what happens " "without it.") # Explicit self.assertRaises(ConfigurationError, MongoClient, ssl=True) # Implied self.assertRaises(ConfigurationError, MongoClient, ssl_certfile=CLIENT_PEM)
def setUp(self): self.replica_set_name = client_context.replica_set_name # Before 2.7.7, SCRAM-SHA-1 had to be enabled from the command line. if client_context.version < Version(2, 7, 7): cmd_line = client_context.cmd_line if 'SCRAM-SHA-1' not in cmd_line.get('parsed', {}).get( 'setParameter', {}).get('authenticationMechanisms', ''): raise SkipTest('SCRAM-SHA-1 mechanism not enabled') client = client_context.rs_or_standalone_client client.pymongo_test.add_user('user', 'pass', roles=['userAdmin', 'readWrite'], writeConcern={'w': client_context.w})