Fix _run_discovery caching

EndpointData._run_discovery thought it was caching already-tried URLs,
but it was really caching each letter of each URL, so the cache wasn't
working:

 tried = set()
 ...
 if vers_url in tried:
     continue
 tried.update(vers_url)  # Adds each char of `vers_url` to `tried`

Changed that last line to:

 tried.add(vers_url)

Added a unit test for same.

Change-Id: I894636d846de4a3b63000f9e2f79f378134c1de8
Closes-Bug: #1703447
This commit is contained in:
Eric Fried 2017-07-10 14:55:35 -05:00
parent 37a2352a21
commit d6449772ba
2 changed files with 25 additions and 1 deletions

View File

@ -708,7 +708,7 @@ class EndpointData(object):
if vers_url in tried:
continue
tried.update(vers_url)
tried.add(vers_url)
try:
self._disc = get_discovery(

View File

@ -11,11 +11,13 @@
# under the License.
import json
import mock
import re
from testtools import matchers
from keystoneauth1 import discover
from keystoneauth1 import exceptions
from keystoneauth1 import fixture
from keystoneauth1 import session
from keystoneauth1.tests.unit import utils
@ -674,3 +676,25 @@ class VersionDataTests(utils.TestCase):
# only the version with both id and links will be actually returned
versions = disc.version_data()
self.assertEqual(1, len(versions))
class EndpointDataTests(utils.TestCase):
@mock.patch('keystoneauth1.discover.get_discovery')
@mock.patch('keystoneauth1.discover.EndpointData.'
'_get_discovery_url_choices')
def test_run_discovery_cache(self, mock_url_choices, mock_get_disc):
# get_discovery raises so we keep looping
mock_get_disc.side_effect = exceptions.DiscoveryFailure()
# Duplicate 'url1' in here to validate the cache behavior
mock_url_choices.return_value = ('url1', 'url2', 'url1', 'url3')
epd = discover.EndpointData()
epd._run_discovery(
session='sess', cache='cache', version='vers', min_version='min',
max_version='max', match_url='match', project_id='projid',
allow_version_hack='allow_hack', allow='allow',
discover_versions='disc_vers')
# Only one call with 'url1'
self.assertEqual(3, mock_get_disc.call_count)
mock_get_disc.assert_has_calls(
[mock.call('sess', url, cache='cache', authenticated=False)
for url in ('url1', 'url2', 'url3')])