Merge "This patch removes the usage of DDT module from test_unauthed.py"
diff --git a/README.rst b/README.rst
index e1a2d04..902b26d 100644
--- a/README.rst
+++ b/README.rst
@@ -23,15 +23,25 @@
 Running the tests
 -----------------
 
+From the tempest directory, setup the tempest virtual environment for the
+designate tempest plugin::
+
+    $ tox -e venv-tempest -- pip3 install -e <path to designate-tempest-plugin>
+
+For example, when using a typical devstack setup::
+
+    $ cd /opt/stack/tempest
+    $ tox -e venv-tempest -- pip3 install -e /opt/stack/designate-tempest-plugin
+
 To run all tests from this plugin, install designate into your environment
 and from the tempest repo, run::
 
-    $ tox -e all-plugin -- designate
+    $ tox -e all -- designate
 
 To run a single test case, run with the test case name, for example::
 
-    $ tox -e all-plugin -- designate_tempest_plugin.tests.api.v2.test_zones.ZonesAdminTest.test_get_other_tenant_zone
+    $ tox -e all -- designate_tempest_plugin.tests.api.v2.test_zones.ZonesTest.test_create_zones
 
 To run all tempest tests including this plugin, run::
 
-    $ tox -e all-plugin
+    $ tox -e all
diff --git a/designate_tempest_plugin/tests/api/v2/test_shared_zones.py b/designate_tempest_plugin/tests/api/v2/test_shared_zones.py
index ecdb7c1..e6a5dd0 100644
--- a/designate_tempest_plugin/tests/api/v2/test_shared_zones.py
+++ b/designate_tempest_plugin/tests/api/v2/test_shared_zones.py
@@ -301,19 +301,30 @@
     @decorators.idempotent_id('2bb7bcb2-b824-11ed-9e56-201e8823901f')
     def test_create_zone_share_all_projects_header(self):
         LOG.info(
-            'Admin user creates shared zone for Alt tenant'
-            ' using "x-auth-all-projects" header')
-        all_projects_header = self.all_projects_header
+            'Admin user creates shared zone for Alt tenant '
+            'using "x-auth-all-projects" header')
+        # Scoped tokens do not have a project ID, work around that here
+        if CONF.enforce_scope.designate:
+            headers = self.all_projects_header.copy()
+            headers.update(
+                {'x-auth-sudo-project-id': self.share_zone_client.project_id})
+        else:
+            headers = self.all_projects_header
+
         shared_zone = self.adm_shr_client.create_zone_share(
             self.zone['id'], self.alt_zone_client.project_id,
-            headers=all_projects_header)[1]
+            headers=headers)[1]
         self.addCleanup(
             self.adm_shr_client.delete_zone_share, self.zone['id'],
-            shared_zone['id'], headers=all_projects_header)
+            shared_zone['id'], headers=self.all_projects_header)
         self.assertTrue(uuidutils.is_uuid_like(shared_zone['id']))
         self.assertEqual(self.zone['id'], shared_zone['zone_id'])
-        self.assertEqual(self.adm_shr_client.project_id,
-                         shared_zone['project_id'])
+        if CONF.enforce_scope.designate:
+            self.assertEqual(self.share_zone_client.project_id,
+                             shared_zone['project_id'])
+        else:
+            self.assertEqual(self.adm_shr_client.project_id,
+                             shared_zone['project_id'])
         self.assertEqual(self.alt_zone_client.project_id,
                          shared_zone['target_project_id'])
         self.assertIsNotNone(shared_zone['created_at'])
@@ -348,17 +359,25 @@
         LOG.info(
             'Admin user creates shared zone for Alt tenant'
             ' using "x-auth-all-projects" header')
-        all_projects_header = self.all_projects_header
+        # Scoped tokens do not have a project ID, work around that here
+        if CONF.enforce_scope.designate:
+            headers = self.all_projects_header.copy()
+            headers.update(
+                {'x-auth-sudo-project-id': self.share_zone_client.project_id})
+        else:
+            headers = self.all_projects_header
+
         shared_zone = self.adm_shr_client.create_zone_share(
             self.zone['id'], self.alt_zone_client.project_id,
-            headers=all_projects_header)[1]
+            headers=headers)[1]
         self.addCleanup(
             self.adm_shr_client.delete_zone_share, self.zone['id'],
-            shared_zone['id'], headers=all_projects_header)
+            shared_zone['id'], headers=self.all_projects_header)
 
         LOG.info('Admin user shows shared zone and validates its content')
         body = self.adm_shr_client.show_zone_share(
-            self.zone['id'], shared_zone['id'], headers=all_projects_header)[1]
+            self.zone['id'], shared_zone['id'],
+            headers=self.all_projects_header)[1]
         self.assertExpected(shared_zone, body, self.excluded_keys)
 
     @decorators.idempotent_id('46f7db22-b90c-11ed-b4ca-201e8823901f')
