Merge "Choose correct microversion to check response" into mcp/epoxy
diff --git a/tempest/api/compute/admin/test_volume_swap.py b/tempest/api/compute/admin/test_volume_swap.py
index 22f773d..24b3ee4 100644
--- a/tempest/api/compute/admin/test_volume_swap.py
+++ b/tempest/api/compute/admin/test_volume_swap.py
@@ -80,6 +80,7 @@
     # to swap volumes directly; swap volume is primarily only for volume
     # live migration and retype callbacks from the volume service, and is slow
     # so it's marked as such.
+    @decorators.skip_because(bug='2112187')
     @decorators.attr(type='slow')
     @decorators.idempotent_id('1769f00d-a693-4d67-a631-6a3496773813')
     def test_volume_swap(self):
@@ -92,8 +93,8 @@
         3. Boot an instance "instance1" with non-admin.
         4. Attach "volume1" to "instance1" with non-admin.
         5. Swap volume from "volume1" to "volume2" as admin.
-        6. Check the swap volume is successful and "volume2"
-           is attached to "instance1" and "volume1" is in available state.
+        6. Check the swap volume is rejected and "volume1"
+           is attached to "instance1" and "volume2" is in available state.
         """
         # Create two volumes.
         # NOTE(gmann): Volumes are created before server creation so that
@@ -115,19 +116,19 @@
         # Attach "volume1" to server
         self.attach_volume(server, volume1)
         # Swap volume from "volume1" to "volume2"
-        self.admin_servers_client.update_attached_volume(
+        self.assertRaises(
+            lib_exc.Conflict, self.admin_servers_client.update_attached_volume,
             server['id'], volume1['id'], volumeId=volume2['id'])
-        waiters.wait_for_volume_resource_status(self.volumes_client,
-                                                volume1['id'], 'available')
-        waiters.wait_for_volume_resource_status(self.volumes_client,
-                                                volume2['id'], 'in-use')
-        self.wait_for_server_volume_swap(server['id'], volume1['id'],
-                                         volume2['id'])
-        # Verify "volume2" is attached to the server
+        # Verify "volume1" is attached to the server
         vol_attachments = self.servers_client.list_volume_attachments(
             server['id'])['volumeAttachments']
         self.assertEqual(1, len(vol_attachments))
-        self.assertIn(volume2['id'], vol_attachments[0]['volumeId'])
+        self.assertIn(volume1['id'], vol_attachments[0]['volumeId'])
+        waiters.wait_for_volume_resource_status(
+            self.volumes_client, volume1['id'], 'in-use')
+        # verify "volume2" is still available
+        waiters.wait_for_volume_resource_status(
+            self.volumes_client, volume2['id'], 'available')
 
 
 class TestMultiAttachVolumeSwap(TestVolumeSwapBase):
diff --git a/tempest/api/compute/admin/test_volumes_negative.py b/tempest/api/compute/admin/test_volumes_negative.py
index 55c842f..e3c3359 100644
--- a/tempest/api/compute/admin/test_volumes_negative.py
+++ b/tempest/api/compute/admin/test_volumes_negative.py
@@ -51,6 +51,7 @@
                           self.server['id'], nonexistent_volume,
                           volumeId=volume['id'])
 
+    @decorators.skip_because(bug='2112187')
     @decorators.related_bug('1629110', status_code=400)
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7dcac15a-b107-46d3-a5f6-cb863f4e454a')
@@ -71,7 +72,7 @@
         self.attach_volume(self.server, volume)
 
         nonexistent_volume = data_utils.rand_uuid()
-        self.assertRaises(lib_exc.BadRequest,
+        self.assertRaises(lib_exc.Conflict,
                           self.admin_servers_client.update_attached_volume,
                           self.server['id'], volume['id'],
                           volumeId=nonexistent_volume)
@@ -104,6 +105,7 @@
     @decorators.attr(type=['negative'])
     @decorators.idempotent_id('7576d497-b7c6-44bd-9cc5-c5b4e50fec71')
     @utils.services('volume')
+    @decorators.skip_because(bug='2112187')
     def test_multiattach_rw_volume_update_failure(self):
         """Test swapping volume attached to multi-servers with read-write mode
 
