def test_mongos_max_staleness(self): # Sanity check that we're sending maxStalenessSeconds coll = client_context.client.pymongo_test.get_collection( "test", read_preference=SecondaryPreferred(max_staleness=120)) # No error coll.find_one() coll = client_context.client.pymongo_test.get_collection( "test", read_preference=SecondaryPreferred(max_staleness=10)) try: coll.find_one() except OperationFailure as exc: self.assertEqual(160, exc.code) else: self.fail("mongos accepted invalid staleness") coll = single_client(readPreference='secondaryPreferred', maxStalenessSeconds=120).pymongo_test.test # No error coll.find_one() coll = single_client(readPreference='secondaryPreferred', maxStalenessSeconds=10).pymongo_test.test try: coll.find_one() except OperationFailure as exc: self.assertEqual(160, exc.code) else: self.fail("mongos accepted invalid staleness")
def test_query_and_read_mode_sharded_op_msg(self): """Test OP_MSG sends non-primary $readPreference and never $query.""" server = MockupDB() server.autoresponds('ismaster', ismaster=True, msg='isdbgrid', minWireVersion=2, maxWireVersion=6) server.run() self.addCleanup(server.stop) client = MongoClient(server.uri) self.addCleanup(client.close) read_prefs = ( Primary(), SecondaryPreferred(), PrimaryPreferred(), Secondary(), Nearest(), SecondaryPreferred([{'tag': 'value'}]),) for query in ({'a': 1}, {'$query': {'a': 1}},): for mode in read_prefs: collection = client.db.get_collection('test', read_preference=mode) cursor = collection.find(query.copy()) with going(next, cursor): request = server.receives() # Command is not nested in $query. request.assert_matches(OpMsg( SON([('find', 'test'), ('filter', {'a': 1}), ('$readPreference', mode.document)]))) request.replies({'cursor': {'id': 0, 'firstBatch': [{}]}})
def test_maybe_add_read_preference(self): # Primary doesn't add $readPreference out = _maybe_add_read_preference({}, Primary()) self.assertEqual(out, {}) pref = PrimaryPreferred() out = _maybe_add_read_preference({}, pref) self.assertEqual( out, SON([("$query", {}), ("$readPreference", pref.document)])) pref = PrimaryPreferred(tag_sets=[{'dc': 'nyc'}]) out = _maybe_add_read_preference({}, pref) self.assertEqual( out, SON([("$query", {}), ("$readPreference", pref.document)])) pref = Secondary() out = _maybe_add_read_preference({}, pref) self.assertEqual( out, SON([("$query", {}), ("$readPreference", pref.document)])) pref = Secondary(tag_sets=[{'dc': 'nyc'}]) out = _maybe_add_read_preference({}, pref) self.assertEqual( out, SON([("$query", {}), ("$readPreference", pref.document)])) # SecondaryPreferred without tag_sets or max_staleness doesn't add # $readPreference pref = SecondaryPreferred() out = _maybe_add_read_preference({}, pref) self.assertEqual(out, {}) pref = SecondaryPreferred(tag_sets=[{'dc': 'nyc'}]) out = _maybe_add_read_preference({}, pref) self.assertEqual( out, SON([("$query", {}), ("$readPreference", pref.document)])) pref = SecondaryPreferred(max_staleness=120) out = _maybe_add_read_preference({}, pref) self.assertEqual( out, SON([("$query", {}), ("$readPreference", pref.document)])) pref = Nearest() out = _maybe_add_read_preference({}, pref) self.assertEqual( out, SON([("$query", {}), ("$readPreference", pref.document)])) pref = Nearest(tag_sets=[{'dc': 'nyc'}]) out = _maybe_add_read_preference({}, pref) self.assertEqual( out, SON([("$query", {}), ("$readPreference", pref.document)])) criteria = SON([("$query", {}), ("$orderby", SON([("_id", 1)]))]) pref = Nearest() out = _maybe_add_read_preference(criteria, pref) self.assertEqual( out, SON([("$query", {}), ("$orderby", SON([("_id", 1)])), ("$readPreference", pref.document)])) pref = Nearest(tag_sets=[{'dc': 'nyc'}]) out = _maybe_add_read_preference(criteria, pref) self.assertEqual( out, SON([("$query", {}), ("$orderby", SON([("_id", 1)])), ("$readPreference", pref.document)]))
def create(self, name: str) -> Client: client = self.clients.get(name) if client != None: return client else: opts = self.load_options(name) if opts == None: return mode = Primary() if opts.read_preference == READ_PREFERENCE_PRIMARY_PREFERRED: mode = PrimaryPreferred() elif opts.read_preference == READ_PREFERENCE_SECONDARY: mode = Secondary() elif opts.read_preference == READ_PREFERENCE_SECONDARY_PREFERRED: mode = SecondaryPreferred() elif opts.read_preference == READ_PREFERENCE_NEAREST: mode = Nearest() kwargs = { "read_preference" : mode, "maxPoolSize" : opts.max_pool_size, "minPoolSize" : opts.min_pool_size, "socketTimeoutMS" : opts.socket_time_out, "connectTimeoutMS" : opts.connect_time_out } _client = MongoClient(host=opts.uri, **kwargs) client = Client(db=name, c=_client, opts=opts) self.clients.set(name, client) return client
def test_mongos(self): shard = client_context.client.config.shards.find_one()['host'] num_members = shard.count(',') + 1 if num_members == 1: raise SkipTest("Need a replica set shard to test.") coll = client_context.client.pymongo_test.get_collection( "test", write_concern=WriteConcern(w=num_members)) coll.drop() res = coll.insert_many([{} for _ in range(5)]) first_id = res.inserted_ids[0] last_id = res.inserted_ids[-1] # Note - this isn't a perfect test since there's no way to # tell what shard member a query ran on. for pref in (Primary(), PrimaryPreferred(), Secondary(), SecondaryPreferred(), Nearest()): qcoll = coll.with_options(read_preference=pref) results = list(qcoll.find().sort([("_id", 1)])) self.assertEqual(first_id, results[0]["_id"]) self.assertEqual(last_id, results[-1]["_id"]) results = list(qcoll.find().sort([("_id", -1)])) self.assertEqual(first_id, results[-1]["_id"]) self.assertEqual(last_id, results[0]["_id"])
def test_query_and_read_mode_sharded_op_query(self): server = MockupDB() server.autoresponds('ismaster', ismaster=True, msg='isdbgrid', minWireVersion=2, maxWireVersion=5) server.run() self.addCleanup(server.stop) client = MongoClient(server.uri) self.addCleanup(client.close) modes_without_query = ( Primary(), SecondaryPreferred(),) modes_with_query = ( PrimaryPreferred(), Secondary(), Nearest(), SecondaryPreferred([{'tag': 'value'}]),) find_command = SON([('find', 'test'), ('filter', {'a': 1})]) for query in ({'a': 1}, {'$query': {'a': 1}},): for mode in modes_with_query + modes_without_query: collection = client.db.get_collection('test', read_preference=mode) cursor = collection.find(query.copy()) with going(next, cursor): request = server.receives() if mode in modes_without_query: # Filter is hoisted out of $query. request.assert_matches(Command(find_command)) self.assertFalse('$readPreference' in request) else: # Command is nested in $query. request.assert_matches(Command( SON([('$query', find_command), ('$readPreference', mode.document)]))) request.replies({'cursor': {'id': 0, 'firstBatch': [{}]}})
class TestReadPreferenceObjects(unittest.TestCase): prefs = [Primary(), Secondary(), Nearest(tag_sets=[{'a': 1}, {'b': 2}]), SecondaryPreferred(max_staleness=30)] def test_pickle(self): for pref in self.prefs: self.assertEqual(pref, pickle.loads(pickle.dumps(pref))) def test_copy(self): for pref in self.prefs: self.assertEqual(pref, copy.copy(pref))
def test_query_and_read_mode_sharded(self): server = MockupDB() server.autoresponds('ismaster', ismaster=True, msg='isdbgrid') server.run() self.addCleanup(server.stop) client = MongoClient(server.uri) self.addCleanup(client.close) modes_without_query = ( Primary(), SecondaryPreferred(),) modes_with_query = ( PrimaryPreferred(), Secondary(), Nearest(), SecondaryPreferred([{'tag': 'value'}]),) for query in ({'a': 1}, {'$query': {'a': 1}},): for mode in modes_with_query + modes_without_query: collection = client.db.get_collection('test', read_preference=mode) cursor = collection.find(query.copy()) with going(next, cursor): request = server.receives(OpQuery) if mode in modes_without_query: # Query is not edited: {'a': 1} is not nested in $query, # {'$query': {'a': 1}} is not hoisted. request.assert_matches(query) self.assertFalse('$readPreference' in request) else: # {'a': 1} is *always* nested in $query. request.assert_matches({ '$query': {'a': 1}, '$readPreference': mode.document }) request.replies({})
def test_read_preference_document(self): pref = Primary() self.assertEqual(pref.document, {'mode': 'primary'}) pref = PrimaryPreferred() self.assertEqual(pref.document, {'mode': 'primaryPreferred'}) pref = PrimaryPreferred(tag_sets=[{'dc': 'sf'}]) self.assertEqual(pref.document, { 'mode': 'primaryPreferred', 'tags': [{ 'dc': 'sf' }] }) pref = PrimaryPreferred(tag_sets=[{'dc': 'sf'}], max_staleness=30) self.assertEqual( pref.document, { 'mode': 'primaryPreferred', 'tags': [{ 'dc': 'sf' }], 'maxStalenessSeconds': 30 }) pref = Secondary() self.assertEqual(pref.document, {'mode': 'secondary'}) pref = Secondary(tag_sets=[{'dc': 'sf'}]) self.assertEqual(pref.document, { 'mode': 'secondary', 'tags': [{ 'dc': 'sf' }] }) pref = Secondary(tag_sets=[{'dc': 'sf'}], max_staleness=30) self.assertEqual(pref.document, { 'mode': 'secondary', 'tags': [{ 'dc': 'sf' }], 'maxStalenessSeconds': 30 }) pref = SecondaryPreferred() self.assertEqual(pref.document, {'mode': 'secondaryPreferred'}) pref = SecondaryPreferred(tag_sets=[{'dc': 'sf'}]) self.assertEqual(pref.document, { 'mode': 'secondaryPreferred', 'tags': [{ 'dc': 'sf' }] }) pref = SecondaryPreferred(tag_sets=[{'dc': 'sf'}], max_staleness=30) self.assertEqual( pref.document, { 'mode': 'secondaryPreferred', 'tags': [{ 'dc': 'sf' }], 'maxStalenessSeconds': 30 }) pref = Nearest() self.assertEqual(pref.document, {'mode': 'nearest'}) pref = Nearest(tag_sets=[{'dc': 'sf'}]) self.assertEqual(pref.document, { 'mode': 'nearest', 'tags': [{ 'dc': 'sf' }] }) pref = Nearest(tag_sets=[{'dc': 'sf'}], max_staleness=30) self.assertEqual(pref.document, { 'mode': 'nearest', 'tags': [{ 'dc': 'sf' }], 'maxStalenessSeconds': 30 }) with self.assertRaises(TypeError): Nearest(max_staleness=1.5) # Float is prohibited. with self.assertRaises(ValueError): Nearest(max_staleness=0) with self.assertRaises(ValueError): Nearest(max_staleness=-2)
def test_read_preference_document(self): pref = Primary() self.assertEqual(pref.document, {'mode': 'primary'}) pref = PrimaryPreferred() self.assertEqual(pref.document, {'mode': 'primaryPreferred'}) pref = PrimaryPreferred(tag_sets=[{'dc': 'sf'}]) self.assertEqual(pref.document, { 'mode': 'primaryPreferred', 'tags': [{ 'dc': 'sf' }] }) pref = PrimaryPreferred(tag_sets=[{'dc': 'sf'}], max_staleness=30) self.assertEqual( pref.document, { 'mode': 'primaryPreferred', 'tags': [{ 'dc': 'sf' }], 'maxStalenessMS': 30000 }) pref = Secondary() self.assertEqual(pref.document, {'mode': 'secondary'}) pref = Secondary(tag_sets=[{'dc': 'sf'}]) self.assertEqual(pref.document, { 'mode': 'secondary', 'tags': [{ 'dc': 'sf' }] }) pref = Secondary(tag_sets=[{'dc': 'sf'}], max_staleness=30) self.assertEqual(pref.document, { 'mode': 'secondary', 'tags': [{ 'dc': 'sf' }], 'maxStalenessMS': 30000 }) pref = SecondaryPreferred() self.assertEqual(pref.document, {'mode': 'secondaryPreferred'}) pref = SecondaryPreferred(tag_sets=[{'dc': 'sf'}]) self.assertEqual(pref.document, { 'mode': 'secondaryPreferred', 'tags': [{ 'dc': 'sf' }] }) pref = SecondaryPreferred(tag_sets=[{'dc': 'sf'}], max_staleness=30) self.assertEqual( pref.document, { 'mode': 'secondaryPreferred', 'tags': [{ 'dc': 'sf' }], 'maxStalenessMS': 30000 }) pref = Nearest() self.assertEqual(pref.document, {'mode': 'nearest'}) pref = Nearest(tag_sets=[{'dc': 'sf'}]) self.assertEqual(pref.document, { 'mode': 'nearest', 'tags': [{ 'dc': 'sf' }] }) pref = Nearest(tag_sets=[{'dc': 'sf'}], max_staleness=30) self.assertEqual(pref.document, { 'mode': 'nearest', 'tags': [{ 'dc': 'sf' }], 'maxStalenessMS': 30000 })