Merge "Moves an incorrectly marked negative test"
diff --git a/requirements.txt b/requirements.txt
index ddd2a6b..c0a9254 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -22,6 +22,6 @@
 iso8601>=0.1.9
 fixtures>=1.3.1
 testscenarios>=0.4
-tempest-lib>=0.9.0
+tempest-lib>=0.10.0
 PyYAML>=3.1.0
 stevedore>=1.5.0 # Apache-2.0
diff --git a/tempest/api/baremetal/admin/test_ports.py b/tempest/api/baremetal/admin/test_ports.py
index 5eaf641..180b848 100644
--- a/tempest/api/baremetal/admin/test_ports.py
+++ b/tempest/api/baremetal/admin/test_ports.py
@@ -11,7 +11,6 @@
 #    under the License.
 
 import six
-from tempest_lib import decorators
 from tempest_lib import exceptions as lib_exc
 
 from tempest.api.baremetal.admin import base
@@ -60,7 +59,6 @@
         _, body = self.client.show_port(uuid)
         self._assertExpected(port, body)
 
-    @decorators.skip_because(bug='1398350')
     @test.idempotent_id('4a02c4b0-6573-42a4-a513-2e36ad485b62')
     def test_create_port_with_extra(self):
         node_id = self.node['uuid']
@@ -237,7 +235,6 @@
         _, body = self.client.show_port(port['uuid'])
         self.assertEqual(extra, body['extra'])
 
-    @decorators.skip_because(bug='1398350')
     @test.idempotent_id('5309e897-0799-4649-a982-0179b04c3876')
     def test_update_port_mixed_ops(self):
         node_id = self.node['uuid']
diff --git a/tempest/api/compute/certificates/test_certificates.py b/tempest/api/compute/certificates/test_certificates.py
index 78a0a93..0096fc2 100644
--- a/tempest/api/compute/certificates/test_certificates.py
+++ b/tempest/api/compute/certificates/test_certificates.py
@@ -14,13 +14,22 @@
 #    under the License.
 
 from tempest.api.compute import base
+from tempest import config
 from tempest import test
 
+CONF = config.CONF
+
 
 class CertificatesV2TestJSON(base.BaseComputeTest):
 
     _api_version = 2
 
+    @classmethod
+    def skip_checks(cls):
+        super(CertificatesV2TestJSON, cls).skip_checks()
+        if not CONF.compute_feature_enabled.nova_cert:
+            raise cls.skipException("Nova cert is not available")
+
     @test.idempotent_id('c070a441-b08e-447e-a733-905909535b1b')
     def test_create_root_certificate(self):
         # create certificates
diff --git a/tempest/common/credentials.py b/tempest/common/credentials.py
index 691bd34..28e95e9 100644
--- a/tempest/common/credentials.py
+++ b/tempest/common/credentials.py
@@ -13,9 +13,9 @@
 
 import os
 
-from tempest.common import accounts
 from tempest.common import cred_provider
 from tempest.common import dynamic_creds
+from tempest.common import preprov_creds
 from tempest import config
 from tempest import exceptions
 
@@ -41,10 +41,10 @@
         if (CONF.auth.test_accounts_file and
                 os.path.isfile(CONF.auth.test_accounts_file)):
             # Most params are not relevant for pre-created accounts
-            return accounts.Accounts(name=name,
-                                     identity_version=identity_version)
+            return preprov_creds.PreProvisionedCredentialProvider(
+                name=name, identity_version=identity_version)
         else:
