def _test_network_error(self, operation_callback): # Verify only the disconnected server is reset by a network failure. # Disable background refresh. with client_knobs(heartbeat_frequency=999999): c = MockClient( standalones=[], members=["a:1", "b:2"], mongoses=[], host="a:1", replicaSet="rs", connect=False ) # Set host-specific information so we can test whether it is reset. c.set_wire_version_range("a:1", 0, 1) c.set_wire_version_range("b:2", 0, 2) c._get_topology().select_servers(writable_server_selector) wait_until(lambda: len(c.nodes) == 2, "connect") c.kill_host("a:1") # MongoClient is disconnected from the primary. self.assertRaises(AutoReconnect, operation_callback, c) # The primary's description is reset. server_a = c._get_topology().get_server_by_address(("a", 1)) sd_a = server_a.description self.assertEqual(SERVER_TYPE.Unknown, sd_a.server_type) self.assertEqual(0, sd_a.min_wire_version) self.assertEqual(0, sd_a.max_wire_version) # ...but not the secondary's. server_b = c._get_topology().get_server_by_address(("b", 2)) sd_b = server_b.description self.assertEqual(SERVER_TYPE.RSSecondary, sd_b.server_type) self.assertEqual(0, sd_b.min_wire_version) self.assertEqual(2, sd_b.max_wire_version)
def test_wire_version(self): c = MockClient(standalones=[], members=['a:1', 'b:2', 'c:3'], mongoses=[], host='a:1', replicaSet='rs', connect=False) c.set_wire_version_range('a:1', 1, 5) c.set_wire_version_range('b:2', 0, 1) c.set_wire_version_range('c:3', 1, 2) c.db.command('ismaster') # Connect. c.set_wire_version_range('a:1', 2, 2) # A secondary doesn't overlap with us. c.set_wire_version_range('b:2', MAX_SUPPORTED_WIRE_VERSION + 1, MAX_SUPPORTED_WIRE_VERSION + 2) def raises_configuration_error(): try: c.db.collection.find_one() return False except ConfigurationError: return True wait_until(raises_configuration_error, 'notice we are incompatible with server') self.assertRaises(ConfigurationError, c.db.collection.insert_one, {})
def test_wire_version_mongos_ha(self): c = MockClient( standalones=[], members=[], mongoses=['a:1', 'b:2', 'c:3'], host='a:1,b:2,c:3', _connect=False) c.set_wire_version_range('a:1', 2, 5) c.set_wire_version_range('b:2', 2, 2) c.set_wire_version_range('c:3', 1, 1) c.db.collection.find_one() # Connect. # Which member did we use? used_host = '%s:%s' % (c.host, c.port) expected_min, expected_max = c.mock_wire_versions[used_host] self.assertEqual(expected_min, c.min_wire_version) self.assertEqual(expected_max, c.max_wire_version) c.set_wire_version_range('a:1', 0, 0) c.set_wire_version_range('b:2', 0, 0) c.set_wire_version_range('c:3', 0, 0) c.disconnect() c.db.collection.find_one() used_host = '%s:%s' % (c.host, c.port) expected_min, expected_max = c.mock_wire_versions[used_host] self.assertEqual(expected_min, c.min_wire_version) self.assertEqual(expected_max, c.max_wire_version)
def test_wire_version_mongos_ha(self): c = MockClient(standalones=[], members=[], mongoses=['a:1', 'b:2', 'c:3'], host='a:1,b:2,c:3', _connect=False) c.set_wire_version_range('a:1', 2, 5) c.set_wire_version_range('b:2', 2, 2) c.set_wire_version_range('c:3', 1, 1) c.db.collection.find_one() # Connect. # Which member did we use? used_host = '%s:%s' % (c.host, c.port) expected_min, expected_max = c.mock_wire_versions[used_host] self.assertEqual(expected_min, c.min_wire_version) self.assertEqual(expected_max, c.max_wire_version) c.set_wire_version_range('a:1', 0, 0) c.set_wire_version_range('b:2', 0, 0) c.set_wire_version_range('c:3', 0, 0) c.disconnect() c.db.collection.find_one() used_host = '%s:%s' % (c.host, c.port) expected_min, expected_max = c.mock_wire_versions[used_host] self.assertEqual(expected_min, c.min_wire_version) self.assertEqual(expected_max, c.max_wire_version)
def test_wire_version(self): c = MockClient( standalones=[], members=['a:1', 'b:2', 'c:3'], mongoses=[], host='a:1', replicaSet='rs', connect=False) c.set_wire_version_range('a:1', 1, 5) c.set_wire_version_range('b:2', 0, 1) c.set_wire_version_range('c:3', 1, 2) c.db.command('ismaster') # Connect. c.set_wire_version_range('a:1', 2, 2) # A secondary doesn't overlap with us. c.set_wire_version_range('b:2', 5, 6) def raises_configuration_error(): try: c.db.collection.find_one() return False except ConfigurationError: return True wait_until(raises_configuration_error, 'notice we are incompatible with server') self.assertRaises(ConfigurationError, c.db.collection.insert_one, {})
def test_wire_version_mongos_ha(self): # TODO: Reimplement Mongos HA with PyMongo 3's MongoClient. raise SkipTest('Mongos HA must be reimplemented in PyMongo 3') c = MockClient( standalones=[], members=[], mongoses=['a:1', 'b:2', 'c:3'], host='a:1,b:2,c:3', connect=False) c.set_wire_version_range('a:1', 2, 5) c.set_wire_version_range('b:2', 2, 2) c.set_wire_version_range('c:3', 1, 1) c.db.command('ismaster') # Connect. # Which member did we use? used_host = '%s:%s' % c.address expected_min, expected_max = c.mock_wire_versions[used_host] self.assertEqual(expected_min, c.min_wire_version) self.assertEqual(expected_max, c.max_wire_version) c.set_wire_version_range('a:1', 0, 0) c.set_wire_version_range('b:2', 0, 0) c.set_wire_version_range('c:3', 0, 0) c.close() c.db.command('ismaster') used_host = '%s:%s' % c.address expected_min, expected_max = c.mock_wire_versions[used_host] self.assertEqual(expected_min, c.min_wire_version) self.assertEqual(expected_max, c.max_wire_version)
def test_wire_version(self): c = MockClient( standalones=[], members=['a:1', 'b:2', 'c:3'], mongoses=[], host='b:2', # Pass a secondary. replicaSet='rs', _connect=False) c.set_wire_version_range('a:1', 1, 5) c.db.collection.find_one() # Connect. self.assertEqual(c.min_wire_version, 1) self.assertEqual(c.max_wire_version, 5) c.set_wire_version_range('a:1', 10, 11) c.disconnect() self.assertRaises(ConfigurationError, c.db.collection.find_one)
def _test_network_error(self, operation_callback): # Verify only the disconnected server is reset by a network failure. # Disable background refresh. with client_knobs(heartbeat_frequency=999999): c = MockClient( standalones=[], members=['a:1', 'b:2'], mongoses=[], host='a:1', replicaSet='rs', connect=False) # Set host-specific information so we can test whether it is reset. c.set_wire_version_range('a:1', 0, 1) c.set_wire_version_range('b:2', 0, 2) c._get_topology().select_servers(writable_server_selector) wait_until(lambda: len(c.nodes) == 2, 'connect') c.kill_host('a:1') # MongoClient is disconnected from the primary. self.assertRaises(AutoReconnect, operation_callback, c) # The primary's description is reset. server_a = c._get_topology().get_server_by_address(('a', 1)) sd_a = server_a.description self.assertEqual(SERVER_TYPE.Unknown, sd_a.server_type) self.assertEqual(0, sd_a.min_wire_version) self.assertEqual(0, sd_a.max_wire_version) # ...but not the secondary's. server_b = c._get_topology().get_server_by_address(('b', 2)) sd_b = server_b.description self.assertEqual(SERVER_TYPE.RSSecondary, sd_b.server_type) self.assertEqual(0, sd_b.min_wire_version) self.assertEqual(2, sd_b.max_wire_version)