def testFetchFromMemcache(self):
     with mock.patch.object(client_signature_fetcher,
                            'ClientSignatureFetcher'):
         mock_memcache_response = 0.1
         client_signature_fetcher.ClientSignatureFetcher(
         ).fetch.return_value = (mock_memcache_response)
         fetcher_results_actual = client_signature_fetcher.ClientSignatureFetcher(
         ).fetch('Faked_key')
         self.assertEqual(mock_memcache_response, fetcher_results_actual)
Ejemplo n.º 2
0
    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)
        ]  # yapf: disable

        query_results_expected = mock_fetched_tools

        # Make sure the resolver is fetching only online tools that match the
        # specified tool ID.
        tool_properties_expected = sliver_tool_fetcher.ToolProperties(
            tool_id=_TOOL_ID, status=message.STATUS_ONLINE)

        client_signature_fetcher.ClientSignatureFetcher(
        ).fetch.return_value = 1.0

        self.assertQueryResultMultiTool(query, mock_fetched_tools,
                                        query_results_expected,
                                        tool_properties_expected)
Ejemplo n.º 3
0
    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)
        ]  # yapf: disable

        # 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 = sliver_tool_fetcher.ToolProperties(
            tool_id=_TOOL_ID, status=message.STATUS_ONLINE)
        client_signature_fetcher.ClientSignatureFetcher(
        ).fetch.return_value = 1.0
        self.assertQueryResultMultiTool(query, mock_fetched_tools,
                                        query_results_expected,
                                        tool_properties_expected)
Ejemplo n.º 4
0
    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 = sliver_tool_fetcher.ToolProperties(
            tool_id=_TOOL_ID,
            address_family=message.ADDRESS_FAMILY_IPv4,
            status=message.STATUS_ONLINE)

        mock_fetched_tools = [close_tool, far_tool]
        client_signature_fetcher.ClientSignatureFetcher(
        ).fetch.return_value = 1.0
        self.assertQueryResultSingleTool(query, mock_fetched_tools, close_tool,
                                         tool_properties_expected)
Ejemplo n.º 5
0
    def _get_closest_n_candidates(self, query, max_results):
        """Selects the top N geographically closest SliverTools to the client.

        Args:
            query: A LookupQuery instance.
            max_results: The maximum number of candidates to return.

        Returns:
            A list of SliverTool entities on success, or None if there is no
            SliverTool available that matches the query.
        """
        candidates = self._get_matching_candidates(query)
        if not candidates:
            return None

        if (query.latitude is None) or (query.longitude is None):
            logging.warning(
                'No latitude/longitude, return random sliver tool(s).')
            return random.sample(candidates, min(len(candidates), max_results))

        # Pre-shuffle the candidates to randomize the order of equidistant
        # results.
        random.shuffle(candidates)

        site_distances = {}
        tool_distances = []

        filtered_candidates = []

        prob = client_signature_fetcher.ClientSignatureFetcher().fetch(
            self.client_signature)
        if random.uniform(0, 1) > prob:
            # NB: the string format makes log monitoring possible.
            logging.info('SIGNATURE_FOUND: %f returned from memcache for %s',
                         prob, self.client_signature)
            # Filter the candidates sites, only keep the '0c' sites
            filtered_candidates = filter(lambda c: c.site_id[-1] == 'c',
                                         candidates)
        else:
            # Filter the candidates sites, only keep the regular sites
            filtered_candidates = filter(lambda c: c.site_id[-1] != 'c',
                                         candidates)

        for candidate in filtered_candidates:
            prob = site_keep_probability.get(candidate.site_id, 1.0)
            if random.uniform(0, 1) < prob:
                # Only add candidate if a random probability is under the "site
                # keep probability" threshold.
                self._add_candidate(query, candidate, site_distances,
                                    tool_distances)

        # Sort the tools by distance
        tool_distances.sort(key=lambda t: t['distance'])

        # Create a new list of just the sorted SliverTool objects.
        sorted_tools = [t['tool'] for t in tool_distances]
        return sorted_tools[:max_results]
Ejemplo n.º 6
0
    def testAnswerQueryWhenNoToolsMatchToolId(self):
        tool_id = 'non_existent_tool'
        query = lookup_query.LookupQuery()
        query.tool_id = tool_id

        # Simulate no matching tools
        sliver_tool_fetcher.SliverToolFetcher().fetch.return_value = []

        client_signature_fetcher.ClientSignatureFetcher(
        ).fetch.return_value = 1.0

        # Result should be None when there are no matches.
        self.assertIsNone(self.resolver.answer_query(query))
Ejemplo n.º 7
0
    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)
        ]  # yapf: disable

        # 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 = sliver_tool_fetcher.ToolProperties(
            tool_id=_TOOL_ID, status=message.STATUS_ONLINE)

        client_signature_fetcher.ClientSignatureFetcher(
        ).fetch.return_value = 1.0

        self.assertQueryResultWithRandomShuffle(query, mock_fetched_tools,
                                                query_results_expected,
                                                tool_properties_expected)
Ejemplo n.º 8
0
    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 = sliver_tool_fetcher.ToolProperties(
            tool_id=_TOOL_ID, status=message.STATUS_ONLINE)

        client_signature_fetcher.ClientSignatureFetcher(
        ).fetch.return_value = 1.0

        self.assertQueryResultWithRandomShuffle(query, mock_fetched_tools,
                                                query_results_expected,
                                                tool_properties_expected)