def test_network_disconnect_primary(self): # Application operation fails against primary. Test that topology # type changes from ReplicaSetWithPrimary to ReplicaSetNoPrimary. # http://bit.ly/1B5ttuL primary, secondary = servers = [MockupDB() for _ in range(2)] for server in servers: server.run() self.addCleanup(server.stop) hosts = [server.address_string for server in servers] primary_response = OpReply(ismaster=True, setName='rs', hosts=hosts, minWireVersion=2, maxWireVersion=6) primary.autoresponds('ismaster', primary_response) secondary.autoresponds( 'ismaster', ismaster=False, secondary=True, setName='rs', hosts=hosts, minWireVersion=2, maxWireVersion=6) client = MongoClient(primary.uri, replicaSet='rs') self.addCleanup(client.close) wait_until(lambda: client.primary == primary.address, 'discover primary') topology = client._topology self.assertEqual(TOPOLOGY_TYPE.ReplicaSetWithPrimary, topology.description.topology_type) # Open a socket in the application pool (calls ismaster). with going(client.db.command, 'buildinfo'): primary.receives('buildinfo').ok() # The primary hangs replying to ismaster. ismaster_future = Future() primary.autoresponds('ismaster', lambda r: r.ok(ismaster_future.result())) # Network error on application operation. with self.assertRaises(ConnectionFailure): with going(client.db.command, 'buildinfo'): primary.receives('buildinfo').hangup() # Topology type is updated. self.assertEqual(TOPOLOGY_TYPE.ReplicaSetNoPrimary, topology.description.topology_type) # Let ismasters through again. ismaster_future.set_result(primary_response) # Demand a primary. with going(client.db.command, 'buildinfo'): wait_until(lambda: client.primary == primary.address, 'rediscover primary') primary.receives('buildinfo').ok() self.assertEqual(TOPOLOGY_TYPE.ReplicaSetWithPrimary, topology.description.topology_type)
def setup_server(self, wire_version): self.server = MockupDB() def responder(request): self.ismaster_time = time.time() return request.ok(ismaster=True, maxWireVersion=wire_version) self.server.autoresponds('ismaster', responder) self.server.run() self.addCleanup(self.server.stop) self.client = MongoClient(self.server.uri, socketTimeoutMS=100) wait_until(lambda: self.client.nodes, 'connect to standalone')
def test_initial_ismaster(self): server = MockupDB() server.run() self.addCleanup(server.stop) start = time.time() client = MongoClient(server.uri) self.addCleanup(client.close) # A single ismaster is enough for the client to be connected. self.assertFalse(client.nodes) server.receives('ismaster').ok(ismaster=True) wait_until(lambda: client.nodes, 'update nodes', timeout=1) # At least 10 seconds before next heartbeat. server.receives('ismaster').ok(ismaster=True) self.assertGreaterEqual(time.time() - start, 10)
def setup_server(self): self.server = MockupDB() def responder(request): self.ismaster_time = time.time() return request.ok(ismaster=True, minWireVersion=2, maxWireVersion=6) self.server.autoresponds('ismaster', responder) self.server.run() self.addCleanup(self.server.stop) kwargs = {'socketTimeoutMS': 100} # Disable retryable reads when pymongo supports it. kwargs['retryReads'] = False self.client = MongoClient(self.server.uri, **kwargs) wait_until(lambda: self.client.nodes, 'connect to standalone')