Merge "Fix AttributeError when test_function_help fails"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 1cccacc..9a9952d 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -802,6 +802,9 @@
 # attributes ipv6_ra_mode and ipv6_address_mode (boolean value)
 #ipv6_subnet_attributes = false
 
+# If false, skip all network api tests with xml (boolean value)
+#xml_api = false
+
 
 [object-storage]
 
diff --git a/setup.cfg b/setup.cfg
index d010ccc..90ea944 100644
--- a/setup.cfg
+++ b/setup.cfg
@@ -1,6 +1,6 @@
 [metadata]
 name = tempest
-version = 2
+version = 3
 summary = OpenStack Integration Testing
 description-file =
     README.rst
diff --git a/tempest/api/baremetal/admin/test_nodes.py b/tempest/api/baremetal/admin/test_nodes.py
index 8ccd36b..41c12c6 100644
--- a/tempest/api/baremetal/admin/test_nodes.py
+++ b/tempest/api/baremetal/admin/test_nodes.py
@@ -130,9 +130,7 @@
 
     @test.attr(type='smoke')
     def test_set_node_boot_device(self):
-        body = self.client.set_node_boot_device(self.node['uuid'], 'pxe')
-        # No content
-        self.assertEqual('', body)
+        self.client.set_node_boot_device(self.node['uuid'], 'pxe')
 
     @test.attr(type='smoke')
     def test_get_node_boot_device(self):
diff --git a/tempest/api/identity/admin/v3/test_endpoints.py b/tempest/api/identity/admin/v3/test_endpoints.py
index f1f1eb6..676f101 100644
--- a/tempest/api/identity/admin/v3/test_endpoints.py
+++ b/tempest/api/identity/admin/v3/test_endpoints.py
@@ -81,8 +81,7 @@
         fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
         self.assertIn(endpoint['id'], fetched_endpoints_id)
         # Deleting the endpoint created in this method
-        _, body = self.client.delete_endpoint(endpoint['id'])
-        self.assertEqual(body, '')
+        self.client.delete_endpoint(endpoint['id'])
         # Checking whether endpoint is deleted successfully
         resp, fetched_endpoints = self.client.list_endpoints()
         fetched_endpoints_id = [e['id'] for e in fetched_endpoints]
diff --git a/tempest/api/messaging/test_queues.py b/tempest/api/messaging/test_queues.py
index 8f9ac20..accbd17 100644
--- a/tempest/api/messaging/test_queues.py
+++ b/tempest/api/messaging/test_queues.py
@@ -20,6 +20,7 @@
 
 from tempest.api.messaging import base
 from tempest.common.utils import data_utils
+from tempest import exceptions
 from tempest import test
 
 
@@ -29,15 +30,22 @@
 class TestQueues(base.BaseMessagingTest):
 
     @test.attr(type='smoke')
-    def test_create_queue(self):
-        # Create Queue
+    def test_create_delete_queue(self):
+        # Create & Delete Queue
         queue_name = data_utils.rand_name('test-')
         _, body = self.create_queue(queue_name)
 
         self.addCleanup(self.client.delete_queue, queue_name)
-
+        # NOTE(gmann): create_queue returns response status code as 201
+        # so specifically checking the expected empty response body as
+        # this is not going to be checked in response_checker().
         self.assertEqual('', body)
 
+        self.delete_queue(queue_name)
+        self.assertRaises(exceptions.NotFound,
+                          self.client.get_queue,
+                          queue_name)
+
 
 class TestManageQueue(base.BaseMessagingTest):
     _interface = 'json'
@@ -53,25 +61,16 @@
             cls.client.create_queue(queue_name)
 
     @test.attr(type='smoke')
-    def test_delete_queue(self):
-        # Delete Queue
-        queue_name = self.queues.pop()
-        _, body = self.delete_queue(queue_name)
-        self.assertEqual('', body)
-
-    @test.attr(type='smoke')
     def test_check_queue_existence(self):
         # Checking Queue Existence
         for queue_name in self.queues:
-            _, body = self.check_queue_exists(queue_name)
-            self.assertEqual('', body)
+            self.check_queue_exists(queue_name)
 
     @test.attr(type='smoke')
     def test_check_queue_head(self):
         # Checking Queue Existence by calling HEAD
         for queue_name in self.queues:
-            _, body = self.check_queue_exists_head(queue_name)
-            self.assertEqual('', body)
+            self.check_queue_exists_head(queue_name)
 
     @test.attr(type='smoke')
     def test_list_queues(self):
@@ -111,8 +110,8 @@
         req_body = dict()
         req_body[data_utils.rand_name('key1')] = req_body1
         # Set Queue Metadata
-        _, body = self.set_queue_metadata(queue_name, req_body)
-        self.assertEqual('', body)
+        self.set_queue_metadata(queue_name, req_body)
+
         # Get Queue Metadata
         _, body = self.get_queue_metadata(queue_name)
         self.assertThat(body, matchers.Equals(req_body))
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 91e3e14..c6480a1 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -62,6 +62,9 @@
         super(BaseNetworkTest, cls).resource_setup()
         if not CONF.service_available.neutron:
             raise cls.skipException("Neutron support is required")
+        if getattr(cls, '_interface', None) == 'xml':
+            if not CONF.network_feature_enabled.xml_api:
+                raise cls.skipException('XML API is not enabled')
 
         os = cls.get_client_manager()
 
diff --git a/tempest/cmd/run_stress.py b/tempest/cmd/run_stress.py
index a3f185c..d21a441 100755
--- a/tempest/cmd/run_stress.py
+++ b/tempest/cmd/run_stress.py
@@ -102,9 +102,11 @@
                                       call_inherited=ns.call_inherited)
 
     if ns.serial:
+        # Duration is total time
+        duration = ns.duration / len(tests)
         for test in tests:
             step_result = driver.stress_openstack([test],
-                                                  ns.duration,
+                                                  duration,
                                                   ns.number,
                                                   ns.stop)
             # NOTE(mkoderer): we just save the last result code
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index 42e4f56..3a0e975 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -16,6 +16,7 @@
 
 import collections
 import json
+import logging as real_logging
 import re
 import time
 
@@ -310,14 +311,15 @@
         caller_name = misc_utils.find_test_caller()
         if secs:
             secs = " %.3fs" % secs
-        self.LOG.info(
-            'Request (%s): %s %s %s%s' % (
-                caller_name,
-                resp['status'],
-                method,
-                req_url,
-                secs),
-            extra=extra)
+        if not self.LOG.isEnabledFor(real_logging.DEBUG):
+            self.LOG.info(
+                'Request (%s): %s %s %s%s' % (
+                    caller_name,
+                    resp['status'],
+                    method,
+                    req_url,
+                    secs),
+                extra=extra)
 
         # Also look everything at DEBUG if you want to filter this
         # out, don't run at debug.
diff --git a/tempest/config.py b/tempest/config.py
index d8f22d4..6e8238a 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -481,7 +481,10 @@
                 help="Allow the execution of IPv6 subnet tests that use "
                      "the extended IPv6 attributes ipv6_ra_mode "
                      "and ipv6_address_mode"
-                )
+                ),
+    cfg.BoolOpt('xml_api',
+                default=False,
+                help='If false, skip all network api tests with xml')
 ]
 
 messaging_group = cfg.OptGroup(name='messaging',
diff --git a/tempest/scenario/test_large_ops.py b/tempest/scenario/test_large_ops.py
index b111939..91b95a8 100644
--- a/tempest/scenario/test_large_ops.py
+++ b/tempest/scenario/test_large_ops.py
@@ -47,6 +47,8 @@
 
     def _wait_for_server_status(self, status):
         for server in self.servers:
+            # Make sure nova list keeps working throughout the build process
+            self.servers_client.list_servers()
             self.servers_client.wait_for_server_status(server['id'], status)
 
     def nova_boot(self):