@@ -388,27 +407,34 @@
         LOG.info(
             "Admin user shares Primary's zone with Alt tenant"
             " using 'x-auth-all-projects' header")
-        all_projects_header = self.all_projects_header
+        # Scoped tokens do not have a project ID, work around that here
+        if CONF.enforce_scope.designate:
+            headers = self.all_projects_header.copy()
+            headers.update(
+                {'x-auth-sudo-project-id': self.share_zone_client.project_id})
+        else:
+            headers = self.all_projects_header
+
         shared_zone = self.adm_shr_client.create_zone_share(
             self.zone['id'], self.alt_zone_client.project_id,
-            headers=all_projects_header)[1]
+            headers=headers)[1]
         self.addCleanup(
             self.adm_shr_client.delete_zone_share, self.zone['id'],
-            shared_zone['id'], headers=all_projects_header)
+            shared_zone['id'], headers=self.all_projects_header)
 
         LOG.info(
             "Admin user shares Primary's zone with Demo tenant"
             " using 'x-auth-all-projects' header")
         shared_zone = self.adm_shr_client.create_zone_share(
             self.zone['id'], self.demo_zone_client.project_id,
-            headers=all_projects_header)[1]
+            headers=headers)[1]
         self.addCleanup(
             self.adm_shr_client.delete_zone_share, self.zone['id'],
-            shared_zone['id'], headers=all_projects_header)
+            shared_zone['id'], headers=self.all_projects_header)
 
         LOG.info('Admin user lists zone shares')
         body = self.adm_shr_client.list_zone_shares(
-            self.zone['id'], headers=all_projects_header)[1]
+            self.zone['id'], headers=self.all_projects_header)[1]
 
         self.assertEqual(2, len(body['shared_zones']))
         targets = []
diff --git a/designate_tempest_plugin/tests/scenario/v2/test_recordsets.py b/designate_tempest_plugin/tests/scenario/v2/test_recordsets.py
index a84077b..c830c25 100644
--- a/designate_tempest_plugin/tests/scenario/v2/test_recordsets.py
+++ b/designate_tempest_plugin/tests/scenario/v2/test_recordsets.py
@@ -12,12 +12,13 @@
 
 import time
 
+import ddt
 from oslo_log import log as logging
 from tempest import config
 from tempest.lib.common.utils import test_utils
 from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
-import ddt
+import testtools
 
 from designate_tempest_plugin.tests import base
 from designate_tempest_plugin.common import constants as const
@@ -124,10 +125,10 @@
                           lambda: self.recordset_client.show_recordset(
                               self.zone['id'], recordset['id']))
 
-    @decorators.attr(type='slow')
-    @decorators.idempotent_id('cbf756b0-ba64-11ec-93d4-201e8823901f')
-    @ddt.file_data("recordset_data.json")
-    def test_update_records_propagated_to_backends(self, name, type, records):
+    @testtools.skipUnless(
+        config.CONF.dns.nameservers,
+        "Config option dns.nameservers is missing or empty")
+    def _test_update_records_propagated_to_backends(self, name, type, records):
         if name:
             recordset_name = name + "." + self.zone['name']
         else:
@@ -171,3 +172,98 @@
                         ' detected on Nameserver:{} within a timeout of:{}'
                         ' seconds.'.format(
                             updated_ttl, ns, config.CONF.dns.build_timeout))
