Merge "Revert "Run test_port_security_macspoofing_port slow tests serially""
diff --git a/roles/run-tempest-26/tasks/main.yaml b/roles/run-tempest-26/tasks/main.yaml
index 7423bfb..7ad5c99 100644
--- a/roles/run-tempest-26/tasks/main.yaml
+++ b/roles/run-tempest-26/tasks/main.yaml
@@ -17,7 +17,7 @@
 
 - name: Limit max concurrency when more than 3 vcpus are available
   set_fact:
-    default_concurrency: "{{ num_cores|int // 2 }}"
+    default_concurrency: "{{ num_cores|int - 2 }}"
   when: num_cores|int > 3
 
 - name: Override target branch
diff --git a/roles/run-tempest/tasks/main.yaml b/roles/run-tempest/tasks/main.yaml
index 3fb494f..3d78557 100644
--- a/roles/run-tempest/tasks/main.yaml
+++ b/roles/run-tempest/tasks/main.yaml
@@ -17,7 +17,7 @@
 
 - name: Limit max concurrency when more than 3 vcpus are available
   set_fact:
-    default_concurrency: "{{ num_cores|int // 2 }}"
+    default_concurrency: "{{ num_cores|int - 2 }}"
   when: num_cores|int > 3
 
 - name: Override target branch
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index b1bfac7..2700cd9 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -326,18 +326,18 @@
             body['id'])
         return body
 
-    def wait_for(self, condition):
+    def wait_for(self, condition, *args):
         """Repeatedly calls condition() until a timeout."""
         start_time = int(time.time())
         while True:
             try:
-                condition()
+                condition(*args)
             except Exception:
                 pass
             else:
                 return
             if int(time.time()) - start_time >= self.build_timeout:
-                condition()
+                condition(*args)
                 return
             time.sleep(self.build_interval)
 
diff --git a/tempest/api/compute/servers/test_attach_interfaces.py b/tempest/api/compute/servers/test_attach_interfaces.py
index efecd6c..9b6bf84 100644
--- a/tempest/api/compute/servers/test_attach_interfaces.py
+++ b/tempest/api/compute/servers/test_attach_interfaces.py
@@ -295,8 +295,8 @@
     def test_reassign_port_between_servers(self):
         """Tests reassigning port between servers
 
-        1. Create a port in Neutron.
-        2. Create two servers in Nova.
+        1. Create two servers in Nova.
+        2. Create a port in Neutron.
         3. Attach the port to the first server.
         4. Detach the port from the first server.
         5. Attach the port to the second server.
@@ -304,11 +304,6 @@
         """
         network = self.get_tenant_network()
         network_id = network['id']
-        port = self.ports_client.create_port(
-            network_id=network_id,
-            name=data_utils.rand_name(self.__class__.__name__))
-        port_id = port['port']['id']
-        self.addCleanup(self.ports_client.delete_port, port_id)
 
         # NOTE(artom) We create two servers one at a time because
         # create_test_server doesn't support multiple validatable servers.
@@ -318,12 +313,21 @@
         def _create_validatable_server():
             _, servers = compute.create_test_server(
                 self.os_primary, tenant_network=network,
-                wait_until='ACTIVE', validatable=True,
+                validatable=True,
                 validation_resources=validation_resources)
             return servers[0]
 
+        # NOTE(danms): We create these with no waiters because we will wait
+        # for them to be validatable (i.e. SSHABLE) below. That way some of
+        # the server creation overlap each other and with create_port.
         servers = [_create_validatable_server(), _create_validatable_server()]
 
+        port = self.ports_client.create_port(
+            network_id=network_id,
+            name=data_utils.rand_name(self.__class__.__name__))
+        port_id = port['port']['id']
+        self.addCleanup(self.ports_client.delete_port, port_id)
+
         # add our cleanups for the servers since we bypassed the base class
         for server in servers:
             self.addCleanup(self.delete_server, server['id'])
@@ -332,7 +336,9 @@
             # NOTE(mgoddard): Get detailed server to ensure addresses are
             # present in fixed IP case.
             server = self.servers_client.show_server(server['id'])['server']
-            self._wait_for_validation(server, validation_resources)
+            compute.wait_for_ssh_or_ping(server, self.os_primary, network,
+                                         True, validation_resources,
+                                         'SSHABLE', True)
             # attach the port to the server
             iface = self.interfaces_client.create_interface(
                 server['id'], port_id=port_id)['interfaceAttachment']
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index f181a99..7afd9c2 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -207,9 +207,9 @@
             # NOTE(mriedem): tearDown requires the server to be started.
             self.client.start_server(server_id)
 
-    def _get_output(self):
+    def _get_output(self, server_id):
         output = self.client.get_console_output(
-            self.server_id, length=3)['output']
+            server_id, length=3)['output']
         self.assertTrue(output, "Console output was empty.")
         lines = len(output.split('\n'))
         self.assertEqual(lines, 3)