diff --git a/tempest/api/compute/servers/test_server_rescue.py b/tempest/api/compute/servers/test_server_rescue.py
index d6c0324..b8a499c 100644
--- a/tempest/api/compute/servers/test_server_rescue.py
+++ b/tempest/api/compute/servers/test_server_rescue.py
@@ -123,6 +123,9 @@
         if not CONF.compute_feature_enabled.stable_rescue:
             msg = "Stable rescue not available."
             raise cls.skipException(msg)
+        if CONF.compute_feature_enabled.barbican_integration_enabled:
+            msg = "Rescue not supported with barbican integration."
+            raise cls.skipException(msg)
 
     @classmethod
     def setup_credentials(cls):
diff --git a/tempest/api/image/v2/admin/test_images.py b/tempest/api/image/v2/admin/test_images.py
index 2c2e9a8..b380f11 100644
--- a/tempest/api/image/v2/admin/test_images.py
+++ b/tempest/api/image/v2/admin/test_images.py
@@ -105,7 +105,7 @@
         # NOTE(gmann): Skip if copy-image import method and multistore
         # are not available.
         if ('copy-image' not in available_import_methods or
-            not available_stores):
+            len(available_stores) < 2):
             raise self.skipException('Either copy-image import method or '
                                      'multistore is not available')
         uuid = data_utils.rand_uuid()
diff --git a/tempest/config.py b/tempest/config.py
index 9196a27..2e51eb3 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -303,6 +303,15 @@
                help="Valid secondary image reference to be used in tests. "
                     "This is a required option, but if only one image is "
                     "available duplicate the value of image_ref above"),
+    cfg.StrOpt('image_full_ref',
+               help="This is image with full OS like ubuntu/centos used"
+                    "in some tests. When not set related tests will be "
+                    "skipped"),
+    cfg.StrOpt('image_full_username',
+               default="ubuntu",
+               help="Username for image_full_ref authentication."),
+    cfg.StrOpt('image_full_flavor_ref',
+               help="Flavor to boot image_full_ref."),
     cfg.StrOpt('certified_image_ref',
                help="Valid image reference to be used in image certificate "
                     "validation tests when enabled. This image must also "
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index fb68e46..23e5ae6 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -239,6 +239,26 @@
                 network=self.new_net,
                 gateway_ip=None)
 
+    def _assign_nic_ip_address_by_port(self, ssh_client, port, device):
+        ip_output = ssh_client.exec_command('ip a')
+        ip_address = port['fixed_ips'][0]['ip_address']
+        ip_mask = CONF.network.project_network_mask_bits
+        # check if the address is not already in use, if not, set it
+        if ' ' + ip_address + '/' + str(ip_mask) not in ip_output:
+            try:
+                ssh_client.exec_command("sudo ip addr add %s/%s dev %s" % (
+                                        ip_address, ip_mask, device))
+                ssh_client.exec_command("sudo ip link set %s up" % device)
+            except exceptions.SSHExecCommandFailed as exc:
+                if 'RTNETLINK answers: File exists' in str(exc):
+                    LOG.debug(
+                        'IP address %(ip_address)s is already set in device '
+                        '%(device)s\nPrevious "ip a" output: %(ip_output)s',
+                        {'ip_address': ip_address, 'device': device,
+                         'ip_output': ip_output})
+                else:
+                    raise exc
+
     def _hotplug_server(self):
         old_floating_ip, server = self.floating_ip_tuple
         ip_address = old_floating_ip['floating_ip_address']
@@ -292,24 +312,7 @@
                                               % CONF.network.build_timeout)
 
         _, new_nic = self.diff_list[0]
