def test_latency_threshold_application(self): selector = SelectionStoreSelector() scenario_def = { 'topology_description': { 'type': 'ReplicaSetWithPrimary', 'servers': [ { 'address': 'b:27017', 'avg_rtt_ms': 10000, 'type': 'RSSecondary', 'tag': {} }, { 'address': 'c:27017', 'avg_rtt_ms': 20000, 'type': 'RSSecondary', 'tag': {} }, { 'address': 'a:27017', 'avg_rtt_ms': 30000, 'type': 'RSPrimary', 'tag': {} }, ] } } # Create & populate Topology such that all but one server is too slow. rtt_times = [ srv['avg_rtt_ms'] for srv in scenario_def['topology_description']['servers'] ] min_rtt_idx = rtt_times.index(min(rtt_times)) seeds, hosts = get_addresses( scenario_def["topology_description"]["servers"]) settings = get_topology_settings_dict(heartbeat_frequency=1, local_threshold_ms=1, seeds=seeds, server_selector=selector) topology = Topology(TopologySettings(**settings)) topology.open() for server in scenario_def['topology_description']['servers']: server_description = make_server_description(server, hosts) topology.on_change(server_description) # Invoke server selection and assert no filtering based on latency # prior to custom server selection logic kicking in. server = topology.select_server(ReadPreference.NEAREST) self.assertEqual(len(selector.selection), len(topology.description.server_descriptions())) # Ensure proper filtering based on latency after custom selection. self.assertEqual(server.description.address, seeds[min_rtt_idx])
def test_server_selector_bypassed(self): selector = FunctionCallCounter(lambda x: x) scenario_def = { 'topology_description': { 'type': 'ReplicaSetNoPrimary', 'servers': [ { 'address': 'b:27017', 'avg_rtt_ms': 10000, 'type': 'RSSecondary', 'tag': {} }, { 'address': 'c:27017', 'avg_rtt_ms': 20000, 'type': 'RSSecondary', 'tag': {} }, { 'address': 'a:27017', 'avg_rtt_ms': 30000, 'type': 'RSSecondary', 'tag': {} }, ] } } # Create & populate Topology such that no server is writeable. seeds, hosts = get_addresses( scenario_def["topology_description"]["servers"]) settings = get_topology_settings_dict(heartbeat_frequency=1, local_threshold_ms=1, seeds=seeds, server_selector=selector) topology = Topology(TopologySettings(**settings)) topology.open() for server in scenario_def['topology_description']['servers']: server_description = make_server_description(server, hosts) topology.on_change(server_description) # Invoke server selection and assert no calls to our custom selector. with self.assertRaisesRegex(ServerSelectionTimeoutError, 'No primary available for writes'): topology.select_server(writable_server_selector, server_selection_timeout=0.1) self.assertEqual(selector.call_count, 0)
def test_latency_threshold_application(self): selector = SelectionStoreSelector() scenario_def = { 'topology_description': { 'type': 'ReplicaSetWithPrimary', 'servers': [ {'address': 'b:27017', 'avg_rtt_ms': 10000, 'type': 'RSSecondary', 'tag': {}}, {'address': 'c:27017', 'avg_rtt_ms': 20000, 'type': 'RSSecondary', 'tag': {}}, {'address': 'a:27017', 'avg_rtt_ms': 30000, 'type': 'RSPrimary', 'tag': {}}, ]}} # Create & populate Topology such that all but one server is too slow. rtt_times = [srv['avg_rtt_ms'] for srv in scenario_def['topology_description']['servers']] min_rtt_idx = rtt_times.index(min(rtt_times)) seeds, hosts = get_addresses( scenario_def["topology_description"]["servers"]) settings = get_topology_settings_dict( heartbeat_frequency=1, local_threshold_ms=1, seeds=seeds, server_selector=selector) topology = Topology(TopologySettings(**settings)) topology.open() for server in scenario_def['topology_description']['servers']: server_description = make_server_description(server, hosts) topology.on_change(server_description) # Invoke server selection and assert no filtering based on latency # prior to custom server selection logic kicking in. server = topology.select_server(ReadPreference.NEAREST) self.assertEqual( len(selector.selection), len(topology.description.server_descriptions())) # Ensure proper filtering based on latency after custom selection. self.assertEqual( server.description.address, seeds[min_rtt_idx])
def test_server_selector_bypassed(self): selector = CallCountSelector() scenario_def = { 'topology_description': { 'type': 'ReplicaSetNoPrimary', 'servers': [ {'address': 'b:27017', 'avg_rtt_ms': 10000, 'type': 'RSSecondary', 'tag': {}}, {'address': 'c:27017', 'avg_rtt_ms': 20000, 'type': 'RSSecondary', 'tag': {}}, {'address': 'a:27017', 'avg_rtt_ms': 30000, 'type': 'RSSecondary', 'tag': {}}, ]}} # Create & populate Topology such that no server is writeable. seeds, hosts = get_addresses( scenario_def["topology_description"]["servers"]) settings = get_topology_settings_dict( heartbeat_frequency=1, local_threshold_ms=1, seeds=seeds, server_selector=selector) topology = Topology(TopologySettings(**settings)) topology.open() for server in scenario_def['topology_description']['servers']: server_description = make_server_description(server, hosts) topology.on_change(server_description) # Invoke server selection and assert no calls to our custom selector. with self.assertRaisesRegex( ServerSelectionTimeoutError, 'No primary available for writes'): topology.select_server( writable_server_selector, server_selection_timeout=0.1) self.assertEqual(selector.call_count, 0)