def testAnswerQueryWhenSingleToolIsClosestAndQuerySpecifiesAf(self): query = lookup_query.LookupQuery() query.tool_id = _TOOL_ID query.latitude = 0.0 query.longitude = 0.0 query.tool_address_family = message.ADDRESS_FAMILY_IPv4 close_tool = _createSliverTool(_TOOL_ID, site_id='abc01', latitude=1.0, longitude=1.0) far_tool = _createSliverTool(_TOOL_ID, site_id='cba01', latitude=5.0, longitude=5.0) # Make sure the resolver is fetching only online tools that match the # specified tool ID. tool_properties_expected = tool_fetcher.ToolProperties( tool_id=_TOOL_ID, address_family=message.ADDRESS_FAMILY_IPv4, status=message.STATUS_ONLINE) mock_fetched_tools = [close_tool, far_tool] self.assertQueryResultSingleTool(query, mock_fetched_tools, close_tool, tool_properties_expected)
def testAnswerQueryWhenMatchingToolsExistAndQuerySpecifiesAf(self): """Resolver should take into account address family when specified.""" query = lookup_query.LookupQuery() query.tool_id = _TOOL_ID query.tool_address_family = message.ADDRESS_FAMILY_IPv6 mock_fetched_tools = [ _createSliverTool(_TOOL_ID), _createSliverTool(_TOOL_ID) ] # AllResolver should not do any additional filtering on the tools it # fetched. query_results_expected = mock_fetched_tools # Make sure the resolver is fetching only tools with IPv6 interface # online that match the specified tool ID. tool_properties_expected = tool_fetcher.ToolProperties( tool_id=_TOOL_ID, address_family=message.ADDRESS_FAMILY_IPv6, status=message.STATUS_ONLINE) self.assertQueryResultMultiTool(query, mock_fetched_tools, query_results_expected, tool_properties_expected)
def testAnswerQueryWhenFewerThanFourToolsMatch(self): """When fewer than four tools match, return whatever matches.""" query = lookup_query.LookupQuery() query.tool_id = _TOOL_ID query.latitude = 0.0 query.longitude = 0.0 mock_fetched_tools = [ _createSliverTool(_TOOL_ID, site_id='abc01', latitude=1.0, longitude=1.0), _createSliverTool(_TOOL_ID, site_id='abc02', latitude=1.0, longitude=1.0), _createSliverTool(_TOOL_ID, site_id='cba01', latitude=5.0, longitude=5.0) ] query_results_expected = mock_fetched_tools # Make sure the resolver is fetching only online tools that match the # specified tool ID. tool_properties_expected = tool_fetcher.ToolProperties( tool_id=_TOOL_ID, status=message.STATUS_ONLINE) self.assertQueryResultMultiTool(query, mock_fetched_tools, query_results_expected, tool_properties_expected)
def testAnswerQueryReturnsRandomToolWhenQueryIsMissingLatLon(self): # TODO(mtlynch): This behavior is confusing because it is inconsistent # with the other resolvers that return None when required attributes are # missing from the query. Change so that all are consistent. query = lookup_query.LookupQuery() query.tool_id = _TOOL_ID mock_fetched_tools = [ _createSliverTool(_TOOL_ID, site_id='abc01', latitude=1.0, longitude=1.0), _createSliverTool(_TOOL_ID, site_id='cba01', latitude=5.0, longitude=5.0) ] # When lat/lon is missing, resolver performs no additional filtering # after fetch filtered_tools_expected = mock_fetched_tools tool_properties_expected = tool_fetcher.ToolProperties( tool_id=_TOOL_ID, status=message.STATUS_ONLINE) self.assertQueryResultMultiToolWithRandomSample( query, mock_fetched_tools, filtered_tools_expected, 1, tool_properties_expected)
def testAnswerQueryReturnsRandomSubsetWhenQueryIsMissingLatLonLowCandidates( self): """When lat/lon is missing, expect a random subset of tools. If the number of matching candidates is lower than the number of tools requested, return all the matching candidates. """ query = lookup_query.LookupQuery() query.tool_id = _TOOL_ID mock_fetched_tools = [ _createSliverTool(_TOOL_ID, site_id='abc01', latitude=1.0, longitude=1.0), _createSliverTool(_TOOL_ID, site_id='abc02', latitude=1.0, longitude=1.0) ] # When lat/lon is missing, resolver performs no additional filtering # after fetch filtered_tools_expected = mock_fetched_tools tool_properties_expected = tool_fetcher.ToolProperties( tool_id=_TOOL_ID, status=message.STATUS_ONLINE) # Normally we expect a random sample of 4, but there are only 2 # candidates in the set self.assertQueryResultMultiToolWithRandomSample( query, mock_fetched_tools, filtered_tools_expected, 2, tool_properties_expected)
def testFetchToolsWithOnlineIpv6(self): self.initStatusSiteGroup() tool_properties = tool_fetcher.ToolProperties( tool_id='mock_tool_a', status=message.STATUS_ONLINE, address_family=message.ADDRESS_FAMILY_IPv6) self.verifyPropertiesReturnExpectedSiteIds( ('abc01', 'xyz01'), tool_properties)
def testFetchAlwaysReturnsNoResultsWhenMetroIsSet(self): """Memcache fetcher has no knowledge of metros, so returns nothing.""" self.createSliverTool( tool_id='mock_tool_a', site_id='abc01', country='CountryA', status_ipv4=message.STATUS_ONLINE, status_ipv6=message.STATUS_ONLINE) tool_properties = tool_fetcher.ToolProperties( tool_id='mock_tool_a', metro='abc') self.verifyPropertiesReturnExpectedSiteIds([], tool_properties)
def testFetchFailsOverToDatastoreWhenDataIsNotInMemcache(self): tool_fetcher.ToolFetcherMemcache().fetch.return_value = [] # The mock response is just ints here for simplicity, though the real # function returns SliverTool objects. mock_datastore_response = [4, 5, 6] tool_fetcher.ToolFetcherDatastore().fetch.return_value = ( mock_datastore_response) tool_properties = tool_fetcher.ToolProperties(tool_id='mock_tool_a') fetcher_results_actual = self.fetcher.fetch(tool_properties) self.assertSequenceEqual(mock_datastore_response, fetcher_results_actual)
def testFetchDoesNotHitDatastoreIfMemcacheHasRequiredData(self): # The mock response is just ints here for simplicity, though the real # function returns SliverTool objects. mock_memcache_response = [1, 2, 3] tool_fetcher.ToolFetcherMemcache().fetch.return_value = ( mock_memcache_response) tool_properties = tool_fetcher.ToolProperties(tool_id='mock_tool_a') fetcher_results_actual = self.fetcher.fetch(tool_properties) self.assertSequenceEqual(mock_memcache_response, fetcher_results_actual) # Verify that we did not attempt to read from the Datastore self.assertFalse(tool_fetcher.ToolFetcherDatastore().fetch.called)
def testAnswerQueryWhenMoreThanFourToolsFromDifferentSitesAreEquallyClosest( self): """When more than four tools tie for closest, randomly select four.""" query = lookup_query.LookupQuery() query.tool_id = _TOOL_ID query.latitude = 0.0 query.longitude = 0.0 mock_fetched_tools = [ _createSliverTool(_TOOL_ID, site_id='aaa01', latitude=1.0, longitude=1.0), _createSliverTool(_TOOL_ID, site_id='bbb01', latitude=-1.0, longitude=-1.0), _createSliverTool(_TOOL_ID, site_id='ccc01', latitude=-1.0, longitude=1.0), _createSliverTool(_TOOL_ID, site_id='ddd01', latitude=1.0, longitude=-1.0), _createSliverTool(_TOOL_ID, site_id='eee01', latitude=-1.0, longitude=-1.0), _createSliverTool(_TOOL_ID, site_id='fff01', latitude=-1.0, longitude=1.0), _createSliverTool(_TOOL_ID, site_id='ggg01', latitude=5.0, longitude=5.0) ] # The mock shuffle reverses the list, so we expect items 2...6 in # reverse order. query_results_expected = mock_fetched_tools[-2:-6:-1] # Make sure the resolver is fetching only online tools that match the # specified tool ID. tool_properties_expected = tool_fetcher.ToolProperties( tool_id=_TOOL_ID, status=message.STATUS_ONLINE) self.assertQueryResultWithRandomShuffle(query, mock_fetched_tools, query_results_expected, tool_properties_expected)
def _tool_properties_from_query(query): """Create ToolProperties from a LookupQuery. Creates a ToolProperties object for use with a resolver, based on a LookupQuery. Note that it only initializes common properties shared by all resolvers (e.g. status, tool_id) whereas resolver-specific properties (e.g. country, metro) are not initialized here. Args: query: LookupQuery from which to create ToolProperties Returns: A ToolProperties object initialized from the query provided. """ tool_properties = tool_fetcher.ToolProperties( tool_id=query.tool_id, status=message.STATUS_ONLINE) if query.tool_address_family: tool_properties.address_family = query.tool_address_family return tool_properties
def testAnswerQueryWhenMatchingToolsExist(self): query = lookup_query.LookupQuery() query.tool_id = _TOOL_ID mock_fetched_tools = [ _createSliverTool(_TOOL_ID), _createSliverTool(_TOOL_ID) ] # AllResolver should not do any additional filtering on the tools it # fetched. query_results_expected = mock_fetched_tools # Make sure the resolver is fetching only online tools that match the # specified tool ID. tool_properties_expected = tool_fetcher.ToolProperties( tool_id=_TOOL_ID, status=message.STATUS_ONLINE) self.assertQueryResultMultiTool(query, mock_fetched_tools, query_results_expected, tool_properties_expected)
def testAnswerQueryWhenFourToolsAreEquallyClosest(self): """When exactly four tools tie for closest, return those four.""" query = lookup_query.LookupQuery() query.tool_id = _TOOL_ID query.latitude = 0.0 query.longitude = 0.0 mock_fetched_tools = [ _createSliverTool(_TOOL_ID, site_id='abc01', latitude=1.0, longitude=1.0), _createSliverTool(_TOOL_ID, site_id='abc02', latitude=1.0, longitude=1.0), _createSliverTool(_TOOL_ID, site_id='abc03', latitude=1.0, longitude=1.0), _createSliverTool(_TOOL_ID, site_id='abc04', latitude=1.0, longitude=1.0), _createSliverTool(_TOOL_ID, site_id='cba01', latitude=5.0, longitude=5.0) ] # Result should be the four closest tools query_results_expected = mock_fetched_tools[:4] # Make sure the resolver is fetching only online tools that match the # specified tool ID. tool_properties_expected = tool_fetcher.ToolProperties( tool_id=_TOOL_ID, status=message.STATUS_ONLINE) self.assertQueryResultMultiTool(query, mock_fetched_tools, query_results_expected, tool_properties_expected)
def testAnswerQueryChoosesRandomlyAmongToolsInMetro(self): query = lookup_query.LookupQuery() query.tool_id = _TOOL_ID query.metro = 'aaa' query.tool_address_family = message.ADDRESS_FAMILY_IPv4 mock_fetched_tools = (_createSliverTool(_TOOL_ID, site_id='aaa01'), _createSliverTool(_TOOL_ID, site_id='aaa02'), _createSliverTool(_TOOL_ID, site_id='aaa03')) filtered_tools_expected = mock_fetched_tools # Make sure the resolver is fetching only online tools that match the # specified tool ID in the specified metro. tool_properties_expected = tool_fetcher.ToolProperties( tool_id=_TOOL_ID, status=message.STATUS_ONLINE, address_family=message.ADDRESS_FAMILY_IPv4, metro=query.metro) self.assertQueryResultSingleToolWithRandomChoice( query, mock_fetched_tools, filtered_tools_expected, tool_properties_expected)
def testAnswerQueryChoosesRandomlyAmongOnlineTools(self): query = lookup_query.LookupQuery() query.tool_id = _TOOL_ID query.tool_address_family = message.ADDRESS_FAMILY_IPv6 mock_fetched_tools = (_createSliverTool(_TOOL_ID, site_id='aaa01'), _createSliverTool(_TOOL_ID, site_id='bbb01'), _createSliverTool(_TOOL_ID, site_id='ccc01'), _createSliverTool(_TOOL_ID, site_id='ddd01')) # Random resolver performs no additional filtering after the fetch. filtered_tools_expected = mock_fetched_tools # Make sure the resolver is fetching only online tools that match the # specified tool ID. tool_properties_expected = tool_fetcher.ToolProperties( tool_id=_TOOL_ID, address_family=message.ADDRESS_FAMILY_IPv6, status=message.STATUS_ONLINE) self.assertQueryResultSingleToolWithRandomChoice( query, mock_fetched_tools, filtered_tools_expected, tool_properties_expected)
def testAnswerQueryWhenSingleToolIsClosest(self): """When a single tool is closest, return that tool.""" query = lookup_query.LookupQuery() query.tool_id = _TOOL_ID query.latitude = 0.0 query.longitude = 0.0 close_tool = _createSliverTool(_TOOL_ID, site_id='abc01', latitude=1.0, longitude=1.0) far_tool = _createSliverTool(_TOOL_ID, site_id='cba01', latitude=5.0, longitude=5.0) # Make sure the resolver is fetching only online tools that match the # specified tool ID. tool_properties_expected = tool_fetcher.ToolProperties( tool_id=_TOOL_ID, status=message.STATUS_ONLINE) mock_fetched_tools = [close_tool, far_tool] self.assertQueryResultSingleTool(query, mock_fetched_tools, close_tool, tool_properties_expected)
def testAnswerQueryWhenMultipleToolsAreEquallyClose(self): """When multiple tools are equally closest, randomly select one.""" query = lookup_query.LookupQuery() query.tool_id = _TOOL_ID query.latitude = 0.0 query.longitude = 0.0 equidistant_tools = (_createSliverTool(_TOOL_ID, site_id='aaa01', latitude=1.0, longitude=5.0), _createSliverTool(_TOOL_ID, site_id='bbb01', latitude=5.0, longitude=1.0)) mock_fetched_tools = [ _createSliverTool(_TOOL_ID, site_id='ccc01', latitude=10.0, longitude=10.0), _createSliverTool(_TOOL_ID, site_id='ddd01', latitude=20.0, longitude=20.0) ] mock_fetched_tools.extend(equidistant_tools) query_results_expected = [equidistant_tools[-1]] tool_properties_expected = tool_fetcher.ToolProperties( tool_id=_TOOL_ID, status=message.STATUS_ONLINE) self.assertQueryResultWithRandomShuffle(query, mock_fetched_tools, query_results_expected, tool_properties_expected)
def testOnlyReturnMlab1(self): self.initToolIdSiteGroup() tool_properties = tool_fetcher.ToolProperties(tool_id='mock_tool_a') for tool in self.fetcher.fetch(tool_properties): self.assertTrue('mlab1' in tool.fqdn) self.assertFalse('mlab2' in tool.fqdn)
def testFetchToolC(self): self.initToolIdSiteGroup() tool_properties = tool_fetcher.ToolProperties(tool_id='mock_tool_c') self.verifyPropertiesReturnExpectedSiteIds(('abc01', 'abc03'), tool_properties)
def testFetchNonExistentTool(self): self.initToolIdSiteGroup() tool_properties = tool_fetcher.ToolProperties(tool_id='no_exist_tool') self.verifyPropertiesReturnExpectedSiteIds([], tool_properties)
def testFetchToolsWithAtLeastOneOfflineInterface(self): self.initStatusSiteGroup() tool_properties = tool_fetcher.ToolProperties( tool_id='mock_tool_a', status=message.STATUS_OFFLINE) self.verifyPropertiesReturnExpectedSiteIds(('abc02', 'abc03', 'xyz01'), tool_properties)
def testFetchWhenNoAfIsSpecifiedButStatusIsOmittedIgnoreAf(self): self.initStatusSiteGroup() tool_properties = tool_fetcher.ToolProperties( tool_id='mock_tool_a', address_family=message.ADDRESS_FAMILY_IPv6) self.verifyPropertiesReturnExpectedSiteIds( ('abc01', 'abc02', 'abc03', 'xyz01'), tool_properties)
def testFetchToolsInCountryB(self): self.initCountrySiteGroup() tool_properties = tool_fetcher.ToolProperties(tool_id='mock_tool_a', country='CountryB') self.verifyPropertiesReturnExpectedSiteIds(('xyz01', ), tool_properties)
def testFetchToolsInNonExistentCountry(self): self.initCountrySiteGroup() tool_properties = tool_fetcher.ToolProperties( tool_id='mock_tool_a', country='non_existent_country') self.verifyPropertiesReturnExpectedSiteIds([], tool_properties)
def testFetchToolsInMetroAbc(self): self.initMetroSiteGroup() tool_properties = tool_fetcher.ToolProperties(tool_id='mock_tool_a', metro='abc') self.verifyPropertiesReturnExpectedSiteIds(('abc01', 'abc02'), tool_properties)
def testFetchToolsInMetroXyz(self): self.initMetroSiteGroup() tool_properties = tool_fetcher.ToolProperties(tool_id='mock_tool_a', metro='xyz') self.verifyPropertiesReturnExpectedSiteIds(('xyz01', ), tool_properties)
def testFetchToolsInNonExistentMetro(self): self.initMetroSiteGroup() tool_properties = tool_fetcher.ToolProperties(tool_id='mock_tool_a', metro='qqq') self.verifyPropertiesReturnExpectedSiteIds([], tool_properties)
def testFetchToolsInMetroDefWithAtLeastOneOnlineInterface(self): self.initMetroSiteGroup() tool_properties = tool_fetcher.ToolProperties( tool_id='mock_tool_a', metro='def', status=message.STATUS_ONLINE) self.verifyPropertiesReturnExpectedSiteIds(('def02', ), tool_properties)