-        ip_output = ssh_client.exec_command('ip a')
-        ip_address = new_port['fixed_ips'][0]['ip_address']
-        ip_mask = CONF.network.project_network_mask_bits
-        # check if the address is not already in use, if not, set it
-        if ' ' + ip_address + '/' + str(ip_mask) not in ip_output:
-            try:
-                ssh_client.exec_command("sudo ip addr add %s/%s dev %s" % (
-                                        ip_address, ip_mask, new_nic))
-                ssh_client.exec_command("sudo ip link set %s up" % new_nic)
-            except exceptions.SSHExecCommandFailed as exc:
-                if 'RTNETLINK answers: File exists' in str(exc):
-                    LOG.debug(
-                        'IP address %(ip_address)s is already set in device '
-                        '%(device)s\nPrevious "ip a" output: %(ip_output)s',
-                        {'ip_address': ip_address, 'device': new_nic,
-                         'ip_output': ip_output})
-                else:
-                    raise exc
+        self._assign_nic_ip_address_by_port(ssh_client, new_port, new_nic)
 
     def _get_server_nics(self, ssh_client):
         reg = re.compile(r'(?P<num>\d+): (?P<nic_name>\w+)[@]?.*:')
@@ -911,6 +914,7 @@
             ).format(ip_address=ip_address, nic=spoof_nic)
 
         ssh_client.exec_command(cmd)
+        self._assign_nic_ip_address_by_port(ssh_client, spoof_port, spoof_nic)
 
         new_mac = ssh_client.get_mac_address(nic=spoof_nic)
         self.assertEqual(spoof_mac, new_mac)
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index d04cb9a..db8f533 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -41,6 +41,11 @@
         super(TestSnapshotPattern, cls).skip_checks()
         if not CONF.compute_feature_enabled.snapshot:
             raise cls.skipException("Snapshotting is not available.")
+        if not all([CONF.compute.image_full_ref,
+                    CONF.compute.image_full_username,
+                    CONF.compute.image_full_flavor_ref]):
+            raise cls.skipException(
+                "Test requires image_full_* options to be set.")
 
     @decorators.idempotent_id('608e604b-1d63-4a82-8e3e-91bc665c90b4')
     @decorators.attr(type='slow')
@@ -51,16 +56,20 @@
         # prepare for booting an instance
         keypair = self.create_keypair()
         security_group = self.create_security_group()
+        username = CONF.compute.image_full_username
 
         # boot an instance and create a timestamp file in it
         server = self.create_server(
             key_name=keypair['name'],
-            security_groups=[{'name': security_group['name']}])
+            security_groups=[{'name': security_group['name']}],
+            flavor=CONF.compute.image_full_flavor_ref,
+            image_id=CONF.compute.image_full_ref)
 
         instance_ip = self.get_server_ip(server)
         timestamp = self.create_timestamp(instance_ip,
                                           private_key=keypair['private_key'],
-                                          server=server)
+                                          server=server,
+                                          username=username)
 
         # snapshot the instance
         snapshot_image = self.create_server_snapshot(server=server)
@@ -74,13 +83,15 @@
         server_from_snapshot = self.create_server(
             image_id=snapshot_image['id'],
             key_name=keypair['name'],
-            security_groups=[{'name': security_group['name']}])
+            security_groups=[{'name': security_group['name']}],
+            flavor=CONF.compute.image_full_flavor_ref)
 
         # check the existence of the timestamp file in the second instance
         server_from_snapshot_ip = self.get_server_ip(server_from_snapshot)
         timestamp2 = self.get_timestamp(server_from_snapshot_ip,
                                         private_key=keypair['private_key'],
-                                        server=server_from_snapshot)
+                                        server=server_from_snapshot,
+                                        username=username)
         self.assertEqual(timestamp, timestamp2)
 
         # snapshot the instance again