Merge "Merge list_flavors_with_detail to list_flavors"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 6424f55..4a43282 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -39,8 +39,8 @@
 # Deprecated group/name - [DEFAULT]/logdir
 #log_dir = <None>
 
-# Use syslog for logging. Existing syslog format is DEPRECATED during
-# I, and changed in J to honor RFC5424. (boolean value)
+# Use syslog for logging. Existing syslog format is DEPRECATED and
+# will be changed later to honor RFC5424. (boolean value)
 #use_syslog = false
 
 # (Optional) Enables or disables syslog rfc5424 format for logging. If
@@ -254,6 +254,10 @@
 # value)
 #build_timeout = 300
 
+# Shell fragments to use before executing a command when sshing to a
+# guest. (string value)
+#ssh_shell_prologue = set -eu -o pipefail; PATH=$$PATH:/sbin;
+
 # Auth method used for authenticate to the instance. Valid choices
 # are: keypair, configured, adminpass and disabled. Keypair: start the
 # servers with a ssh keypair. Configured: use the configured user and
diff --git a/requirements.txt b/requirements.txt
index cb0031d..1d512a0 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,22 +1,22 @@
 # The order of packages is significant, because pip processes them in the order
 # of appearance. Changing the order has an impact on the overall integration
 # process, which may cause wedges in the gate later.
-pbr>=0.11,<2.0
+pbr<2.0,>=0.11
 anyjson>=0.3.3
 httplib2>=0.7.5
-jsonschema>=2.0.0,<3.0.0,!=2.5.0
-testtools>=0.9.36,!=1.2.0
+jsonschema!=2.5.0,<3.0.0,>=2.0.0
+testtools>=1.4.0
 boto>=2.32.1
 paramiko>=1.13.0
 netaddr>=0.7.12
 testrepository>=0.0.18
 pyOpenSSL>=0.11
-oslo.concurrency>=2.0.0         # Apache-2.0
-oslo.config>=1.11.0  # Apache-2.0
-oslo.i18n>=1.5.0  # Apache-2.0
-oslo.log>=1.2.0  # Apache-2.0
-oslo.serialization>=1.4.0               # Apache-2.0
-oslo.utils>=1.4.0                       # Apache-2.0
+oslo.concurrency>=2.0.0 # Apache-2.0
+oslo.config>=1.11.0 # Apache-2.0
+oslo.i18n>=1.5.0 # Apache-2.0
+oslo.log>=1.2.0 # Apache-2.0
+oslo.serialization>=1.4.0 # Apache-2.0
+oslo.utils>=1.6.0 # Apache-2.0
 six>=1.9.0
 iso8601>=0.1.9
 fixtures>=0.3.14
diff --git a/setup.py b/setup.py
old mode 100755
new mode 100644
index 7363757..056c16c
--- a/setup.py
+++ b/setup.py
@@ -1,4 +1,3 @@
-#!/usr/bin/env python
 # Copyright (c) 2013 Hewlett-Packard Development Company, L.P.
 #
 # Licensed under the Apache License, Version 2.0 (the "License");
diff --git a/tempest/api/telemetry/base.py b/tempest/api/telemetry/base.py
index 43180e5..cce8e2a 100644
--- a/tempest/api/telemetry/base.py
+++ b/tempest/api/telemetry/base.py
@@ -55,8 +55,7 @@
         cls.nova_notifications = ['memory', 'vcpus', 'disk.root.size',
                                   'disk.ephemeral.size']
 
-        cls.glance_notifications = ['image.update', 'image.upload',
-                                    'image.delete']
+        cls.glance_notifications = ['image.size']
 
         cls.glance_v2_notifications = ['image.download', 'image.serve']
 
diff --git a/tempest/api/telemetry/test_telemetry_notification_api.py b/tempest/api/telemetry/test_telemetry_notification_api.py
index d49b2ba..52793c8 100644
--- a/tempest/api/telemetry/test_telemetry_notification_api.py
+++ b/tempest/api/telemetry/test_telemetry_notification_api.py
@@ -10,7 +10,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-from tempest_lib import decorators
 import testtools
 
 from tempest.api.telemetry import base
@@ -46,7 +45,6 @@
     @test.services("image")
     @testtools.skipIf(not CONF.image_feature_enabled.api_v1,
                       "Glance api v1 is disabled")
-    @decorators.skip_because(bug='1351627')
     def test_check_glance_v1_notifications(self):
         body = self.create_image(self.image_client)
         self.image_client.update_image(body['id'], data='data')
@@ -63,7 +61,6 @@
     @test.services("image")
     @testtools.skipIf(not CONF.image_feature_enabled.api_v2,
                       "Glance api v2 is disabled")
-    @decorators.skip_because(bug='1351627')
     def test_check_glance_v2_notifications(self):
         body = self.create_image(self.image_client_v2)
 
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index 4b3995b..d4e6eb8 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -14,6 +14,7 @@
 import re
 import time
 