+
+    # These tests were unrolled from DDT to allow accurate tracking by
+    # idempotent_id's. The naming convention for the tests has been preserved.
+    @decorators.attr(type='slow')
+    @decorators.idempotent_id('cbf756b0-ba64-11ec-93d4-201e8823901f')
+    def test_update_records_propagated_to_backends_01_A(self):
+        self._test_update_records_propagated_to_backends(
+            "www", "A", ["192.0.2.1", "192.0.2.2", "192.0.2.3"])
+
+    @decorators.attr(type='slow')
+    @decorators.idempotent_id('258f7f57-9a74-4e72-bbfb-c709c411af14')
+    def test_update_records_propagated_to_backends_02_AAAA(self):
+        self._test_update_records_propagated_to_backends(
+            "www", "AAAA", ["2001:db8::1", "2001:db8::1", "2001:db8::"])
+
+    @decorators.attr(type='slow')
+    @decorators.idempotent_id('304adbc5-668a-457e-9496-8efd20b8ae82')
+    def test_update_records_propagated_to_backends_03_SRV_TCP(self):
+        self._test_update_records_propagated_to_backends(
+            "_sip._tcp", "SRV", ["10 60 5060 server1.example.com.",
+                                 "20 60 5060 server2.example.com.",
+                                 "20 30 5060 server3.example.com."])
+
+    @decorators.attr(type='slow')
+    @decorators.idempotent_id('bd1283b3-423c-4bb9-8c4f-a205f31f1c2d')
+    def test_update_records_propagated_to_backends_04_SRV_UDP(self):
+        self._test_update_records_propagated_to_backends(
+            "_sip._udp", "SRV", ["10 60 5060 server1.example.com.",
+                                 "10 60 5060 server2.example.com.",
+                                 "20 30 5060 server3.example.com."])
+
+    @decorators.attr(type='slow')
+    @decorators.idempotent_id('8b53ae20-d096-4651-a6cf-efd7c98ae8d1')
+    def test_update_records_propagated_to_backends_05_CNAME(self):
+        self._test_update_records_propagated_to_backends(
+            "alias-of-target", "CNAME", ["target.example.org."])
+
+    @decorators.attr(type='slow')
+    @decorators.idempotent_id('0fd0046a-ac5a-468d-94b3-8a6bde790589')
+    def test_update_records_propagated_to_backends_06_MX_at_APEX(self):
+        self._test_update_records_propagated_to_backends(
+            None, "MX", ["10 mail1.example.org.",
+                         "20 mail2.example.org."])
+
+    @decorators.attr(type='slow')
+    @decorators.idempotent_id('31176def-3f95-459d-8bdd-b9994335b2d9')
+    def test_update_records_propagated_to_backends_07_MX_under_APEX(self):
+        self._test_update_records_propagated_to_backends(
+            "under", "MX", ["10 mail.example.org."])
+
+    @decorators.attr(type='slow')
+    @decorators.idempotent_id('0009d787-c590-4149-9f30-082195326fad')
+    def test_update_records_propagated_to_backends_08_SSHFP(self):
+        self._test_update_records_propagated_to_backends(
+            "www", "SSHFP", ["2 1 123456789abcdef67890123456789abcdef67890"])
+
+    @decorators.attr(type='slow')
+    @decorators.idempotent_id('af7cec16-dfad-4071-aa05-cafa60bf12a5')
+    def test_update_records_propagated_to_backends_09_TXT(self):
+        self._test_update_records_propagated_to_backends(
+            "www", "TXT", ["\"Any Old Text Goes Here\""])
+
+    @decorators.attr(type='slow')
+    @decorators.idempotent_id('b3fd1f77-c318-4ab0-b18d-34611e51e9e4')
+    def test_update_records_propagated_to_backends_10_SPF(self):
+        self._test_update_records_propagated_to_backends(
+            "*.sub", "SPF", ["\"v=spf1; a -all\""])
+
+    @decorators.attr(type='slow')
+    @decorators.idempotent_id('c310b94b-f3a5-4d26-bab6-2529e6f29fbf')
+    def test_update_records_propagated_to_backends_11_PTR_IPV4(self):
+        self._test_update_records_propagated_to_backends(
+            "PTR_Record_IPV4", "PTR", ["34.216.184.93.in-addr.arpa."])
+
+    @decorators.attr(type='slow')
+    @decorators.idempotent_id('3e31e406-621f-4f89-b401-b6f38aa63347')
+    def test_update_records_propagated_to_backends_12_PTR_IPV6(self):
+        self._test_update_records_propagated_to_backends(
+            "PTR_Record_IPV6", "PTR",
+            ["6.4.9.1.8.c.5.2.3.9.8.1.8.4.2.0.1.0.0.0.0.2.2.0.0.0.8.2.6.0.6.2"
+             ".ip6.arpa."])
+
+    @decorators.attr(type='slow')
+    @decorators.idempotent_id('6fd96280-fb62-4eaf-81f9-609cdb7c126e')
+    def test_update_records_propagated_to_backends_13_CAA_Record(self):
+        self._test_update_records_propagated_to_backends(
+            "CAA_Record", "CAA", ["0 issue letsencrypt.org"])
+
+    @decorators.attr(type='slow')
+    @decorators.idempotent_id('45a11efe-bee3-4896-ab7c-daee1cb5eb3a')
+    def test_update_records_propagated_to_backends_14_NAPTR_Record(self):
+        self._test_update_records_propagated_to_backends(
+            "NAPTR_Record", "NAPTR",
+            ["0 0 S SIP+D2U !^.*$!sip:customer-service@example.com! "
+             "_sip._udp.example.com."])