-            return accounts.NotLockingAccounts(
+            return preprov_creds.NonLockingCredentialProvider(
                 name=name, identity_version=identity_version)
 
 
@@ -59,7 +59,8 @@
     # Check whether test accounts file has the admin specified or not
     elif (CONF.auth.test_accounts_file and
             os.path.isfile(CONF.auth.test_accounts_file)):
-        check_accounts = accounts.Accounts(name='check_admin')
+        check_accounts = preprov_creds.PreProvisionedCredentialProvider(
+            name='check_admin')
         if not check_accounts.admin_available():
             is_admin = False
     else:
@@ -81,9 +82,11 @@
     # Check whether test accounts file has the admin specified or not
     if (CONF.auth.test_accounts_file and
             os.path.isfile(CONF.auth.test_accounts_file)):
-        check_accounts = accounts.Accounts(name='check_alt')
+        check_accounts = preprov_creds.PreProvisionedCredentialProvider(
+            name='check_alt')
     else:
-        check_accounts = accounts.NotLockingAccounts(name='check_alt')
+        check_accounts = preprov_creds.NonLockingCredentialProvider(
+            name='check_alt')
     try:
         if not check_accounts.is_multi_user():
             return False
diff --git a/tempest/common/accounts.py b/tempest/common/preprov_creds.py
similarity index 97%
rename from tempest/common/accounts.py
rename to tempest/common/preprov_creds.py
index d843fea..eac7f4e 100644
--- a/tempest/common/accounts.py
+++ b/tempest/common/preprov_creds.py
@@ -36,11 +36,11 @@
     return accounts
 
 
-class Accounts(cred_provider.CredentialProvider):
+class PreProvisionedCredentialProvider(cred_provider.CredentialProvider):
 
     def __init__(self, identity_version=None, name=None):
-        super(Accounts, self).__init__(identity_version=identity_version,
-                                       name=name)
+        super(PreProvisionedCredentialProvider, self).__init__(
+            identity_version=identity_version, name=name)
         if (CONF.auth.test_accounts_file and
                 os.path.isfile(CONF.auth.test_accounts_file)):
             accounts = read_accounts_yaml(CONF.auth.test_accounts_file)
@@ -249,7 +249,7 @@
             'utf-8'), None)
         # The force kwarg is used to allocate an additional set of creds with
         # the same role list. The index used for the previously allocation
-        # in the preprov_creds dict will be moved.
+        # in the _creds dict will be moved.
         if exist_creds and not force_new:
             return exist_creds
         elif exist_creds and force_new:
@@ -295,7 +295,7 @@
         return net_creds
 
 