+from oslo_log import log as logging
 import six
 from tempest_lib.common import ssh
 
@@ -22,6 +23,8 @@
 
 CONF = config.CONF
 
+LOG = logging.getLogger(__name__)
+
 
 class RemoteClient(object):
 
@@ -48,7 +51,8 @@
     def exec_command(self, cmd):
         # Shell options below add more clearness on failures,
         # path is extended for some non-cirros guest oses (centos7)
-        cmd = "set -eu -o pipefail; PATH=$PATH:/sbin; " + cmd
+        cmd = CONF.compute.ssh_shell_prologue + " " + cmd
+        LOG.debug("Remote command: %s" % cmd)
         return self.ssh_client.exec_command(cmd)
 
     def validate_authentication(self):
diff --git a/tempest/config.py b/tempest/config.py
index 0fa5bf5..fc55723 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -206,6 +206,10 @@
                help="Timeout in seconds to wait for an instance to build. "
                     "Other services that do not define build_timeout will "
                     "inherit this value."),
+    cfg.StrOpt('ssh_shell_prologue',
+               default="set -eu -o pipefail; PATH=$$PATH:/sbin;",
+               help="Shell fragments to use before executing a command "
+                    "when sshing to a guest."),
     cfg.StrOpt('ssh_auth_method',
                default='keypair',
                help="Auth method used for authenticate to the instance. "
diff --git a/tempest/tests/cmd/test_javelin.py b/tempest/tests/cmd/test_javelin.py
index a0b250e..f0921d5 100644
--- a/tempest/tests/cmd/test_javelin.py
+++ b/tempest/tests/cmd/test_javelin.py
@@ -109,7 +109,7 @@
         self.fake_client.identity.get_tenant_by_name.return_value = \
             self.fake_object['tenant']
         self.fake_client.identity.get_user_by_username.side_effect = \
-            lib_exc.NotFound()
+            lib_exc.NotFound("user is not found")
         self.useFixture(mockpatch.PatchObject(javelin, "keystone_admin",
                                               return_value=self.fake_client))
 
@@ -126,7 +126,7 @@
 
     def test_create_user_missing_tenant(self):
         self.fake_client.identity.get_tenant_by_name.side_effect = \
-            lib_exc.NotFound()
+            lib_exc.NotFound("tenant is not found")
         self.useFixture(mockpatch.PatchObject(javelin, "keystone_admin",
                                               return_value=self.fake_client))
 
@@ -245,14 +245,49 @@
         mocked_function = self.fake_client.volumes.wait_for_volume_status
         self.assertFalse(mocked_function.called)
 
+    def test_create_router(self):
+
+        self.fake_client.networks.list_routers.return_value = {'routers': []}
+        self.useFixture(mockpatch.PatchObject(javelin, "client_for_user",
+                                              return_value=self.fake_client))
+
+        javelin.create_routers([self.fake_object])
+
+        mocked_function = self.fake_client.networks.create_router
+        mocked_function.assert_called_once_with(self.fake_object['name'])
+
+    def test_create_router_existing(self):
+        self.fake_client.networks.list_routers.return_value = {
+            'routers': [self.fake_object]}
+        self.useFixture(mockpatch.PatchObject(javelin, "client_for_user",
+                                              return_value=self.fake_client))
+
+        javelin.create_routers([self.fake_object])
+
+        mocked_function = self.fake_client.networks.create_router
+        self.assertFalse(mocked_function.called)
+
+    def test_create_secgroup(self):
+        self.useFixture(mockpatch.PatchObject(javelin, "client_for_user",
+                                              return_value=self.fake_client))
+        self.fake_client.secgroups.list_security_groups.return_value = []
+        self.fake_client.secgroups.create_security_group.return_value = \
+            {'id': self.fake_object['secgroup_id']}
+
+        javelin.create_secgroups([self.fake_object])
+
+        mocked_function = self.fake_client.secgroups.create_security_group
+        mocked_function.assert_called_once_with(
+            self.fake_object['name'],
+            self.fake_object['description'])
+
 
 class TestDestroyResources(JavelinUnitTest):
 
     def test_destroy_tenants(self):
 
         fake_tenant = self.fake_object['tenant']
-
-        fake_auth = mock.MagicMock()
+        fake_auth = self.fake_client
         fake_auth.identity.get_tenant_by_name.return_value = fake_tenant
 
         self.useFixture(mockpatch.PatchObject(javelin, "keystone_admin",
@@ -267,7 +302,7 @@
         fake_user = self.fake_object['user']
         fake_tenant = self.fake_object['tenant']
 
-        fake_auth = mock.MagicMock()
+        fake_auth = self.fake_client
         fake_auth.identity.get_tenant_by_name.return_value = fake_tenant
         fake_auth.identity.get_user_by_username.return_value = fake_user
 
@@ -281,42 +316,40 @@
 
     def test_destroy_objects(self):
 
-        fake_client = mock.MagicMock()
-        fake_client.objects.delete_object.return_value = {'status': "200"}, ""
+        self.fake_client.objects.delete_object.return_value = \
+            {'status': "200"}, ""
         self.useFixture(mockpatch.PatchObject(javelin, "client_for_user",
-                                              return_value=fake_client))
+                                              return_value=self.fake_client))
         javelin.destroy_objects([self.fake_object])
 
-        mocked_function = fake_client.objects.delete_object
+        mocked_function = self.fake_client.objects.delete_object
         mocked_function.asswert_called_once(self.fake_object['container'],
                                             self.fake_object['name'])
 
     def test_destroy_images(self):
 
-        fake_client = mock.MagicMock()
         self.useFixture(mockpatch.PatchObject(javelin, "client_for_user",
-                                              return_value=fake_client))
+                                              return_value=self.fake_client))
         self.useFixture(mockpatch.PatchObject(javelin, "_get_image_by_name",
                         return_value=self.fake_object['image']))
 
         javelin.destroy_images([self.fake_object])
 
