Tempest plugin for the Neutron project.
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

202 lines
8.2 KiB

  1. # Copyright (c) 2017 x-ion GmbH
  2. # All Rights Reserved.
  3. #
  4. # Licensed under the Apache License, Version 2.0 (the "License"); you may
  5. # not use this file except in compliance with the License. You may obtain
  6. # a copy of the License at
  7. #
  8. # http://www.apache.org/licenses/LICENSE-2.0
  9. #
  10. # Unless required by applicable law or agreed to in writing, software
  11. # distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
  12. # WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
  13. # License for the specific language governing permissions and limitations
  14. # under the License.
  15. import ipaddress
  16. import testtools
  17. from tempest.common import utils
  18. from tempest.common import waiters
  19. from tempest.lib.common.utils import data_utils
  20. from tempest.lib import decorators
  21. from tempest.lib import exceptions as lib_exc
  22. from neutron_tempest_plugin.api import base as base_api
  23. from neutron_tempest_plugin import config
  24. from neutron_tempest_plugin.scenario import base
  25. from neutron_tempest_plugin.scenario import constants
  26. CONF = config.CONF
  27. # Note(jh): Need to do a bit of juggling here in order to avoid failures
  28. # when designate_tempest_plugin is not available
  29. dns_base = testtools.try_import('designate_tempest_plugin.tests.base')
  30. dns_waiters = testtools.try_import('designate_tempest_plugin.common.waiters')
  31. if dns_base:
  32. DNSMixin = dns_base.BaseDnsV2Test
  33. else:
  34. DNSMixin = object
  35. class BaseDNSIntegrationTests(base.BaseTempestTestCase, DNSMixin):
  36. credentials = ['primary']
  37. @classmethod
  38. def setup_clients(cls):
  39. super(BaseDNSIntegrationTests, cls).setup_clients()
  40. cls.dns_client = cls.os_tempest.zones_client
  41. cls.query_client = cls.os_tempest.query_client
  42. cls.query_client.build_timeout = 30
  43. @classmethod
  44. def skip_checks(cls):
  45. super(BaseDNSIntegrationTests, cls).skip_checks()
  46. if not ('designate' in CONF.service_available and
  47. CONF.service_available.designate):
  48. raise cls.skipException("Designate support is required")
  49. if not (dns_base and dns_waiters):
  50. raise cls.skipException("Designate tempest plugin is missing")
  51. @classmethod
  52. @utils.requires_ext(extension="dns-integration", service="network")
  53. def resource_setup(cls):
  54. super(BaseDNSIntegrationTests, cls).resource_setup()
  55. _, cls.zone = cls.dns_client.create_zone()
  56. cls.addClassResourceCleanup(cls.dns_client.delete_zone,
  57. cls.zone['id'], ignore_errors=lib_exc.NotFound)
  58. dns_waiters.wait_for_zone_status(
  59. cls.dns_client, cls.zone['id'], 'ACTIVE')
  60. cls.network = cls.create_network(dns_domain=cls.zone['name'])
  61. cls.subnet = cls.create_subnet(cls.network)
  62. cls.subnet_v6 = cls.create_subnet(cls.network, ip_version=6)
  63. cls.router = cls.create_router_by_client()
  64. cls.create_router_interface(cls.router['id'], cls.subnet['id'])
  65. cls.keypair = cls.create_keypair()
  66. def _create_floatingip_with_dns(self, dns_name):
  67. return self.create_floatingip(client=self.os_primary.network_client,
  68. dns_name=dns_name,
  69. dns_domain=self.zone['name'])
  70. def _create_server(self, name=None):
  71. port = self.create_port(self.network)
  72. server = self.create_server(
  73. flavor_ref=CONF.compute.flavor_ref,
  74. image_ref=CONF.compute.image_ref,
  75. key_name=self.keypair['name'], name=name,
  76. networks=[{'port': port['id']}])['server']
  77. waiters.wait_for_server_status(self.os_primary.servers_client,
  78. server['id'],
  79. constants.SERVER_STATUS_ACTIVE)
  80. fip = self.create_floatingip(port=port)
  81. return {'port': port, 'fip': fip, 'server': server}
  82. def _verify_dns_records(self, address, name, found=True, record_type='A'):
  83. client = self.query_client
  84. forward = name + '.' + self.zone['name']
  85. reverse = ipaddress.ip_address(address).reverse_pointer
  86. dns_waiters.wait_for_query(client, forward, record_type, found)
  87. dns_waiters.wait_for_query(client, reverse, 'PTR', found)
  88. if not found:
  89. return
  90. fwd_response = client.query(forward, record_type)
  91. rev_response = client.query(reverse, 'PTR')
  92. for r in fwd_response:
  93. for rr in r.answer:
  94. self.assertIn(address, rr.to_text())
  95. for r in rev_response:
  96. for rr in r.answer:
  97. self.assertIn(forward, rr.to_text())
  98. class DNSIntegrationTests(BaseDNSIntegrationTests):
  99. @decorators.idempotent_id('850ee378-4b5a-4f71-960e-0e7b12e03a34')
  100. def test_server_with_fip(self):
  101. name = data_utils.rand_name('server-test')
  102. server = self._create_server(name=name)
  103. server_ip = server['fip']['floating_ip_address']
  104. self._verify_dns_records(server_ip, name)
  105. self.delete_floatingip(server['fip'])
  106. self._verify_dns_records(server_ip, name, found=False)
  107. @decorators.idempotent_id('a8f2fade-8d5c-40f9-80f0-3de4b8d91985')
  108. def test_fip(self):
  109. name = data_utils.rand_name('fip-test')
  110. fip = self._create_floatingip_with_dns(name)
  111. addr = fip['floating_ip_address']
  112. self._verify_dns_records(addr, name)
  113. self.delete_floatingip(fip)
  114. self._verify_dns_records(addr, name, found=False)
  115. class DNSIntegrationAdminTests(BaseDNSIntegrationTests,
  116. base_api.BaseAdminNetworkTest):
  117. credentials = ['primary', 'admin']
  118. @classmethod
  119. def resource_setup(cls):
  120. super(DNSIntegrationAdminTests, cls).resource_setup()
  121. # TODO(jh): We should add the segmentation_id as tempest option
  122. # so that it can be changed to match the deployment if needed
  123. cls.network2 = cls.create_network(dns_domain=cls.zone['name'],
  124. provider_network_type='vxlan',
  125. provider_segmentation_id=12345)
  126. cls.subnet2 = cls.create_subnet(cls.network2)
  127. @decorators.idempotent_id('fa6477ce-a12b-41da-b671-5a3bbdafab07')
  128. def test_port_on_special_network(self):
  129. name = data_utils.rand_name('port-test')
  130. port = self.create_port(self.network2,
  131. dns_name=name)
  132. addr = port['fixed_ips'][0]['ip_address']
  133. self._verify_dns_records(addr, name)
  134. self.client.delete_port(port['id'])
  135. self._verify_dns_records(addr, name, found=False)
  136. @decorators.idempotent_id('d44cd5b8-ac67-4965-96ff-cb77ab6aea8b')
  137. def test_fip_admin_delete(self):
  138. name = data_utils.rand_name('fip-test')
  139. fip = self._create_floatingip_with_dns(name)
  140. addr = fip['floating_ip_address']
  141. self._verify_dns_records(addr, name)
  142. self.delete_floatingip(fip, client=self.admin_client)
  143. self._verify_dns_records(addr, name, found=False)
  144. class DNSIntegrationExtraTests(BaseDNSIntegrationTests):
  145. required_extensions = ["subnet-dns-publish-fixed-ip"]
  146. @classmethod
  147. def resource_setup(cls):
  148. super(DNSIntegrationExtraTests, cls).resource_setup()
  149. cls.network2 = cls.create_network()
  150. cls.subnet2 = cls.create_subnet(cls.network2)
  151. cls.subnet2_v6 = cls.create_subnet(cls.network2,
  152. ip_version=6,
  153. dns_publish_fixed_ip=True)
  154. @decorators.idempotent_id('e10e0e5d-69ac-4172-b39f-27ab344b7f99')
  155. def test_port_with_publishing_subnet(self):
  156. name = data_utils.rand_name('port-test')
  157. port = self.create_port(self.network2,
  158. dns_domain=self.zone['name'],
  159. dns_name=name)
  160. fixed_ips = port['fixed_ips']
  161. if fixed_ips[1]['subnet_id'] == self.subnet2_v6['id']:
  162. v6_index = 1
  163. else:
  164. v6_index = 0
  165. addr_v4 = port['fixed_ips'][1 - v6_index]['ip_address']
  166. addr_v6 = port['fixed_ips'][v6_index]['ip_address']
  167. self._verify_dns_records(addr_v6, name, record_type='AAAA')
  168. self._verify_dns_records(addr_v4, name, found=False)
  169. self.client.delete_port(port['id'])
  170. self._verify_dns_records(addr_v6, name, record_type='AAAA',
  171. found=False)