-class NotLockingAccounts(Accounts):
+class NonLockingCredentialProvider(PreProvisionedCredentialProvider):
     """Credentials provider which always returns the first and second
     configured accounts as primary and alt users.
     This credential provider can be used in case of serial test execution
diff --git a/tempest/config.py b/tempest/config.py
index 3c25e1f..d91fb04 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -422,6 +422,9 @@
     cfg.BoolOpt('ec2_api',
                 default=True,
                 help='Does the test environment have the ec2 api running?'),
+    cfg.BoolOpt('nova_cert',
+                default=True,
+                help='Does the test environment have the nova cert running?'),
     # TODO(mriedem): Remove preserve_ports once juno-eol happens.
     cfg.BoolOpt('preserve_ports',
                 default=False,
diff --git a/tempest/manager.py b/tempest/manager.py
index c39d3e5..6a003bc 100644
--- a/tempest/manager.py
+++ b/tempest/manager.py
@@ -47,8 +47,8 @@
         # Check if passed or default credentials are valid
         if not self.credentials.is_valid():
             raise exceptions.InvalidCredentials()
-        # Tenant isolation creates TestResources, but Accounts and some tests
-        # creates Credentials
+        # Tenant isolation creates TestResources, but
+        # PreProvisionedCredentialProvider and some tests create Credentials
         if isinstance(credentials, cred_provider.TestResources):
             creds = self.credentials.credentials
         else:
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index a9394cb..3df92cf 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -143,8 +143,9 @@
                  self._list_ports(device_id=sid,
                                   network_id=self.network_v6.id)]
         self.assertEqual(1, len(ports),
-                         message="Multiple IPv6 ports found on network %s"
-                         % self.network_v6)
+                         message=("Multiple IPv6 ports found on network %s. "
+                                  "ports: %s")
+                         % (self.network_v6, ports))
         mac6 = ports[0]
         ssh.turn_nic_on(ssh.get_nic_name(mac6))
 
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index ba419a6..d4bddc0 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -96,14 +96,6 @@
         vol_name = data_utils.rand_name('volume')
         return self.create_volume(name=vol_name, snapshot_id=snap_id)
 
-    def _stop_instances(self, instances):
-        # NOTE(gfidente): two loops so we do not wait for the status twice
-        for i in instances:
-            self.servers_client.stop_server(i['id'])
-        for i in instances:
-            waiters.wait_for_server_status(self.servers_client,
-                                           i['id'], 'SHUTOFF')
-
     def _ssh_to_server(self, server, keypair):
         if CONF.compute.use_floatingip_for_ssh:
             ip = self.create_floating_ip(server)['ip']
@@ -172,10 +164,6 @@
         ssh_client = self._ssh_to_server(instance_from_snapshot, keypair)
         self._check_content_of_written_file(ssh_client, text)
 
-        # NOTE(gfidente): ensure resources are in clean state for
-        # deletion operations to succeed
-        self._stop_instances([instance_2nd, instance_from_snapshot])
-
     @decorators.skip_because(bug='1489581')
     @test.idempotent_id('36c34c67-7b54-4b59-b188-02a2f458a63b')
     @test.services('compute', 'volume', 'image')
diff --git a/tempest/services/compute/json/fixed_ips_client.py b/tempest/services/compute/json/fixed_ips_client.py
index d826655..7b374aa 100644
--- a/tempest/services/compute/json/fixed_ips_client.py
+++ b/tempest/services/compute/json/fixed_ips_client.py
@@ -33,4 +33,4 @@
         url = "os-fixed-ips/%s/action" % fixed_ip
         resp, body = self.post(url, json.dumps(kwargs))
         self.validate_response(schema.reserve_unreserve_fixed_ip, resp, body)
-        return service_client.ResponseBody(resp)
+        return service_client.ResponseBody(resp, body)
diff --git a/tempest/test_discover/plugins.py b/tempest/test_discover/plugins.py
index 640b004..58a9905 100644
--- a/tempest/test_discover/plugins.py
+++ b/tempest/test_discover/plugins.py
@@ -88,7 +88,11 @@
 
     def register_plugin_opts(self, conf):
         for plug in self.ext_plugins:
-            plug.obj.register_opts(conf)
+            try:
+                plug.obj.register_opts(conf)
+            except Exception:
+                LOG.exception('Plugin %s raised an exception trying to run '
+                              'register_opts' % plug.name)
 
     def get_plugin_options_list(self):
         plugin_options = []
diff --git a/tempest/tests/common/test_admin_available.py b/tempest/tests/common/test_admin_available.py
index cd02597..8490c4d 100644
--- a/tempest/tests/common/test_admin_available.py
+++ b/tempest/tests/common/test_admin_available.py
@@ -50,7 +50,7 @@
                                  'password': 'p',
                                  'types': ['admin']})
             self.useFixture(mockpatch.Patch(
-                'tempest.common.accounts.read_accounts_yaml',
+                'tempest.common.preprov_creds.read_accounts_yaml',
                 return_value=accounts))
             cfg.CONF.set_default('test_accounts_file',
                                  use_accounts_file, group='auth')
diff --git a/tempest/tests/common/test_accounts.py b/tempest/tests/common/test_preprov_creds.py
similarity index 82%
rename from tempest/tests/common/test_accounts.py
rename to tempest/tests/common/test_preprov_creds.py
index 9bf8059..cb7240b 100644
--- a/tempest/tests/common/test_accounts.py
+++ b/tempest/tests/common/test_preprov_creds.py
@@ -24,8 +24,8 @@
 from tempest_lib import auth
 from tempest_lib.services.identity.v2 import token_client
 
-from tempest.common import accounts
 from tempest.common import cred_provider
+from tempest.common import preprov_creds
 from tempest import config
 from tempest import exceptions
 from tempest.tests import base
@@ -34,10 +34,10 @@
 from tempest.tests import fake_identity
 
 
-class TestAccount(base.TestCase):
+class TestPreProvisionedCredentials(base.TestCase):
 
     def setUp(self):
-        super(TestAccount, self).setUp()
+        super(TestPreProvisionedCredentials, self).setUp()
         self.useFixture(fake_config.ConfigFixture())
         self.stubs.Set(config, 'TempestConfigPrivate', fake_config.FakePrivate)
         self.fake_http = fake_http.fake_httplib2(return_type=200)
@@ -71,7 +71,7 @@
              'password': 'p', 'roles': [cfg.CONF.identity.admin_role]},
         ]
         self.accounts_mock = self.useFixture(mockpatch.Patch(
-            'tempest.common.accounts.read_accounts_yaml',
+            'tempest.common.preprov_creds.read_accounts_yaml',
             return_value=self.test_accounts))
         cfg.CONF.set_default('test_accounts_file', 'fake_path', group='auth')
         self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
@@ -88,7 +88,8 @@
     def test_get_hash(self):
         self.stubs.Set(token_client.TokenClient, 'raw_request',
                        fake_identity._fake_v2_response)
-        test_account_class = accounts.Accounts('v2', 'test_name')
+        test_account_class = preprov_creds.PreProvisionedCredentialProvider(
+            'v2', 'test_name')
         hash_list = self._get_hash_list(self.test_accounts)
         test_cred_dict = self.test_accounts[3]
         test_creds = auth.get_credentials(fake_identity.FAKE_AUTH_URL,
@@ -97,7 +98,8 @@
         self.assertEqual(hash_list[3], results)
 
     def test_get_hash_dict(self):
-        test_account_class = accounts.Accounts('v2', 'test_name')
+        test_account_class = preprov_creds.PreProvisionedCredentialProvider(
+            'v2', 'test_name')
         hash_dict = test_account_class.get_hash_dict(self.test_accounts)
         hash_list = self._get_hash_list(self.test_accounts)
         for hash in hash_list:
@@ -109,7 +111,9 @@
         self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
         with mock.patch('six.moves.builtins.open', mock.mock_open(),
                         create=True):
-            test_account_class = accounts.Accounts('v2', 'test_name')
+            test_account_class = (
+                preprov_creds.PreProvisionedCredentialProvider(
+                    'v2', 'test_name'))
             res = test_account_class._create_hash_file('12345')
         self.assertFalse(res, "_create_hash_file should return False if the "
                          "pseudo-lock file already exists")
@@ -119,7 +123,9 @@
         self.useFixture(mockpatch.Patch('os.path.isfile', return_value=False))
         with mock.patch('six.moves.builtins.open', mock.mock_open(),
                         create=True):
-            test_account_class = accounts.Accounts('v2', 'test_name')
+            test_account_class = (
+                preprov_creds.PreProvisionedCredentialProvider(
+                    'v2', 'test_name'))
             res = test_account_class._create_hash_file('12345')
         self.assertTrue(res, "_create_hash_file should return True if the "
                         "pseudo-lock doesn't already exist")
@@ -131,16 +137,16 @@
         hash_list = self._get_hash_list(self.test_accounts)
         mkdir_mock = self.useFixture(mockpatch.Patch('os.mkdir'))
         self.useFixture(mockpatch.Patch('os.path.isfile', return_value=False))
-        test_account_class = accounts.Accounts('v2', 'test_name')
+        test_account_class = preprov_creds.PreProvisionedCredentialProvider(
+            'v2', 'test_name')
         with mock.patch('six.moves.builtins.open', mock.mock_open(),
                         create=True) as open_mock:
             test_account_class._get_free_hash(hash_list)
-            lock_path = os.path.join(lockutils.get_lock_path(accounts.CONF),
-                                     'test_accounts',
-                                     hash_list[0])
+            lock_path = os.path.join(lockutils.get_lock_path(
+                preprov_creds.CONF), 'test_accounts', hash_list[0])
             open_mock.assert_called_once_with(lock_path, 'w')
-        mkdir_path = os.path.join(accounts.CONF.oslo_concurrency.lock_path,
-                                  'test_accounts')
+        mkdir_path = os.path.join(
+            preprov_creds.CONF.oslo_concurrency.lock_path, 'test_accounts')
         mkdir_mock.mock.assert_called_once_with(mkdir_path)
 
     @mock.patch('oslo_concurrency.lockutils.lock')
@@ -150,7 +156,8 @@
         self.useFixture(mockpatch.Patch('os.path.isdir', return_value=True))
         # Emulate all lcoks in list are in use
         self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
-        test_account_class = accounts.Accounts('v2', 'test_name')
+        test_account_class = preprov_creds.PreProvisionedCredentialProvider(
+            'v2', 'test_name')
         with mock.patch('six.moves.builtins.open', mock.mock_open(),
                         create=True):
             self.assertRaises(exceptions.InvalidConfiguration,
@@ -161,7 +168,8 @@
         # Emulate no pre-existing lock
         self.useFixture(mockpatch.Patch('os.path.isdir', return_value=True))
         hash_list = self._get_hash_list(self.test_accounts)
-        test_account_class = accounts.Accounts('v2', 'test_name')
+        test_account_class = preprov_creds.PreProvisionedCredentialProvider(
+            'v2', 'test_name')
 
         def _fake_is_file(path):
             # Fake isfile() to return that the path exists unless a specific
@@ -174,9 +182,9 @@
         with mock.patch('six.moves.builtins.open', mock.mock_open(),
                         create=True) as open_mock:
             test_account_class._get_free_hash(hash_list)
-            lock_path = os.path.join(lockutils.get_lock_path(accounts.CONF),
-                                     'test_accounts',
-                                     hash_list[3])
+            lock_path = os.path.join(
+                lockutils.get_lock_path(preprov_creds.CONF),
+                'test_accounts', hash_list[3])
             open_mock.assert_has_calls([mock.call(lock_path, 'w')])
 
     @mock.patch('oslo_concurrency.lockutils.lock')
@@ -186,14 +194,15 @@
         self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
         # Pretend the lock dir is empty
         self.useFixture(mockpatch.Patch('os.listdir', return_value=[]))
-        test_account_class = accounts.Accounts('v2', 'test_name')
+        test_account_class = preprov_creds.PreProvisionedCredentialProvider(
+            'v2', 'test_name')
         remove_mock = self.useFixture(mockpatch.Patch('os.remove'))
         rmdir_mock = self.useFixture(mockpatch.Patch('os.rmdir'))
         test_account_class.remove_hash(hash_list[2])
-        hash_path = os.path.join(lockutils.get_lock_path(accounts.CONF),
+        hash_path = os.path.join(lockutils.get_lock_path(preprov_creds.CONF),
                                  'test_accounts',
                                  hash_list[2])
-        lock_path = os.path.join(accounts.CONF.oslo_concurrency.lock_path,
+        lock_path = os.path.join(preprov_creds.CONF.oslo_concurrency.lock_path,
                                  'test_accounts')
         remove_mock.mock.assert_called_once_with(hash_path)
         rmdir_mock.mock.assert_called_once_with(lock_path)
@@ -206,33 +215,37 @@
         # Pretend the lock dir is empty
         self.useFixture(mockpatch.Patch('os.listdir', return_value=[
             hash_list[1], hash_list[4]]))
-        test_account_class = accounts.Accounts('v2', 'test_name')
+        test_account_class = preprov_creds.PreProvisionedCredentialProvider(
+            'v2', 'test_name')
         remove_mock = self.useFixture(mockpatch.Patch('os.remove'))
         rmdir_mock = self.useFixture(mockpatch.Patch('os.rmdir'))
         test_account_class.remove_hash(hash_list[2])
-        hash_path = os.path.join(lockutils.get_lock_path(accounts.CONF),
+        hash_path = os.path.join(lockutils.get_lock_path(preprov_creds.CONF),
                                  'test_accounts',
                                  hash_list[2])
         remove_mock.mock.assert_called_once_with(hash_path)
         rmdir_mock.mock.assert_not_called()
 
     def test_is_multi_user(self):
-        test_accounts_class = accounts.Accounts('v2', 'test_name')
+        test_accounts_class = preprov_creds.PreProvisionedCredentialProvider(
+            'v2', 'test_name')
         self.assertTrue(test_accounts_class.is_multi_user())
 
     def test_is_not_multi_user(self):
         self.test_accounts = [self.test_accounts[0]]
         self.useFixture(mockpatch.Patch(
-            'tempest.common.accounts.read_accounts_yaml',
+            'tempest.common.preprov_creds.read_accounts_yaml',
             return_value=self.test_accounts))
-        test_accounts_class = accounts.Accounts('v2', 'test_name')
+        test_accounts_class = preprov_creds.PreProvisionedCredentialProvider(
+            'v2', 'test_name')
         self.assertFalse(test_accounts_class.is_multi_user())
 
     def test__get_creds_by_roles_one_role(self):
         self.useFixture(mockpatch.Patch(
-            'tempest.common.accounts.read_accounts_yaml',
+            'tempest.common.preprov_creds.read_accounts_yaml',
             return_value=self.test_accounts))
-        test_accounts_class = accounts.Accounts('v2', 'test_name')
+        test_accounts_class = preprov_creds.PreProvisionedCredentialProvider(
+            'v2', 'test_name')
         hashes = test_accounts_class.hash_dict['roles']['role4']
         temp_hash = hashes[0]
         get_free_hash_mock = self.useFixture(mockpatch.PatchObject(
@@ -247,9 +260,10 @@
 
     def test__get_creds_by_roles_list_role(self):
         self.useFixture(mockpatch.Patch(
-            'tempest.common.accounts.read_accounts_yaml',
+            'tempest.common.preprov_creds.read_accounts_yaml',
             return_value=self.test_accounts))
-        test_accounts_class = accounts.Accounts('v2', 'test_name')
+        test_accounts_class = preprov_creds.PreProvisionedCredentialProvider(
+            'v2', 'test_name')
         hashes = test_accounts_class.hash_dict['roles']['role4']
         hashes2 = test_accounts_class.hash_dict['roles']['role2']
         hashes = list(set(hashes) & set(hashes2))
@@ -266,9 +280,10 @@
 
     def test__get_creds_by_roles_no_admin(self):
         self.useFixture(mockpatch.Patch(
-            'tempest.common.accounts.read_accounts_yaml',
+            'tempest.common.preprov_creds.read_accounts_yaml',
             return_value=self.test_accounts))
-        test_accounts_class = accounts.Accounts('v2', 'test_name')
+        test_accounts_class = preprov_creds.PreProvisionedCredentialProvider(
+            'v2', 'test_name')
         hashes = list(test_accounts_class.hash_dict['creds'].keys())
         admin_hashes = test_accounts_class.hash_dict['roles'][
             cfg.CONF.identity.admin_role]
@@ -292,9 +307,10 @@
              'password': 'p', 'roles': ['role-7', 'role-11'],
              'resources': {'network': 'network-2'}}]
         self.useFixture(mockpatch.Patch(
-            'tempest.common.accounts.read_accounts_yaml',
+            'tempest.common.preprov_creds.read_accounts_yaml',
             return_value=test_accounts))
-        test_accounts_class = accounts.Accounts('v2', 'test_name')
+        test_accounts_class = preprov_creds.PreProvisionedCredentialProvider(
+            'v2', 'test_name')
         with mock.patch('tempest.services.compute.json.networks_client.'
                         'NetworksClient.list_networks',
                         return_value={'networks': [{'name': 'network-2',
@@ -326,13 +342,14 @@
              'password': 'p'},
         ]
         self.useFixture(mockpatch.Patch(
-            'tempest.common.accounts.read_accounts_yaml',
+            'tempest.common.preprov_creds.read_accounts_yaml',
             return_value=self.test_accounts))
         cfg.CONF.set_default('test_accounts_file', '', group='auth')
         self.useFixture(mockpatch.Patch('os.path.isfile', return_value=True))
 
     def test_get_creds_roles_nonlocking_invalid(self):
-        test_accounts_class = accounts.NotLockingAccounts('v2', 'test_name')
+        test_accounts_class = preprov_creds.NonLockingCredentialProvider(
+            'v2', 'test_name')
         self.assertRaises(exceptions.InvalidConfiguration,
                           test_accounts_class.get_creds_by_roles,
                           ['fake_role'])
diff --git a/tempest/tests/services/compute/test_fixedIPs_client.py b/tempest/tests/services/compute/test_fixedIPs_client.py
index 5acb422..b537baa 100644
--- a/tempest/tests/services/compute/test_fixedIPs_client.py
+++ b/tempest/tests/services/compute/test_fixedIPs_client.py
@@ -44,3 +44,16 @@
 
     def test_show_fixed_ip_with_bytes_body(self):
         self._test_show_fixed_ip(True)
+
+    def _test_reserve_fixed_ip(self, bytes_body=False):
+        self.check_service_client_function(
+            self.fixedIPsClient.reserve_fixed_ip,
+            'tempest.common.service_client.ServiceClient.post',
+            {}, bytes_body,
+            status=202, fixed_ip='Identifier')
+
+    def test_reserve_fixed_ip_with_str_body(self):
+        self._test_reserve_fixed_ip()
+
+    def test_reserve_fixed_ip_with_bytes_body(self):
+        self._test_reserve_fixed_ip(True)