def test_document_class(self): c = MongoClient(host, port) db = c.pymongo_test db.test.insert({"x": 1}) ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) self.assertEqual(dict, c.document_class) self.assertTrue(isinstance(db.test.find_one(), dict)) self.assertFalse(isinstance(db.test.find_one(), SON)) c.document_class = SON db = c.pymongo_test self.assertEqual(SON, c.document_class) self.assertTrue(isinstance(db.test.find_one(), SON)) self.assertFalse(isinstance(db.test.find_one(as_class=dict), SON)) c = MongoClient(host, port, document_class=SON) db = c.pymongo_test self.assertEqual(SON, c.document_class) self.assertTrue(isinstance(db.test.find_one(), SON)) self.assertFalse(isinstance(db.test.find_one(as_class=dict), SON)) c.document_class = dict db = c.pymongo_test self.assertEqual(dict, c.document_class) self.assertTrue(isinstance(db.test.find_one(), dict)) self.assertFalse(isinstance(db.test.find_one(), SON)) finally: ctx.exit()
def test_base_object(self): ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) c = self.client self.assertFalse(c.slave_okay) self.assertTrue(bool(c.read_preference)) self.assertTrue(c.safe) self.assertEqual({}, c.get_lasterror_options()) db = c.pymongo_test self.assertFalse(db.slave_okay) self.assertTrue(bool(c.read_preference)) self.assertTrue(db.safe) self.assertEqual({}, db.get_lasterror_options()) coll = db.test coll.drop() self.assertFalse(coll.slave_okay) self.assertTrue(bool(c.read_preference)) self.assertTrue(coll.safe) self.assertEqual({}, coll.get_lasterror_options()) cursor = coll.find() self.assertFalse(cursor._Cursor__slave_okay) self.assertTrue(bool(cursor._Cursor__read_preference)) w = 1 + len(self.slaves) wtimeout=10000 # Wait 10 seconds for replication to complete c.set_lasterror_options(w=w, wtimeout=wtimeout) self.assertFalse(c.slave_okay) self.assertTrue(bool(c.read_preference)) self.assertTrue(c.safe) self.assertEqual({'w': w, 'wtimeout': wtimeout}, c.get_lasterror_options()) db = c.pymongo_test self.assertFalse(db.slave_okay) self.assertTrue(bool(c.read_preference)) self.assertTrue(db.safe) self.assertEqual({'w': w, 'wtimeout': wtimeout}, db.get_lasterror_options()) coll = db.test self.assertFalse(coll.slave_okay) self.assertTrue(bool(c.read_preference)) self.assertTrue(coll.safe) self.assertEqual({'w': w, 'wtimeout': wtimeout}, coll.get_lasterror_options()) cursor = coll.find() self.assertFalse(cursor._Cursor__slave_okay) self.assertTrue(bool(cursor._Cursor__read_preference)) coll.insert({'foo': 'bar'}) self.assertEqual(1, coll.find({'foo': 'bar'}).count()) self.assertTrue(coll.find({'foo': 'bar'})) coll.remove({'foo': 'bar'}) self.assertEqual(0, coll.find({'foo': 'bar'}).count()) c.safe = False c.unset_lasterror_options() self.assertFalse(self.client.slave_okay) self.assertTrue(bool(self.client.read_preference)) self.assertFalse(self.client.safe) self.assertEqual({}, self.client.get_lasterror_options()) finally: ctx.exit()
def test_gridfs_secondary(self): primary_host, primary_port = self.primary primary_connection = MongoClient(primary_host, primary_port) secondary_host, secondary_port = self.secondaries[0] ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) for secondary_connection in [ MongoClient(secondary_host, secondary_port, slave_okay=True), MongoClient(secondary_host, secondary_port, read_preference=ReadPreference.SECONDARY), ]: primary_connection.pymongo_test.drop_collection("fs.files") primary_connection.pymongo_test.drop_collection("fs.chunks") # Should detect it's connected to secondary and not attempt to # create index fs = gridfs.GridFS(secondary_connection.pymongo_test) # This won't detect secondary, raises error self.assertRaises(ConnectionFailure, fs.put, b('foo')) finally: ctx.exit()
def setUp(self): self.master = MongoClient(host, port) self.slaves = [] try: self.slaves.append( MongoClient(host2, port2, read_preference=ReadPreference.SECONDARY)) except ConnectionFailure: pass try: self.slaves.append( MongoClient(host3, port3, read_preference=ReadPreference.SECONDARY)) except ConnectionFailure: pass if not self.slaves: raise SkipTest("Not connected to master-slave set") self.ctx = catch_warnings() warnings.simplefilter("ignore", DeprecationWarning) self.client = MasterSlaveConnection(self.master, self.slaves) self.db = self.client.pymongo_test
def test_auto_start_request(self): ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) for bad_horrible_value in (None, 5, 'hi!'): self.assertRaises( (TypeError, ConfigurationError), lambda: get_client(auto_start_request=bad_horrible_value) ) # auto_start_request should default to False client = get_client() self.assertFalse(client.auto_start_request) client = get_client(auto_start_request=True) self.assertTrue(client.auto_start_request) # Assure we acquire a request socket. client.pymongo_test.test.find_one() self.assertTrue(client.in_request()) pool = get_pool(client) self.assertRequestSocket(pool) self.assertSameSock(pool) client.end_request() self.assertNoRequest(pool) self.assertDifferentSock(pool) # Trigger auto_start_request client.pymongo_test.test.find_one() self.assertRequestSocket(pool) self.assertSameSock(pool) finally: ctx.exit()
def test_command_read_pref_warning(self): ctx = catch_warnings() try: warnings.simplefilter("error", UserWarning) warnings.simplefilter("ignore", DeprecationWarning) self.assertRaises( UserWarning, self.c.pymongo_test.command, "ping", read_preference=ReadPreference.SECONDARY ) try: self.c.pymongo_test.command("dbStats", read_preference=ReadPreference.SECONDARY_PREFERRED) except UserWarning: self.fail("Shouldn't have raised UserWarning.") primary = MongoClient(host, port) try: primary.pymongo_test.command("ping", read_preference=ReadPreference.SECONDARY_PREFERRED) except UserWarning: self.fail("Shouldn't have raised UserWarning.") secondary_addr = iter(self.c.secondaries).next() secondary = MongoClient(*secondary_addr) msclient = MasterSlaveConnection(primary, [secondary]) self.assertRaises( UserWarning, msclient.pymongo_test.command, "ping", read_preference=ReadPreference.SECONDARY ) try: msclient.pymongo_test.command("dbStats", read_preference=ReadPreference.SECONDARY_PREFERRED) except UserWarning: self.fail("Shouldn't have raised UserWarning.") finally: ctx.exit()
def test_aggregate_command_with_out(self): if not version.at_least(self.c, (2, 5, 2)): raise SkipTest("Aggregation with $out requires MongoDB >= 2.5.2") # Tests aggregate command when pipeline contains $out. self.c.pymongo_test.test.insert({"x": 1, "y": 1}, w=self.w) self.c.pymongo_test.test.insert({"x": 1, "y": 2}, w=self.w) self.c.pymongo_test.test.insert({"x": 2, "y": 1}, w=self.w) self.c.pymongo_test.test.insert({"x": 2, "y": 2}, w=self.w) # Aggregate with $out always goes to primary, doesn't obey read prefs. # Test aggregate command sent directly to db.command. ctx = catch_warnings() try: warnings.simplefilter("ignore", UserWarning) self._test_fn(False, lambda: self.c.pymongo_test.command( "aggregate", "test", pipeline=[{"$match": {"x": 1}}, {"$out": "agg_out"}] )) # Test aggregate when sent through the collection aggregate function. self._test_fn(False, lambda: self.c.pymongo_test.test.aggregate( [{"$match": {"x": 2}}, {"$out": "agg_out"}] )) finally: ctx.exit() self.c.pymongo_test.drop_collection("test") self.c.pymongo_test.drop_collection("agg_out")
def test_init_disconnected(self): c = MongoClient(host, port, _connect=False) ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) self.assertIsInstance(c.is_primary, bool) self.assertIsInstance(c.is_mongos, bool) self.assertIsInstance(c.max_pool_size, int) self.assertIsInstance(c.use_greenlets, bool) self.assertIsInstance(c.nodes, frozenset) self.assertIsInstance(c.auto_start_request, bool) self.assertEqual(dict, c.get_document_class()) self.assertIsInstance(c.tz_aware, bool) self.assertIsInstance(c.max_bson_size, int) self.assertIsInstance(c.min_wire_version, int) self.assertIsInstance(c.max_wire_version, int) self.assertIsInstance(c.max_write_batch_size, int) self.assertEqual(None, c.host) self.assertEqual(None, c.port) finally: ctx.exit() c.pymongo_test.test.find_one() # Auto-connect. self.assertEqual((host, port), c.address) if version.at_least(c, (2, 5, 4, -1)): self.assertTrue(c.max_wire_version > 0) else: self.assertEqual(c.max_wire_version, 0) self.assertTrue(c.min_wire_version >= 0) bad_host = "somedomainthatdoesntexist.org" c = MongoClient(bad_host, port, connectTimeoutMS=1, _connect=False) self.assertRaises(ConnectionFailure, c.pymongo_test.test.find_one)
def test_client_read_preference(self): preferences = ( Primary(), Secondary([{'dc': 'ny'}]), Nearest([{'dc': 'ny'}, {}])) tags = [{'foo': 'bar'}] ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) for pref in preferences: client = MongoClient(read_preference=pref, connect=False) self.assertEqual(client.read_preference, pref.mode) self.assertEqual(client.tag_sets, pref.tag_sets) client = MongoClient( read_preference=pref, tag_sets=tags, connect=False) self.assertEqual(client.read_preference, pref.mode) self.assertEqual(client.tag_sets, pref.tag_sets) client = MongoReplicaSetClient( read_preference=pref, replicaSet='foo', connect=False) self.assertEqual(client.read_preference, pref.mode) self.assertEqual(client.tag_sets, pref.tag_sets) client = MongoReplicaSetClient( read_preference=pref, tag_sets=tags, replicaSet='foo', connect=False) self.assertEqual(client.read_preference, pref.mode) self.assertEqual(client.tag_sets, pref.tag_sets) finally: ctx.exit()
def test_backport_latency_validation(self): ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) self.assertEqual(17, self._get_client( localThresholdMS=17 ).secondary_acceptable_latency_ms) self.assertEqual(42, self._get_client( secondaryAcceptableLatencyMS=42 ).local_threshold_ms) self.assertEqual(666, self._get_client( localThresholdMS=666 ).local_threshold_ms) self.assertEqual(0, self._get_client( localthresholdms=0 ).local_threshold_ms) self.assertRaises(ConfigurationError, self._get_client, localthresholdms=-1) finally: ctx.exit()
def test_backport_localthresholdms_uri(self): uri = "mongodb://%s:%s" % (host, port) lt_uri = "mongodb://%s:%d/?localThresholdMS=10" % (host, port) sl_uri = ("mongodb://%s:%d/?secondaryAcceptableLatencyMS=10" % (host, port)) lt_sl_uri = ("mongodb://%s:%d/?localThresholdMS=10;" "secondaryAcceptableLatencyMS=8" % (host, port)) ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) # Just localThresholdMS client = MongoClient(uri) self.assertEqual(client.secondary_acceptable_latency_ms, 15) self.assertEqual(client.local_threshold_ms, 15) client = MongoClient(uri, localThresholdMS=10) self.assertEqual(client.secondary_acceptable_latency_ms, 10) self.assertEqual(client.local_threshold_ms, 10) client = MongoClient(uri, localThresholdMS=10, secondaryAcceptableLatencyMS=8) self.assertEqual(client.secondary_acceptable_latency_ms, 10) self.assertEqual(client.local_threshold_ms, 10) # URI options take precedence over kwargs but localThresholdMS # takes precedence over secondaryAcceptableLatencyMS always. Test # to make sure the precedence is correct between URI vs. kwargs. client = MongoClient(lt_uri) self.assertEqual(client.secondary_acceptable_latency_ms, 10) self.assertEqual(client.local_threshold_ms, 10) client = MongoClient(lt_uri, localThresholdMS=8) self.assertEqual(client.secondary_acceptable_latency_ms, 10) self.assertEqual(client.local_threshold_ms, 10) client = MongoClient(lt_uri, secondaryAcceptableLatencyMS=8) self.assertEqual(client.secondary_acceptable_latency_ms, 10) self.assertEqual(client.local_threshold_ms, 10) client = MongoClient(lt_uri, localThresholdMS=8, secondaryAcceptableLatencyMS=6) self.assertEqual(client.secondary_acceptable_latency_ms, 10) self.assertEqual(client.local_threshold_ms, 10) client = MongoClient(sl_uri, secondaryAcceptableLatencyMS=8) self.assertEqual(client.secondary_acceptable_latency_ms, 10) self.assertEqual(client.local_threshold_ms, 10) client = MongoClient(sl_uri, localThresholdMS=10) self.assertEqual(client.secondary_acceptable_latency_ms, 10) self.assertEqual(client.local_threshold_ms, 10) client = MongoClient(sl_uri, localThresholdMS=10, secondaryAcceptableLatencyMS=6) self.assertEqual(client.secondary_acceptable_latency_ms, 10) self.assertEqual(client.local_threshold_ms, 10) client = MongoClient(lt_sl_uri) self.assertEqual(client.secondary_acceptable_latency_ms, 10) self.assertEqual(client.local_threshold_ms, 10) client = MongoClient(lt_sl_uri, localThresholdMS=8, secondaryAcceptableLatencyMS=4) self.assertEqual(client.secondary_acceptable_latency_ms, 10) self.assertEqual(client.local_threshold_ms, 10) finally: ctx.exit()
def test_cursor_transfer(self): # This is just a test, don't try this at home... self.db.test.remove({}) self.db.test.insert({'_id': i} for i in xrange(200)) class CManager(CursorManager): def __init__(self, connection): super(CManager, self).__init__(connection) def close(self, dummy): # Do absolutely nothing... pass client = self.db.connection ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) client.set_cursor_manager(CManager) docs = [] cursor = self.db.test.find().batch_size(10) docs.append(cursor.next()) cursor.close() docs.extend(cursor) self.assertEqual(len(docs), 10) cmd_cursor = {'id': cursor.cursor_id, 'firstBatch': []} ccursor = CommandCursor(cursor.collection, cmd_cursor, cursor.conn_id, retrieved=cursor.retrieved) docs.extend(ccursor) self.assertEqual(len(docs), 200) finally: client.set_cursor_manager(CursorManager) ctx.exit()
def test_drop_collection(self): ctx = catch_warnings() try: warnings.simplefilter("ignore", UserWarning) self._test_fn(False, lambda: self.c.pymongo_test.drop_collection("some_collection")) self._test_fn(False, lambda: self.c.pymongo_test.some_collection.drop()) finally: ctx.exit()
def test_alive(self): ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) self.assertTrue(get_client().alive()) client = MongoClient('doesnt exist', _connect=False) self.assertFalse(client.alive()) finally: ctx.exit()
def test_replica_set_connection(self): c = ReplicaSetConnection(pair, replicaSet=self.name) ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) self.assertTrue(c.auto_start_request) self.assertEqual(None, c.max_pool_size) self.assertFalse(c.slave_okay) self.assertFalse(c.safe) self.assertEqual({}, c.get_lasterror_options()) # ReplicaSetConnection's writes are unacknowledged by default doc = {"_id": ObjectId()} coll = c.pymongo_test.write_concern_test coll.drop() coll.insert(doc) coll.insert(doc) c = ReplicaSetConnection( "mongodb://%s:%s/?replicaSet=%s&safe=true" % (host, port, self.name)) self.assertTrue(c.safe) finally: ctx.exit() # To preserve legacy ReplicaSetConnection's behavior, max_size should # be None. Pool should handle this without error. pool = get_pool(c) self.assertEqual(None, pool.max_size) c.end_request() # To preserve legacy ReplicaSetConnection's behavior, max_size should # be None. Pool should handle this without error. rs_state = c._MongoReplicaSetClient__rs_state pool = rs_state.primary_member.pool self.assertEqual(None, pool.max_size) c.end_request() # ReplicaSetConnection's network_timeout argument is translated into # socketTimeoutMS self.assertEqual( 123, ReplicaSetConnection( pair, replicaSet=self.name, network_timeout=123)._MongoReplicaSetClient__net_timeout) for network_timeout in 'foo', 0, -1: self.assertRaises(ConfigurationError, ReplicaSetConnection, pair, replicaSet=self.name, network_timeout=network_timeout)
def test_use_greenlets(self): ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) self.assertFalse(MongoClient(host, port).use_greenlets) if thread_util.have_gevent: self.assertTrue( MongoClient( host, port, use_greenlets=True).use_greenlets) finally: ctx.exit()
def test_primary_with_tags(self): # Tags not allowed with PRIMARY ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) self.assertRaises( ConfigurationError, self._get_client, tag_sets=[{'dc': 'ny'}]) finally: ctx.exit()
def test_create_collection(self): # Collections should be created on primary, obviously ctx = catch_warnings() try: warnings.simplefilter("ignore", UserWarning) self._test_fn(False, lambda: self.c.pymongo_test.command( 'create', 'some_collection%s' % random.randint(0, sys.maxint))) self._test_fn(False, lambda: self.c.pymongo_test.create_collection( 'some_collection%s' % random.randint(0, sys.maxint))) finally: ctx.exit()
def test_drop_collection(self): ctx = catch_warnings() try: warnings.simplefilter("ignore", UserWarning) self._test_fn( False, lambda: self.c.pymongo_test.drop_collection('some_collection')) self._test_fn(False, lambda: self.c.pymongo_test.some_collection.drop()) finally: ctx.exit()
def test_command_read_pref_warning(self): ctx = catch_warnings() try: warnings.simplefilter("error", UserWarning) self.assertRaises(UserWarning, self.client.pymongo_test.command, 'ping', read_preference=ReadPreference.SECONDARY) try: self.client.pymongo_test.command('dbStats', read_preference=ReadPreference.SECONDARY_PREFERRED) except UserWarning: self.fail("Shouldn't have raised UserWarning.") finally: ctx.exit()
def test_from_uri(self): c = MongoClient(host, port) ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) self.assertEqual(c, MongoClient("mongodb://%s:%d" % (host, port))) self.assertTrue(MongoClient( "mongodb://%s:%d" % (host, port), slave_okay=True).slave_okay) self.assertTrue(MongoClient( "mongodb://%s:%d/?slaveok=true;w=2" % (host, port)).slave_okay) finally: ctx.exit()
def test_map_reduce(self): # mapreduce fails if no collection self.c.pymongo_test.test.insert({}, w=self.w) ctx = catch_warnings() try: warnings.simplefilter("ignore", UserWarning) self._test_fn(False, lambda: self.c.pymongo_test.test.map_reduce( 'function() { }', 'function() { }', 'mr_out')) finally: ctx.exit() self._test_fn(True, lambda: self.c.pymongo_test.test.map_reduce( 'function() { }', 'function() { }', {'inline': 1}))
def test_create_collection(self): # Collections should be created on primary, obviously ctx = catch_warnings() try: warnings.simplefilter("ignore", UserWarning) self._test_fn( False, lambda: self.c.pymongo_test.command( 'create', 'some_collection%s' % random.randint( 0, sys.maxint))) self._test_fn( False, lambda: self.c.pymongo_test.create_collection( 'some_collection%s' % random.randint(0, sys.maxint))) finally: ctx.exit()
def test_last_status(self): db = self.client.pymongo_test db.test.remove({}) db.test.save({"i": 1}) ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) db.test.update({"i": 1}, {"$set": {"i": 2}}, w=0) self.assertTrue(db.last_status()["updatedExisting"]) db.test.update({"i": 1}, {"$set": {"i": 500}}, w=0) self.assertFalse(db.last_status()["updatedExisting"]) finally: ctx.exit()
def test_map_reduce(self): # mapreduce fails if no collection self.c.pymongo_test.test.insert({}, w=self.w) ctx = catch_warnings() try: warnings.simplefilter("ignore", UserWarning) self._test_fn( False, lambda: self.c.pymongo_test.test.map_reduce( 'function() { }', 'function() { }', 'mr_out')) finally: ctx.exit() self._test_fn( True, lambda: self.c.pymongo_test.test.map_reduce( 'function() { }', 'function() { }', {'inline': 1}))
def test_map_reduce_command(self): raise SkipTest("map reduce doesn't run on secondaries") # mapreduce fails if no collection self.c.pymongo_test.test.insert({}, w=self.w) # Non-inline mapreduce always goes to primary, doesn't obey read prefs. # Test with command in a SON and with kwargs ctx = catch_warnings() try: warnings.simplefilter("ignore", UserWarning) self._test_fn( False, lambda: self.c.pymongo_test.command( SON([('mapreduce', 'test'), ('map', 'function() { }'), ('reduce', 'function() { }'), ('out', 'mr_out')]))) self._test_fn( False, lambda: self.c.pymongo_test.command('mapreduce', 'test', map='function() { }', reduce='function() { }', out='mr_out')) self._test_fn( False, lambda: self.c.pymongo_test.command( 'mapreduce', 'test', map='function() { }', reduce='function() { }', out={'replace': 'some_collection'})) finally: ctx.exit() # Inline mapreduce obeys read prefs self._test_fn( True, lambda: self.c.pymongo_test.command('mapreduce', 'test', map='function() { }', reduce='function() { }', out={'inline': True})) self._test_fn( True, lambda: self.c.pymongo_test.command( SON([('mapreduce', 'test'), ('map', 'function() { }'), ('reduce', 'function() { }'), ('out', { 'inline': True })])))
def test_backport_localthresholdms_kwarg(self): # Test that localThresholdMS takes precedence over # secondaryAcceptableLatencyMS. ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) client = MockClient( standalones=[], members=[], mongoses=['a:1', 'b:2', 'c:3'], host='a:1,b:2,c:3', localThresholdMS=7, secondaryAcceptableLatencyMS=0) self.assertEqual(7, client.secondary_acceptable_latency_ms) self.assertEqual(7, client.local_threshold_ms) # No error client.db.collection.find_one() client = MockClient( standalones=[], members=[], mongoses=['a:1', 'b:2', 'c:3'], host='a:1,b:2,c:3', localThresholdMS=0, secondaryAcceptableLatencyMS=15) self.assertEqual(0, client.secondary_acceptable_latency_ms) self.assertEqual(0, client.local_threshold_ms) # Test that using localThresholdMS works in the same way as using # secondaryAcceptableLatencyMS. client.db.collection.find_one() # Our chosen mongos goes down. client.kill_host('%s:%s' % client.address) try: client.db.collection.find_one() except: pass # No error client.db.collection.find_one() finally: ctx.exit()
def test_replica_set_connection(self): c = ReplicaSetConnection(pair, replicaSet=self.name) ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) self.assertTrue(c.auto_start_request) self.assertEqual(None, c.max_pool_size) self.assertFalse(c.slave_okay) self.assertFalse(c.safe) self.assertEqual({}, c.get_lasterror_options()) # ReplicaSetConnection's writes are unacknowledged by default doc = {"_id": ObjectId()} coll = c.pymongo_test.write_concern_test coll.drop() coll.insert(doc) coll.insert(doc) c = ReplicaSetConnection("mongodb://%s:%s/?replicaSet=%s&safe=true" % ( host, port, self.name)) self.assertTrue(c.safe) finally: ctx.exit() # To preserve legacy ReplicaSetConnection's behavior, max_size should # be None. Pool should handle this without error. pool = get_pool(c) self.assertEqual(None, pool.max_size) c.end_request() # ReplicaSetConnection's network_timeout argument is translated into # socketTimeoutMS self.assertEqual(123, ReplicaSetConnection( pair, replicaSet=self.name, network_timeout=123 )._MongoReplicaSetClient__net_timeout) for network_timeout in 'foo', 0, -1: self.assertRaises( ConfigurationError, ReplicaSetConnection, pair, replicaSet=self.name, network_timeout=network_timeout)
def _test_fn(self, obedient, fn): ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) if not obedient: for mode in modes: self.c.read_preference = mode # Run it a few times to make sure we don't just get lucky # the first time. for _ in range(10): self.assertExecutedOn('primary', self.c, fn) else: for mode, expected_state in [ (ReadPreference.PRIMARY, 'primary'), (ReadPreference.PRIMARY_PREFERRED, 'primary'), (ReadPreference.SECONDARY, 'secondary'), (ReadPreference.SECONDARY_PREFERRED, 'secondary'), (ReadPreference.NEAREST, 'any')]: self.c.read_preference = mode for _ in range(10): if expected_state in ('primary', 'secondary'): self.assertExecutedOn(expected_state, self.c, fn) elif expected_state == 'any': used = set() for _ in range(1000): member = self.executed_on_which_member( self.c, fn) used.add(member.host) if len(used) == len(self.c.secondaries) + 1: # Success break unused = self.c.secondaries.union( set([self.c.primary]) ).difference(used) if unused: self.fail( "Some members not used for NEAREST: %s" % ( unused)) finally: ctx.exit()
def test_aggregate_command_with_out(self): if not version.at_least(self.c, (2, 5, 2)): raise SkipTest("Aggregation with $out requires MongoDB >= 2.5.2") # Tests aggregate command when pipeline contains $out. self.c.pymongo_test.test.insert({"x": 1, "y": 1}, w=self.w) self.c.pymongo_test.test.insert({"x": 1, "y": 2}, w=self.w) self.c.pymongo_test.test.insert({"x": 2, "y": 1}, w=self.w) self.c.pymongo_test.test.insert({"x": 2, "y": 2}, w=self.w) # Aggregate with $out always goes to primary, doesn't obey read prefs. # Test aggregate command sent directly to db.command. ctx = catch_warnings() try: warnings.simplefilter("ignore", UserWarning) self._test_fn( False, lambda: self.c.pymongo_test.command("aggregate", "test", pipeline=[{ "$match": { "x": 1 } }, { "$out": "agg_out" }])) # Test aggregate when sent through the collection aggregate function. self._test_fn( False, lambda: self.c.pymongo_test.test.aggregate([{ "$match": { "x": 2 } }, { "$out": "agg_out" }])) finally: ctx.exit() self.c.pymongo_test.drop_collection("test") self.c.pymongo_test.drop_collection("agg_out")
def test_mongo_replica_set_client(self): c = MongoClient(pair) ismaster = c.admin.command('ismaster') if 'setName' in ismaster: setname = str(ismaster.get('setName')) else: raise SkipTest("Not connected to a replica set.") m = MongoReplicaSetClient(pair, replicaSet=setname, w=0) coll = m.pymongo_test.write_concern_test coll.drop() ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) doc = {"_id": ObjectId()} coll.insert(doc) self.assertTrue(coll.insert(doc, safe=False)) self.assertTrue(coll.insert(doc, w=0)) self.assertTrue(coll.insert(doc)) self.assertRaises(OperationFailure, coll.insert, doc, safe=True) self.assertRaises(OperationFailure, coll.insert, doc, w=1) m = MongoReplicaSetClient(pair, replicaSet=setname) coll = m.pymongo_test.write_concern_test self.assertTrue(coll.insert(doc, safe=False)) self.assertTrue(coll.insert(doc, w=0)) self.assertRaises(OperationFailure, coll.insert, doc) self.assertRaises(OperationFailure, coll.insert, doc, safe=True) self.assertRaises(OperationFailure, coll.insert, doc, w=1) m = MongoReplicaSetClient("mongodb://%s/?replicaSet=%s" % (pair, setname)) self.assertTrue(m.safe) coll = m.pymongo_test.write_concern_test self.assertRaises(OperationFailure, coll.insert, doc) m = MongoReplicaSetClient("mongodb://%s/?replicaSet=%s;w=0" % (pair, setname)) self.assertFalse(m.safe) coll = m.pymongo_test.write_concern_test self.assertTrue(coll.insert(doc)) finally: ctx.exit()
def test_kill_cursors_warning(self): # If kill_cursors is called while the client is disconnected, it # can't risk taking the lock to reconnect, in case it's being called # from Cursor.__del__, see PYTHON-799. Test that it shows a warning # in this case. client = MongoClient(host, port) collection = client.pymongo_test.test collection.insert({} for _ in range(4)) cursor = collection.find().batch_size(1) cursor.next() client.disconnect() ctx = catch_warnings() try: warnings.simplefilter("error", UserWarning) self.assertRaises(UserWarning, cursor.close) finally: ctx.exit() # Reconnect. collection.find_one() cursor.close()
def setUp(self): self.master = MongoClient(host, port) self.slaves = [] try: self.slaves.append(MongoClient(host2, port2, read_preference=ReadPreference.SECONDARY)) except ConnectionFailure: pass try: self.slaves.append(MongoClient(host3, port3, read_preference=ReadPreference.SECONDARY)) except ConnectionFailure: pass if not self.slaves: raise SkipTest("Not connected to master-slave set") self.ctx = catch_warnings() warnings.simplefilter("ignore", DeprecationWarning) self.client = MasterSlaveConnection(self.master, self.slaves) self.db = self.client.pymongo_test
def test_copy_db(self): c = self._get_client() ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) self.assertRaises(TypeError, c.copy_database, 4, "foo") self.assertRaises(TypeError, c.copy_database, "foo", 4) self.assertRaises(InvalidName, c.copy_database, "foo", "$foo") c.pymongo_test.test.drop() c.pymongo_test.test.insert({"foo": "bar"}) c.drop_database("pymongo_test1") self.assertFalse("pymongo_test1" in c.database_names()) c.copy_database("pymongo_test", "pymongo_test1") self.assertTrue("pymongo_test1" in c.database_names()) self.assertEqual("bar", c.pymongo_test1.test.find_one()["foo"]) c.drop_database("pymongo_test1") finally: ctx.exit()
def test_kill_cursors_warning(self): # If kill_cursors is called while the client is disconnected, it # can't risk taking the lock to reconnect, in case it's being called # from Cursor.__del__, see PYTHON-799. Test that it shows a warning # in this case. client = MongoClient(host, port) collection = client.pymongo_test.test collection.insert({} for _ in range(4)) cursor = collection.find().batch_size(1) cursor.next() client.close() ctx = catch_warnings() try: warnings.simplefilter("error", UserWarning) self.assertRaises(UserWarning, cursor.close) finally: ctx.exit() # Reconnect. collection.find_one() cursor.close()
def test_only_secondary_ok_commands_have_read_prefs(self): c = get_client(read_preference=ReadPreference.SECONDARY) ctx = catch_warnings() try: warnings.simplefilter("ignore", UserWarning) is_mongos = utils.is_mongos(c) finally: ctx.exit() if not is_mongos: raise SkipTest("Only mongos have read_prefs added to the spec") # Ensure secondary_ok_commands have readPreference for cmd in secondary_ok_commands: if cmd == 'mapreduce': # map reduce is a special case continue command = SON([(cmd, 1)]) cursor = c.pymongo_test["$cmd"].find(command.copy()) # White-listed commands also have to be wrapped in $query command = SON([('$query', command)]) command['$readPreference'] = {'mode': 'secondary'} self.assertEqual(command, cursor._Cursor__query_spec()) # map_reduce inline should have read prefs command = SON([('mapreduce', 'test'), ('out', {'inline': 1})]) cursor = c.pymongo_test["$cmd"].find(command.copy()) # White-listed commands also have to be wrapped in $query command = SON([('$query', command)]) command['$readPreference'] = {'mode': 'secondary'} self.assertEqual(command, cursor._Cursor__query_spec()) # map_reduce that outputs to a collection shouldn't have read prefs command = SON([('mapreduce', 'test'), ('out', {'mrtest': 1})]) cursor = c.pymongo_test["$cmd"].find(command.copy()) self.assertEqual(command, cursor._Cursor__query_spec()) # Other commands shouldn't be changed for cmd in ('drop', 'create', 'any-future-cmd'): command = SON([(cmd, 1)]) cursor = c.pymongo_test["$cmd"].find(command.copy()) self.assertEqual(command, cursor._Cursor__query_spec())
def test_copy_db(self): c = MongoClient(host, port) # Due to SERVER-2329, databases may not disappear # from a master in a master-slave pair. if server_is_master_with_slave(c): raise SkipTest("SERVER-2329") ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) self.assertRaises(TypeError, c.copy_database, 4, "foo") self.assertRaises(TypeError, c.copy_database, "foo", 4) self.assertRaises(InvalidName, c.copy_database, "foo", "$foo") c.pymongo_test.test.drop() c.pymongo_test.test.insert({"foo": "bar"}) c.drop_database("pymongo_test1") self.assertFalse("pymongo_test1" in c.database_names()) c.copy_database("pymongo_test", "pymongo_test1") self.assertTrue("pymongo_test1" in c.database_names()) self.assertEqual("bar", c.pymongo_test1.test.find_one()["foo"]) c.drop_database("pymongo_test1") # XXX - SERVER-15318 if not (version.at_least(c, (2, 6, 4)) and is_mongos(c)): self.assertFalse(c.in_request()) c.copy_database("pymongo_test", "pymongo_test1", "%s:%d" % (host, port)) # copy_database() didn't accidentally restart the request self.assertFalse(c.in_request()) self.assertTrue("pymongo_test1" in c.database_names()) self.assertEqual("bar", c.pymongo_test1.test.find_one()["foo"]) c.drop_database("pymongo_test1") finally: ctx.exit()
def test_uuid_queries(self): if not should_test_uuid: raise SkipTest("No uuid module") c = get_client() coll = c.pymongo_test.test coll.drop() uu = uuid.uuid4() # Wrap uu.bytes in binary_type to work # around http://bugs.python.org/issue7380. coll.insert({'uuid': Binary(binary_type(uu.bytes), 3)}) self.assertEqual(1, coll.count()) ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) # Test UUIDLegacy queries. coll.uuid_subtype = 4 self.assertEqual(0, coll.find({'uuid': uu}).count()) cur = coll.find({'uuid': UUIDLegacy(uu)}) self.assertEqual(1, cur.count()) retrieved = cur.next() self.assertEqual(uu, retrieved['uuid']) # Test regular UUID queries (using subtype 4). coll.insert({'uuid': uu}) self.assertEqual(2, coll.count()) cur = coll.find({'uuid': uu}) self.assertEqual(1, cur.count()) retrieved = cur.next() self.assertEqual(uu, retrieved['uuid']) # Test both. cur = coll.find({'uuid': {'$in': [uu, UUIDLegacy(uu)]}}) self.assertEqual(2, cur.count()) coll.drop() finally: ctx.exit()
def test_mongo_client(self): m = MongoClient(pair, w=0) coll = m.pymongo_test.write_concern_test coll.drop() ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) doc = {"_id": ObjectId()} coll.insert(doc) self.assertTrue(coll.insert(doc, safe=False)) self.assertTrue(coll.insert(doc, w=0)) self.assertTrue(coll.insert(doc)) self.assertRaises(OperationFailure, coll.insert, doc, safe=True) self.assertRaises(OperationFailure, coll.insert, doc, w=1) m = MongoClient(pair) coll = m.pymongo_test.write_concern_test self.assertTrue(coll.insert(doc, safe=False)) self.assertTrue(coll.insert(doc, w=0)) self.assertRaises(OperationFailure, coll.insert, doc) self.assertRaises(OperationFailure, coll.insert, doc, safe=True) self.assertRaises(OperationFailure, coll.insert, doc, w=1) m = MongoClient("mongodb://%s/" % (pair,)) self.assertTrue(m.safe) coll = m.pymongo_test.write_concern_test self.assertRaises(OperationFailure, coll.insert, doc) m = MongoClient("mongodb://%s/?w=0" % (pair,)) self.assertFalse(m.safe) coll = m.pymongo_test.write_concern_test self.assertTrue(coll.insert(doc)) finally: ctx.exit() # Equality tests self.assertEqual(m, MongoClient("mongodb://%s/?w=0" % (pair,))) self.assertFalse(m != MongoClient("mongodb://%s/?w=0" % (pair,)))
def test_errors(self): if is_mongos(self.client): raise SkipTest('getpreverror not supported by mongos') db = self.client.pymongo_test ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) db.reset_error_history() self.assertEqual(None, db.error()) self.assertEqual(None, db.previous_error()) db.command("forceerror", check=False) self.assertTrue(db.error()) self.assertTrue(db.previous_error()) db.command("forceerror", check=False) self.assertTrue(db.error()) prev_error = db.previous_error() self.assertEqual(prev_error["nPrev"], 1) del prev_error["nPrev"] prev_error.pop("lastOp", None) error = db.error() error.pop("lastOp", None) # getLastError includes "connectionId" in recent # server versions, getPrevError does not. error.pop("connectionId", None) self.assertEqual(error, prev_error) db.test.find_one() self.assertEqual(None, db.error()) self.assertTrue(db.previous_error()) self.assertEqual(db.previous_error()["nPrev"], 2) db.reset_error_history() self.assertEqual(None, db.error()) self.assertEqual(None, db.previous_error()) finally: ctx.exit()
def test_authenticate_add_remove_user(self): authed_client = auth_context.client db = authed_client.pymongo_test # Configuration errors self.assertRaises(ValueError, db.add_user, "user", '') self.assertRaises(TypeError, db.add_user, "user", 'password', 15) self.assertRaises(ConfigurationError, db.add_user, "user", 'password', 'True') self.assertRaises(ConfigurationError, db.add_user, "user", 'password', True, roles=['read']) if version.at_least(authed_client, (2, 5, 3, -1)): ctx = catch_warnings() try: warnings.simplefilter("error", DeprecationWarning) self.assertRaises(DeprecationWarning, db.add_user, "user", "password") self.assertRaises(DeprecationWarning, db.add_user, "user", "password", True) finally: ctx.exit() self.assertRaises(ConfigurationError, db.add_user, "user", "password", digestPassword=True) authed_client.admin.add_user("admin", "password") self.client.admin.authenticate("admin", "password") db = self.client.pymongo_test try: # Add / authenticate / remove db.add_user("mike", "password") self.assertRaises(TypeError, db.authenticate, 5, "password") self.assertRaises(TypeError, db.authenticate, "mike", 5) self.assertRaises(OperationFailure, db.authenticate, "mike", "not a real password") self.assertRaises(OperationFailure, db.authenticate, "faker", "password") self.assertTrue(db.authenticate("mike", "password")) db.logout() self.assertTrue(db.authenticate(u"mike", u"password")) db.remove_user("mike") db.logout() self.assertRaises(OperationFailure, db.authenticate, "mike", "password") # Add / authenticate / change password self.assertRaises(OperationFailure, db.authenticate, "Gustave", u"Dor\xe9") db.add_user("Gustave", u"Dor\xe9") self.assertTrue(db.authenticate("Gustave", u"Dor\xe9")) db.add_user("Gustave", "password") db.logout() self.assertRaises(OperationFailure, db.authenticate, "Gustave", u"Dor\xe9") self.assertTrue(db.authenticate("Gustave", u"password")) if not version.at_least(authed_client, (2, 5, 3, -1)): # Add a readOnly user db.add_user("Ross", "password", read_only=True) db.logout() self.assertTrue(db.authenticate("Ross", u"password")) self.assertTrue( db.system.users.find({ "readOnly": True }).count()) db.logout() # Cleanup finally: remove_all_users(db) self.client.admin.remove_user("admin") self.client.admin.logout()
def test_command(self): # Test generic 'command' method. Some commands obey read preference, # most don't. # Disobedient commands, always go to primary ctx = catch_warnings() try: warnings.simplefilter("ignore", UserWarning) self._test_fn(False, lambda: self.c.pymongo_test.command('ping')) self._test_fn(False, lambda: self.c.admin.command('buildinfo')) finally: ctx.exit() # Obedient commands. self._test_fn( True, lambda: self.c.pymongo_test.command( 'group', { 'ns': 'test', 'key': { 'a': 1 }, '$reduce': 'function(obj, prev) { }', 'initial': {} })) self._test_fn(True, lambda: self.c.pymongo_test.command('dbStats')) # collStats fails if no collection self.c.pymongo_test.test.insert({}, w=self.w) self._test_fn(True, lambda: self.c.pymongo_test.command('collStats', 'test')) # Count self._test_fn(True, lambda: self.c.pymongo_test.command('count', 'test')) self._test_fn( True, lambda: self.c.pymongo_test.command( 'count', 'test', query={'a': 1})) self._test_fn( True, lambda: self.c.pymongo_test.command( SON([('count', 'test'), ('query', { 'a': 1 })]))) # Distinct self._test_fn( True, lambda: self.c.pymongo_test.command('distinct', 'test', key='a')) self._test_fn( True, lambda: self.c.pymongo_test.command( 'distinct', 'test', key='a', query={'a': 1})) self._test_fn( True, lambda: self.c.pymongo_test.command( SON([('distinct', 'test'), ('key', 'a'), ('query', { 'a': 1 })]))) # Geo stuff. self.c.pymongo_test.test.create_index([('location', '2d')]) self.c.pymongo_test.test.create_index([('location', 'geoHaystack'), ('key', 1)], bucketSize=100) # Attempt to await replication of indexes replicated. self.c.pymongo_test.test2.insert({}, w=self.w) self.c.pymongo_test.test2.remove({}, w=self.w) self._test_fn( True, lambda: self.c.pymongo_test.command( 'geoNear', 'test', near=[0, 0])) self._test_fn( True, lambda: self.c.pymongo_test.command( SON([('geoNear', 'test'), ('near', [0, 0])]))) self._test_fn( True, lambda: self.c.pymongo_test.command('geoSearch', 'test', near=[33, 33], maxDistance=6, search={'type': 'restaurant'}, limit=30)) self._test_fn( True, lambda: self.c.pymongo_test.command( SON([('geoSearch', 'test'), ('near', [33, 33]), ('maxDistance', 6), ('search', { 'type': 'restaurant' }), ('limit', 30)]))) if version.at_least(self.c, (2, 1, 0)): self._test_fn( True, lambda: self.c.pymongo_test.command( SON([('aggregate', 'test'), ('pipeline', [])])))
def test_command(self): # Test generic 'command' method. Some commands obey read preference, # most don't. # Disobedient commands, always go to primary ctx = catch_warnings() try: warnings.simplefilter("ignore", UserWarning) self._test_fn(False, lambda: self.c.pymongo_test.command('ping')) self._test_fn(False, lambda: self.c.admin.command('buildinfo')) finally: ctx.exit() # Obedient commands. self._test_fn( True, lambda: self.c.pymongo_test.command( 'group', { 'ns': 'test', 'key': { 'a': 1 }, '$reduce': 'function(obj, prev) { }', 'initial': {} })) self._test_fn(True, lambda: self.c.pymongo_test.command('dbStats')) # collStats fails if no collection self.c.pymongo_test.test.insert({}, w=self.w) time.sleep(1) # wait for slaves to apply self._test_fn(True, lambda: self.c.pymongo_test.command('collStats', 'test')) # Count self._test_fn(True, lambda: self.c.pymongo_test.command('count', 'test')) self._test_fn( True, lambda: self.c.pymongo_test.command( 'count', 'test', query={'a': 1})) self._test_fn( True, lambda: self.c.pymongo_test.command( SON([('count', 'test'), ('query', { 'a': 1 })]))) # Distinct self._test_fn( True, lambda: self.c.pymongo_test.command('distinct', 'test', key='a')) self._test_fn( True, lambda: self.c.pymongo_test.command( 'distinct', 'test', key='a', query={'a': 1})) self._test_fn( True, lambda: self.c.pymongo_test.command( SON([('distinct', 'test'), ('key', 'a'), ('query', { 'a': 1 })]))) if version.tokumx_at_least( self.c, (2, )) and not version.tokumx_at_least(self.c, (2, 0, 9999)): # Geo stuff. Make sure a 2d index is created and replicated self.c.pymongo_test.system.indexes.insert( { 'key': { 'location': '2d' }, 'ns': 'pymongo_test.test', 'name': 'location_2d' }, w=self.w) self.c.pymongo_test.system.indexes.insert(SON([ ('ns', 'pymongo_test.test'), ('key', SON([('location', 'geoHaystack'), ('key', 1)])), ('bucketSize', 100), ('name', 'location_geoHaystack'), ]), w=self.w) self._test_fn( True, lambda: self.c.pymongo_test.command( 'geoNear', 'test', near=[0, 0])) self._test_fn( True, lambda: self.c.pymongo_test.command( SON([('geoNear', 'test'), ('near', [0, 0])]))) self._test_fn( True, lambda: self.c.pymongo_test.command( 'geoSearch', 'test', near=[33, 33], maxDistance=6, search={'type': 'restaurant'}, limit=30)) self._test_fn( True, lambda: self.c.pymongo_test.command( SON([('geoSearch', 'test'), ('near', [33, 33]), ('maxDistance', 6), ('search', { 'type': 'restaurant' }), ('limit', 30)]))) if version.at_least(self.c, (2, 1, 0)): self._test_fn( True, lambda: self.c.pymongo_test.command( SON([('aggregate', 'test'), ('pipeline', [])]))) # Text search. if version.at_least(self.c, (2, 3, 2)) and version.tokumx_at_least( self.c, (2, 2)): ctx = catch_warnings() try: warnings.simplefilter("ignore", UserWarning) utils.enable_text_search(self.c) finally: ctx.exit() db = self.c.pymongo_test # Only way to create an index and wait for all members to build it. index = { 'ns': 'pymongo_test.test', 'name': 't_text', 'key': { 't': 'text' } } db.system.indexes.insert(index, manipulate=False, check_keys=False, w=self.w) self._test_fn( True, lambda: self.c.pymongo_test.command( SON([('text', 'test'), ('search', 'foo')]))) self.c.pymongo_test.test.drop_indexes()
def test_authenticate_add_remove_user(self): if (is_mongos(self.client) and not version.at_least(self.client, (2, 0, 0))): raise SkipTest("Auth with sharding requires MongoDB >= 2.0.0") if is_mongos(self.client): raise SkipTest("Auth fails on sharding due to write concern race, see Tokutek/mongo#77") if not server_started_with_auth(self.client): raise SkipTest('Authentication is not enabled on server') db = self.client.pymongo_test # Configuration errors self.assertRaises(ValueError, db.add_user, "user", '') self.assertRaises(TypeError, db.add_user, "user", 'password', 15) self.assertRaises(ConfigurationError, db.add_user, "user", 'password', 'True') self.assertRaises(ConfigurationError, db.add_user, "user", 'password', True, roles=['read']) if version.at_least(self.client, (2, 5, 3, -1)): ctx = catch_warnings() try: warnings.simplefilter("error", DeprecationWarning) self.assertRaises(DeprecationWarning, db.add_user, "user", "password") self.assertRaises(DeprecationWarning, db.add_user, "user", "password", True) finally: ctx.exit() self.assertRaises(ConfigurationError, db.add_user, "user", "password", digestPassword=True) self.client.admin.add_user("admin", "password") self.client.admin.authenticate("admin", "password") try: # Add / authenticate / remove db.add_user("mike", "password") self.assertRaises(TypeError, db.authenticate, 5, "password") self.assertRaises(TypeError, db.authenticate, "mike", 5) self.assertRaises(OperationFailure, db.authenticate, "mike", "not a real password") self.assertRaises(OperationFailure, db.authenticate, "faker", "password") self.assertTrue(db.authenticate("mike", "password")) db.logout() self.assertTrue(db.authenticate(u"mike", u"password")) db.remove_user("mike") db.logout() self.assertRaises(OperationFailure, db.authenticate, "mike", "password") # Add / authenticate / change password self.assertRaises(OperationFailure, db.authenticate, "Gustave", u"Dor\xe9") db.add_user("Gustave", u"Dor\xe9") self.assertTrue(db.authenticate("Gustave", u"Dor\xe9")) db.add_user("Gustave", "password") db.logout() self.assertRaises(OperationFailure, db.authenticate, "Gustave", u"Dor\xe9") self.assertTrue(db.authenticate("Gustave", u"password")) if not version.at_least(self.client, (2, 5, 3, -1)): # Add a readOnly user db.add_user("Ross", "password", read_only=True) db.logout() self.assertTrue(db.authenticate("Ross", u"password")) self.assertTrue(db.system.users.find({"readOnly": True}).count()) db.logout() # Cleanup finally: remove_all_users(db) self.client.admin.remove_user("admin") self.client.admin.logout()
def test_base_object(self): ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) c = self.client self.assertFalse(c.slave_okay) self.assertTrue(bool(c.read_preference)) self.assertTrue(c.safe) self.assertEqual({}, c.get_lasterror_options()) db = c.pymongo_test self.assertFalse(db.slave_okay) self.assertTrue(bool(c.read_preference)) self.assertTrue(db.safe) self.assertEqual({}, db.get_lasterror_options()) coll = db.test coll.drop() self.assertFalse(coll.slave_okay) self.assertTrue(bool(c.read_preference)) self.assertTrue(coll.safe) self.assertEqual({}, coll.get_lasterror_options()) cursor = coll.find() self.assertFalse(cursor._Cursor__slave_okay) self.assertTrue(bool(cursor._Cursor__read_preference)) w = 1 + len(self.slaves) wtimeout = 10000 # Wait 10 seconds for replication to complete c.set_lasterror_options(w=w, wtimeout=wtimeout) self.assertFalse(c.slave_okay) self.assertTrue(bool(c.read_preference)) self.assertTrue(c.safe) self.assertEqual({ 'w': w, 'wtimeout': wtimeout }, c.get_lasterror_options()) db = c.pymongo_test self.assertFalse(db.slave_okay) self.assertTrue(bool(c.read_preference)) self.assertTrue(db.safe) self.assertEqual({ 'w': w, 'wtimeout': wtimeout }, db.get_lasterror_options()) coll = db.test self.assertFalse(coll.slave_okay) self.assertTrue(bool(c.read_preference)) self.assertTrue(coll.safe) self.assertEqual({ 'w': w, 'wtimeout': wtimeout }, coll.get_lasterror_options()) cursor = coll.find() self.assertFalse(cursor._Cursor__slave_okay) self.assertTrue(bool(cursor._Cursor__read_preference)) coll.insert({'foo': 'bar'}) self.assertEqual(1, coll.find({'foo': 'bar'}).count()) self.assertTrue(coll.find({'foo': 'bar'})) coll.remove({'foo': 'bar'}) self.assertEqual(0, coll.find({'foo': 'bar'}).count()) c.safe = False c.unset_lasterror_options() self.assertFalse(self.client.slave_okay) self.assertTrue(bool(self.client.read_preference)) self.assertFalse(self.client.safe) self.assertEqual({}, self.client.get_lasterror_options()) finally: ctx.exit()
def test_mongos_connection(self): c = get_client() is_mongos = utils.is_mongos(c) # Test default mode, PRIMARY cursor = c.pymongo_test.test.find() if is_mongos: # We only set $readPreference if it's something other than # PRIMARY to avoid problems with mongos versions that don't # support read preferences. self.assertEqual( None, cursor._Cursor__query_spec().get('$readPreference')) else: self.assertFalse('$readPreference' in cursor._Cursor__query_spec()) # Copy these constants for brevity PRIMARY_PREFERRED = ReadPreference.PRIMARY_PREFERRED SECONDARY = ReadPreference.SECONDARY SECONDARY_PREFERRED = ReadPreference.SECONDARY_PREFERRED NEAREST = ReadPreference.NEAREST SLAVE_OKAY = _QUERY_OPTIONS['slave_okay'] ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) # Test non-PRIMARY modes which can be combined with tags for kwarg, value, mongos_mode in (('read_preference', PRIMARY_PREFERRED, 'primaryPreferred'), ('read_preference', SECONDARY, 'secondary'), ('read_preference', SECONDARY_PREFERRED, 'secondaryPreferred'), ('read_preference', NEAREST, 'nearest'), ('slave_okay', True, 'secondaryPreferred'), ('slave_okay', False, 'primary')): for tag_sets in (None, [{}]): # Create a client e.g. with read_preference=NEAREST or # slave_okay=True c = get_client(tag_sets=tag_sets, **{kwarg: value}) self.assertEqual(is_mongos, c.is_mongos) cursor = c.pymongo_test.test.find() if is_mongos: # We don't set $readPreference for SECONDARY_PREFERRED # unless tags are in use. slaveOkay has the same effect. if mongos_mode == 'secondaryPreferred': self.assertEqual( None, cursor._Cursor__query_spec().get( '$readPreference')) self.assertTrue(cursor._Cursor__query_options() & SLAVE_OKAY) # Don't send $readPreference for PRIMARY either elif mongos_mode == 'primary': self.assertEqual( None, cursor._Cursor__query_spec().get( '$readPreference')) self.assertFalse(cursor._Cursor__query_options() & SLAVE_OKAY) else: self.assertEqual({'mode': mongos_mode}, cursor._Cursor__query_spec().get( '$readPreference')) self.assertTrue(cursor._Cursor__query_options() & SLAVE_OKAY) else: self.assertFalse( '$readPreference' in cursor._Cursor__query_spec()) for tag_sets in ( [{ 'dc': 'la' }], [{ 'dc': 'la' }, { 'dc': 'sf' }], [{ 'dc': 'la' }, { 'dc': 'sf' }, {}], ): if kwarg == 'slave_okay': # Can't use tags with slave_okay True or False, need a # real read preference self.assertRaises(ConfigurationError, get_client, tag_sets=tag_sets, **{kwarg: value}) continue c = get_client(tag_sets=tag_sets, **{kwarg: value}) self.assertEqual(is_mongos, c.is_mongos) cursor = c.pymongo_test.test.find() if is_mongos: self.assertEqual( { 'mode': mongos_mode, 'tags': tag_sets }, cursor._Cursor__query_spec().get( '$readPreference')) else: self.assertFalse( '$readPreference' in cursor._Cursor__query_spec()) finally: ctx.exit()
def test_baseobject(self): ctx = catch_warnings() try: warnings.simplefilter("error", UserWarning) self.assertRaises(UserWarning, lambda: MongoClient(host, port, wtimeout=1000, w=0)) try: MongoClient(host, port, wtimeout=1000, w=1) except UserWarning: self.fail() try: MongoClient(host, port, wtimeout=1000) except UserWarning: self.fail() finally: ctx.exit() # Connection tests ctx = catch_warnings() try: warnings.simplefilter("ignore", DeprecationWarning) c = Connection(pair) self.assertFalse(c.slave_okay) self.assertFalse(c.safe) self.assertEqual({}, c.get_lasterror_options()) db = c.pymongo_test db.drop_collection("test") self.assertFalse(db.slave_okay) self.assertFalse(db.safe) self.assertEqual({}, db.get_lasterror_options()) coll = db.test self.assertFalse(coll.slave_okay) self.assertFalse(coll.safe) self.assertEqual({}, coll.get_lasterror_options()) self.assertEqual((False, {}), coll._get_write_mode()) coll.safe = False coll.write_concern.update(w=1) self.assertEqual((True, {}), coll._get_write_mode()) coll.write_concern.update(w=3) self.assertEqual((True, {'w': 3}), coll._get_write_mode()) coll.safe = True coll.write_concern.update(w=0) self.assertEqual((False, {}), coll._get_write_mode()) coll = db.test cursor = coll.find() self.assertFalse(cursor._Cursor__slave_okay) cursor = coll.find(slave_okay=True) self.assertTrue(cursor._Cursor__slave_okay) # MongoClient test c = MongoClient(pair) self.assertFalse(c.slave_okay) self.assertTrue(c.safe) self.assertEqual({}, c.get_lasterror_options()) db = c.pymongo_test db.drop_collection("test") self.assertFalse(db.slave_okay) self.assertTrue(db.safe) self.assertEqual({}, db.get_lasterror_options()) coll = db.test self.assertFalse(coll.slave_okay) self.assertTrue(coll.safe) self.assertEqual({}, coll.get_lasterror_options()) self.assertEqual((True, {}), coll._get_write_mode()) coll.safe = False coll.write_concern.update(w=1) self.assertEqual((True, {}), coll._get_write_mode()) coll.write_concern.update(w=3) self.assertEqual((True, {'w': 3}), coll._get_write_mode()) coll.safe = True coll.write_concern.update(w=0) self.assertEqual((False, {}), coll._get_write_mode()) coll = db.test cursor = coll.find() self.assertFalse(cursor._Cursor__slave_okay) cursor = coll.find(slave_okay=True) self.assertTrue(cursor._Cursor__slave_okay) # Setting any safe operations overrides explicit safe self.assertTrue(MongoClient(host, port, wtimeout=1000, safe=False).safe) c = MongoClient(pair, slaveok=True, w='majority', wtimeout=300, fsync=True, j=True) self.assertTrue(c.slave_okay) self.assertTrue(c.safe) d = {'w': 'majority', 'wtimeout': 300, 'fsync': True, 'j': True} self.assertEqual(d, c.get_lasterror_options()) db = c.pymongo_test self.assertTrue(db.slave_okay) self.assertTrue(db.safe) self.assertEqual(d, db.get_lasterror_options()) coll = db.test self.assertTrue(coll.slave_okay) self.assertTrue(coll.safe) self.assertEqual(d, coll.get_lasterror_options()) cursor = coll.find() self.assertTrue(cursor._Cursor__slave_okay) cursor = coll.find(slave_okay=False) self.assertFalse(cursor._Cursor__slave_okay) c = MongoClient('mongodb://%s/?' 'w=2;wtimeoutMS=300;fsync=true;' 'journal=true' % (pair,)) self.assertTrue(c.safe) d = {'w': 2, 'wtimeout': 300, 'fsync': True, 'j': True} self.assertEqual(d, c.get_lasterror_options()) c = MongoClient('mongodb://%s/?' 'slaveok=true;w=1;wtimeout=300;' 'fsync=true;j=true' % (pair,)) self.assertTrue(c.slave_okay) self.assertTrue(c.safe) d = {'w': 1, 'wtimeout': 300, 'fsync': True, 'j': True} self.assertEqual(d, c.get_lasterror_options()) self.assertEqual(d, c.write_concern) db = c.pymongo_test self.assertTrue(db.slave_okay) self.assertTrue(db.safe) self.assertEqual(d, db.get_lasterror_options()) self.assertEqual(d, db.write_concern) coll = db.test self.assertTrue(coll.slave_okay) self.assertTrue(coll.safe) self.assertEqual(d, coll.get_lasterror_options()) self.assertEqual(d, coll.write_concern) cursor = coll.find() self.assertTrue(cursor._Cursor__slave_okay) cursor = coll.find(slave_okay=False) self.assertFalse(cursor._Cursor__slave_okay) c.unset_lasterror_options() self.assertTrue(c.slave_okay) self.assertTrue(c.safe) c.safe = False self.assertFalse(c.safe) c.slave_okay = False self.assertFalse(c.slave_okay) self.assertEqual({}, c.get_lasterror_options()) self.assertEqual({}, c.write_concern) db = c.pymongo_test self.assertFalse(db.slave_okay) self.assertFalse(db.safe) self.assertEqual({}, db.get_lasterror_options()) self.assertEqual({}, db.write_concern) coll = db.test self.assertFalse(coll.slave_okay) self.assertFalse(coll.safe) self.assertEqual({}, coll.get_lasterror_options()) self.assertEqual({}, coll.write_concern) cursor = coll.find() self.assertFalse(cursor._Cursor__slave_okay) cursor = coll.find(slave_okay=True) self.assertTrue(cursor._Cursor__slave_okay) coll.set_lasterror_options(fsync=True) self.assertEqual({'fsync': True}, coll.get_lasterror_options()) self.assertEqual({'fsync': True}, coll.write_concern) self.assertEqual({}, db.get_lasterror_options()) self.assertEqual({}, db.write_concern) self.assertFalse(db.safe) self.assertEqual({}, c.get_lasterror_options()) self.assertEqual({}, c.write_concern) self.assertFalse(c.safe) db.set_lasterror_options(w='majority') self.assertEqual({'fsync': True}, coll.get_lasterror_options()) self.assertEqual({'fsync': True}, coll.write_concern) self.assertEqual({'w': 'majority'}, db.get_lasterror_options()) self.assertEqual({'w': 'majority'}, db.write_concern) self.assertEqual({}, c.get_lasterror_options()) self.assertEqual({}, c.write_concern) self.assertFalse(c.safe) db.slave_okay = True self.assertTrue(db.slave_okay) self.assertFalse(c.slave_okay) self.assertFalse(coll.slave_okay) cursor = coll.find() self.assertFalse(cursor._Cursor__slave_okay) cursor = db.coll2.find() self.assertTrue(cursor._Cursor__slave_okay) cursor = db.coll2.find(slave_okay=False) self.assertFalse(cursor._Cursor__slave_okay) self.assertRaises(ConfigurationError, coll.set_lasterror_options, foo=20) self.assertRaises(TypeError, coll._BaseObject__set_slave_okay, 20) self.assertRaises(TypeError, coll._BaseObject__set_safe, 20) coll.remove() self.assertEqual(None, coll.find_one(slave_okay=True)) coll.unset_lasterror_options() coll.set_lasterror_options(w=4, wtimeout=10) # Fails if we don't have 4 active nodes or we don't have replication... self.assertRaises(OperationFailure, coll.insert, {'foo': 'bar'}) # Succeeds since we override the lasterror settings per query. self.assertTrue(coll.insert({'foo': 'bar'}, fsync=True)) drop_collections(db) finally: ctx.exit()