"Fossies" - the Fresh Open Source Software Archive

Member "keystone-17.0.0/keystone/tests/unit/catalog/test_backends.py" (13 May 2020, 26864 Bytes) of package /linux/misc/openstack/keystone-17.0.0.tar.gz:


As a special service "Fossies" has tried to format the requested source page into HTML format using (guessed) Python source code syntax highlighting (style: standard) with prefixed line numbers. Alternatively you can here view or download the uninterpreted source code file. See also the latest Fossies "Diffs" side-by-side code changes report for "test_backends.py": 16.0.1_vs_17.0.0.

    1 # Licensed under the Apache License, Version 2.0 (the "License"); you may
    2 # not use this file except in compliance with the License. You may obtain
    3 # a copy of the License at
    4 #
    5 #      http://www.apache.org/licenses/LICENSE-2.0
    6 #
    7 # Unless required by applicable law or agreed to in writing, software
    8 # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
    9 # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
   10 # License for the specific language governing permissions and limitations
   11 # under the License.
   12 
   13 import copy
   14 from unittest import mock
   15 import uuid
   16 
   17 from testtools import matchers
   18 
   19 from keystone.catalog.backends import base
   20 from keystone.common import driver_hints
   21 from keystone.common import provider_api
   22 from keystone import exception
   23 from keystone.tests import unit
   24 
   25 PROVIDERS = provider_api.ProviderAPIs
   26 
   27 
   28 class CatalogTests(object):
   29 
   30     _legacy_endpoint_id_in_endpoint = True
   31     _enabled_default_to_true_when_creating_endpoint = False
   32 
   33     def test_region_crud(self):
   34         # create
   35         region_id = 'default'
   36         new_region = unit.new_region_ref(id=region_id)
   37         res = PROVIDERS.catalog_api.create_region(new_region)
   38 
   39         # Ensure that we don't need to have a
   40         # parent_region_id in the original supplied
   41         # ref dict, but that it will be returned from
   42         # the endpoint, with None value.
   43         expected_region = new_region.copy()
   44         expected_region['parent_region_id'] = None
   45         self.assertDictEqual(expected_region, res)
   46 
   47         # Test adding another region with the one above
   48         # as its parent. We will check below whether deleting
   49         # the parent successfully deletes any child regions.
   50         parent_region_id = region_id
   51         new_region = unit.new_region_ref(parent_region_id=parent_region_id)
   52         region_id = new_region['id']
   53         res = PROVIDERS.catalog_api.create_region(new_region)
   54         self.assertDictEqual(new_region, res)
   55 
   56         # list
   57         regions = PROVIDERS.catalog_api.list_regions()
   58         self.assertThat(regions, matchers.HasLength(2))
   59         region_ids = [x['id'] for x in regions]
   60         self.assertIn(parent_region_id, region_ids)
   61         self.assertIn(region_id, region_ids)
   62 
   63         # update
   64         region_desc_update = {'description': uuid.uuid4().hex}
   65         res = PROVIDERS.catalog_api.update_region(
   66             region_id, region_desc_update
   67         )
   68         expected_region = new_region.copy()
   69         expected_region['description'] = region_desc_update['description']
   70         self.assertDictEqual(expected_region, res)
   71 
   72         # delete
   73         PROVIDERS.catalog_api.delete_region(parent_region_id)
   74         self.assertRaises(exception.RegionNotFound,
   75                           PROVIDERS.catalog_api.delete_region,
   76                           parent_region_id)
   77         self.assertRaises(exception.RegionNotFound,
   78                           PROVIDERS.catalog_api.get_region,
   79                           parent_region_id)
   80         # Ensure the child is also gone...
   81         self.assertRaises(exception.RegionNotFound,
   82                           PROVIDERS.catalog_api.get_region,
   83                           region_id)
   84 
   85     def _create_region_with_parent_id(self, parent_id=None):
   86         new_region = unit.new_region_ref(parent_region_id=parent_id)
   87         PROVIDERS.catalog_api.create_region(new_region)
   88         return new_region
   89 
   90     def test_list_regions_filtered_by_parent_region_id(self):
   91         new_region = self._create_region_with_parent_id()
   92         parent_id = new_region['id']
   93         new_region = self._create_region_with_parent_id(parent_id)
   94         new_region = self._create_region_with_parent_id(parent_id)
   95 
   96         # filter by parent_region_id
   97         hints = driver_hints.Hints()
   98         hints.add_filter('parent_region_id', parent_id)
   99         regions = PROVIDERS.catalog_api.list_regions(hints)
  100         for region in regions:
  101             self.assertEqual(parent_id, region['parent_region_id'])
  102 
  103     @unit.skip_if_cache_disabled('catalog')
  104     def test_cache_layer_region_crud(self):
  105         new_region = unit.new_region_ref()
  106         region_id = new_region['id']
  107         PROVIDERS.catalog_api.create_region(new_region.copy())
  108         updated_region = copy.deepcopy(new_region)
  109         updated_region['description'] = uuid.uuid4().hex
  110         # cache the result
  111         PROVIDERS.catalog_api.get_region(region_id)
  112         # update the region bypassing catalog_api
  113         PROVIDERS.catalog_api.driver.update_region(region_id, updated_region)
  114         self.assertDictContainsSubset(
  115             new_region, PROVIDERS.catalog_api.get_region(region_id)
  116         )
  117         PROVIDERS.catalog_api.get_region.invalidate(
  118             PROVIDERS.catalog_api, region_id
  119         )
  120         self.assertDictContainsSubset(
  121             updated_region, PROVIDERS.catalog_api.get_region(region_id)
  122         )
  123         # delete the region
  124         PROVIDERS.catalog_api.driver.delete_region(region_id)
  125         # still get the old region
  126         self.assertDictContainsSubset(
  127             updated_region, PROVIDERS.catalog_api.get_region(region_id)
  128         )
  129         PROVIDERS.catalog_api.get_region.invalidate(
  130             PROVIDERS.catalog_api, region_id
  131         )
  132         self.assertRaises(exception.RegionNotFound,
  133                           PROVIDERS.catalog_api.get_region, region_id)
  134 
  135     @unit.skip_if_cache_disabled('catalog')
  136     def test_invalidate_cache_when_updating_region(self):
  137         new_region = unit.new_region_ref()
  138         region_id = new_region['id']
  139         PROVIDERS.catalog_api.create_region(new_region)
  140 
  141         # cache the region
  142         PROVIDERS.catalog_api.get_region(region_id)
  143 
  144         # update the region via catalog_api
  145         new_description = {'description': uuid.uuid4().hex}
  146         PROVIDERS.catalog_api.update_region(region_id, new_description)
  147 
  148         # assert that we can get the new region
  149         current_region = PROVIDERS.catalog_api.get_region(region_id)
  150         self.assertEqual(new_description['description'],
  151                          current_region['description'])
  152 
  153     def test_update_region_extras(self):
  154         new_region = unit.new_region_ref()
  155         region_id = new_region['id']
  156         PROVIDERS.catalog_api.create_region(new_region)
  157 
  158         email = 'keystone@openstack.org'
  159         new_ref = {'description': uuid.uuid4().hex,
  160                    'email': email}
  161         PROVIDERS.catalog_api.update_region(region_id, new_ref)
  162 
  163         current_region = PROVIDERS.catalog_api.get_region(region_id)
  164         self.assertEqual(email,
  165                          current_region['email'])
  166 
  167     def test_create_region_with_duplicate_id(self):
  168         new_region = unit.new_region_ref()
  169         PROVIDERS.catalog_api.create_region(new_region)
  170         # Create region again with duplicate id
  171         self.assertRaises(exception.Conflict,
  172                           PROVIDERS.catalog_api.create_region,
  173                           new_region)
  174 
  175     def test_get_region_returns_not_found(self):
  176         self.assertRaises(exception.RegionNotFound,
  177                           PROVIDERS.catalog_api.get_region,
  178                           uuid.uuid4().hex)
  179 
  180     def test_delete_region_returns_not_found(self):
  181         self.assertRaises(exception.RegionNotFound,
  182                           PROVIDERS.catalog_api.delete_region,
  183                           uuid.uuid4().hex)
  184 
  185     def test_create_region_invalid_parent_region_returns_not_found(self):
  186         new_region = unit.new_region_ref(parent_region_id=uuid.uuid4().hex)
  187         self.assertRaises(exception.RegionNotFound,
  188                           PROVIDERS.catalog_api.create_region,
  189                           new_region)
  190 
  191     def test_avoid_creating_circular_references_in_regions_update(self):
  192         region_one = self._create_region_with_parent_id()
  193 
  194         # self circle: region_one->region_one
  195         self.assertRaises(exception.CircularRegionHierarchyError,
  196                           PROVIDERS.catalog_api.update_region,
  197                           region_one['id'],
  198                           {'parent_region_id': region_one['id']})
  199 
  200         # region_one->region_two->region_one
  201         region_two = self._create_region_with_parent_id(region_one['id'])
  202         self.assertRaises(exception.CircularRegionHierarchyError,
  203                           PROVIDERS.catalog_api.update_region,
  204                           region_one['id'],
  205                           {'parent_region_id': region_two['id']})
  206 
  207         # region_one region_two->region_three->region_four->region_two
  208         region_three = self._create_region_with_parent_id(region_two['id'])
  209         region_four = self._create_region_with_parent_id(region_three['id'])
  210         self.assertRaises(exception.CircularRegionHierarchyError,
  211                           PROVIDERS.catalog_api.update_region,
  212                           region_two['id'],
  213                           {'parent_region_id': region_four['id']})
  214 
  215     @mock.patch.object(base.CatalogDriverBase,
  216                        "_ensure_no_circle_in_hierarchical_regions")
  217     def test_circular_regions_can_be_deleted(self, mock_ensure_on_circle):
  218         # turn off the enforcement so that cycles can be created for the test
  219         mock_ensure_on_circle.return_value = None
  220 
  221         region_one = self._create_region_with_parent_id()
  222 
  223         # self circle: region_one->region_one
  224         PROVIDERS.catalog_api.update_region(
  225             region_one['id'],
  226             {'parent_region_id': region_one['id']})
  227         PROVIDERS.catalog_api.delete_region(region_one['id'])
  228         self.assertRaises(exception.RegionNotFound,
  229                           PROVIDERS.catalog_api.get_region,
  230                           region_one['id'])
  231 
  232         # region_one->region_two->region_one
  233         region_one = self._create_region_with_parent_id()
  234         region_two = self._create_region_with_parent_id(region_one['id'])
  235         PROVIDERS.catalog_api.update_region(
  236             region_one['id'],
  237             {'parent_region_id': region_two['id']})
  238         PROVIDERS.catalog_api.delete_region(region_one['id'])
  239         self.assertRaises(exception.RegionNotFound,
  240                           PROVIDERS.catalog_api.get_region,
  241                           region_one['id'])
  242         self.assertRaises(exception.RegionNotFound,
  243                           PROVIDERS.catalog_api.get_region,
  244                           region_two['id'])
  245 
  246         # region_one->region_two->region_three->region_one
  247         region_one = self._create_region_with_parent_id()
  248         region_two = self._create_region_with_parent_id(region_one['id'])
  249         region_three = self._create_region_with_parent_id(region_two['id'])
  250         PROVIDERS.catalog_api.update_region(
  251             region_one['id'],
  252             {'parent_region_id': region_three['id']})
  253         PROVIDERS.catalog_api.delete_region(region_two['id'])
  254         self.assertRaises(exception.RegionNotFound,
  255                           PROVIDERS.catalog_api.get_region,
  256                           region_two['id'])
  257         self.assertRaises(exception.RegionNotFound,
  258                           PROVIDERS.catalog_api.get_region,
  259                           region_one['id'])
  260         self.assertRaises(exception.RegionNotFound,
  261                           PROVIDERS.catalog_api.get_region,
  262                           region_three['id'])
  263 
  264     def test_service_crud(self):
  265         # create
  266         new_service = unit.new_service_ref()
  267         service_id = new_service['id']
  268         res = PROVIDERS.catalog_api.create_service(service_id, new_service)
  269         self.assertDictEqual(new_service, res)
  270 
  271         # list
  272         services = PROVIDERS.catalog_api.list_services()
  273         self.assertIn(service_id, [x['id'] for x in services])
  274 
  275         # update
  276         service_name_update = {'name': uuid.uuid4().hex}
  277         res = PROVIDERS.catalog_api.update_service(
  278             service_id, service_name_update
  279         )
  280         expected_service = new_service.copy()
  281         expected_service['name'] = service_name_update['name']
  282         self.assertDictEqual(expected_service, res)
  283 
  284         # delete
  285         PROVIDERS.catalog_api.delete_service(service_id)
  286         self.assertRaises(exception.ServiceNotFound,
  287                           PROVIDERS.catalog_api.delete_service,
  288                           service_id)
  289         self.assertRaises(exception.ServiceNotFound,
  290                           PROVIDERS.catalog_api.get_service,
  291                           service_id)
  292 
  293     def _create_random_service(self):
  294         new_service = unit.new_service_ref()
  295         service_id = new_service['id']
  296         return PROVIDERS.catalog_api.create_service(service_id, new_service)
  297 
  298     def test_service_filtering(self):
  299         target_service = self._create_random_service()
  300         unrelated_service1 = self._create_random_service()
  301         unrelated_service2 = self._create_random_service()
  302 
  303         # filter by type
  304         hint_for_type = driver_hints.Hints()
  305         hint_for_type.add_filter(name="type", value=target_service['type'])
  306         services = PROVIDERS.catalog_api.list_services(hint_for_type)
  307 
  308         self.assertEqual(1, len(services))
  309         filtered_service = services[0]
  310         self.assertEqual(target_service['type'], filtered_service['type'])
  311         self.assertEqual(target_service['id'], filtered_service['id'])
  312 
  313         # filter should have been removed, since it was already used by the
  314         # backend
  315         self.assertEqual(0, len(hint_for_type.filters))
  316 
  317         # the backend shouldn't filter by name, since this is handled by the
  318         # front end
  319         hint_for_name = driver_hints.Hints()
  320         hint_for_name.add_filter(name="name", value=target_service['name'])
  321         services = PROVIDERS.catalog_api.list_services(hint_for_name)
  322 
  323         self.assertEqual(3, len(services))
  324 
  325         # filter should still be there, since it wasn't used by the backend
  326         self.assertEqual(1, len(hint_for_name.filters))
  327 
  328         PROVIDERS.catalog_api.delete_service(target_service['id'])
  329         PROVIDERS.catalog_api.delete_service(unrelated_service1['id'])
  330         PROVIDERS.catalog_api.delete_service(unrelated_service2['id'])
  331 
  332     @unit.skip_if_cache_disabled('catalog')
  333     def test_cache_layer_service_crud(self):
  334         new_service = unit.new_service_ref()
  335         service_id = new_service['id']
  336         res = PROVIDERS.catalog_api.create_service(service_id, new_service)
  337         self.assertDictEqual(new_service, res)
  338         PROVIDERS.catalog_api.get_service(service_id)
  339         updated_service = copy.deepcopy(new_service)
  340         updated_service['description'] = uuid.uuid4().hex
  341         # update bypassing catalog api
  342         PROVIDERS.catalog_api.driver.update_service(
  343             service_id, updated_service
  344         )
  345         self.assertDictContainsSubset(
  346             new_service, PROVIDERS.catalog_api.get_service(service_id)
  347         )
  348         PROVIDERS.catalog_api.get_service.invalidate(
  349             PROVIDERS.catalog_api, service_id
  350         )
  351         self.assertDictContainsSubset(
  352             updated_service, PROVIDERS.catalog_api.get_service(service_id)
  353         )
  354 
  355         # delete bypassing catalog api
  356         PROVIDERS.catalog_api.driver.delete_service(service_id)
  357         self.assertDictContainsSubset(
  358             updated_service, PROVIDERS.catalog_api.get_service(service_id)
  359         )
  360         PROVIDERS.catalog_api.get_service.invalidate(
  361             PROVIDERS.catalog_api, service_id
  362         )
  363         self.assertRaises(exception.ServiceNotFound,
  364                           PROVIDERS.catalog_api.delete_service,
  365                           service_id)
  366         self.assertRaises(exception.ServiceNotFound,
  367                           PROVIDERS.catalog_api.get_service,
  368                           service_id)
  369 
  370     @unit.skip_if_cache_disabled('catalog')
  371     def test_invalidate_cache_when_updating_service(self):
  372         new_service = unit.new_service_ref()
  373         service_id = new_service['id']
  374         PROVIDERS.catalog_api.create_service(service_id, new_service)
  375 
  376         # cache the service
  377         PROVIDERS.catalog_api.get_service(service_id)
  378 
  379         # update the service via catalog api
  380         new_type = {'type': uuid.uuid4().hex}
  381         PROVIDERS.catalog_api.update_service(service_id, new_type)
  382 
  383         # assert that we can get the new service
  384         current_service = PROVIDERS.catalog_api.get_service(service_id)
  385         self.assertEqual(new_type['type'], current_service['type'])
  386 
  387     def test_delete_service_with_endpoint(self):
  388         # create a service
  389         service = unit.new_service_ref()
  390         PROVIDERS.catalog_api.create_service(service['id'], service)
  391 
  392         # create an endpoint attached to the service
  393         endpoint = unit.new_endpoint_ref(service_id=service['id'],
  394                                          region_id=None)
  395         PROVIDERS.catalog_api.create_endpoint(endpoint['id'], endpoint)
  396 
  397         # deleting the service should also delete the endpoint
  398         PROVIDERS.catalog_api.delete_service(service['id'])
  399         self.assertRaises(exception.EndpointNotFound,
  400                           PROVIDERS.catalog_api.get_endpoint,
  401                           endpoint['id'])
  402         self.assertRaises(exception.EndpointNotFound,
  403                           PROVIDERS.catalog_api.delete_endpoint,
  404                           endpoint['id'])
  405 
  406     def test_cache_layer_delete_service_with_endpoint(self):
  407         service = unit.new_service_ref()
  408         PROVIDERS.catalog_api.create_service(service['id'], service)
  409 
  410         # create an endpoint attached to the service
  411         endpoint = unit.new_endpoint_ref(service_id=service['id'],
  412                                          region_id=None)
  413         PROVIDERS.catalog_api.create_endpoint(endpoint['id'], endpoint)
  414         # cache the result
  415         PROVIDERS.catalog_api.get_service(service['id'])
  416         PROVIDERS.catalog_api.get_endpoint(endpoint['id'])
  417         # delete the service bypassing catalog api
  418         PROVIDERS.catalog_api.driver.delete_service(service['id'])
  419         self.assertDictContainsSubset(endpoint,
  420                                       PROVIDERS.catalog_api.
  421                                       get_endpoint(endpoint['id']))
  422         self.assertDictContainsSubset(service,
  423                                       PROVIDERS.catalog_api.
  424                                       get_service(service['id']))
  425         PROVIDERS.catalog_api.get_endpoint.invalidate(
  426             PROVIDERS.catalog_api, endpoint['id']
  427         )
  428         self.assertRaises(exception.EndpointNotFound,
  429                           PROVIDERS.catalog_api.get_endpoint,
  430                           endpoint['id'])
  431         self.assertRaises(exception.EndpointNotFound,
  432                           PROVIDERS.catalog_api.delete_endpoint,
  433                           endpoint['id'])
  434         # multiple endpoints associated with a service
  435         second_endpoint = unit.new_endpoint_ref(service_id=service['id'],
  436                                                 region_id=None)
  437         PROVIDERS.catalog_api.create_service(service['id'], service)
  438         PROVIDERS.catalog_api.create_endpoint(endpoint['id'], endpoint)
  439         PROVIDERS.catalog_api.create_endpoint(
  440             second_endpoint['id'], second_endpoint
  441         )
  442         PROVIDERS.catalog_api.delete_service(service['id'])
  443         self.assertRaises(exception.EndpointNotFound,
  444                           PROVIDERS.catalog_api.get_endpoint,
  445                           endpoint['id'])
  446         self.assertRaises(exception.EndpointNotFound,
  447                           PROVIDERS.catalog_api.delete_endpoint,
  448                           endpoint['id'])
  449         self.assertRaises(exception.EndpointNotFound,
  450                           PROVIDERS.catalog_api.get_endpoint,
  451                           second_endpoint['id'])
  452         self.assertRaises(exception.EndpointNotFound,
  453                           PROVIDERS.catalog_api.delete_endpoint,
  454                           second_endpoint['id'])
  455 
  456     def test_get_service_returns_not_found(self):
  457         self.assertRaises(exception.ServiceNotFound,
  458                           PROVIDERS.catalog_api.get_service,
  459                           uuid.uuid4().hex)
  460 
  461     def test_delete_service_returns_not_found(self):
  462         self.assertRaises(exception.ServiceNotFound,
  463                           PROVIDERS.catalog_api.delete_service,
  464                           uuid.uuid4().hex)
  465 
  466     def test_create_endpoint_nonexistent_service(self):
  467         endpoint = unit.new_endpoint_ref(service_id=uuid.uuid4().hex,
  468                                          region_id=None)
  469         self.assertRaises(exception.ValidationError,
  470                           PROVIDERS.catalog_api.create_endpoint,
  471                           endpoint['id'],
  472                           endpoint)
  473 
  474     def test_update_endpoint_nonexistent_service(self):
  475         dummy_service, enabled_endpoint, dummy_disabled_endpoint = (
  476             self._create_endpoints())
  477         new_endpoint = unit.new_endpoint_ref(service_id=uuid.uuid4().hex)
  478         self.assertRaises(exception.ValidationError,
  479                           PROVIDERS.catalog_api.update_endpoint,
  480                           enabled_endpoint['id'],
  481                           new_endpoint)
  482 
  483     def test_create_endpoint_nonexistent_region(self):
  484         service = unit.new_service_ref()
  485         PROVIDERS.catalog_api.create_service(service['id'], service)
  486 
  487         endpoint = unit.new_endpoint_ref(service_id=service['id'])
  488         self.assertRaises(exception.ValidationError,
  489                           PROVIDERS.catalog_api.create_endpoint,
  490                           endpoint['id'],
  491                           endpoint)
  492 
  493     def test_update_endpoint_nonexistent_region(self):
  494         dummy_service, enabled_endpoint, dummy_disabled_endpoint = (
  495             self._create_endpoints())
  496         new_endpoint = unit.new_endpoint_ref(service_id=uuid.uuid4().hex)
  497         self.assertRaises(exception.ValidationError,
  498                           PROVIDERS.catalog_api.update_endpoint,
  499                           enabled_endpoint['id'],
  500                           new_endpoint)
  501 
  502     def test_get_endpoint_returns_not_found(self):
  503         self.assertRaises(exception.EndpointNotFound,
  504                           PROVIDERS.catalog_api.get_endpoint,
  505                           uuid.uuid4().hex)
  506 
  507     def test_delete_endpoint_returns_not_found(self):
  508         self.assertRaises(exception.EndpointNotFound,
  509                           PROVIDERS.catalog_api.delete_endpoint,
  510                           uuid.uuid4().hex)
  511 
  512     def test_create_endpoint(self):
  513         service = unit.new_service_ref()
  514         PROVIDERS.catalog_api.create_service(service['id'], service)
  515 
  516         endpoint = unit.new_endpoint_ref(service_id=service['id'],
  517                                          region_id=None)
  518         PROVIDERS.catalog_api.create_endpoint(endpoint['id'], endpoint.copy())
  519 
  520     def test_update_endpoint(self):
  521         dummy_service_ref, endpoint_ref, dummy_disabled_endpoint_ref = (
  522             self._create_endpoints())
  523         res = PROVIDERS.catalog_api.update_endpoint(
  524             endpoint_ref['id'], {'interface': 'private'}
  525         )
  526         expected_endpoint = endpoint_ref.copy()
  527         expected_endpoint['enabled'] = True
  528         expected_endpoint['interface'] = 'private'
  529         if self._legacy_endpoint_id_in_endpoint:
  530             expected_endpoint['legacy_endpoint_id'] = None
  531         if self._enabled_default_to_true_when_creating_endpoint:
  532             expected_endpoint['enabled'] = True
  533         self.assertDictEqual(expected_endpoint, res)
  534 
  535     def _create_endpoints(self):
  536         # Creates a service and 2 endpoints for the service in the same region.
  537         # The 'public' interface is enabled and the 'internal' interface is
  538         # disabled.
  539 
  540         def create_endpoint(service_id, region, **kwargs):
  541             ref = unit.new_endpoint_ref(
  542                 service_id=service_id,
  543                 region_id=region,
  544                 url='http://localhost/%s' % uuid.uuid4().hex,
  545                 **kwargs)
  546 
  547             PROVIDERS.catalog_api.create_endpoint(ref['id'], ref)
  548             return ref
  549 
  550         # Create a service for use with the endpoints.
  551         service_ref = unit.new_service_ref()
  552         service_id = service_ref['id']
  553         PROVIDERS.catalog_api.create_service(service_id, service_ref)
  554 
  555         region = unit.new_region_ref()
  556         PROVIDERS.catalog_api.create_region(region)
  557 
  558         # Create endpoints
  559         enabled_endpoint_ref = create_endpoint(service_id, region['id'])
  560         disabled_endpoint_ref = create_endpoint(
  561             service_id, region['id'], enabled=False, interface='internal')
  562 
  563         return service_ref, enabled_endpoint_ref, disabled_endpoint_ref
  564 
  565     def test_list_endpoints(self):
  566         service = unit.new_service_ref()
  567         PROVIDERS.catalog_api.create_service(service['id'], service)
  568 
  569         expected_ids = set([uuid.uuid4().hex for _ in range(3)])
  570         for endpoint_id in expected_ids:
  571             endpoint = unit.new_endpoint_ref(service_id=service['id'],
  572                                              id=endpoint_id,
  573                                              region_id=None)
  574             PROVIDERS.catalog_api.create_endpoint(endpoint['id'], endpoint)
  575 
  576         endpoints = PROVIDERS.catalog_api.list_endpoints()
  577         self.assertEqual(expected_ids, set(e['id'] for e in endpoints))
  578 
  579     def test_get_v3_catalog_endpoint_disabled(self):
  580         """Get back only enabled endpoints when get the v3 catalog."""
  581         enabled_endpoint_ref = self._create_endpoints()[1]
  582 
  583         user_id = uuid.uuid4().hex
  584         # Use the project created by the default fixture since the project
  585         # should exist if we want to filter the catalog by the project or
  586         # replace the url with a valid project id.
  587         catalog = PROVIDERS.catalog_api.get_v3_catalog(
  588             user_id, self.project_bar['id']
  589         )
  590 
  591         endpoint_ids = [x['id'] for x in catalog[0]['endpoints']]
  592         self.assertEqual([enabled_endpoint_ref['id']], endpoint_ids)
  593 
  594     @unit.skip_if_cache_disabled('catalog')
  595     def test_invalidate_cache_when_updating_endpoint(self):
  596         service = unit.new_service_ref()
  597         PROVIDERS.catalog_api.create_service(service['id'], service)
  598 
  599         # create an endpoint attached to the service
  600         endpoint = unit.new_endpoint_ref(service_id=service['id'],
  601                                          region_id=None)
  602         PROVIDERS.catalog_api.create_endpoint(endpoint['id'], endpoint)
  603 
  604         # cache the endpoint
  605         PROVIDERS.catalog_api.get_endpoint(endpoint['id'])
  606 
  607         # update the endpoint via catalog api
  608         new_url = {'url': uuid.uuid4().hex}
  609         PROVIDERS.catalog_api.update_endpoint(endpoint['id'], new_url)
  610 
  611         # assert that we can get the new endpoint
  612         current_endpoint = PROVIDERS.catalog_api.get_endpoint(endpoint['id'])
  613         self.assertEqual(new_url['url'], current_endpoint['url'])