-        mocked_function = fake_client.images.delete_image
+        mocked_function = self.fake_client.images.delete_image
         mocked_function.assert_called_once_with(
             self.fake_object['image']['id'])
 
     def test_destroy_networks(self):
 
-        fake_client = mock.MagicMock()
         self.useFixture(mockpatch.PatchObject(javelin, "client_for_user",
-                                              return_value=fake_client))
+                                              return_value=self.fake_client))
         self.useFixture(mockpatch.PatchObject(
             javelin, "_get_resource_by_name",
             return_value=self.fake_object['resource']))
 
         javelin.destroy_networks([self.fake_object])
 
-        mocked_function = fake_client.networks.delete_network
+        mocked_function = self.fake_client.networks.delete_network
         mocked_function.assert_called_once_with(
             self.fake_object['resource']['id'])
 
@@ -334,3 +367,47 @@
         mocked_function.assert_called_once_with(self.fake_object.volume['id'])
         mocked_function = self.fake_client.volumes.delete_volume
         mocked_function.assert_called_once_with(self.fake_object.volume['id'])
+
+    def test_destroy_subnets(self):
+
+        self.useFixture(mockpatch.PatchObject(javelin, "client_for_user",
+                                              return_value=self.fake_client))
+        fake_subnet_id = self.fake_object['subnet_id']
+        self.useFixture(mockpatch.PatchObject(javelin, "_get_resource_by_name",
+                                              return_value={
+                                                  'id': fake_subnet_id}))
+
+        javelin.destroy_subnets([self.fake_object])
+
+        mocked_function = self.fake_client.networks.delete_subnet
+        mocked_function.assert_called_once_with(fake_subnet_id)
+
+    def test_destroy_routers(self):
+        self.useFixture(mockpatch.PatchObject(javelin, "client_for_user",
+                                              return_value=self.fake_client))
+
+        # this function is used on 2 different occasions in the code
+        def _fake_get_resource_by_name(*args):
+            if args[1] == "routers":
+                return {"id": self.fake_object['router_id']}
+            elif args[1] == "subnets":
+                return {"id": self.fake_object['subnet_id']}
+        javelin._get_resource_by_name = _fake_get_resource_by_name
+
+        javelin.destroy_routers([self.fake_object])
+
+        mocked_function = self.fake_client.networks.delete_router
+        mocked_function.assert_called_once_with(
+            self.fake_object['router_id'])
+
+    def test_destroy_secgroup(self):
+        self.useFixture(mockpatch.PatchObject(javelin, "client_for_user",
+                                              return_value=self.fake_client))
+        fake_secgroup = {'id': self.fake_object['id']}
+        self.useFixture(mockpatch.PatchObject(javelin, "_get_resource_by_name",
+                                              return_value=fake_secgroup))
+
+        javelin.destroy_secgroups([self.fake_object])
+
+        mocked_function = self.fake_client.secgroups.delete_security_group
+        mocked_function.assert_called_once_with(self.fake_object['id'])
diff --git a/test-requirements.txt b/test-requirements.txt
index 7169610..9bd3f46 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -3,11 +3,11 @@
 # process, which may cause wedges in the gate later.
 hacking<0.11,>=0.10.0
 # needed for doc build
-sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
+sphinx!=1.2.0,!=1.3b1,<1.3,>=1.1.2
 python-subunit>=0.0.18
-oslosphinx>=2.5.0  # Apache-2.0
+oslosphinx>=2.5.0 # Apache-2.0
 mox>=0.5.3
 mock>=1.0
 coverage>=3.6
-oslotest>=1.5.1  # Apache-2.0
-stevedore>=1.5.0  # Apache-2.0
+oslotest>=1.5.1 # Apache-2.0
+stevedore>=1.5.0 # Apache-2.0