def test_tag_sets_validation(self): S = Secondary(tag_sets=[{}]) self.assertEqual([{}], rs_client(read_preference=S).read_preference.tag_sets) S = Secondary(tag_sets=[{'k': 'v'}]) self.assertEqual([{ 'k': 'v' }], rs_client(read_preference=S).read_preference.tag_sets) S = Secondary(tag_sets=[{'k': 'v'}, {}]) self.assertEqual([{ 'k': 'v' }, {}], rs_client(read_preference=S).read_preference.tag_sets) self.assertRaises(ValueError, Secondary, tag_sets=[]) # One dict not ok, must be a list of dicts self.assertRaises(TypeError, Secondary, tag_sets={'k': 'v'}) self.assertRaises(TypeError, Secondary, tag_sets='foo') self.assertRaises(TypeError, Secondary, tag_sets=['foo'])
def test_tag_sets_validation(self): # Can't use tags with PRIMARY self.assertRaises(ConfigurationError, _ServerMode, 0, tag_sets=[{'k': 'v'}]) # ... but empty tag sets are ok with PRIMARY self.assertRaises(ConfigurationError, _ServerMode, 0, tag_sets=[{}]) S = Secondary(tag_sets=[{}]) self.assertEqual( [{}], rs_client(read_preference=S).read_preference.tag_sets) S = Secondary(tag_sets=[{'k': 'v'}]) self.assertEqual( [{'k': 'v'}], rs_client(read_preference=S).read_preference.tag_sets) S = Secondary(tag_sets=[{'k': 'v'}, {}]) self.assertEqual( [{'k': 'v'}, {}], rs_client(read_preference=S).read_preference.tag_sets) self.assertRaises(ValueError, Secondary, tag_sets=[]) # One dict not ok, must be a list of dicts self.assertRaises(TypeError, Secondary, tag_sets={'k': 'v'}) self.assertRaises(TypeError, Secondary, tag_sets='foo') self.assertRaises(TypeError, Secondary, tag_sets=['foo'])
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 test_read_preference(self): # Check the default cx = motor_asyncio.AsyncIOMotorClient(test.env.uri, io_loop=self.loop) self.assertEqual(ReadPreference.PRIMARY, cx.read_preference) # We can set mode, tags, and latency. cx = self.asyncio_client( read_preference=Secondary(tag_sets=[{ 'foo': 'bar' }]), localThresholdMS=42) self.assertEqual(ReadPreference.SECONDARY.mode, cx.read_preference.mode) self.assertEqual([{'foo': 'bar'}], cx.read_preference.tag_sets) self.assertEqual(42, cx.local_threshold_ms) # Make a MotorCursor and get its PyMongo Cursor collection = cx.motor_test.test_collection.with_options( read_preference=Nearest(tag_sets=[{ 'yay': 'jesse' }])) motor_cursor = collection.find() cursor = motor_cursor.delegate self.assertEqual(Nearest(tag_sets=[{ 'yay': 'jesse' }]), cursor._Cursor__read_preference) cx.close()
def test_sub_collection(self): # Verify that a collection with a dotted name inherits options from its # parent collection. write_concern = WriteConcern(w=2, j=True) read_concern = ReadConcern("majority") read_preference = Secondary([{"dc": "sf"}]) codec_options = CodecOptions(tz_aware=True, uuid_representation=JAVA_LEGACY) coll1 = self.db.get_collection( "test", write_concern=write_concern, read_concern=read_concern, read_preference=read_preference, codec_options=codec_options, ) coll2 = coll1.subcollection coll3 = coll1["subcollection"] for c in [coll1, coll2, coll3]: self.assertEqual(write_concern, c.write_concern) self.assertEqual(read_concern, c.read_concern) self.assertEqual(read_preference, c.read_preference) self.assertEqual(codec_options, c.codec_options)
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_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_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_parallel_scan(self): if not (yield from at_least(self.cx, (2, 5, 5))): raise SkipTest("Requires MongoDB >= 2.5.5") yield from skip_if_mongos(self.cx) collection = self.collection.with_options( write_concern=WriteConcern(test.env.w)) # Enough documents that each cursor requires multiple batches. yield from collection.delete_many({}) yield from collection.insert_many(({'_id': i} for i in range(8000))) if test.env.is_replica_set: # Test that getMore messages are sent to the right server. client = self.asyncio_rsc(read_preference=Secondary()) collection = client.motor_test.test_collection docs = [] @asyncio.coroutine def f(cursor): self.assertTrue(isinstance(cursor, AsyncIOMotorCommandCursor)) while (yield from cursor.fetch_next): docs.append(cursor.next_object()) cursors = yield from collection.parallel_scan(3) yield from asyncio.wait([f(cursor) for cursor in cursors], loop=self.loop) self.assertEqual(len(docs), (yield from collection.count()))
def test_parallel_scan(self): yield skip_if_mongos(self.cx) collection = self.collection.with_options( write_concern=WriteConcern(test.env.w)) # Enough documents that each cursor requires multiple batches. yield collection.delete_many({}) yield collection.insert_many(({'_id': i} for i in range(8000))) if test.env.is_replica_set: # Test that getMore messages are sent to the right server. client = self.motor_rsc(read_preference=Secondary()) collection = client.motor_test.test_collection docs = [] @gen.coroutine def f(cursor): self.assertTrue( isinstance(cursor, motor.motor_tornado.MotorCommandCursor)) while (yield cursor.fetch_next): docs.append(cursor.next_object()) cursors = yield collection.parallel_scan(3) yield [f(cursor) for cursor in cursors] self.assertEqual(len(docs), (yield collection.count_documents({})))
def test_properties(self): c = client_context.client c.admin.command('ping') wait_until(lambda: c.primary == self.primary, "discover primary") wait_until(lambda: c.secondaries == self.secondaries, "discover secondaries") # SERVER-32845 if not (client_context.version >= (3, 7, 2) and client_context.auth_enabled and client_context.is_rs): wait_until(lambda: c.arbiters == self.arbiters, "discover arbiters") self.assertEqual(c.arbiters, self.arbiters) self.assertEqual(c.primary, self.primary) self.assertEqual(c.secondaries, self.secondaries) self.assertEqual(c.max_pool_size, 100) # Make sure MongoClient's properties are copied to Database and # Collection. for obj in c, c.pymongo_test, c.pymongo_test.test: self.assertEqual(obj.codec_options, CodecOptions()) self.assertEqual(obj.read_preference, ReadPreference.PRIMARY) self.assertEqual(obj.write_concern, WriteConcern()) cursor = c.pymongo_test.test.find() self.assertEqual( ReadPreference.PRIMARY, cursor._Cursor__read_preference) tag_sets = [{'dc': 'la', 'rack': '2'}, {'foo': 'bar'}] secondary = Secondary(tag_sets=tag_sets) c = rs_client( maxPoolSize=25, document_class=SON, tz_aware=True, read_preference=secondary, localThresholdMS=77, j=True) self.assertEqual(c.max_pool_size, 25) for obj in c, c.pymongo_test, c.pymongo_test.test: self.assertEqual(obj.codec_options, CodecOptions(SON, True)) self.assertEqual(obj.read_preference, secondary) self.assertEqual(obj.write_concern, WriteConcern(j=True)) cursor = c.pymongo_test.test.find() self.assertEqual( secondary, cursor._Cursor__read_preference) nearest = Nearest(tag_sets=[{'dc': 'ny'}, {}]) cursor = c.pymongo_test.get_collection( "test", read_preference=nearest).find() self.assertEqual(nearest, cursor._Cursor__read_preference) self.assertEqual(c.max_bson_size, 16777216) c.close()
class TestReadPreferenceObjects(unittest.TestCase): prefs = [Primary(), Secondary(), Nearest(tag_sets=[{'a': 1}, {'b': 2}])] 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_with_options(self): db = self.db codec_options = CodecOptions(tz_aware=True, uuid_representation=JAVA_LEGACY) write_concern = WriteConcern(w=2, j=True) db2 = db.with_options(codec_options, ReadPreference.SECONDARY, write_concern) self.assertTrue(isinstance(db2, motor.MotorDatabase)) self.assertEqual(codec_options, db2.codec_options) self.assertEqual(Secondary(), db2.read_preference) self.assertEqual(write_concern, db2.write_concern) pref = Secondary([{"dc": "sf"}]) db2 = db.with_options(read_preference=pref) self.assertEqual(pref, db2.read_preference) self.assertEqual(db.codec_options, db2.codec_options) self.assertEqual(db.write_concern, db2.write_concern)
def test_with_options(self): coll = self.db.test codec_options = CodecOptions(tz_aware=True, uuid_representation=JAVA_LEGACY) write_concern = WriteConcern(w=2, j=True) coll2 = coll.with_options(codec_options, ReadPreference.SECONDARY, write_concern) self.assertTrue(isinstance(coll2, motor.MotorCollection)) self.assertEqual(codec_options, coll2.codec_options) self.assertEqual(Secondary(), coll2.read_preference) self.assertEqual(write_concern, coll2.write_concern) pref = Secondary([{"dc": "sf"}]) coll2 = coll.with_options(read_preference=pref) self.assertEqual(pref, coll2.read_preference) self.assertEqual(coll.codec_options, coll2.codec_options) self.assertEqual(coll.write_concern, coll2.write_concern)
def test_no_secondary(self): t = create_mock_topology(replica_set_name='rs') got_ismaster(t, address, { 'ok': 1, 'ismaster': True, 'setName': 'rs', 'hosts': ['a']}) self.assertMessage( 'No replica set members match selector' ' "Secondary(tag_sets=None, max_staleness=-1)"', t, ReadPreference.SECONDARY) self.assertMessage( "No replica set members match selector" " \"Secondary(tag_sets=[{'dc': 'ny'}], max_staleness=-1)\"", t, Secondary(tag_sets=[{'dc': 'ny'}]))
def test_get_collection(self): codec_options = CodecOptions(tz_aware=True, uuid_representation=JAVA_LEGACY) write_concern = WriteConcern(w=2, j=True) coll = self.db.get_collection('foo', codec_options, ReadPreference.SECONDARY, write_concern) self.assertTrue(isinstance(coll, motor.MotorCollection)) self.assertEqual('foo', coll.name) self.assertEqual(codec_options, coll.codec_options) self.assertEqual(ReadPreference.SECONDARY, coll.read_preference) self.assertEqual(write_concern, coll.write_concern) pref = Secondary([{"dc": "sf"}]) coll = self.db.get_collection('foo', read_preference=pref) self.assertEqual(pref, coll.read_preference) self.assertEqual(self.db.codec_options, coll.codec_options) self.assertEqual(self.db.write_concern, coll.write_concern)
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_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': [{}]}})
def test_with_options(self): coll = self.db.test codec_options = CodecOptions( tz_aware=True, uuid_representation=JAVA_LEGACY) write_concern = WriteConcern(w=2, j=True) coll2 = coll.with_options( codec_options, ReadPreference.SECONDARY, write_concern) self.assertTrue(isinstance(coll2, AsyncIOMotorCollection)) self.assertEqual(codec_options, coll2.codec_options) self.assertEqual(JAVA_LEGACY, coll2.uuid_subtype) self.assertEqual(ReadPreference.SECONDARY, coll2.read_preference) self.assertEqual(write_concern.document, coll2.write_concern) pref = Secondary([{"dc": "sf"}]) coll2 = coll.with_options(read_preference=pref) self.assertEqual(pref.mode, coll2.read_preference) self.assertEqual(pref.tag_sets, coll2.tag_sets) self.assertEqual(coll.codec_options, coll2.codec_options) self.assertEqual(coll.uuid_subtype, coll2.uuid_subtype) self.assertEqual(coll.write_concern, coll2.write_concern)
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_readable_writable(self): t = create_mock_topology(replica_set_name='rs') got_ismaster(t, ('a', 27017), { 'ok': 1, 'ismaster': True, 'setName': 'rs', 'hosts': ['a', 'b'] }) got_ismaster( t, ('b', 27017), { 'ok': 1, 'ismaster': False, 'secondary': True, 'setName': 'rs', 'hosts': ['a', 'b'] }) self.assertTrue(t.description.topology_type_name, 'ReplicaSetWithPrimary') self.assertTrue(t.description.has_writable_server()) self.assertTrue(t.description.has_readable_server()) self.assertTrue(t.description.has_readable_server(Secondary())) self.assertFalse( t.description.has_readable_server( Secondary(tag_sets=[{ 'tag': 'exists' }]))) t = create_mock_topology(replica_set_name='rs') got_ismaster( t, ('a', 27017), { 'ok': 1, 'ismaster': False, 'secondary': False, 'setName': 'rs', 'hosts': ['a', 'b'] }) got_ismaster( t, ('b', 27017), { 'ok': 1, 'ismaster': False, 'secondary': True, 'setName': 'rs', 'hosts': ['a', 'b'] }) self.assertTrue(t.description.topology_type_name, 'ReplicaSetNoPrimary') self.assertFalse(t.description.has_writable_server()) self.assertFalse(t.description.has_readable_server()) self.assertTrue(t.description.has_readable_server(Secondary())) self.assertFalse( t.description.has_readable_server( Secondary(tag_sets=[{ 'tag': 'exists' }]))) t = create_mock_topology(replica_set_name='rs') got_ismaster(t, ('a', 27017), { 'ok': 1, 'ismaster': True, 'setName': 'rs', 'hosts': ['a', 'b'] }) got_ismaster( t, ('b', 27017), { 'ok': 1, 'ismaster': False, 'secondary': True, 'setName': 'rs', 'hosts': ['a', 'b'], 'tags': { 'tag': 'exists' } }) self.assertTrue(t.description.topology_type_name, 'ReplicaSetWithPrimary') self.assertTrue(t.description.has_writable_server()) self.assertTrue(t.description.has_readable_server()) self.assertTrue(t.description.has_readable_server(Secondary())) self.assertTrue( t.description.has_readable_server( Secondary(tag_sets=[{ 'tag': 'exists' }])))
def test_direct_connection(self): for server_type, ismaster_response in [ (SERVER_TYPE.RSPrimary, { 'ok': 1, 'ismaster': True, 'hosts': ['a'], 'setName': 'rs', 'maxWireVersion': 6 }), (SERVER_TYPE.RSSecondary, { 'ok': 1, 'ismaster': False, 'secondary': True, 'hosts': ['a'], 'setName': 'rs', 'maxWireVersion': 6 }), (SERVER_TYPE.Mongos, { 'ok': 1, 'ismaster': True, 'msg': 'isdbgrid', 'maxWireVersion': 6 }), (SERVER_TYPE.RSArbiter, { 'ok': 1, 'ismaster': False, 'arbiterOnly': True, 'hosts': ['a'], 'setName': 'rs', 'maxWireVersion': 6 }), (SERVER_TYPE.Standalone, { 'ok': 1, 'ismaster': True, 'maxWireVersion': 6 }), # Slave. (SERVER_TYPE.Standalone, { 'ok': 1, 'ismaster': False, 'maxWireVersion': 6 }), ]: t = create_mock_topology() # Can't select a server while the only server is of type Unknown. with self.assertRaisesRegex(ConnectionFailure, 'No servers found yet'): t.select_servers(any_server_selector, server_selection_timeout=0) got_ismaster(t, address, ismaster_response) # Topology type never changes. self.assertEqual(TOPOLOGY_TYPE.Single, t.description.topology_type) # No matter whether the server is writable, # select_servers() returns it. s = t.select_server(writable_server_selector) self.assertEqual(server_type, s.description.server_type) # Topology type single is always readable and writable regardless # of server type or state. self.assertEqual(t.description.topology_type_name, 'Single') self.assertTrue(t.description.has_writable_server()) self.assertTrue(t.description.has_readable_server()) self.assertTrue(t.description.has_readable_server(Secondary())) self.assertTrue( t.description.has_readable_server( Secondary(tag_sets=[{ 'tag': 'does-not-exist' }])))
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 })