Merge "Add config options for enabled extensions"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 9357b62..1080ddf 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -43,7 +43,7 @@
 #logging_exception_prefix=%(asctime)s.%(msecs)03d %(process)d TRACE %(name)s %(instance)s
 
 # list of logger=LEVEL pairs (list value)
-#default_log_levels=amqplib=WARN,sqlalchemy=WARN,boto=WARN,suds=INFO,keystone=INFO
+#default_log_levels=amqplib=WARN,sqlalchemy=WARN,boto=WARN,suds=INFO,keystone=INFO,paramiko=INFO
 
 # publish error events (boolean value)
 #publish_errors=false
diff --git a/etc/whitelist.yaml b/etc/whitelist.yaml
index e5a0d4d..a822fae 100644
--- a/etc/whitelist.yaml
+++ b/etc/whitelist.yaml
@@ -160,14 +160,6 @@
     - module: "cinder.brick.local_dev.lvm"
       message: "Can't remove open logical volume"
 
-q-dhpc:
-    - module: "neutron.common.legacy"
-      message: "Skipping unknown group key: firewall_driver"
-    - module: "neutron.agent.dhcp_agent"
-      message: "Unable to enable dhcp"
-    - module: "neutron.agent.dhcp_agent"
-      message: " Network .* RPC info call failed"
-
 ceilometer-collector:
     - module: "stevedore.extension"
       message: ".*"
diff --git a/requirements.txt b/requirements.txt
index 4f6a1d3..cd11aa7 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -5,9 +5,9 @@
 jsonschema>=1.3.0,!=1.4.0
 testtools>=0.9.32
 lxml>=2.3
-boto>=2.4.0,!=2.13.0
+boto>=2.12.0,!=2.13.0
 paramiko>=1.8.0
-netaddr
+netaddr>=0.7.6
 python-glanceclient>=0.9.0
 python-keystoneclient>=0.4.1
 python-novaclient>=2.15.0
@@ -20,5 +20,5 @@
 oslo.config>=1.2.0
 eventlet>=0.13.0
 six>=1.4.1
-iso8601>=0.1.4
+iso8601>=0.1.8
 fixtures>=0.3.14
diff --git a/tempest/api/compute/admin/test_services_negative.py b/tempest/api/compute/admin/test_services_negative.py
index f4449d3..da1482e 100644
--- a/tempest/api/compute/admin/test_services_negative.py
+++ b/tempest/api/compute/admin/test_services_negative.py
@@ -19,7 +19,7 @@
 from tempest.test import attr
 
 
-class ServicesAdminTestJSON(base.BaseV2ComputeAdminTest):
+class ServicesAdminNegativeTestJSON(base.BaseV2ComputeAdminTest):
 
     """
     Tests Services API. List and Enable/Disable require admin privileges.
@@ -29,7 +29,7 @@
 
     @classmethod
     def setUpClass(cls):
-        super(ServicesAdminTestJSON, cls).setUpClass()
+        super(ServicesAdminNegativeTestJSON, cls).setUpClass()
         cls.client = cls.os_adm.services_client
         cls.non_admin_client = cls.services_client
 
@@ -66,5 +66,5 @@
         self.assertEqual(0, len(services))
 
 
-class ServicesAdminTestXML(ServicesAdminTestJSON):
+class ServicesAdminNegativeTestXML(ServicesAdminNegativeTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index e72f3fc..3c00851 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -178,6 +178,11 @@
                                                     kwargs['wait_until'])
             resp, image = cls.images_client.get_image(image_id)
 
+            if kwargs['wait_until'] == 'ACTIVE':
+                if kwargs.get('wait_for_server', True):
+                    cls.servers_client.wait_for_server_status(server_id,
+                                                              'ACTIVE')
+
         return resp, image
 
     @classmethod
diff --git a/tempest/api/compute/images/test_images.py b/tempest/api/compute/images/test_images.py
index 4539981..55260bf 100644
--- a/tempest/api/compute/images/test_images.py
+++ b/tempest/api/compute/images/test_images.py
@@ -98,7 +98,8 @@
         snapshot_name = data_utils.rand_name('test-snap-')
         resp, image = self.create_image_from_server(server['id'],
                                                     name=snapshot_name,
-                                                    wait_until='ACTIVE')
+                                                    wait_until='ACTIVE',
+                                                    wait_for_server=False)
         self.addCleanup(self.client.delete_image, image['id'])
         self.assertEqual(snapshot_name, image['name'])
 
diff --git a/tempest/api/compute/images/test_list_image_filters.py b/tempest/api/compute/images/test_list_image_filters.py
index 1401654..ac2ecba 100644
--- a/tempest/api/compute/images/test_list_image_filters.py
+++ b/tempest/api/compute/images/test_list_image_filters.py
@@ -16,7 +16,6 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest.common.utils import data_utils
 from tempest import exceptions
 from tempest.openstack.common import log as logging
 from tempest.test import attr
@@ -45,24 +44,21 @@
                                                       'ACTIVE')
 
             # Create images to be used in the filter tests
-            resp, body = cls.create_image_from_server(cls.server1['id'])
-            cls.image1_id = data_utils.parse_image_id(resp['location'])
-            cls.client.wait_for_image_status(cls.image1_id, 'ACTIVE')
-            resp, cls.image1 = cls.client.get_image(cls.image1_id)
+            resp, cls.image1 = cls.create_image_from_server(
+                cls.server1['id'], wait_until='ACTIVE')
+            cls.image1_id = cls.image1['id']
 
             # Servers have a hidden property for when they are being imaged
             # Performing back-to-back create image calls on a single
             # server will sometimes cause failures
-            resp, body = cls.create_image_from_server(cls.server2['id'])
-            cls.image3_id = data_utils.parse_image_id(resp['location'])
-            cls.client.wait_for_image_status(cls.image3_id, 'ACTIVE')
-            resp, cls.image3 = cls.client.get_image(cls.image3_id)
+            resp, cls.image3 = cls.create_image_from_server(
+                cls.server2['id'], wait_until='ACTIVE')
+            cls.image3_id = cls.image3['id']
 
-            resp, body = cls.create_image_from_server(cls.server1['id'])
-            cls.image2_id = data_utils.parse_image_id(resp['location'])
-
-            cls.client.wait_for_image_status(cls.image2_id, 'ACTIVE')
-            resp, cls.image2 = cls.client.get_image(cls.image2_id)
+            # Wait for the server to be active after the image upload
+            resp, cls.image2 = cls.create_image_from_server(
+                cls.server1['id'], wait_until='ACTIVE')
+            cls.image2_id = cls.image2['id']
         except Exception as exc:
             LOG.exception(exc)
             cls.tearDownClass()
diff --git a/tempest/openstack/common/log.py b/tempest/openstack/common/log.py
index 5cf8ed6..abb44ef 100644
--- a/tempest/openstack/common/log.py
+++ b/tempest/openstack/common/log.py
@@ -132,6 +132,7 @@
                     'boto=WARN',
                     'suds=INFO',
                     'keystone=INFO',
+                    'paramiko=INFO'
                 ],
                 help='list of logger=LEVEL pairs'),
     cfg.BoolOpt('publish_errors',
diff --git a/test-requirements.txt b/test-requirements.txt
index 41a784e..9486244 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -1,7 +1,8 @@
 hacking>=0.8.0,<0.9
 # needed for doc build
 docutils==0.9.1
-sphinx>=1.1.2
+sphinx>=1.1.2,<1.2
 python-subunit
 oslo.sphinx
 mox>=0.5.3
+mock>=1.0