Merge "Improve router deletion logging in tempest cleanup"
diff --git a/.zuul.yaml b/.zuul.yaml
index bee60bf..7d77b71 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -297,6 +297,16 @@
         c-bak: false
 
 - job:
+    name: tempest-full-stein
+    parent: tempest-full
+    override-checkout: stable/stein
+
+- job:
+    name: tempest-full-stein-py3
+    parent: tempest-full-py3
+    override-checkout: stable/stein
+
+- job:
     name: tempest-full-rocky
     parent: tempest-full
     nodeset: openstack-single-node-xenial
@@ -514,6 +524,10 @@
         - tempest-full-py3-ipv6:
             voting: false
             irrelevant-files: *tempest-irrelevant-files
+        - tempest-full-stein:
+            irrelevant-files: *tempest-irrelevant-files
+        - tempest-full-stein-py3:
+            irrelevant-files: *tempest-irrelevant-files
         - tempest-full-rocky:
             irrelevant-files: *tempest-irrelevant-files
         - tempest-full-rocky-py3:
@@ -615,6 +629,8 @@
             irrelevant-files: *tempest-irrelevant-files
     periodic-stable:
       jobs:
+        - tempest-full-stein
+        - tempest-full-stein-py3
         - tempest-full-rocky
         - tempest-full-rocky-py3
         - tempest-full-queens
diff --git a/HACKING.rst b/HACKING.rst
index eb6551a..1559fc6 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -28,6 +28,8 @@
 - [T117] Check negative tests have ``@decorators.attr(type=['negative'])``
   applied.
 
+It is recommended to use ``tox -eautopep8`` before submitting a patch.
+
 Test Data/Configuration
 -----------------------
 - Assume nothing about existing test data
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index f3d7476..93bd817 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -288,6 +288,17 @@
         self.assertEqual('in-use', vol_after_rebuild['status'])
         self.assertEqual(self.server_id,
                          vol_after_rebuild['attachments'][0]['server_id'])
+        if CONF.validation.run_validation:
+            validation_resources = self.get_class_validation_resources(
+                self.os_primary)
+            linux_client = remote_client.RemoteClient(
+                self.get_server_ip(server, validation_resources),
+                self.ssh_user,
+                password=None,
+                pkey=validation_resources['keypair']['private_key'],
+                server=server,
+                servers_client=self.client)
+            linux_client.validate_authentication()
 
     def _test_resize_server_confirm(self, server_id, stop=False):
         # The server's RAM and disk space should be modified to that of
diff --git a/tempest/api/compute/volumes/test_attach_volume.py b/tempest/api/compute/volumes/test_attach_volume.py
index 8bb4eaa..f83e62c 100644
--- a/tempest/api/compute/volumes/test_attach_volume.py
+++ b/tempest/api/compute/volumes/test_attach_volume.py
@@ -126,7 +126,7 @@
     @decorators.idempotent_id('7fa563fe-f0f7-43eb-9e22-a1ece036b513')
     def test_list_get_volume_attachments(self):
         # List volume attachment of the server
-        server, _ = self._create_server()
+        server, validation_resources = self._create_server()
         volume_1st = self.create_volume()
         attachment_1st = self.attach_volume(server, volume_1st)
         body = self.servers_client.list_volume_attachments(
@@ -149,6 +149,16 @@
             server['id'])['volumeAttachments']
         self.assertEqual(2, len(body))
 
+        if CONF.validation.run_validation:
+            linux_client = remote_client.RemoteClient(
+                self.get_server_ip(server, validation_resources),
+                self.image_ssh_user,
+                self.image_ssh_password,
+                validation_resources['keypair']['private_key'],
+                server=server,
+                servers_client=self.servers_client)
+            linux_client.validate_authentication()
+
         for attachment in [attachment_1st, attachment_2nd]:
             body = self.servers_client.show_volume_attachment(
                 server['id'], attachment['id'])['volumeAttachment']
diff --git a/tempest/clients.py b/tempest/clients.py
index e5d5be1..0506646 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -44,6 +44,7 @@
         self._set_object_storage_clients()
         self._set_image_clients()
         self._set_network_clients()
+        self.placement_client = self.placement.PlacementClient()
         # TODO(andreaf) This is maintained for backward compatibility
         # with plugins, but it should removed eventually, since it was
         # never a stable interface and it's not useful anyways
diff --git a/tempest/tests/lib/services/registry_fixture.py b/tempest/tests/lib/services/registry_fixture.py
index 1da2112..07af68a 100644
--- a/tempest/tests/lib/services/registry_fixture.py
+++ b/tempest/tests/lib/services/registry_fixture.py
@@ -37,8 +37,9 @@
     def __init__(self):
         """Initialise the registry fixture"""
         self.services = set(['compute', 'identity.v2', 'identity.v3',
-                             'image.v1', 'image.v2', 'network', 'volume.v1',
-                             'volume.v2', 'volume.v3', 'object-storage'])
+                             'image.v1', 'image.v2', 'network', 'placement',
+                             'volume.v1', 'volume.v2', 'volume.v3',
+                             'object-storage'])
 
     def _setUp(self):
         # Cleanup the registry
diff --git a/tools/format.sh b/tools/format.sh
index adffb8c..dec8f1c 100755
--- a/tools/format.sh
+++ b/tools/format.sh
@@ -1,5 +1,29 @@
 #!/bin/bash
+
 cd $(dirname "$(readlink -f "$0")")
 
-autopep8 --exit-code --max-line-length=79 --experimental --in-place -r ../tempest ../setup.py && echo Formatting was not needed. >&2
+AUTOPEP8=`which autopep8 2>/dev/null`
 
+if [[ -z "$AUTOPEP8" ]]; then
+    AUTOPEP8=`which autopep8-3`
+fi
+
+if [[ -z "$AUTOPEP8" ]]; then
+    echo "Unable to locate autopep8" >&2
+    exit 2
+fi
+
+# isort is not compatible with the default flake8 (H306), maybe flake8-isort
+# isort -rc -sl -fss ../tempest ../setup.py
+$AUTOPEP8 --exit-code --max-line-length=79 --experimental --in-place -r ../tempest ../setup.py
+ERROR=$?
+
+if [[ $ERROR -eq 0 ]]; then
+    echo "Formatting was not needed." >&2
+    exit 0
+elif [[ $ERROR -eq 1 ]]; then
+    echo "Formatting failed.." >&2
+    exit 1
+else
+    echo "done" >&2
+fi
diff --git a/tox.ini b/tox.ini
index 433f168..230249f 100644
--- a/tox.ini
+++ b/tox.ini
@@ -198,7 +198,7 @@
 
 [testenv:pep8]
 deps =
-    -r test-requirements.txt
+    -r{toxinidir}/test-requirements.txt
     autopep8
 basepython = python3
 commands =
@@ -210,7 +210,7 @@
 deps = autopep8
 basepython = python3
 commands =
-    autopep8 --max-line-length=79  --experimental --in-place -r tempest setup.py
+    {toxinidir}/tools/format.sh
 
 [testenv:uuidgen]
 commands =