@@ -335,7 +335,7 @@
         # "console-log" API.
         # The detail is https://bugs.launchpad.net/nova/+bug/1251920
         self.reboot_server(self.server_id, type='HARD')
-        self.wait_for(self._get_output)
+        self.wait_for(self._get_output, self.server_id)
 
     @decorators.idempotent_id('bd61a9fd-062f-4670-972b-2d6c3e3b9e73')
     @testtools.skipUnless(CONF.compute_feature_enabled.pause,
@@ -707,6 +707,7 @@
 
         self.wait_for(_check_full_length_console_log)
 
+    @decorators.skip_because(bug='2028851')
     @decorators.idempotent_id('5b65d4e7-4ecd-437c-83c0-d6b79d927568')
     @testtools.skipUnless(CONF.compute_feature_enabled.console_output,
                           'Console output not supported.')
@@ -725,7 +726,7 @@
 
         self.client.stop_server(temp_server_id)
         waiters.wait_for_server_status(self.client, temp_server_id, 'SHUTOFF')
-        self.wait_for(self._get_output)
+        self.wait_for(self._get_output, temp_server_id)
 
     @decorators.idempotent_id('77eba8e0-036e-4635-944b-f7a8f3b78dc9')
     @testtools.skipUnless(CONF.compute_feature_enabled.shelve,
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index b4ba643..4d35bbb 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -1140,14 +1140,19 @@
                                             server=server,
                                             username=username)
 
+        # Default the directory in which to write the timestamp file to /tmp
+        # and only use the mount_path as the target directory if we mounted
+        # dev_name to mount_path.
+        target_dir = '/tmp'
         if dev_name is not None:
             ssh_client.make_fs(dev_name, fs=fs)
             ssh_client.exec_command('sudo mount /dev/%s %s' % (dev_name,
                                                                mount_path))
-        cmd_timestamp = 'sudo sh -c "date > %s/timestamp; sync"' % mount_path
+            target_dir = mount_path
+        cmd_timestamp = 'sudo sh -c "date > %s/timestamp; sync"' % target_dir
         ssh_client.exec_command(cmd_timestamp)
         timestamp = ssh_client.exec_command('sudo cat %s/timestamp'
-                                            % mount_path)
+                                            % target_dir)
         if dev_name is not None:
             ssh_client.exec_command('sudo umount %s' % mount_path)
         return timestamp
@@ -1172,10 +1177,15 @@
                                             server=server,
                                             username=username)
 
+        # Default the directory from which to read the timestamp file to /tmp
+        # and only use the mount_path as the target directory if we mounted
+        # dev_name to mount_path.
+        target_dir = '/tmp'
         if dev_name is not None:
             ssh_client.mount(dev_name, mount_path)
+            target_dir = mount_path
         timestamp = ssh_client.exec_command('sudo cat %s/timestamp'
-                                            % mount_path)
+                                            % target_dir)
         if dev_name is not None:
             ssh_client.exec_command('sudo umount %s' % mount_path)
         return timestamp
diff --git a/zuul.d/integrated-gate.yaml b/zuul.d/integrated-gate.yaml
index 0901788..8ac0b42 100644
--- a/zuul.d/integrated-gate.yaml
+++ b/zuul.d/integrated-gate.yaml
@@ -393,12 +393,24 @@
         # Keystone policies are changed to work for both system as well as
         # for project scoped, we need to keep scope check disable for
         # keystone.
-        NOVA_ENFORCE_SCOPE: true
+        # Nova and Glance have enabled the new defaults and scope by default
+        # in devstack.
         CINDER_ENFORCE_SCOPE: true
-        GLANCE_ENFORCE_SCOPE: true
         NEUTRON_ENFORCE_SCOPE: true
         PLACEMENT_ENFORCE_SCOPE: true
 
+- job:
+    name: tempest-all-rbac-old-defaults
+    parent: tempest-all
+    description: |
+      Integration test that runs all tests on RBAC old defaults.
+      devstack_localrc:
+        # NOTE(gmann): Nova and Glance have enabled the new defaults and scope
+        # by default in devstack so we need some jobs keep testing the old
+        # defaults until they are removed from service side.
+        NOVA_ENFORCE_SCOPE: false
+        GLANCE_ENFORCE_SCOPE: false
+
 - project-template:
     name: integrated-gate-networking
     description: |
diff --git a/zuul.d/project.yaml b/zuul.d/project.yaml
index 3223a1e..894e623 100644
--- a/zuul.d/project.yaml
+++ b/zuul.d/project.yaml
@@ -157,6 +157,7 @@
             irrelevant-files: *tempest-irrelevant-files
         - tempest-all:
             irrelevant-files: *tempest-irrelevant-files
+        - tempest-all-rbac-old-defaults
         - tempest-full-parallel
         - tempest-full-zed-extra-tests
         - tempest-full-yoga-extra-tests
@@ -191,6 +192,7 @@
     periodic:
       jobs:
         - tempest-all
+        - tempest-all-rbac-old-defaults
         - tempest-full-parallel
         - tempest-full-oslo-master
         - tempest-stestr-master