class ReplicaSetsTestCase(unittest.TestCase): def setUp(self): PortPool().change_range() self.rs = ReplicaSets() self.rs.set_settings(os.environ.get('MONGOBIN', None)) def tearDown(self): self.rs.cleanup() def waiting(self, fn, timeout=300, sleep=10): t_start = time.time() while not fn(): if time.time() - t_start > timeout: return False time.sleep(sleep) return True def test_singleton(self): self.assertEqual(id(self.rs), id(ReplicaSets())) def test_set_settings(self): default_release = 'old-release' releases = {default_release: os.path.join(os.getcwd(), 'bin')} self.rs.set_settings(releases, default_release) self.assertEqual(releases, self.rs.releases) self.assertEqual(default_release, self.rs.default_release) def test_bool(self): self.assertEqual(False, bool(self.rs)) self.rs.create({'id': 'test-rs-1', 'members': [{}, {}]}) self.assertEqual(True, bool(self.rs)) def test_operations(self): repl_cfg = {'members': [{}, {}]} repl = ReplicaSet(repl_cfg) self.assertEqual(len(self.rs), 0) operator.setitem(self.rs, 1, repl) self.assertEqual(len(self.rs), 1) self.assertEqual(operator.getitem(self.rs, 1).repl_id, repl.repl_id) operator.delitem(self.rs, 1) self.assertEqual(len(self.rs), 0) self.assertRaises(KeyError, operator.getitem, self.rs, 1) def test_operations2(self): self.assertTrue(len(self.rs) == 0) self.rs.create({'id': 'test-rs-1', 'members': [{}, {}]}) self.rs.create({'id': 'test-rs-2', 'members': [{}, {}]}) self.assertTrue(len(self.rs) == 2) for key in self.rs: self.assertTrue(key in ('test-rs-1', 'test-rs-2')) for key in ('test-rs-1', 'test-rs-2'): self.assertTrue(key in self.rs) def test_cleanup(self): self.assertTrue(len(self.rs) == 0) self.rs.create({'id': 'test-rs-1', 'members': [{}, {}]}) self.rs.create({'id': 'test-rs-2', 'members': [{}, {}]}) self.assertTrue(len(self.rs) == 2) self.rs.cleanup() self.assertTrue(len(self.rs) == 0) def test_rs_new(self): port1, port2 = PortPool().port(check=True), PortPool().port(check=True) repl_id = self.rs.create({ 'id': 'test-rs-1', 'members': [{ "procParams": { "port": port1 } }, { "procParams": { "port": port2 } }] }) self.assertEqual(repl_id, 'test-rs-1') server1 = "{hostname}:{port}".format(hostname=HOSTNAME, port=port1) server2 = "{hostname}:{port}".format(hostname=HOSTNAME, port=port2) c = pymongo.MongoClient([server1, server2], replicaSet=repl_id) self.assertEqual(c.admin.eval("rs.conf()")['_id'], repl_id) c.close() def test_rs_new_with_auth(self): port1, port2 = PortPool().port(check=True), PortPool().port(check=True) repl_id = self.rs.create({ 'id': 'test-rs-1', 'auth_key': 'sercret', 'login': '******', 'password': '******', 'members': [{ "procParams": { "port": port1 } }, { "procParams": { "port": port2 } }] }) self.assertEqual(repl_id, 'test-rs-1') server1 = "{hostname}:{port}".format(hostname=HOSTNAME, port=port1) server2 = "{hostname}:{port}".format(hostname=HOSTNAME, port=port2) c = pymongo.MongoClient([server1, server2], replicaSet=repl_id) self.assertRaises(pymongo.errors.OperationFailure, c.admin.collection_names) self.assertTrue(c.admin.authenticate('admin', 'admin')) self.assertTrue(isinstance(c.admin.collection_names(), list)) c.admin.logout() self.assertRaises(pymongo.errors.OperationFailure, c.admin.collection_names) c.close() def test_info(self): repl_id = self.rs.create({'id': 'test-rs-1', 'members': [{}, {}]}) info = self.rs.info(repl_id) self.assertTrue(isinstance(info, dict)) for item in ("id", "mongodb_uri", "members", "orchestration"): self.assertTrue(item in info) self.assertEqual(info['id'], repl_id) self.assertEqual(len(info['members']), 2) mongodb_uri = info['mongodb_uri'] for member in self.rs.members(repl_id): self.assertIn(member['host'], mongodb_uri) self.assertTrue(mongodb_uri.find('mongodb://') == 0) self.assertEqual(info['orchestration'], 'replica_sets') def test_info_with_auth(self): repl_id = self.rs.create({ 'id': 'test-rs-1', 'login': '******', 'password': '******', 'members': [{}, {}] }) info = self.rs.info(repl_id) self.assertTrue(isinstance(info, dict)) self.assertEqual(info['id'], repl_id) self.assertEqual(len(info['members']), 2) def test_primary(self): repl_id = self.rs.create({'id': 'test-rs-1', 'members': [{}, {}]}) primary = self.rs.primary(repl_id)['mongodb_uri'] c = pymongo.MongoClient(primary) self.assertTrue(c.is_primary) c.close() def test_primary_stepdown(self): # This tests Server, but only makes sense in the context of a replica set. repl_id = self.rs.create({ 'id': 'test-rs-stepdown', 'members': [{}, {}, { "rsParams": { "priority": 1.4 } }] }) primary = self.rs.primary(repl_id) primary_server = Servers()._storage[primary['server_id']] # No Exception. primary_server.stepdown() self.assertNotEqual(primary['mongodb_uri'], self.rs.primary(repl_id)['mongodb_uri']) def test_rs_del(self): self.rs.create({'members': [{}, {}]}) repl_id = self.rs.create({'members': [{}, {}]}) self.assertEqual(len(self.rs), 2) primary = self.rs.primary(repl_id)['mongodb_uri'] self.assertTrue(pymongo.MongoClient(primary)) self.rs.remove(repl_id) self.assertEqual(len(self.rs), 1) self.assertRaises(pymongo.errors.PyMongoError, pymongo.MongoClient, primary) def test_members(self): port1, port2 = PortPool().port(check=True), PortPool().port(check=True) server1 = "{hostname}:{port}".format(hostname=HOSTNAME, port=port1) server2 = "{hostname}:{port}".format(hostname=HOSTNAME, port=port2) repl_id = self.rs.create({ 'members': [{ "procParams": { "port": port1 } }, { "procParams": { "port": port2 } }] }) members = self.rs.members(repl_id) self.assertEqual(len(members), 2) self.assertTrue(server1 in [member['host'] for member in members]) self.assertTrue(server2 in [member['host'] for member in members]) def test_secondaries(self): repl_id = self.rs.create( {'members': [{ "rsParams": { "priority": 1.5 } }, {}, {}]}) secondaries = self.rs.secondaries(repl_id) self.assertEqual(len(secondaries), 2) def test_arbiters(self): repl_id = self.rs.create({ 'members': [{ "rsParams": { "priority": 1.5 } }, {}, { "rsParams": { "arbiterOnly": True } }] }) arbiters = self.rs.arbiters(repl_id) self.assertEqual(len(arbiters), 1) def test_hidden(self): repl_id = self.rs.create({ 'members': [{ "rsParams": { "priority": 1.5 } }, {}, { "rsParams": { "priority": 0, "hidden": True } }] }) hidden = self.rs.hidden(repl_id) self.assertEqual(len(hidden), 1) def test_passives(self): config = { "members": [{}, { "rsParams": { "priority": 0 } }, { "rsParams": { "arbiterOnly": True } }, { "rsParams": { "priority": 0, 'hidden': True } }, { "rsParams": { "priority": 0, 'slaveDelay': 5 } }] } repl_id = self.rs.create(config) passives = self.rs.passives(repl_id) self.assertEqual(len(passives), 1) def test_servers(self): config = { "members": [{}, { "rsParams": { "priority": 0 } }, { "rsParams": { "arbiterOnly": True } }, { "rsParams": { "priority": 0, 'hidden': True } }, { "rsParams": { "priority": 0, 'slaveDelay': 5 } }] } repl_id = self.rs.create(config) servers = self.rs.servers(repl_id) self.assertEqual(len(servers), 1) def test_compare_passives_and_servers(self): config = { "members": [{}, { "rsParams": { "priority": 0 } }, { "rsParams": { "arbiterOnly": True } }, { "rsParams": { "priority": 0, 'hidden': True } }, { "rsParams": { "priority": 0, 'slaveDelay': 5 } }] } repl_id = self.rs.create(config) passives = [server['host'] for server in self.rs.passives(repl_id)] servers = [server['host'] for server in self.rs.servers(repl_id)] for item in passives: self.assertTrue(item not in servers) for item in servers: self.assertTrue(item not in passives) def test_member_info(self): repl_id = self.rs.create({ 'members': [{ "rsParams": { "priority": 1.5 } }, { "rsParams": { "arbiterOnly": True } }, { "rsParams": { "priority": 0, "hidden": True } }] }) info = self.rs.member_info(repl_id, 0) for key in ('procInfo', 'mongodb_uri', 'statuses', 'rsInfo'): self.assertTrue(key in info) self.assertEqual(info['_id'], 0) self.assertTrue(info['statuses']['primary']) info = self.rs.member_info(repl_id, 1) for key in ('procInfo', 'mongodb_uri', 'statuses', 'rsInfo'): self.assertTrue(key in info) self.assertEqual(info['_id'], 1) self.assertTrue(info['rsInfo']['arbiterOnly']) info = self.rs.member_info(repl_id, 2) for key in ('procInfo', 'mongodb_uri', 'statuses', 'rsInfo'): self.assertTrue(key in info) self.assertEqual(info['_id'], 2) self.assertTrue(info['rsInfo']['hidden']) def test_tagging(self): tags_0 = {"status": "primary"} tags_1 = {"status": "arbiter"} tags_2 = {"status": "hidden"} repl_id = self.rs.create({ 'members': [{ "rsParams": { "priority": 1.5, "tags": tags_0 } }, { "rsParams": { "arbiterOnly": True }, "tags": tags_1 }, { "rsParams": { "priority": 0, "hidden": True, "tags": tags_2 } }] }) self.assertEqual(tags_0, self.rs.primary(repl_id)['rsInfo']['tags']) member_arbiter = self.rs.arbiters(repl_id)[0]['_id'] self.assertFalse( 'tags' in self.rs.member_info(repl_id, member_arbiter)['rsInfo']) member_hidden = self.rs.hidden(repl_id)[0]['_id'] self.assertTrue( 'tags' in self.rs.member_info(repl_id, member_hidden)['rsInfo']) def test_member_del(self): repl_id = self.rs.create( {'members': [{ "rsParams": { "priority": 1.5 } }, {}, {}]}) self.assertEqual(len(self.rs.members(repl_id)), 3) secondary = self.rs.secondaries(repl_id)[0] self.assertTrue(pymongo.MongoClient(secondary['host'])) self.assertTrue(self.rs.member_del(repl_id, secondary['_id'])) self.assertEqual(len(self.rs.members(repl_id)), 2) self.assertRaises(pymongo.errors.PyMongoError, pymongo.MongoClient, secondary['host']) def test_member_add(self): repl_id = self.rs.create( {'members': [{ "rsParams": { "priority": 1.5 } }, {}]}) self.assertEqual(len(self.rs.members(repl_id)), 2) member_id = self.rs.member_add( repl_id, {"rsParams": { "priority": 0, "hidden": True }}) self.assertEqual(len(self.rs.members(repl_id)), 3) info = self.rs.member_info(repl_id, member_id) self.assertTrue(info['rsInfo']['hidden']) def test_member_command(self): _id = 1 repl_id = self.rs.create( {'members': [{ "rsParams": { "priority": 1.5 } }, {}]}) self.assertTrue(self.rs.member_info(repl_id, _id)['procInfo']['alive']) self.rs.member_command(repl_id, _id, 'stop') self.assertFalse( self.rs.member_info(repl_id, _id)['procInfo']['alive']) self.rs.member_command(repl_id, _id, 'start') self.assertTrue(self.rs.member_info(repl_id, _id)['procInfo']['alive']) self.rs.member_command(repl_id, _id, 'restart') self.assertTrue(self.rs.member_info(repl_id, _id)['procInfo']['alive']) def test_member_freeze(self): # This tests Server, but only makes sense in the context of a replica set. repl_id = self.rs.create({ 'members': [{ "rsParams": { "priority": 19 } }, { "rsParams": { "priority": 5 } }, {}] }) next_primary_info = self.rs.member_info(repl_id, 2) next_primary = next_primary_info['mongodb_uri'] secondary_info = self.rs.member_info(repl_id, 1) secondary_server = Servers()._storage[secondary_info['server_id']] primary_info = self.rs.member_info(repl_id, 0) primary_server = Servers()._storage[primary_info['server_id']] assert_eventually(lambda: primary_server.connection.is_primary) def freeze_and_stop(): self.assertTrue(secondary_server.freeze(10)) try: # Call replSetStepDown before killing the primary's process. # This raises OperationFailure if no secondaries are capable # of taking over. primary_server.connection.admin.command('replSetStepDown', 10) except pymongo.errors.AutoReconnect: # Have to stop the server as well so it doesn't get reelected. primary_server.stop() return True except pymongo.errors.OperationFailure: # No secondaries within 10 seconds of my optime... return False assert_eventually(freeze_and_stop, "Primary didn't step down.") assert_eventually( lambda: (self.rs.primary(repl_id)['mongodb_uri'] == next_primary), "Secondary did not freeze.", max_tries=120) assert_eventually( lambda: (self.rs.primary(repl_id)['mongodb_uri'] == self.rs. member_info(repl_id, 1)['mongodb_uri']), "Higher priority secondary never promoted.") def test_member_update(self): repl_id = self.rs.create({ 'members': [{ "rsParams": { "priority": 1.5 } }, { "rsParams": { "priority": 0, "hidden": True } }, {}] }) hidden = self.rs.hidden(repl_id)[0] self.assertTrue( self.rs.member_info(repl_id, hidden['_id'])['rsInfo']['hidden']) self.rs.member_update(repl_id, hidden['_id'], {"rsParams": { "priority": 1, "hidden": False }}) self.assertEqual(len(self.rs.hidden(repl_id)), 0) self.assertFalse( self.rs.member_info(repl_id, hidden['_id'])['rsInfo'].get('hidden', False)) def test_member_update_with_auth(self): repl_id = self.rs.create({ 'login': '******', 'password': '******', 'members': [{ "rsParams": { "priority": 1.5 } }, { "rsParams": { "priority": 0, "hidden": True } }, {}] }) hidden = self.rs.hidden(repl_id)[0] self.assertTrue( self.rs.member_info(repl_id, hidden['_id'])['rsInfo']['hidden']) self.rs.member_update(repl_id, hidden['_id'], {"rsParams": { "priority": 1, "hidden": False }}) self.assertEqual(len(self.rs.hidden(repl_id)), 0) self.assertFalse( self.rs.member_info(repl_id, hidden['_id'])['rsInfo'].get('hidden', False))
Route('/replica_sets/<rs_id>/members', method='GET'): members, Route('/replica_sets/<rs_id>/secondaries', method='GET'): secondaries, Route('/replica_sets/<rs_id>/arbiters', method='GET'): arbiters, Route('/replica_sets/<rs_id>/hidden', method='GET'): hidden, Route('/replica_sets/<rs_id>/passives', method='GET'): passives, Route('/replica_sets/<rs_id>/servers', method='GET'): servers, Route('/replica_sets/<rs_id>/primary', method='GET'): rs_member_primary, Route('/replica_sets/<rs_id>/members/<member_id>', method='GET'): member_info, Route('/replica_sets/<rs_id>/members/<member_id>', method='DELETE'): member_del, Route('/replica_sets/<rs_id>/members/<member_id>', method='PATCH'): member_update } setup_versioned_routes(ROUTES, version='v1') # Assume v1 if no version is specified. setup_versioned_routes(ROUTES) if __name__ == '__main__': rs = ReplicaSets() rs.set_settings() run(host='localhost', port=8889, debug=True, reloader=False)
class ReplicaSetsTestCase(unittest.TestCase): def setUp(self): PortPool().change_range() self.rs = ReplicaSets() self.rs.set_settings(os.environ.get('MONGOBIN', None)) def tearDown(self): self.rs.cleanup() def waiting(self, fn, timeout=300, sleep=10): t_start = time.time() while not fn(): if time.time() - t_start > timeout: return False time.sleep(sleep) return True def test_singleton(self): self.assertEqual(id(self.rs), id(ReplicaSets())) def test_set_settings(self): default_release = 'old-release' releases = {default_release: os.path.join(os.getcwd(), 'bin')} self.rs.set_settings(releases, default_release) self.assertEqual(releases, self.rs.releases) self.assertEqual(default_release, self.rs.default_release) def test_bool(self): self.assertEqual(False, bool(self.rs)) self.rs.create({'id': 'test-rs-1', 'members': [{}, {}]}) self.assertEqual(True, bool(self.rs)) def test_operations(self): repl_cfg = {'members': [{}, {}]} repl = ReplicaSet(repl_cfg) self.assertEqual(len(self.rs), 0) operator.setitem(self.rs, 1, repl) self.assertEqual(len(self.rs), 1) self.assertEqual(operator.getitem(self.rs, 1).repl_id, repl.repl_id) operator.delitem(self.rs, 1) self.assertEqual(len(self.rs), 0) self.assertRaises(KeyError, operator.getitem, self.rs, 1) def test_operations2(self): self.assertTrue(len(self.rs) == 0) self.rs.create({'id': 'test-rs-1', 'members': [{}, {}]}) self.rs.create({'id': 'test-rs-2', 'members': [{}, {}]}) self.assertTrue(len(self.rs) == 2) for key in self.rs: self.assertTrue(key in ('test-rs-1', 'test-rs-2')) for key in ('test-rs-1', 'test-rs-2'): self.assertTrue(key in self.rs) def test_cleanup(self): self.assertTrue(len(self.rs) == 0) self.rs.create({'id': 'test-rs-1', 'members': [{}, {}]}) self.rs.create({'id': 'test-rs-2', 'members': [{}, {}]}) self.assertTrue(len(self.rs) == 2) self.rs.cleanup() self.assertTrue(len(self.rs) == 0) def test_rs_new(self): port1, port2 = PortPool().port(check=True), PortPool().port(check=True) repl_id = self.rs.create({'id': 'test-rs-1', 'members': [{"procParams": {"port": port1}}, {"procParams": {"port": port2}} ]}) self.assertEqual(repl_id, 'test-rs-1') server1 = "{hostname}:{port}".format(hostname=HOSTNAME, port=port1) server2 = "{hostname}:{port}".format(hostname=HOSTNAME, port=port2) c = pymongo.MongoClient([server1, server2], replicaSet=repl_id) self.assertEqual(c.admin.eval("rs.conf()")['_id'], repl_id) c.close() def test_rs_new_with_auth(self): port1, port2 = PortPool().port(check=True), PortPool().port(check=True) repl_id = self.rs.create({'id': 'test-rs-1', 'auth_key': 'sercret', 'login': '******', 'password': '******', 'members': [{"procParams": {"port": port1}}, {"procParams": {"port": port2}} ]}) self.assertEqual(repl_id, 'test-rs-1') server1 = "{hostname}:{port}".format(hostname=HOSTNAME, port=port1) server2 = "{hostname}:{port}".format(hostname=HOSTNAME, port=port2) c = pymongo.MongoClient([server1, server2], replicaSet=repl_id) self.assertRaises(pymongo.errors.OperationFailure, c.admin.collection_names) self.assertTrue(c.admin.authenticate('admin', 'admin')) self.assertTrue(isinstance(c.admin.collection_names(), list)) c.admin.logout() self.assertRaises(pymongo.errors.OperationFailure, c.admin.collection_names) c.close() def test_info(self): repl_id = self.rs.create({'id': 'test-rs-1', 'members': [{}, {}]}) info = self.rs.info(repl_id) self.assertTrue(isinstance(info, dict)) for item in ("id", "mongodb_uri", "members", "orchestration"): self.assertTrue(item in info) self.assertEqual(info['id'], repl_id) self.assertEqual(len(info['members']), 2) mongodb_uri = info['mongodb_uri'] for member in self.rs.members(repl_id): self.assertIn(member['host'], mongodb_uri) self.assertTrue(mongodb_uri.find('mongodb://') == 0) self.assertEqual(info['orchestration'], 'replica_sets') def test_info_with_auth(self): repl_id = self.rs.create({'id': 'test-rs-1', 'login': '******', 'password': '******', 'members': [{}, {}]}) info = self.rs.info(repl_id) self.assertTrue(isinstance(info, dict)) self.assertEqual(info['id'], repl_id) self.assertEqual(len(info['members']), 2) def test_primary(self): repl_id = self.rs.create({'id': 'test-rs-1', 'members': [{}, {}]}) primary = self.rs.primary(repl_id)['mongodb_uri'] c = pymongo.MongoClient(primary) self.assertTrue(c.is_primary) c.close() def test_primary_stepdown(self): # This tests Server, but only makes sense in the context of a replica set. repl_id = self.rs.create( {'id': 'test-rs-stepdown', 'members': [{}, {}, {"rsParams": {"priority": 1.4}}]}) primary = self.rs.primary(repl_id) primary_server = Servers()._storage[primary['server_id']] # No Exception. primary_server.stepdown() self.assertNotEqual(primary['mongodb_uri'], self.rs.primary(repl_id)['mongodb_uri']) def test_rs_del(self): self.rs.create({'members': [{}, {}]}) repl_id = self.rs.create({'members': [{}, {}]}) self.assertEqual(len(self.rs), 2) primary = self.rs.primary(repl_id)['mongodb_uri'] self.assertTrue(pymongo.MongoClient(primary)) self.rs.remove(repl_id) self.assertEqual(len(self.rs), 1) self.assertRaises(pymongo.errors.PyMongoError, pymongo.MongoClient, primary) def test_members(self): port1, port2 = PortPool().port(check=True), PortPool().port(check=True) server1 = "{hostname}:{port}".format(hostname=HOSTNAME, port=port1) server2 = "{hostname}:{port}".format(hostname=HOSTNAME, port=port2) repl_id = self.rs.create({'members': [{"procParams": {"port": port1}}, {"procParams": {"port": port2}}]}) members = self.rs.members(repl_id) self.assertEqual(len(members), 2) self.assertTrue(server1 in [member['host'] for member in members]) self.assertTrue(server2 in [member['host'] for member in members]) def test_secondaries(self): repl_id = self.rs.create({'members': [{"rsParams": {"priority": 1.5}}, {}, {}]}) secondaries = self.rs.secondaries(repl_id) self.assertEqual(len(secondaries), 2) def test_arbiters(self): repl_id = self.rs.create({'members': [{"rsParams": {"priority": 1.5}}, {}, {"rsParams": {"arbiterOnly": True}}]}) arbiters = self.rs.arbiters(repl_id) self.assertEqual(len(arbiters), 1) def test_hidden(self): repl_id = self.rs.create({'members': [{"rsParams": {"priority": 1.5}}, {}, {"rsParams": {"priority": 0, "hidden": True}}]}) hidden = self.rs.hidden(repl_id) self.assertEqual(len(hidden), 1) def test_passives(self): config = {"members": [{}, {"rsParams": {"priority": 0}}, {"rsParams": {"arbiterOnly": True}}, {"rsParams": {"priority": 0, 'hidden': True}}, {"rsParams": {"priority": 0, 'slaveDelay': 5}}]} repl_id = self.rs.create(config) passives = self.rs.passives(repl_id) self.assertEqual(len(passives), 1) def test_servers(self): config = {"members": [{}, {"rsParams": {"priority": 0}}, {"rsParams": {"arbiterOnly": True}}, {"rsParams": {"priority": 0, 'hidden': True}}, {"rsParams": {"priority": 0, 'slaveDelay': 5}}]} repl_id = self.rs.create(config) servers = self.rs.servers(repl_id) self.assertEqual(len(servers), 1) def test_compare_passives_and_servers(self): config = {"members": [{}, {"rsParams": {"priority": 0}}, {"rsParams": {"arbiterOnly": True}}, {"rsParams": {"priority": 0, 'hidden': True}}, {"rsParams": {"priority": 0, 'slaveDelay': 5}}]} repl_id = self.rs.create(config) passives = [server['host'] for server in self.rs.passives(repl_id)] servers = [server['host'] for server in self.rs.servers(repl_id)] for item in passives: self.assertTrue(item not in servers) for item in servers: self.assertTrue(item not in passives) def test_member_info(self): repl_id = self.rs.create({'members': [{"rsParams": {"priority": 1.5}}, {"rsParams": {"arbiterOnly": True}}, {"rsParams": {"priority": 0, "hidden": True}}]}) info = self.rs.member_info(repl_id, 0) for key in ('procInfo', 'mongodb_uri', 'statuses', 'rsInfo'): self.assertTrue(key in info) self.assertEqual(info['_id'], 0) self.assertTrue(info['statuses']['primary']) info = self.rs.member_info(repl_id, 1) for key in ('procInfo', 'mongodb_uri', 'statuses', 'rsInfo'): self.assertTrue(key in info) self.assertEqual(info['_id'], 1) self.assertTrue(info['rsInfo']['arbiterOnly']) info = self.rs.member_info(repl_id, 2) for key in ('procInfo', 'mongodb_uri', 'statuses', 'rsInfo'): self.assertTrue(key in info) self.assertEqual(info['_id'], 2) self.assertTrue(info['rsInfo']['hidden']) def test_tagging(self): tags_0 = {"status": "primary"} tags_1 = {"status": "arbiter"} tags_2 = {"status": "hidden"} repl_id = self.rs.create({'members': [{"rsParams": {"priority": 1.5, "tags": tags_0}}, {"rsParams": {"arbiterOnly": True}, "tags": tags_1}, {"rsParams": {"priority": 0, "hidden": True, "tags": tags_2}}]}) self.assertEqual(tags_0, self.rs.primary(repl_id)['rsInfo']['tags']) member_arbiter = self.rs.arbiters(repl_id)[0]['_id'] self.assertFalse('tags' in self.rs.member_info(repl_id, member_arbiter)['rsInfo']) member_hidden = self.rs.hidden(repl_id)[0]['_id'] self.assertTrue('tags' in self.rs.member_info(repl_id, member_hidden)['rsInfo']) def test_member_del(self): repl_id = self.rs.create({'members': [{"rsParams": {"priority": 1.5}}, {}, {}]}) self.assertEqual(len(self.rs.members(repl_id)), 3) secondary = self.rs.secondaries(repl_id)[0] self.assertTrue(pymongo.MongoClient(secondary['host'])) self.assertTrue(self.rs.member_del(repl_id, secondary['_id'])) self.assertEqual(len(self.rs.members(repl_id)), 2) self.assertRaises(pymongo.errors.PyMongoError, pymongo.MongoClient, secondary['host']) def test_member_add(self): repl_id = self.rs.create({'members': [{"rsParams": {"priority": 1.5}}, {}]}) self.assertEqual(len(self.rs.members(repl_id)), 2) member_id = self.rs.member_add(repl_id, {"rsParams": {"priority": 0, "hidden": True}}) self.assertEqual(len(self.rs.members(repl_id)), 3) info = self.rs.member_info(repl_id, member_id) self.assertTrue(info['rsInfo']['hidden']) def test_member_command(self): _id = 1 repl_id = self.rs.create({'members': [{"rsParams": {"priority": 1.5}}, {}]}) self.assertTrue(self.rs.member_info(repl_id, _id)['procInfo']['alive']) self.rs.member_command(repl_id, _id, 'stop') self.assertFalse(self.rs.member_info(repl_id, _id)['procInfo']['alive']) self.rs.member_command(repl_id, _id, 'start') self.assertTrue(self.rs.member_info(repl_id, _id)['procInfo']['alive']) self.rs.member_command(repl_id, _id, 'restart') self.assertTrue(self.rs.member_info(repl_id, _id)['procInfo']['alive']) def test_member_freeze(self): # This tests Server, but only makes sense in the context of a replica set. repl_id = self.rs.create( {'members': [{"rsParams": {"priority": 19}}, {"rsParams": {"priority": 5}}, {}]}) next_primary_info = self.rs.member_info(repl_id, 2) next_primary = next_primary_info['mongodb_uri'] secondary_info = self.rs.member_info(repl_id, 1) secondary_server = Servers()._storage[secondary_info['server_id']] primary_info = self.rs.member_info(repl_id, 0) primary_server = Servers()._storage[primary_info['server_id']] assert_eventually(lambda: primary_server.connection.is_primary) def freeze_and_stop(): self.assertTrue(secondary_server.freeze(10)) try: # Call replSetStepDown before killing the primary's process. # This raises OperationFailure if no secondaries are capable # of taking over. primary_server.connection.admin.command('replSetStepDown', 10) except pymongo.errors.AutoReconnect: # Have to stop the server as well so it doesn't get reelected. primary_server.stop() return True except pymongo.errors.OperationFailure: # No secondaries within 10 seconds of my optime... return False assert_eventually(freeze_and_stop, "Primary didn't step down.") assert_eventually(lambda: ( self.rs.primary(repl_id)['mongodb_uri'] == next_primary), "Secondary did not freeze.", max_tries=120 ) assert_eventually(lambda: ( self.rs.primary(repl_id)['mongodb_uri'] == self.rs.member_info(repl_id, 1)['mongodb_uri']), "Higher priority secondary never promoted.") def test_member_update(self): repl_id = self.rs.create({'members': [{"rsParams": {"priority": 1.5}}, {"rsParams": {"priority": 0, "hidden": True}}, {}]}) hidden = self.rs.hidden(repl_id)[0] self.assertTrue(self.rs.member_info(repl_id, hidden['_id'])['rsInfo']['hidden']) self.rs.member_update(repl_id, hidden['_id'], {"rsParams": {"priority": 1, "hidden": False}}) self.assertEqual(len(self.rs.hidden(repl_id)), 0) self.assertFalse(self.rs.member_info(repl_id, hidden['_id'])['rsInfo'].get('hidden', False)) def test_member_update_with_auth(self): repl_id = self.rs.create({'login': '******', 'password': '******', 'members': [{"rsParams": {"priority": 1.5}}, {"rsParams": {"priority": 0, "hidden": True}}, {}]}) hidden = self.rs.hidden(repl_id)[0] self.assertTrue(self.rs.member_info(repl_id, hidden['_id'])['rsInfo']['hidden']) self.rs.member_update(repl_id, hidden['_id'], {"rsParams": {"priority": 1, "hidden": False}}) self.assertEqual(len(self.rs.hidden(repl_id)), 0) self.assertFalse(self.rs.member_info(repl_id, hidden['_id'])['rsInfo'].get('hidden', False))
Route('/replica_sets', method='GET'): rs_list, Route('/replica_sets/<rs_id>', method='GET'): rs_info, Route('/replica_sets/<rs_id>', method='POST'): rs_command, Route('/replica_sets/<rs_id>', method='PUT'): rs_create_by_id, Route('/replica_sets/<rs_id>', method='DELETE'): rs_del, Route('/replica_sets/<rs_id>/members', method='POST'): member_add, Route('/replica_sets/<rs_id>/members', method='GET'): members, Route('/replica_sets/<rs_id>/secondaries', method='GET'): secondaries, Route('/replica_sets/<rs_id>/arbiters', method='GET'): arbiters, Route('/replica_sets/<rs_id>/hidden', method='GET'): hidden, Route('/replica_sets/<rs_id>/passives', method='GET'): passives, Route('/replica_sets/<rs_id>/servers', method='GET'): servers, Route('/replica_sets/<rs_id>/primary', method='GET'): rs_member_primary, Route('/replica_sets/<rs_id>/members/<member_id>', method='GET'): member_info, Route('/replica_sets/<rs_id>/members/<member_id>', method='DELETE'): member_del, Route('/replica_sets/<rs_id>/members/<member_id>', method='PATCH'): member_update } setup_versioned_routes(ROUTES, version='v1') # Assume v1 if no version is specified. setup_versioned_routes(ROUTES) if __name__ == '__main__': rs = ReplicaSets() rs.set_settings() run(host='localhost', port=8889, debug=True, reloader=False)