Merge "Adds test_update_all_metadata_field_not_included negative test"
diff --git a/HACKING.rst b/HACKING.rst
index 2fa949d..7d995c3 100644
--- a/HACKING.rst
+++ b/HACKING.rst
@@ -2,22 +2,12 @@
 ====================
 
 - Step 1: Read the OpenStack Style Commandments
-  https://github.com/openstack-dev/hacking/blob/master/HACKING.rst
+  http://docs.openstack.org/developer/hacking/
 - Step 2: Read on
 
 Tempest Specific Commandments
 ------------------------------
 
-[T101] If a test is broken because of a bug it is appropriate to skip the test until
-bug has been fixed. However, the skip message should be formatted so that
-Tempest's skip tracking tool can watch the bug status. The skip message should
-contain the string 'Bug' immediately followed by a space. Then the bug number
-should be included in the message '#' in front of the number.
-
-Example::
-
-  @testtools.skip("Skipped until the Bug #980688 is resolved")
-
 - [T102] Cannot import OpenStack python clients in tempest/api tests
 - [T103] tempest/tests is deprecated
 - [T104] Scenario tests require a services decorator
@@ -115,6 +105,32 @@
 in tempest.api.compute would require a service tag for those services, however
 they do not need to be tagged as compute.
 
+Negative Tests
+--------------
+When adding negative tests to tempest there are 2 requirements. First the tests
+must be marked with a negative attribute. For example::
+
+  @attr(type=negative)
+  def test_resource_no_uuid(self):
+    ...
+
+The second requirement is that all negative tests must be added to a negative
+test file. If such a file doesn't exist for the particular resource being
+tested a new test file should be added.
+
+Test skips because of Known Bugs
+--------------------------------
+
+If a test is broken because of a bug it is appropriate to skip the test until
+bug has been fixed. You should use the skip_because decorator so that
+Tempest's skip tracking tool can watch the bug status.
+
+Example::
+
+  @skip_because(bug="980688")
+  def test_this_and_that(self):
+    ...
+
 Guidelines
 ----------
 - Do not submit changesets with only testcases which are skipped as
@@ -123,8 +139,8 @@
   earlier a problem is detected the easier it is to debug, especially
   where there is complicated setup required.
 
-Parallel Test Exectution
-------------------------
+Parallel Test Execution
+-----------------------
 Tempest by default runs its tests in parallel this creates the possibility for
 interesting interactions between tests which can cause unexpected failures.
 Tenant isolation provides protection from most of the potential race conditions
@@ -133,7 +149,7 @@
 
 - Resources outside of a tenant scope still have the potential to conflict. This
   is a larger concern for the admin tests since most resources and actions that
-  require admin privleges are outside of tenants.
+  require admin privileges are outside of tenants.
 
 - Races between methods in the same class are not a problem because
   parallelization in tempest is at the test class level, but if there is a json
diff --git a/doc/source/conf.py b/doc/source/conf.py
index 178bf62..cf838c0 100644
--- a/doc/source/conf.py
+++ b/doc/source/conf.py
@@ -11,7 +11,8 @@
 # All configuration values have a default; values that are commented out
 # serve to show the default.
 
-import sys, os
+import sys
+import os
 
 # If extensions (or modules to document with autodoc) are in another directory,
 # add these directories to sys.path here. If the directory is relative to the
@@ -25,7 +26,14 @@
 
 # Add any Sphinx extension module names here, as strings. They can be extensions
 # coming with Sphinx (named 'sphinx.ext.*') or your custom ones.
-extensions = ['sphinx.ext.autodoc', 'sphinx.ext.todo', 'sphinx.ext.viewcode']
+extensions = ['sphinx.ext.autodoc',
+              'sphinx.ext.intersphinx',
+              'sphinx.ext.todo',
+              'sphinx.ext.viewcode',
+              'oslo.sphinx'
+             ]
+
+todo_include_todos = True
 
 # Add any paths that contain templates here, relative to this directory.
 templates_path = ['_templates']
@@ -41,16 +49,18 @@
 
 # General information about the project.
 project = u'Tempest'
-copyright = u'2013, Sean Dague'
+copyright = u'2013, OpenStack QA Team'
 
 # The version info for the project you're documenting, acts as replacement for
 # |version| and |release|, also used in various other places throughout the
 # built documents.
 #
 # The short X.Y version.
-version = 'havana'
+import pbr.version
+version_info = pbr.version.VersionInfo('tempest')
+version = version_info.version_string()
 # The full version, including alpha/beta/rc tags.
-release = 'havana'
+release = version_info.release_string()
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
@@ -74,17 +84,17 @@
 
 # If true, the current module name will be prepended to all description
 # unit titles (such as .. function::).
-#add_module_names = True
+add_module_names = False
 
 # If true, sectionauthor and moduleauthor directives will be shown in the
 # output. They are ignored by default.
-#show_authors = False
+show_authors = False
 
 # The name of the Pygments (syntax highlighting) style to use.
 pygments_style = 'sphinx'
 
 # A list of ignored prefixes for module index sorting.
-#modindex_common_prefix = []
+modindex_common_prefix = ['tempest.']
 
 
 # -- Options for HTML output ---------------------------------------------------
@@ -124,7 +134,8 @@
 
 # If not '', a 'Last updated on:' timestamp is inserted at every page bottom,
 # using the given strftime format.
-#html_last_updated_fmt = '%b %d, %Y'
+git_cmd = "git log --pretty=format:'%ad, commit %h' --date=local -n1"
+html_last_updated_fmt = os.popen(git_cmd).read()
 
 # If true, SmartyPants will be used to convert quotes and dashes to
 # typographically correct entities.
@@ -184,7 +195,7 @@
 # (source start file, target name, title, author, documentclass [howto/manual]).
 latex_documents = [
   ('index', 'Tempest.tex', u'Tempest Documentation',
-   u'Sean Dague', 'manual'),
+   u'OpenStack QA Team', 'manual'),
 ]
 
 # The name of an image file (relative to this directory) to place at the top of
@@ -214,7 +225,7 @@
 # (source start file, name, description, authors, manual section).
 man_pages = [
     ('index', 'tempest', u'Tempest Documentation',
-     [u'Sean Dague'], 1)
+     [u'OpenStack QA Team'], 1)
 ]
 
 # If true, show URL addresses after external links.
@@ -228,7 +239,7 @@
 #  dir menu entry, description, category)
 texinfo_documents = [
   ('index', 'Tempest', u'Tempest Documentation',
-   u'Sean Dague', 'Tempest', 'One line description of project.',
+   u'OpenStack QA Team', 'Tempest', 'One line description of project.',
    'Miscellaneous'),
 ]
 
@@ -247,8 +258,8 @@
 # Bibliographic Dublin Core info.
 epub_title = u'Tempest'
 epub_author = u'Sean Dague'
-epub_publisher = u'Sean Dague'
-epub_copyright = u'2013, Sean Dague'
+epub_publisher = u'OpenStack QA Team'
+epub_copyright = u'2013, OpenStack QA Team'
 
 # The language of the text. It defaults to the language option
 # or en if the language is not set.
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index ec14c7e..115a2b5 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -222,7 +222,7 @@
 tenant_network_cidr = 10.100.0.0/16
 
 # The mask bits used to partition the tenant block.
-tenant_network_mask_bits = 28
+tenant_network_mask_bits = 24
 
 # If tenant networks are reachable, connectivity checks will be
 # performed directly against addresses on those networks.
diff --git a/etc/whitelist.yaml b/etc/whitelist.yaml
new file mode 100644
index 0000000..6762f9f
--- /dev/null
+++ b/etc/whitelist.yaml
@@ -0,0 +1,131 @@
+n-cpu:
+    - module: "nova.virt.libvirt.driver"
+      message: "During wait destroy, instance disappeared"
+    - module: "glanceclient.common.http"
+      message: "Request returned failure status"
+    - module: "nova.openstack.common.periodic_task"
+      message: "Error during ComputeManager\\.update_available_resource: \
+        'NoneType' object is not iterable"
+    - module: "nova.compute.manager"
+      message: "Possibly task preempted"
+    - module: "nova.openstack.common.rpc.amqp"
+      message: "Exception during message handling"
+    - module: "nova.network.api"
+      message: "Failed storing info cache"
+    - module: "nova.compute.manager"
+      message: "Error while trying to clean up image"
+    - module: "nova.virt.libvirt.driver"
+      message: "Error injecting data into image.*\\(Unexpected error while \
+        running command"
+    - module: "nova.compute.manager"
+      message: "Instance failed to spawn"
+    - module: "nova.compute.manager"
+      message: "Error: Unexpected error while running command"
+
+g-api:
+    - module: "glance.store.sheepdog"
+      message: "Error in store configuration: Unexpected error while \
+        running command"
+    - module: "swiftclient"
+      message: "Container HEAD failed: .*404 Not Found"
+
+ceilometer-acompute:
+    - module: "ceilometer.compute.pollsters.disk"
+      message: "Requested operation is not valid: domain is not running"
+    - module: "ceilometer.compute.pollsters.disk"
+      message: "Domain not found: no domain with matching uuid"
+
+h-api:
+    - module: "root"
+      message: "Returning 400 to user: The server could not comply with \
+        the request since it is either malformed or otherwise incorrect"
+    - module: "root"
+      message: "Unexpected error occurred serving API: Request limit \
+        exceeded: Template exceeds maximum allowed size"
+    - module: "root"
+      message: "Unexpected error occurred serving API: The Stack \
+        .*could not be found"
+
+h-eng:
+    - module: "heat.openstack.common.rpc.amqp"
+      message: "Exception during message handling"
+    - module: "heat.openstack.common.rpc.common"
+      message: "The Stack .* could not be found"
+
+n-api:
+    - module: "glanceclient.common.http"
+      message: "Request returned failure status"
+    - module: "nova.api.openstack"
+      message: "Caught error: Quota exceeded for"
+    - module: "nova.compute.api"
+      message: "ServerDiskConfigTest"
+    - module: "nova.compute.api"
+      message: "ServersTest"
+    - module: "nova.compute.api"
+      message: "\\{u'kernel_id'.*u'ramdisk_id':"
+
+n-cond:
+    - module: "nova.notifications"
+      message: "Failed to send state update notification"
+
+n-sch:
+    - module: "nova.scheduler.filter_scheduler"
+      message: "Error from last host: "
+
+c-api:
+    - module: "cinder.api.middleware.fault"
+      message: "Caught error: Volume .* could not be found"
+
+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: ".*"
+    - module: "ceilometer.collector.dispatcher.database"
+      message: "duplicate key value violates unique constraint"
+
+q-agt:
+    - module: "neutron.agent.linux.ovs_lib"
+      message: "Unable to execute.*Exception:"
+
+q-dhcp:
+    - 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"
+
+q-l3:
+    - module: "neutron.common.legacy"
+      message: "Skipping unknown group key: firewall_driver"
+    - module: "neutron.agent.l3_agent"
+      message: "Failed synchronizing routers"
+
+
+q-lbaas:
+    - module: "neutron.common.legacy"
+      message: "Skipping unknown group key: firewall_driver"
+    - module: "neutron.services.loadbalancer.drivers.haproxy.agent_manager"
+      message: "Error upating stats"
+    - module: "neutron.services.loadbalancer.drivers.haproxy.agent_manager"
+      message: "Unable to destroy device for pool"
+
+q-svc:
+    - module: "neutron.common.legacy"
+      message: "Skipping unknown group key: firewall_driver"
+    - module: "neutron.openstack.common.rpc.amqp"
+      message: "Exception during message handling"
+    - module: "neutron.openstack.common.rpc.common"
+      message: "Network .* could not be found"
+    - module: "neutron.openstack.common.rpc.common"
+      message: "Pool .* could not be found"
+    - module: "neutron.api.v2.resource"
+      message: "show failed"
+
diff --git a/requirements.txt b/requirements.txt
index b15fb92..3b9ec44 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -17,7 +17,7 @@
 testresources>=0.2.4
 keyring>=1.6.1
 testrepository>=0.0.17
-oslo.config>=1.1.0
+oslo.config>=1.2.0
 eventlet>=0.13.0
 six<1.4.0
 iso8601>=0.1.4
diff --git a/run_tests.sh b/run_tests.sh
index 710fbaa..5c8ce7d 100755
--- a/run_tests.sh
+++ b/run_tests.sh
@@ -58,12 +58,12 @@
     -c|--nova-coverage) let nova_coverage=1;;
     -C|--config) config_file=$2; shift;;
     -p|--pep8) let just_pep8=1;;
-    -s|--smoke) testrargs="$testrargs smoke";;
+    -s|--smoke) testrargs+="smoke"; noseargs+="--attr=type=smoke";;
     -t|--serial) serial=1;;
     -l|--logging) logging=1;;
     -L|--logging-config) logging_config=$2; shift;;
     --) [ "yes" == "$first_uu" ] || testrargs="$testrargs $1"; first_uu=no  ;;
-    *) testrargs="$testrargs $1"
+    *) testrargs="$testrargs $1"; noseargs+=" $1" ;;
   esac
   shift
 done
@@ -107,12 +107,13 @@
 }
 
 function run_tests_nose {
-    NOSE_WITH_OPENSTACK=1
-    NOSE_OPENSTACK_COLOR=1
-    NOSE_OPENSTACK_RED=15.00
-    NOSE_OPENSTACK_YELLOW=3.00
-    NOSE_OPENSTACK_SHOW_ELAPSED=1
-    NOSE_OPENSTACK_STDOUT=1
+    export NOSE_WITH_OPENSTACK=1
+    export NOSE_OPENSTACK_COLOR=1
+    export NOSE_OPENSTACK_RED=15.00
+    export NOSE_OPENSTACK_YELLOW=3.00
+    export NOSE_OPENSTACK_SHOW_ELAPSED=1
+    export NOSE_OPENSTACK_STDOUT=1
+    export TEMPEST_PY26_NOSE_COMPAT=1
     if [[ "x$noseargs" =~ "tempest" ]]; then
         noseargs="$testrargs"
     else
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index a5dceca..14ab236 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -15,25 +15,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import fixtures
-
 from tempest.api.compute import base
+from tempest.common import tempest_fixtures as fixtures
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
-from tempest.openstack.common import lockutils
 from tempest.test import attr
 
 
-class LockFixture(fixtures.Fixture):
-    def __init__(self, name):
-        self.mgr = lockutils.lock(name, 'tempest-', True)
-
-    def setUp(self):
-        super(LockFixture, self).setUp()
-        self.addCleanup(self.mgr.__exit__, None, None, None)
-        self.mgr.__enter__()
-
-
 class AggregatesAdminTestJSON(base.BaseComputeAdminTest):
 
     """
@@ -109,6 +97,38 @@
         self.assertEqual(aggregate['availability_zone'],
                          body['availability_zone'])
 
+    @attr(type='gate')
+    def test_aggregate_create_update_with_az(self):
+        # Update an aggregate and ensure properties are updated correctly
+        self.useFixture(fixtures.LockFixture('availability_zone'))
+        aggregate_name = rand_name(self.aggregate_name_prefix)
+        az_name = rand_name(self.az_name_prefix)
+        resp, aggregate = self.client.create_aggregate(aggregate_name, az_name)
+        self.addCleanup(self.client.delete_aggregate, aggregate['id'])
+
+        self.assertEqual(200, resp.status)
+        self.assertEqual(aggregate_name, aggregate['name'])
+        self.assertEqual(az_name, aggregate['availability_zone'])
+        self.assertIsNotNone(aggregate['id'])
+
+        aggregate_id = aggregate['id']
+        new_aggregate_name = aggregate_name + '_new'
+        new_az_name = az_name + '_new'
+
+        resp, resp_aggregate = self.client.update_aggregate(aggregate_id,
+                                                            new_aggregate_name,
+                                                            new_az_name)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(new_aggregate_name, resp_aggregate['name'])
+        self.assertEqual(new_az_name, resp_aggregate['availability_zone'])
+
+        resp, aggregates = self.client.list_aggregates()
+        self.assertEqual(200, resp.status)
+        self.assertIn((aggregate_id, new_aggregate_name, new_az_name),
+                      map(lambda x:
+                         (x['id'], x['name'], x['availability_zone']),
+                          aggregates))
+
     @attr(type=['negative', 'gate'])
     def test_aggregate_create_as_user(self):
         # Regular user is not allowed to create an aggregate.
@@ -160,7 +180,7 @@
     @attr(type='gate')
     def test_aggregate_add_remove_host(self):
         # Add an host to the given aggregate and remove.
-        self.useFixture(LockFixture('availability_zone'))
+        self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate_name = rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
@@ -182,7 +202,7 @@
     @attr(type='gate')
     def test_aggregate_add_host_list(self):
         # Add an host to the given aggregate and list.
-        self.useFixture(LockFixture('availability_zone'))
+        self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate_name = rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
@@ -200,7 +220,7 @@
     @attr(type='gate')
     def test_aggregate_add_host_get_details(self):
         # Add an host to the given aggregate and get details.
-        self.useFixture(LockFixture('availability_zone'))
+        self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate_name = rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
@@ -215,7 +235,7 @@
     @attr(type='gate')
     def test_aggregate_add_host_create_server_with_az(self):
         # Add an host to the given aggregate and create a server.
-        self.useFixture(LockFixture('availability_zone'))
+        self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate_name = rand_name(self.aggregate_name_prefix)
         az_name = rand_name(self.az_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name, az_name)
@@ -262,7 +282,7 @@
     @attr(type=['negative', 'gate'])
     def test_aggregate_remove_host_as_user(self):
         # Regular user is not allowed to remove a host from an aggregate.
-        self.useFixture(LockFixture('availability_zone'))
+        self.useFixture(fixtures.LockFixture('availability_zone'))
         aggregate_name = rand_name(self.aggregate_name_prefix)
         resp, aggregate = self.client.create_aggregate(aggregate_name)
         self.addCleanup(self.client.delete_aggregate, aggregate['id'])
diff --git a/tempest/api/compute/admin/test_fixed_ips.py b/tempest/api/compute/admin/test_fixed_ips.py
index 85b03e6..ee262df 100644
--- a/tempest/api/compute/admin/test_fixed_ips.py
+++ b/tempest/api/compute/admin/test_fixed_ips.py
@@ -16,7 +16,6 @@
 #    under the License.
 
 from tempest.api.compute import base
-from tempest import config
 from tempest import exceptions
 from tempest.test import attr
 
@@ -24,8 +23,6 @@
 class FixedIPsTestJson(base.BaseComputeAdminTest):
     _interface = 'json'
 
-    CONF = config.TempestConfig()
-
     @classmethod
     def setUpClass(cls):
         super(FixedIPsTestJson, cls).setUpClass()
diff --git a/tempest/api/compute/admin/test_flavors.py b/tempest/api/compute/admin/test_flavors.py
index 3ef75ba..004268e 100644
--- a/tempest/api/compute/admin/test_flavors.py
+++ b/tempest/api/compute/admin/test_flavors.py
@@ -15,14 +15,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
-
 from tempest.api import compute
 from tempest.api.compute import base
 from tempest.common.utils.data_utils import rand_int_id
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
 class FlavorsAdminTestJSON(base.BaseComputeAdminTest):
@@ -195,7 +194,7 @@
                 flag = True
         self.assertTrue(flag)
 
-    @testtools.skip("Skipped until the Bug #1209101 is resolved")
+    @skip_because(bug="1209101")
     @attr(type='gate')
     def test_list_non_public_flavor(self):
         # Create a flavor with os-flavor-access:is_public false should
diff --git a/tempest/api/compute/admin/test_flavors_access.py b/tempest/api/compute/admin/test_flavors_access.py
index 107b23d..8213839 100644
--- a/tempest/api/compute/admin/test_flavors_access.py
+++ b/tempest/api/compute/admin/test_flavors_access.py
@@ -15,6 +15,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import uuid
+
 from tempest.api import compute
 from tempest.api.compute import base
 from tempest.common.utils.data_utils import rand_int_id
@@ -123,6 +125,48 @@
                           new_flavor['id'],
                           self.tenant_id)
 
+    @attr(type=['negative', 'gate'])
+    def test_add_flavor_access_duplicate(self):
+        # Create a new flavor.
+        flavor_name = rand_name(self.flavor_name_prefix)
+        new_flavor_id = rand_int_id(start=1000)
+        resp, new_flavor = self.client.create_flavor(flavor_name,
+                                                     self.ram, self.vcpus,
+                                                     self.disk,
+                                                     new_flavor_id,
+                                                     is_public='False')
+        self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+
+        # Add flavor access to a tenant.
+        self.client.add_flavor_access(new_flavor['id'], self.tenant_id)
+        self.addCleanup(self.client.remove_flavor_access,
+                        new_flavor['id'], self.tenant_id)
+
+        # An exception should be raised when adding flavor access to the same
+        # tenant
+        self.assertRaises(exceptions.Duplicate,
+                          self.client.add_flavor_access,
+                          new_flavor['id'],
+                          self.tenant_id)
+
+    @attr(type=['negative', 'gate'])
+    def test_remove_flavor_access_not_found(self):
+        # Create a new flavor.
+        flavor_name = rand_name(self.flavor_name_prefix)
+        new_flavor_id = rand_int_id(start=1000)
+        resp, new_flavor = self.client.create_flavor(flavor_name,
+                                                     self.ram, self.vcpus,
+                                                     self.disk,
+                                                     new_flavor_id,
+                                                     is_public='False')
+        self.addCleanup(self.client.delete_flavor, new_flavor['id'])
+
+        # An exception should be raised when flavor access is not found
+        self.assertRaises(exceptions.NotFound,
+                          self.client.remove_flavor_access,
+                          new_flavor['id'],
+                          str(uuid.uuid4()))
+
 
 class FlavorsAdminTestXML(FlavorsAccessTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/admin/test_flavors_extra_specs.py b/tempest/api/compute/admin/test_flavors_extra_specs.py
index ce326a3..fb6a463 100644
--- a/tempest/api/compute/admin/test_flavors_extra_specs.py
+++ b/tempest/api/compute/admin/test_flavors_extra_specs.py
@@ -115,6 +115,14 @@
                           self.flavor['id'],
                           'key1')
 
+    @attr(type=['negative', 'gate'])
+    def test_flavor_unset_nonexistent_key(self):
+        nonexistent_key = rand_name('flavor_key')
+        self.assertRaises(exceptions.NotFound,
+                          self.client.unset_flavor_extra_spec,
+                          self.flavor['id'],
+                          nonexistent_key)
+
 
 class FlavorsExtraSpecsTestXML(FlavorsExtraSpecsTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/admin/test_hosts.py b/tempest/api/compute/admin/test_hosts.py
index 19d7973..bf09428 100644
--- a/tempest/api/compute/admin/test_hosts.py
+++ b/tempest/api/compute/admin/test_hosts.py
@@ -15,6 +15,7 @@
 #    under the License.
 
 from tempest.api.compute import base
+from tempest.common import tempest_fixtures as fixtures
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
 from tempest.test import attr
@@ -42,6 +43,7 @@
 
     @attr(type='gate')
     def test_list_hosts_with_zone(self):
+        self.useFixture(fixtures.LockFixture('availability_zone'))
         resp, hosts = self.client.list_hosts()
         host = hosts[0]
         zone_name = host['zone']
diff --git a/tempest/api/compute/admin/test_quotas.py b/tempest/api/compute/admin/test_quotas.py
index f55f152..e744200 100644
--- a/tempest/api/compute/admin/test_quotas.py
+++ b/tempest/api/compute/admin/test_quotas.py
@@ -52,15 +52,6 @@
                                      'instances', 'security_group_rules',
                                      'cores', 'security_groups'))
 
-    @classmethod
-    def tearDownClass(cls):
-        for server in cls.servers:
-            try:
-                cls.servers_client.delete_server(server['id'])
-            except exceptions.NotFound:
-                continue
-        super(QuotasAdminTestJSON, cls).tearDownClass()
-
     @attr(type='smoke')
     def test_get_default_quotas(self):
         # Admin can get the default resource quota set for a tenant
diff --git a/tempest/api/compute/admin/test_servers.py b/tempest/api/compute/admin/test_servers.py
index cb47066..97e0e69 100644
--- a/tempest/api/compute/admin/test_servers.py
+++ b/tempest/api/compute/admin/test_servers.py
@@ -15,8 +15,11 @@
 #    under the License.
 
 from tempest.api.compute import base
+from tempest.common.utils.data_utils import rand_int_id
 from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
 class ServersAdminTestJSON(base.BaseComputeAdminTest):
@@ -31,14 +34,32 @@
     def setUpClass(cls):
         super(ServersAdminTestJSON, cls).setUpClass()
         cls.client = cls.os_adm.servers_client
+        cls.non_adm_client = cls.servers_client
+        cls.flavors_client = cls.os_adm.flavors_client
+        cls.identity_client = cls._get_identity_admin_client()
+        tenant = cls.identity_client.get_tenant_by_name(
+            cls.client.tenant_name)
+        cls.tenant_id = tenant['id']
 
         cls.s1_name = rand_name('server')
         resp, server = cls.create_server(name=cls.s1_name,
                                          wait_until='ACTIVE')
+        cls.s1_id = server['id']
+
         cls.s2_name = rand_name('server')
         resp, server = cls.create_server(name=cls.s2_name,
                                          wait_until='ACTIVE')
 
+    def _get_unused_flavor_id(self):
+        flavor_id = rand_int_id(start=1000)
+        while True:
+            try:
+                resp, body = self.flavors_client.get_flavor_details(flavor_id)
+            except exceptions.NotFound:
+                break
+            flavor_id = rand_int_id(start=1000)
+        return flavor_id
+
     @attr(type='gate')
     def test_list_servers_by_admin(self):
         # Listing servers by admin user returns empty list by default
@@ -59,6 +80,104 @@
         self.assertIn(self.s1_name, servers_name)
         self.assertIn(self.s2_name, servers_name)
 
+    @attr(type='gate')
+    def test_admin_delete_servers_of_others(self):
+        # Administrator can delete servers of others
+        _, server = self.create_server()
+        resp, _ = self.client.delete_server(server['id'])
+        self.assertEqual('204', resp['status'])
+        self.servers_client.wait_for_server_termination(server['id'])
+
+    @attr(type=['negative', 'gate'])
+    def test_resize_server_using_overlimit_ram(self):
+        flavor_name = rand_name("flavor-")
+        flavor_id = self._get_unused_flavor_id()
+        resp, quota_set = self.quotas_client.get_default_quota_set(
+            self.tenant_id)
+        ram = int(quota_set['ram']) + 1
+        vcpus = 8
+        disk = 10
+        resp, flavor_ref = self.flavors_client.create_flavor(flavor_name,
+                                                             ram, vcpus, disk,
+                                                             flavor_id)
+        self.addCleanup(self.flavors_client.delete_flavor, flavor_id)
+        self.assertRaises(exceptions.OverLimit,
+                          self.client.resize,
+                          self.servers[0]['id'],
+                          flavor_ref['id'])
+
+    @attr(type=['negative', 'gate'])
+    def test_resize_server_using_overlimit_vcpus(self):
+        flavor_name = rand_name("flavor-")
+        flavor_id = self._get_unused_flavor_id()
+        ram = 512
+        resp, quota_set = self.quotas_client.get_default_quota_set(
+            self.tenant_id)
+        vcpus = int(quota_set['cores']) + 1
+        disk = 10
+        resp, flavor_ref = self.flavors_client.create_flavor(flavor_name,
+                                                             ram, vcpus, disk,
+                                                             flavor_id)
+        self.addCleanup(self.flavors_client.delete_flavor, flavor_id)
+        self.assertRaises(exceptions.OverLimit,
+                          self.client.resize,
+                          self.servers[0]['id'],
+                          flavor_ref['id'])
+
+    @attr(type='gate')
+    def test_reset_state_server(self):
+        # Reset server's state to 'error'
+        resp, server = self.client.reset_state(self.s1_id)
+        self.assertEqual(202, resp.status)
+
+        # Verify server's state
+        resp, server = self.client.get_server(self.s1_id)
+        self.assertEqual(server['status'], 'ERROR')
+
+        # Reset server's state to 'active'
+        resp, server = self.client.reset_state(self.s1_id, state='active')
+        self.assertEqual(202, resp.status)
+
+        # Verify server's state
+        resp, server = self.client.get_server(self.s1_id)
+        self.assertEqual(server['status'], 'ACTIVE')
+
+    @attr(type=['negative', 'gate'])
+    def test_reset_state_server_invalid_state(self):
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.reset_state, self.s1_id,
+                          state='invalid')
+
+    @attr(type=['negative', 'gate'])
+    def test_reset_state_server_invalid_type(self):
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.reset_state, self.s1_id,
+                          state=1)
+
+    @attr(type=['negative', 'gate'])
+    def test_reset_state_server_nonexistent_server(self):
+        self.assertRaises(exceptions.NotFound,
+                          self.client.reset_state, '999')
+
+    @attr(type='gate')
+    @skip_because(bug="1240043")
+    def test_get_server_diagnostics_by_admin(self):
+        # Retrieve server diagnostics by admin user
+        resp, diagnostic = self.client.get_server_diagnostics(self.s1_id)
+        self.assertEqual(200, resp.status)
+        basic_attrs = ['rx_packets', 'rx_errors', 'rx_drop',
+                       'tx_packets', 'tx_errors', 'tx_drop',
+                       'read_req', 'write_req', 'cpu', 'memory']
+        for key in basic_attrs:
+            self.assertIn(key, str(diagnostic.keys()))
+
+    @attr(type=['negative', 'gate'])
+    def test_get_server_diagnostics_by_non_admin(self):
+        # Non-admin user can not view server diagnostics according to policy
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_adm_client.get_server_diagnostics,
+                          self.s1_id)
+
 
 class ServersAdminTestXML(ServersAdminTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index d2f437b..885adcf 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -22,6 +22,7 @@
 from tempest.common import isolated_creds
 from tempest.common.utils.data_utils import parse_image_id
 from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
 from tempest.openstack.common import log as logging
 import tempest.test
 
@@ -99,10 +100,26 @@
                 pass
 
     @classmethod
+    def rebuild_server(cls, **kwargs):
+        # Destroy an existing server and creates a new one
+        try:
+            cls.servers_client.delete_server(cls.server_id)
+            cls.servers_client.wait_for_server_termination(cls.server_id)
+        except Exception as exc:
+            LOG.exception(exc)
+            pass
+        resp, server = cls.create_server(wait_until='ACTIVE', **kwargs)
+        cls.server_id = server['id']
+        cls.password = server['adminPass']
+
+    @classmethod
     def clear_images(cls):
         for image_id in cls.images:
             try:
                 cls.images_client.delete_image(image_id)
+            except exceptions.NotFound:
+                # The image may have already been deleted which is OK.
+                pass
             except Exception as exc:
                 LOG.info('Exception raised deleting image %s', image_id)
                 LOG.exception(exc)
diff --git a/tempest/api/compute/floating_ips/test_list_floating_ips.py b/tempest/api/compute/floating_ips/test_list_floating_ips.py
index 1c72eba..3c76069 100644
--- a/tempest/api/compute/floating_ips/test_list_floating_ips.py
+++ b/tempest/api/compute/floating_ips/test_list_floating_ips.py
@@ -93,6 +93,14 @@
         self.assertRaises(exceptions.NotFound,
                           self.client.get_floating_ip_details, non_exist_id)
 
+    @attr(type='gate')
+    def test_list_floating_ip_pools(self):
+        # Positive test:Should return the list of floating IP Pools
+        resp, floating_ip_pools = self.client.list_floating_ip_pools()
+        self.assertEqual(200, resp.status)
+        self.assertNotEqual(0, len(floating_ip_pools),
+                            "Expected floating IP Pools. Got zero.")
+
 
 class FloatingIPDetailsTestXML(FloatingIPDetailsTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/images/test_images_oneserver.py b/tempest/api/compute/images/test_images_oneserver.py
index 7df9010..800b2de 100644
--- a/tempest/api/compute/images/test_images_oneserver.py
+++ b/tempest/api/compute/images/test_images_oneserver.py
@@ -24,6 +24,7 @@
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
 class ImagesOneServerTestJSON(base.BaseComputeTest):
@@ -64,7 +65,7 @@
                 cls.alt_manager = clients.AltManager()
             cls.alt_client = cls.alt_manager.images_client
 
-    @testtools.skip("Skipped until the Bug #1006725 is resolved.")
+    @skip_because(bug="1006725")
     @attr(type=['negative', 'gate'])
     def test_create_image_specify_multibyte_character_image_name(self):
         # Return an error if the image name has multi-byte characters
diff --git a/tempest/api/compute/security_groups/test_security_group_rules.py b/tempest/api/compute/security_groups/test_security_group_rules.py
index 61db61d..cbc0080 100644
--- a/tempest/api/compute/security_groups/test_security_group_rules.py
+++ b/tempest/api/compute/security_groups/test_security_group_rules.py
@@ -15,13 +15,12 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
-
 from tempest.api.compute import base
 from tempest.common.utils.data_utils import rand_name
 from tempest import config
 from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
 class SecurityGroupRulesTestJSON(base.BaseComputeTest):
@@ -94,8 +93,8 @@
         self.addCleanup(self.client.delete_security_group_rule, rule['id'])
         self.assertEqual(200, resp.status)
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
-                      "Skipped until the Bug #1182384 is resolved")
+    @skip_because(bug="1182384",
+                  condition=config.TempestConfig().service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_group_rules_create_with_invalid_id(self):
         # Negative test: Creation of Security Group rule should FAIL
@@ -186,8 +185,8 @@
                           self.client.create_security_group_rule,
                           secgroup_id, ip_protocol, from_port, to_port)
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
-                      "Skipped until the Bug #1182384 is resolved")
+    @skip_because(bug="1182384",
+                  condition=config.TempestConfig().service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_group_rules_delete_with_invalid_id(self):
         # Negative test: Deletion of Security Group rule should be FAIL
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index 5cca3b2..fba2f53 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -22,6 +22,7 @@
 from tempest import config
 from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
 class SecurityGroupsTestJSON(base.BaseComputeTest):
@@ -107,8 +108,8 @@
                          "The fetched Security Group is different "
                          "from the created Group")
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
-                      "Skipped until the Bug #1182384 is resolved")
+    @skip_because(bug="1182384",
+                  condition=config.TempestConfig().service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_group_get_nonexistant_group(self):
         # Negative test:Should not be able to GET the details
@@ -125,8 +126,8 @@
         self.assertRaises(exceptions.NotFound, self.client.get_security_group,
                           non_exist_id)
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
-                      "Skipped until the Bug #1161411 is resolved")
+    @skip_because(bug="1161411",
+                  condition=config.TempestConfig().service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_group_create_with_invalid_group_name(self):
         # Negative test: Security Group should not be created with group name
@@ -145,8 +146,8 @@
                           self.client.create_security_group, s_name,
                           s_description)
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
-                      "Skipped until the Bug #1161411 is resolved")
+    @skip_because(bug="1161411",
+                  condition=config.TempestConfig().service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_security_group_create_with_invalid_group_description(self):
         # Negative test:Security Group should not be created with description
@@ -197,8 +198,8 @@
                           self.client.delete_security_group,
                           default_security_group_id)
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
-                      "Skipped until the Bug #1182384 is resolved")
+    @skip_because(bug="1182384",
+                  condition=config.TempestConfig().service_available.neutron)
     @attr(type=['negative', 'gate'])
     def test_delete_nonexistant_security_group(self):
         # Negative test:Deletion of a non-existent Security Group should Fail
diff --git a/tempest/api/compute/servers/test_list_server_filters.py b/tempest/api/compute/servers/test_list_server_filters.py
index a56bdf3..8e95671 100644
--- a/tempest/api/compute/servers/test_list_server_filters.py
+++ b/tempest/api/compute/servers/test_list_server_filters.py
@@ -15,14 +15,13 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
-
 from tempest.api.compute import base
 from tempest.api import utils
 from tempest.common.utils.data_utils import rand_name
 from tempest import config
 from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
 class ListServerFiltersTestJSON(base.BaseComputeTest):
@@ -58,32 +57,26 @@
             raise RuntimeError("Image %s (image_ref_alt) was not found!" %
                                cls.image_ref_alt)
 
-        cls.s1_name = rand_name('server')
-        resp, cls.s1 = cls.client.create_server(cls.s1_name, cls.image_ref,
-                                                cls.flavor_ref)
-        cls.s2_name = rand_name('server')
-        resp, cls.s2 = cls.client.create_server(cls.s2_name, cls.image_ref_alt,
-                                                cls.flavor_ref)
-        cls.s3_name = rand_name('server')
-        resp, cls.s3 = cls.client.create_server(cls.s3_name, cls.image_ref,
-                                                cls.flavor_ref_alt)
+        cls.s1_name = rand_name(cls.__name__ + '-instance')
+        resp, cls.s1 = cls.create_server(name=cls.s1_name,
+                                         image_id=cls.image_ref,
+                                         flavor=cls.flavor_ref,
+                                         wait_until='ACTIVE')
 
-        cls.client.wait_for_server_status(cls.s1['id'], 'ACTIVE')
-        resp, cls.s1 = cls.client.get_server(cls.s1['id'])
-        cls.client.wait_for_server_status(cls.s2['id'], 'ACTIVE')
-        resp, cls.s2 = cls.client.get_server(cls.s2['id'])
-        cls.client.wait_for_server_status(cls.s3['id'], 'ACTIVE')
-        resp, cls.s3 = cls.client.get_server(cls.s3['id'])
+        cls.s2_name = rand_name(cls.__name__ + '-instance')
+        resp, cls.s2 = cls.create_server(name=cls.s2_name,
+                                         image_id=cls.image_ref_alt,
+                                         flavor=cls.flavor_ref,
+                                         wait_until='ACTIVE')
+
+        cls.s3_name = rand_name(cls.__name__ + '-instance')
+        resp, cls.s3 = cls.create_server(name=cls.s3_name,
+                                         image_id=cls.image_ref,
+                                         flavor=cls.flavor_ref_alt,
+                                         wait_until='ACTIVE')
 
         cls.fixed_network_name = cls.config.compute.fixed_network_name
 
-    @classmethod
-    def tearDownClass(cls):
-        cls.client.delete_server(cls.s1['id'])
-        cls.client.delete_server(cls.s2['id'])
-        cls.client.delete_server(cls.s3['id'])
-        super(ListServerFiltersTestJSON, cls).tearDownClass()
-
     @utils.skip_unless_attr('multiple_images', 'Only one image found')
     @attr(type='gate')
     def test_list_servers_filter_by_image(self):
@@ -185,8 +178,8 @@
 
     @attr(type='gate')
     def test_list_servers_filtered_by_name_wildcard(self):
-        # List all servers that contains 'server' in name
-        params = {'name': 'server'}
+        # List all servers that contains '-instance' in name
+        params = {'name': '-instance'}
         resp, body = self.client.list_servers(params)
         servers = body['servers']
 
@@ -205,11 +198,12 @@
         self.assertNotIn(self.s2_name, map(lambda x: x['name'], servers))
         self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
 
-    @testtools.skip('Skipped until the Bug #1170718 is resolved.')
+    @skip_because(bug="1170718")
     @attr(type='gate')
     def test_list_servers_filtered_by_ip(self):
         # Filter servers by ip
         # Here should be listed 1 server
+        resp, self.s1 = self.client.get_server(self.s1['id'])
         ip = self.s1['addresses'][self.fixed_network_name][0]['addr']
         params = {'ip': ip}
         resp, body = self.client.list_servers(params)
@@ -219,13 +213,14 @@
         self.assertNotIn(self.s2_name, map(lambda x: x['name'], servers))
         self.assertNotIn(self.s3_name, map(lambda x: x['name'], servers))
 
-    @testtools.skipIf(config.TempestConfig().service_available.neutron,
-                      "Skipped until the Bug #1182883 is resolved")
+    @skip_because(bug="1182883",
+                  condition=config.TempestConfig().service_available.neutron)
     @attr(type='gate')
     def test_list_servers_filtered_by_ip_regex(self):
         # Filter servers by regex ip
         # List all servers filtered by part of ip address.
         # Here should be listed all servers
+        resp, self.s1 = self.client.get_server(self.s1['id'])
         ip = self.s1['addresses'][self.fixed_network_name][0]['addr'][0:-3]
         params = {'ip': ip}
         resp, body = self.client.list_servers(params)
diff --git a/tempest/api/compute/servers/test_list_servers_negative.py b/tempest/api/compute/servers/test_list_servers_negative.py
index 1050054..9dd2e27 100644
--- a/tempest/api/compute/servers/test_list_servers_negative.py
+++ b/tempest/api/compute/servers/test_list_servers_negative.py
@@ -28,6 +28,26 @@
     _interface = 'json'
 
     @classmethod
+    def _ensure_no_servers(cls, servers, username, tenant_name):
+        """
+        If there are servers and there is tenant isolation then a
+        skipException is raised to skip the test since it requires no servers
+        to already exist for the given user/tenant.
+        If there are servers and there is not tenant isolation then the test
+        blocks while the servers are being deleted.
+        """
+        if len(servers):
+            if not cls.config.compute.allow_tenant_isolation:
+                for srv in servers:
+                    cls.client.wait_for_server_termination(srv['id'],
+                                                           ignore_error=True)
+            else:
+                msg = ("User/tenant %(u)s/%(t)s already have "
+                       "existing server instances. Skipping test." %
+                       {'u': username, 't': tenant_name})
+                raise cls.skipException(msg)
+
+    @classmethod
     def setUpClass(cls):
         super(ListServersNegativeTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
@@ -54,26 +74,14 @@
         # start of the test instead of destroying any existing
         # servers.
         resp, body = cls.client.list_servers()
-        servers = body['servers']
-        num_servers = len(servers)
-        if num_servers > 0:
-            username = cls.os.username
-            tenant_name = cls.os.tenant_name
-            msg = ("User/tenant %(u)s/%(t)s already have "
-                   "existing server instances. Skipping test." %
-                   {'u': username, 't': tenant_name})
-            raise cls.skipException(msg)
+        cls._ensure_no_servers(body['servers'],
+                               cls.os.username,
+                               cls.os.tenant_name)
 
         resp, body = cls.alt_client.list_servers()
-        servers = body['servers']
-        num_servers = len(servers)
-        if num_servers > 0:
-            username = cls.alt_manager.username
-            tenant_name = cls.alt_manager.tenant_name
-            msg = ("Alt User/tenant %(u)s/%(t)s already have "
-                   "existing server instances. Skipping test." %
-                   {'u': username, 't': tenant_name})
-            raise cls.skipException(msg)
+        cls._ensure_no_servers(body['servers'],
+                               cls.alt_manager.username,
+                               cls.alt_manager.tenant_name)
 
         # The following servers are created for use
         # by the test methods in this class. These
@@ -81,6 +89,7 @@
         # tearDownClass method of the super-class.
         cls.existing_fixtures = []
         cls.deleted_fixtures = []
+        cls.start_time = datetime.datetime.utcnow()
         for x in xrange(2):
             resp, srv = cls.create_server()
             cls.existing_fixtures.append(srv)
@@ -173,8 +182,7 @@
     @attr(type='gate')
     def test_list_servers_by_changes_since(self):
         # Servers are listed by specifying changes-since date
-        since = datetime.datetime.utcnow() - datetime.timedelta(minutes=2)
-        changes_since = {'changes-since': since.isoformat()}
+        changes_since = {'changes-since': self.start_time.isoformat()}
         resp, body = self.client.list_servers(changes_since)
         self.assertEqual('200', resp['status'])
         # changes-since returns all instances, including deleted.
diff --git a/tempest/api/compute/servers/test_server_actions.py b/tempest/api/compute/servers/test_server_actions.py
index 77f92c9..255beb7 100644
--- a/tempest/api/compute/servers/test_server_actions.py
+++ b/tempest/api/compute/servers/test_server_actions.py
@@ -27,6 +27,7 @@
 import tempest.config
 from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
 class ServerActionsTestJSON(base.BaseComputeTest):
@@ -43,13 +44,13 @@
             self.client.wait_for_server_status(self.server_id, 'ACTIVE')
         except Exception:
             # Rebuild server if something happened to it during a test
-            self.rebuild_servers()
+            self.rebuild_server()
 
     @classmethod
     def setUpClass(cls):
         super(ServerActionsTestJSON, cls).setUpClass()
         cls.client = cls.servers_client
-        cls.rebuild_servers()
+        cls.rebuild_server()
 
     @testtools.skipUnless(compute.CHANGE_PASSWORD_AVAILABLE,
                           'Change password not available.')
@@ -86,7 +87,7 @@
             new_boot_time = linux_client.get_boot_time()
             self.assertGreater(new_boot_time, boot_time)
 
-    @testtools.skip('Skipped until the Bug #1014647 is resolved.')
+    @skip_because(bug="1014647")
     @attr(type='smoke')
     def test_reboot_server_soft(self):
         # The server should be signaled to reboot gracefully
@@ -117,7 +118,8 @@
         password = 'rebuildPassw0rd'
         resp, rebuilt_server = self.client.rebuild(self.server_id,
                                                    self.image_ref_alt,
-                                                   name=new_name, meta=meta,
+                                                   name=new_name,
+                                                   metadata=meta,
                                                    personality=personality,
                                                    adminPass=password)
 
@@ -196,6 +198,18 @@
                 raise exceptions.TimeoutException(message)
 
     @attr(type=['negative', 'gate'])
+    def test_resize_server_using_nonexist_flavor(self):
+        flavor_id = -1
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.resize, self.server_id, flavor_id)
+
+    @attr(type=['negative', 'gate'])
+    def test_resize_server_using_null_flavor(self):
+        flavor_id = ""
+        self.assertRaises(exceptions.BadRequest,
+                          self.client.resize, self.server_id, flavor_id)
+
+    @attr(type=['negative', 'gate'])
     def test_reboot_nonexistent_server_soft(self):
         # Negative Test: The server reboot on non existent server should return
         # an error
@@ -213,7 +227,8 @@
         self.assertRaises(exceptions.NotFound,
                           self.client.rebuild,
                           999, self.image_ref_alt,
-                          name=new_name, meta=meta,
+                          name=new_name,
+                          metadata=meta,
                           personality=personality,
                           adminPass='rebuild')
 
@@ -238,7 +253,7 @@
                           self.servers_client.get_console_output,
                           '!@#$%^&*()', 10)
 
-    @testtools.skip('Skipped until the Bug #1014683 is resolved.')
+    @skip_because(bug="1014683")
     @attr(type='gate')
     def test_get_console_output_server_id_in_reboot_status(self):
         # Positive test:Should be able to GET the console output
@@ -271,14 +286,6 @@
         self.assertEqual(202, resp.status)
         self.client.wait_for_server_status(self.server_id, 'ACTIVE')
 
-    @classmethod
-    def rebuild_servers(cls):
-        # Destroy any existing server and creates a new one
-        cls.clear_servers()
-        resp, server = cls.create_server(wait_until='ACTIVE')
-        cls.server_id = server['id']
-        cls.password = server['adminPass']
-
     @attr(type='gate')
     def test_stop_start_server(self):
         resp, server = self.servers_client.stop(self.server_id)
@@ -288,6 +295,27 @@
         self.assertEqual(202, resp.status)
         self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
 
+    @skip_because(bug="1233026")
+    @attr(type='gate')
+    def test_lock_unlock_server(self):
+        # Lock the server,try server stop(exceptions throw),unlock it and retry
+        resp, server = self.servers_client.lock_server(self.server_id)
+        self.assertEqual(202, resp.status)
+        resp, server = self.servers_client.get_server(self.server_id)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(server['status'], 'ACTIVE')
+        # Locked server is not allowed to be stopped by non-admin user
+        self.assertRaises(exceptions.BadRequest,
+                          self.servers_client.stop, self.server_id)
+        resp, server = self.servers_client.unlock_server(self.server_id)
+        self.assertEqual(202, resp.status)
+        resp, server = self.servers_client.stop(self.server_id)
+        self.assertEqual(202, resp.status)
+        self.servers_client.wait_for_server_status(self.server_id, 'SHUTOFF')
+        resp, server = self.servers_client.start(self.server_id)
+        self.assertEqual(202, resp.status)
+        self.servers_client.wait_for_server_status(self.server_id, 'ACTIVE')
+
 
 class ServerActionsTestXML(ServerActionsTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/servers/test_servers.py b/tempest/api/compute/servers/test_servers.py
index 625964c..5ce51c0 100644
--- a/tempest/api/compute/servers/test_servers.py
+++ b/tempest/api/compute/servers/test_servers.py
@@ -112,6 +112,13 @@
         resp, _ = self.client.delete_server(server['id'])
         self.assertEqual('204', resp['status'])
 
+    @attr(type='gate')
+    def test_delete_active_server(self):
+        # Delete a server while it's VM state is Active
+        resp, server = self.create_server(wait_until='ACTIVE')
+        resp, _ = self.client.delete_server(server['id'])
+        self.assertEqual('204', resp['status'])
+
 
 class ServersTestXML(ServersTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/compute/servers/test_servers_negative.py b/tempest/api/compute/servers/test_servers_negative.py
index e864343..c896224 100644
--- a/tempest/api/compute/servers/test_servers_negative.py
+++ b/tempest/api/compute/servers/test_servers_negative.py
@@ -16,6 +16,7 @@
 #    under the License.
 
 import sys
+import uuid
 
 from tempest.api.compute import base
 from tempest import clients
@@ -27,6 +28,13 @@
 class ServersNegativeTestJSON(base.BaseComputeTest):
     _interface = 'json'
 
+    def setUp(self):
+        super(ServersNegativeTestJSON, self).setUp()
+        try:
+            self.client.wait_for_server_status(self.server_id, 'ACTIVE')
+        except Exception:
+            self.rebuild_server()
+
     @classmethod
     def setUpClass(cls):
         super(ServersNegativeTestJSON, cls).setUpClass()
@@ -34,6 +42,8 @@
         cls.img_client = cls.images_client
         cls.alt_os = clients.AltManager()
         cls.alt_client = cls.alt_os.servers_client
+        resp, server = cls.create_server(wait_until='ACTIVE')
+        cls.server_id = server['id']
 
     @attr(type=['negative', 'gate'])
     def test_server_name_blank(self):
@@ -91,8 +101,6 @@
     @attr(type=['negative', 'gate'])
     def test_reboot_deleted_server(self):
         # Reboot a deleted server
-        resp, server = self.create_server()
-        self.server_id = server['id']
         self.client.delete_server(self.server_id)
         self.client.wait_for_server_termination(self.server_id)
         self.assertRaises(exceptions.NotFound, self.client.reboot,
@@ -101,8 +109,6 @@
     @attr(type=['negative', 'gate'])
     def test_pause_paused_server(self):
         # Pause a paused server.
-        resp, server = self.create_server(wait_until='ACTIVE')
-        self.server_id = server['id']
         self.client.pause_server(self.server_id)
         self.client.wait_for_server_status(self.server_id, 'PAUSED')
         self.assertRaises(exceptions.Duplicate,
@@ -112,9 +118,6 @@
     @attr(type=['negative', 'gate'])
     def test_rebuild_deleted_server(self):
         # Rebuild a deleted server
-
-        resp, server = self.create_server()
-        self.server_id = server['id']
         self.client.delete_server(self.server_id)
         self.client.wait_for_server_termination(self.server_id)
 
@@ -194,21 +197,19 @@
     def test_update_server_of_another_tenant(self):
         # Update name of a server that belongs to another tenant
 
-        resp, server = self.create_server(wait_until='ACTIVE')
-        new_name = server['id'] + '_new'
+        new_name = self.server_id + '_new'
         self.assertRaises(exceptions.NotFound,
-                          self.alt_client.update_server, server['id'],
+                          self.alt_client.update_server, self.server_id,
                           name=new_name)
 
     @attr(type=['negative', 'gate'])
     def test_update_server_name_length_exceeds_256(self):
         # Update name of server exceed the name length limit
 
-        resp, server = self.create_server(wait_until='ACTIVE')
         new_name = 'a' * 256
         self.assertRaises(exceptions.BadRequest,
                           self.client.update_server,
-                          server['id'],
+                          self.server_id,
                           name=new_name)
 
     @attr(type=['negative', 'gate'])
@@ -221,10 +222,9 @@
     @attr(type=['negative', 'gate'])
     def test_delete_a_server_of_another_tenant(self):
         # Delete a server that belongs to another tenant
-        resp, server = self.create_server(wait_until='ACTIVE')
         self.assertRaises(exceptions.NotFound,
                           self.alt_client.delete_server,
-                          server['id'])
+                          self.server_id)
 
     @attr(type=['negative', 'gate'])
     def test_delete_server_pass_negative_id(self):
@@ -258,16 +258,56 @@
     @attr(type=['negative', 'gate'])
     def test_stop_non_existent_server(self):
         # Stop a non existent server
-        non_exist_id = rand_name('non-existent-server')
         self.assertRaises(exceptions.NotFound, self.servers_client.stop,
-                          non_exist_id)
+                          str(uuid.uuid4()))
 
     @attr(type=['negative', 'gate'])
     def test_pause_non_existent_server(self):
         # pause a non existent server
-        non_exist_id = rand_name('non-existent-server')
         self.assertRaises(exceptions.NotFound, self.client.pause_server,
-                          non_exist_id)
+                          str(uuid.uuid4()))
+
+    @attr(type=['negative', 'gate'])
+    def test_unpause_non_existent_server(self):
+        # unpause a non existent server
+        self.assertRaises(exceptions.NotFound, self.client.unpause_server,
+                          str(uuid.uuid4()))
+
+    @attr(type=['negative', 'gate'])
+    def test_unpause_server_invalid_state(self):
+        # unpause an active server.
+        self.assertRaises(exceptions.Duplicate,
+                          self.client.unpause_server,
+                          self.server_id)
+
+    @attr(type=['negative', 'gate'])
+    def test_suspend_non_existent_server(self):
+        # suspend a non existent server
+        self.assertRaises(exceptions.NotFound, self.client.suspend_server,
+                          str(uuid.uuid4()))
+
+    @attr(type=['negative', 'gate'])
+    def test_suspend_server_invalid_state(self):
+        # suspend a suspended server.
+        resp, _ = self.client.suspend_server(self.server_id)
+        self.assertEqual(202, resp.status)
+        self.client.wait_for_server_status(self.server_id, 'SUSPENDED')
+        self.assertRaises(exceptions.Duplicate,
+                          self.client.suspend_server,
+                          self.server_id)
+
+    @attr(type=['negative', 'gate'])
+    def test_resume_non_existent_server(self):
+        # resume a non existent server
+        self.assertRaises(exceptions.NotFound, self.client.resume_server,
+                          str(uuid.uuid4()))
+
+    @attr(type=['negative', 'gate'])
+    def test_resume_server_invalid_state(self):
+        # resume an active server.
+        self.assertRaises(exceptions.Duplicate,
+                          self.client.resume_server,
+                          self.server_id)
 
 
 class ServersNegativeTestXML(ServersNegativeTestJSON):
diff --git a/tempest/api/compute/servers/test_virtual_interfaces.py b/tempest/api/compute/servers/test_virtual_interfaces.py
index b743a85..2c7ff32 100644
--- a/tempest/api/compute/servers/test_virtual_interfaces.py
+++ b/tempest/api/compute/servers/test_virtual_interfaces.py
@@ -16,13 +16,13 @@
 #    under the License.
 
 import netaddr
-import testtools
 
 from tempest.api.compute import base
 from tempest.common.utils.data_utils import rand_name
 from tempest import config
 from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
 class VirtualInterfacesTestJSON(base.BaseComputeTest):
@@ -37,8 +37,8 @@
         resp, server = cls.create_server(wait_until='ACTIVE')
         cls.server_id = server['id']
 
-    @testtools.skipIf(CONF.service_available.neutron, "Not implemented by " +
-                      "Neutron. Skipped until the Bug #1183436 is resolved.")
+    @skip_because(bug="1183436",
+                  condition=CONF.service_available.neutron)
     @attr(type='gate')
     def test_list_virtual_interfaces(self):
         # Positive test:Should be able to GET the virtual interfaces list
diff --git a/tempest/api/identity/admin/test_users.py b/tempest/api/identity/admin/test_users.py
index 689ab29..66d35cb 100644
--- a/tempest/api/identity/admin/test_users.py
+++ b/tempest/api/identity/admin/test_users.py
@@ -19,7 +19,6 @@
 
 from tempest.api.identity import base
 from tempest.common.utils.data_utils import rand_name
-from tempest import exceptions
 from tempest.test import attr
 
 
@@ -46,60 +45,19 @@
         self.assertEqual('200', resp['status'])
         self.assertEqual(self.alt_user, user['name'])
 
-    @attr(type=['negative', 'gate'])
-    def test_create_user_by_unauthorized_user(self):
-        # Non-administrator should not be authorized to create a user
+    @attr(type='smoke')
+    def test_create_user_with_enabled(self):
+        # Create a user with enabled : False
         self.data.setup_test_tenant()
-        self.assertRaises(exceptions.Unauthorized,
-                          self.non_admin_client.create_user, self.alt_user,
-                          self.alt_password, self.data.tenant['id'],
-                          self.alt_email)
-
-    @attr(type=['negative', 'gate'])
-    def test_create_user_with_empty_name(self):
-        # User with an empty name should not be created
-        self.data.setup_test_tenant()
-        self.assertRaises(exceptions.BadRequest, self.client.create_user, '',
-                          self.alt_password, self.data.tenant['id'],
-                          self.alt_email)
-
-    @attr(type=['negative', 'gate'])
-    def test_create_user_with_name_length_over_255(self):
-        # Length of user name filed should be restricted to 255 characters
-        self.data.setup_test_tenant()
-        self.assertRaises(exceptions.BadRequest, self.client.create_user,
-                          'a' * 256, self.alt_password,
-                          self.data.tenant['id'], self.alt_email)
-
-    @attr(type=['negative', 'gate'])
-    def test_create_user_with_duplicate_name(self):
-        # Duplicate user should not be created
-        self.data.setup_test_user()
-        self.assertRaises(exceptions.Duplicate, self.client.create_user,
-                          self.data.test_user, self.data.test_password,
-                          self.data.tenant['id'], self.data.test_email)
-
-    @attr(type=['negative', 'gate'])
-    def test_create_user_for_non_existant_tenant(self):
-        # Attempt to create a user in a non-existent tenant should fail
-        self.assertRaises(exceptions.NotFound, self.client.create_user,
-                          self.alt_user, self.alt_password, '49ffgg99999',
-                          self.alt_email)
-
-    @attr(type=['negative', 'gate'])
-    def test_create_user_request_without_a_token(self):
-        # Request to create a user without a valid token should fail
-        self.data.setup_test_tenant()
-        # Get the token of the current client
-        token = self.client.get_auth()
-        # Delete the token from database
-        self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized, self.client.create_user,
-                          self.alt_user, self.alt_password,
-                          self.data.tenant['id'], self.alt_email)
-
-        # Unset the token to allow further tests to generate a new token
-        self.client.clear_auth()
+        name = rand_name('test_user_')
+        resp, user = self.client.create_user(name, self.alt_password,
+                                             self.data.tenant['id'],
+                                             self.alt_email, enabled=False)
+        self.data.users.append(user)
+        self.assertEqual('200', resp['status'])
+        self.assertEqual(name, user['name'])
+        self.assertEqual('false', str(user['enabled']).lower())
+        self.assertEqual(self.alt_email, user['email'])
 
     @attr(type='smoke')
     def test_update_user(self):
@@ -141,20 +99,6 @@
         resp, body = self.client.delete_user(user['id'])
         self.assertEqual('204', resp['status'])
 
-    @attr(type=['negative', 'gate'])
-    def test_delete_users_by_unauthorized_user(self):
-        # Non-administrator user should not be authorized to delete a user
-        self.data.setup_test_user()
-        self.assertRaises(exceptions.Unauthorized,
-                          self.non_admin_client.delete_user,
-                          self.data.user['id'])
-
-    @attr(type=['negative', 'gate'])
-    def test_delete_non_existant_user(self):
-        # Attempt to delete a non-existent user should fail
-        self.assertRaises(exceptions.NotFound, self.client.delete_user,
-                          'junk12345123')
-
     @attr(type='smoke')
     def test_user_authentication(self):
         # Valid user's token is authenticated
@@ -168,51 +112,6 @@
                                             self.data.test_tenant)
         self.assertEqual('200', resp['status'])
 
-    @attr(type=['negative', 'gate'])
-    def test_authentication_for_disabled_user(self):
-        # Disabled user's token should not get authenticated
-        self.data.setup_test_user()
-        self.disable_user(self.data.test_user)
-        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
-                          self.data.test_user,
-                          self.data.test_password,
-                          self.data.test_tenant)
-
-    @attr(type=['negative', 'gate'])
-    def test_authentication_when_tenant_is_disabled(self):
-        # User's token for a disabled tenant should not be authenticated
-        self.data.setup_test_user()
-        self.disable_tenant(self.data.test_tenant)
-        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
-                          self.data.test_user,
-                          self.data.test_password,
-                          self.data.test_tenant)
-
-    @attr(type=['negative', 'gate'])
-    def test_authentication_with_invalid_tenant(self):
-        # User's token for an invalid tenant should not be authenticated
-        self.data.setup_test_user()
-        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
-                          self.data.test_user,
-                          self.data.test_password,
-                          'junktenant1234')
-
-    @attr(type=['negative', 'gate'])
-    def test_authentication_with_invalid_username(self):
-        # Non-existent user's token should not get authenticated
-        self.data.setup_test_user()
-        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
-                          'junkuser123', self.data.test_password,
-                          self.data.test_tenant)
-
-    @attr(type=['negative', 'gate'])
-    def test_authentication_with_invalid_password(self):
-        # User's token with invalid password should not be authenticated
-        self.data.setup_test_user()
-        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
-                          self.data.test_user, 'junkpass1234',
-                          self.data.test_tenant)
-
     @attr(type='gate')
     def test_authentication_request_without_token(self):
         # Request for token authentication with a valid token in header
@@ -239,21 +138,6 @@
                         Contains(self.data.test_user),
                         "Could not find %s" % self.data.test_user)
 
-    @attr(type=['negative', 'gate'])
-    def test_get_users_by_unauthorized_user(self):
-        # Non-administrator user should not be authorized to get user list
-        self.data.setup_test_user()
-        self.assertRaises(exceptions.Unauthorized,
-                          self.non_admin_client.get_users)
-
-    @attr(type=['negative', 'gate'])
-    def test_get_users_request_without_token(self):
-        # Request to get list of users without a valid token should fail
-        token = self.client.get_auth()
-        self.client.delete_token(token)
-        self.assertRaises(exceptions.Unauthorized, self.client.get_users)
-        self.client.clear_auth()
-
     @attr(type='gate')
     def test_list_users_for_tenant(self):
         # Return a list of all users for a tenant
@@ -326,21 +210,6 @@
                          "Failed to find user %s in fetched list" %
                          ', '.join(m_user for m_user in missing_users))
 
-    @attr(type=['negative', 'gate'])
-    def test_list_users_with_invalid_tenant(self):
-        # Should not be able to return a list of all
-        # users for a non-existent tenant
-        # Assign invalid tenant ids
-        invalid_id = list()
-        invalid_id.append(rand_name('999'))
-        invalid_id.append('alpha')
-        invalid_id.append(rand_name("dddd@#%%^$"))
-        invalid_id.append('!@#()$%^&*?<>{}[]')
-        # List the users with invalid tenant id
-        for invalid in invalid_id:
-            self.assertRaises(exceptions.NotFound,
-                              self.client.list_users_for_tenant, invalid)
-
 
 class UsersTestXML(UsersTestJSON):
     _interface = 'xml'
diff --git a/tempest/api/identity/admin/test_users_negative.py b/tempest/api/identity/admin/test_users_negative.py
new file mode 100644
index 0000000..7cb9aef
--- /dev/null
+++ b/tempest/api/identity/admin/test_users_negative.py
@@ -0,0 +1,236 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.identity import base
+from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
+from tempest.test import attr
+import uuid
+
+
+class UsersNegativeTestJSON(base.BaseIdentityAdminTest):
+    _interface = 'json'
+
+    @classmethod
+    def setUpClass(cls):
+        super(UsersNegativeTestJSON, cls).setUpClass()
+        cls.alt_user = rand_name('test_user_')
+        cls.alt_password = rand_name('pass_')
+        cls.alt_email = cls.alt_user + '@testmail.tm'
+        cls.alt_tenant = rand_name('test_tenant_')
+        cls.alt_description = rand_name('desc_')
+
+    @attr(type=['negative', 'gate'])
+    def test_create_user_by_unauthorized_user(self):
+        # Non-administrator should not be authorized to create a user
+        self.data.setup_test_tenant()
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_admin_client.create_user, self.alt_user,
+                          self.alt_password, self.data.tenant['id'],
+                          self.alt_email)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_user_with_empty_name(self):
+        # User with an empty name should not be created
+        self.data.setup_test_tenant()
+        self.assertRaises(exceptions.BadRequest, self.client.create_user, '',
+                          self.alt_password, self.data.tenant['id'],
+                          self.alt_email)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_user_with_name_length_over_255(self):
+        # Length of user name filed should be restricted to 255 characters
+        self.data.setup_test_tenant()
+        self.assertRaises(exceptions.BadRequest, self.client.create_user,
+                          'a' * 256, self.alt_password,
+                          self.data.tenant['id'], self.alt_email)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_user_with_duplicate_name(self):
+        # Duplicate user should not be created
+        self.data.setup_test_user()
+        self.assertRaises(exceptions.Duplicate, self.client.create_user,
+                          self.data.test_user, self.data.test_password,
+                          self.data.tenant['id'], self.data.test_email)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_user_for_non_existant_tenant(self):
+        # Attempt to create a user in a non-existent tenant should fail
+        self.assertRaises(exceptions.NotFound, self.client.create_user,
+                          self.alt_user, self.alt_password, '49ffgg99999',
+                          self.alt_email)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_user_request_without_a_token(self):
+        # Request to create a user without a valid token should fail
+        self.data.setup_test_tenant()
+        # Get the token of the current client
+        token = self.client.get_auth()
+        # Delete the token from database
+        self.client.delete_token(token)
+        self.assertRaises(exceptions.Unauthorized, self.client.create_user,
+                          self.alt_user, self.alt_password,
+                          self.data.tenant['id'], self.alt_email)
+
+        # Unset the token to allow further tests to generate a new token
+        self.client.clear_auth()
+
+    @attr(type=['negative', 'gate'])
+    def test_create_user_with_enabled_non_bool(self):
+        # Attempt to create a user with valid enabled para should fail
+        self.data.setup_test_tenant()
+        name = rand_name('test_user_')
+        self.assertRaises(exceptions.BadRequest, self.client.create_user,
+                          name, self.alt_password,
+                          self.data.tenant['id'],
+                          self.alt_email, enabled=3)
+
+    @attr(type=['negative', 'gate'])
+    def test_update_user_for_non_existant_user(self):
+        # Attempt to update a user non-existent user should fail
+        user_name = rand_name('user-')
+        non_existent_id = str(uuid.uuid4())
+        self.assertRaises(exceptions.NotFound, self.client.update_user,
+                          non_existent_id, name=user_name)
+
+    @attr(type=['negative', 'gate'])
+    def test_update_user_request_without_a_token(self):
+        # Request to update a user without a valid token should fail
+
+        # Get the token of the current client
+        token = self.client.get_auth()
+        # Delete the token from database
+        self.client.delete_token(token)
+        self.assertRaises(exceptions.Unauthorized, self.client.update_user,
+                          self.alt_user)
+
+        # Unset the token to allow further tests to generate a new token
+        self.client.clear_auth()
+
+    @attr(type=['negative', 'gate'])
+    def test_update_user_by_unauthorized_user(self):
+        # Non-administrator should not be authorized to update user
+        self.data.setup_test_tenant()
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_admin_client.update_user, self.alt_user)
+
+    @attr(type=['negative', 'gate'])
+    def test_delete_users_by_unauthorized_user(self):
+        # Non-administrator user should not be authorized to delete a user
+        self.data.setup_test_user()
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_admin_client.delete_user,
+                          self.data.user['id'])
+
+    @attr(type=['negative', 'gate'])
+    def test_delete_non_existant_user(self):
+        # Attempt to delete a non-existent user should fail
+        self.assertRaises(exceptions.NotFound, self.client.delete_user,
+                          'junk12345123')
+
+    @attr(type=['negative', 'gate'])
+    def test_delete_user_request_without_a_token(self):
+        # Request to delete a user without a valid token should fail
+
+        # Get the token of the current client
+        token = self.client.get_auth()
+        # Delete the token from database
+        self.client.delete_token(token)
+        self.assertRaises(exceptions.Unauthorized, self.client.delete_user,
+                          self.alt_user)
+
+        # Unset the token to allow further tests to generate a new token
+        self.client.clear_auth()
+
+    @attr(type=['negative', 'gate'])
+    def test_authentication_for_disabled_user(self):
+        # Disabled user's token should not get authenticated
+        self.data.setup_test_user()
+        self.disable_user(self.data.test_user)
+        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
+                          self.data.test_user,
+                          self.data.test_password,
+                          self.data.test_tenant)
+
+    @attr(type=['negative', 'gate'])
+    def test_authentication_when_tenant_is_disabled(self):
+        # User's token for a disabled tenant should not be authenticated
+        self.data.setup_test_user()
+        self.disable_tenant(self.data.test_tenant)
+        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
+                          self.data.test_user,
+                          self.data.test_password,
+                          self.data.test_tenant)
+
+    @attr(type=['negative', 'gate'])
+    def test_authentication_with_invalid_tenant(self):
+        # User's token for an invalid tenant should not be authenticated
+        self.data.setup_test_user()
+        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
+                          self.data.test_user,
+                          self.data.test_password,
+                          'junktenant1234')
+
+    @attr(type=['negative', 'gate'])
+    def test_authentication_with_invalid_username(self):
+        # Non-existent user's token should not get authenticated
+        self.data.setup_test_user()
+        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
+                          'junkuser123', self.data.test_password,
+                          self.data.test_tenant)
+
+    @attr(type=['negative', 'gate'])
+    def test_authentication_with_invalid_password(self):
+        # User's token with invalid password should not be authenticated
+        self.data.setup_test_user()
+        self.assertRaises(exceptions.Unauthorized, self.token_client.auth,
+                          self.data.test_user, 'junkpass1234',
+                          self.data.test_tenant)
+
+    @attr(type=['negative', 'gate'])
+    def test_get_users_by_unauthorized_user(self):
+        # Non-administrator user should not be authorized to get user list
+        self.data.setup_test_user()
+        self.assertRaises(exceptions.Unauthorized,
+                          self.non_admin_client.get_users)
+
+    @attr(type=['negative', 'gate'])
+    def test_get_users_request_without_token(self):
+        # Request to get list of users without a valid token should fail
+        token = self.client.get_auth()
+        self.client.delete_token(token)
+        self.assertRaises(exceptions.Unauthorized, self.client.get_users)
+        self.client.clear_auth()
+
+    @attr(type=['negative', 'gate'])
+    def test_list_users_with_invalid_tenant(self):
+        # Should not be able to return a list of all
+        # users for a non-existent tenant
+        # Assign invalid tenant ids
+        invalid_id = list()
+        invalid_id.append(rand_name('999'))
+        invalid_id.append('alpha')
+        invalid_id.append(rand_name("dddd@#%%^$"))
+        invalid_id.append('!@#()$%^&*?<>{}[]')
+        # List the users with invalid tenant id
+        for invalid in invalid_id:
+            self.assertRaises(exceptions.NotFound,
+                              self.client.list_users_for_tenant, invalid)
+
+
+class UsersNegativeTestXML(UsersNegativeTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/identity/admin/v3/test_projects.py b/tempest/api/identity/admin/v3/test_projects.py
new file mode 100644
index 0000000..36ced70
--- /dev/null
+++ b/tempest/api/identity/admin/v3/test_projects.py
@@ -0,0 +1,256 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 OpenStack, LLC
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.api.identity import base
+from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
+from tempest.test import attr
+
+
+class ProjectsTestJSON(base.BaseIdentityAdminTest):
+    _interface = 'json'
+
+    def _delete_project(self, project_id):
+        resp, _ = self.v3_client.delete_project(project_id)
+        self.assertEqual(resp['status'], '204')
+        self.assertRaises(
+            exceptions.NotFound, self.v3_client.get_project, project_id)
+
+    @attr(type='gate')
+    def test_project_list_delete(self):
+        # Create several projects and delete them
+        for _ in xrange(3):
+            resp, project = self.v3_client.create_project(
+                rand_name('project-new'))
+            self.addCleanup(self._delete_project, project['id'])
+
+        resp, list_projects = self.v3_client.list_projects()
+        self.assertEqual(resp['status'], '200')
+
+        resp, get_project = self.v3_client.get_project(project['id'])
+        self.assertIn(get_project, list_projects)
+
+    @attr(type='gate')
+    def test_project_create_with_description(self):
+        # Create project with a description
+        project_name = rand_name('project-')
+        project_desc = rand_name('desc-')
+        resp, project = self.v3_client.create_project(
+            project_name, description=project_desc)
+        self.v3data.projects.append(project)
+        st1 = resp['status']
+        project_id = project['id']
+        desc1 = project['description']
+        self.assertEqual(st1, '201')
+        self.assertEqual(desc1, project_desc, 'Description should have '
+                         'been sent in response for create')
+        resp, body = self.v3_client.get_project(project_id)
+        desc2 = body['description']
+        self.assertEqual(desc2, project_desc, 'Description does not appear'
+                         'to be set')
+
+    @attr(type='gate')
+    def test_project_create_enabled(self):
+        # Create a project that is enabled
+        project_name = rand_name('project-')
+        resp, project = self.v3_client.create_project(
+            project_name, enabled=True)
+        self.v3data.projects.append(project)
+        project_id = project['id']
+        st1 = resp['status']
+        en1 = project['enabled']
+        self.assertEqual(st1, '201')
+        self.assertTrue(en1, 'Enable should be True in response')
+        resp, body = self.v3_client.get_project(project_id)
+        en2 = body['enabled']
+        self.assertTrue(en2, 'Enable should be True in lookup')
+
+    @attr(type='gate')
+    def test_project_create_not_enabled(self):
+        # Create a project that is not enabled
+        project_name = rand_name('project-')
+        resp, project = self.v3_client.create_project(
+            project_name, enabled=False)
+        self.v3data.projects.append(project)
+        st1 = resp['status']
+        en1 = project['enabled']
+        self.assertEqual(st1, '201')
+        self.assertEqual('false', str(en1).lower(),
+                         'Enable should be False in response')
+        resp, body = self.v3_client.get_project(project['id'])
+        en2 = body['enabled']
+        self.assertEqual('false', str(en2).lower(),
+                         'Enable should be False in lookup')
+
+    @attr(type='gate')
+    def test_project_update_name(self):
+        # Update name attribute of a project
+        p_name1 = rand_name('project-')
+        resp, project = self.v3_client.create_project(p_name1)
+        self.v3data.projects.append(project)
+
+        resp1_name = project['name']
+
+        p_name2 = rand_name('project2-')
+        resp, body = self.v3_client.update_project(project['id'], name=p_name2)
+        st2 = resp['status']
+        resp2_name = body['name']
+        self.assertEqual(st2, '200')
+        self.assertNotEqual(resp1_name, resp2_name)
+
+        resp, body = self.v3_client.get_project(project['id'])
+        resp3_name = body['name']
+
+        self.assertNotEqual(resp1_name, resp3_name)
+        self.assertEqual(p_name1, resp1_name)
+        self.assertEqual(resp2_name, resp3_name)
+
+    @attr(type='gate')
+    def test_project_update_desc(self):
+        # Update description attribute of a project
+        p_name = rand_name('project-')
+        p_desc = rand_name('desc-')
+        resp, project = self.v3_client.create_project(
+            p_name, description=p_desc)
+        self.v3data.projects.append(project)
+        resp1_desc = project['description']
+
+        p_desc2 = rand_name('desc2-')
+        resp, body = self.v3_client.update_project(
+            project['id'], description=p_desc2)
+        st2 = resp['status']
+        resp2_desc = body['description']
+        self.assertEqual(st2, '200')
+        self.assertNotEqual(resp1_desc, resp2_desc)
+
+        resp, body = self.v3_client.get_project(project['id'])
+        resp3_desc = body['description']
+
+        self.assertNotEqual(resp1_desc, resp3_desc)
+        self.assertEqual(p_desc, resp1_desc)
+        self.assertEqual(resp2_desc, resp3_desc)
+
+    @attr(type='gate')
+    def test_project_update_enable(self):
+        # Update the enabled attribute of a project
+        p_name = rand_name('project-')
+        p_en = False
+        resp, project = self.v3_client.create_project(p_name, enabled=p_en)
+        self.v3data.projects.append(project)
+
+        resp1_en = project['enabled']
+
+        p_en2 = True
+        resp, body = self.v3_client.update_project(
+            project['id'], enabled=p_en2)
+        st2 = resp['status']
+        resp2_en = body['enabled']
+        self.assertEqual(st2, '200')
+        self.assertNotEqual(resp1_en, resp2_en)
+
+        resp, body = self.v3_client.get_project(project['id'])
+        resp3_en = body['enabled']
+
+        self.assertNotEqual(resp1_en, resp3_en)
+        self.assertEqual('false', str(resp1_en).lower())
+        self.assertEqual(resp2_en, resp3_en)
+
+    @attr(type='gate')
+    def test_associate_user_to_project(self):
+        #Associate a user to a project
+        #Create a Project
+        p_name = rand_name('project-')
+        resp, project = self.v3_client.create_project(p_name)
+        self.v3data.projects.append(project)
+
+        #Create a User
+        u_name = rand_name('user-')
+        u_desc = u_name + 'description'
+        u_email = u_name + '@testmail.tm'
+        u_password = rand_name('pass-')
+        resp, user = self.v3_client.create_user(
+            u_name, description=u_desc, password=u_password,
+            email=u_email, project_id=project['id'])
+        self.assertEqual(resp['status'], '201')
+        # Delete the User at the end of this method
+        self.addCleanup(self.v3_client.delete_user, user['id'])
+
+        # Get User To validate the user details
+        resp, new_user_get = self.v3_client.get_user(user['id'])
+        #Assert response body of GET
+        self.assertEqual(u_name, new_user_get['name'])
+        self.assertEqual(u_desc, new_user_get['description'])
+        self.assertEqual(project['id'],
+                         new_user_get['project_id'])
+        self.assertEqual(u_email, new_user_get['email'])
+
+    @attr(type=['negative', 'gate'])
+    def test_list_projects_by_unauthorized_user(self):
+        # Non-admin user should not be able to list projects
+        self.assertRaises(exceptions.Unauthorized,
+                          self.v3_non_admin_client.list_projects)
+
+    @attr(type=['negative', 'gate'])
+    def test_project_create_duplicate(self):
+        # Project names should be unique
+        project_name = rand_name('project-dup-')
+        resp, project = self.v3_client.create_project(project_name)
+        self.v3data.projects.append(project)
+
+        self.assertRaises(
+            exceptions.Duplicate, self.v3_client.create_project, project_name)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_project_by_unauthorized_user(self):
+        # Non-admin user should not be authorized to create a project
+        project_name = rand_name('project-')
+        self.assertRaises(
+            exceptions.Unauthorized, self.v3_non_admin_client.create_project,
+            project_name)
+
+    @attr(type=['negative', 'gate'])
+    def test_create_project_with_empty_name(self):
+        # Project name should not be empty
+        self.assertRaises(exceptions.BadRequest, self.v3_client.create_project,
+                          name='')
+
+    @attr(type=['negative', 'gate'])
+    def test_create_projects_name_length_over_64(self):
+        # Project name length should not be greater than 64 characters
+        project_name = 'a' * 65
+        self.assertRaises(exceptions.BadRequest, self.v3_client.create_project,
+                          project_name)
+
+    @attr(type=['negative', 'gate'])
+    def test_project_delete_by_unauthorized_user(self):
+        # Non-admin user should not be able to delete a project
+        project_name = rand_name('project-')
+        resp, project = self.v3_client.create_project(project_name)
+        self.v3data.projects.append(project)
+        self.assertRaises(
+            exceptions.Unauthorized, self.v3_non_admin_client.delete_project,
+            project['id'])
+
+    @attr(type=['negative', 'gate'])
+    def test_delete_non_existent_project(self):
+        # Attempt to delete a non existent project should fail
+        self.assertRaises(exceptions.NotFound, self.v3_client.delete_project,
+                          'junk_Project_123456abc')
+
+
+class ProjectsTestXML(ProjectsTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/identity/admin/v3/test_tokens.py b/tempest/api/identity/admin/v3/test_tokens.py
index 22d74d3..f8a62a6 100644
--- a/tempest/api/identity/admin/v3/test_tokens.py
+++ b/tempest/api/identity/admin/v3/test_tokens.py
@@ -19,13 +19,11 @@
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
 from tempest.test import attr
-import testtools
 
 
 class UsersTestJSON(base.BaseIdentityAdminTest):
     _interface = 'json'
 
-    @testtools.skip("Skipped until the Bug #1221889 is resolved")
     @attr(type='smoke')
     def test_tokens(self):
         # Valid user's token is authenticated
@@ -51,7 +49,7 @@
         self.assertEqual(token_details['user']['name'], u_name)
         # Perform Delete Token
         resp, _ = self.v3_client.delete_token(subject_token)
-        self.assertRaises(exceptions.Unauthorized, self.v3_client.get_token,
+        self.assertRaises(exceptions.NotFound, self.v3_client.get_token,
                           subject_token)
 
 
diff --git a/tempest/api/identity/base.py b/tempest/api/identity/base.py
index 09fdd22..ab89af4 100644
--- a/tempest/api/identity/base.py
+++ b/tempest/api/identity/base.py
@@ -40,13 +40,16 @@
             raise cls.skipException("Admin extensions disabled")
 
         cls.data = DataGenerator(cls.client)
+        cls.v3data = DataGenerator(cls.v3_client)
 
         os = clients.Manager(interface=cls._interface)
         cls.non_admin_client = os.identity_client
+        cls.v3_non_admin_client = os.identity_v3_client
 
     @classmethod
     def tearDownClass(cls):
         cls.data.teardown_all()
+        cls.v3data.teardown_all()
         super(BaseIdentityAdminTest, cls).tearDownClass()
 
     def disable_user(self, user_name):
@@ -84,6 +87,9 @@
             self.tenants = []
             self.roles = []
             self.role_name = None
+            self.v3_users = []
+            self.projects = []
+            self.v3_roles = []
 
         def setup_test_user(self):
             """Set up a test user."""
@@ -112,6 +118,33 @@
             resp, self.role = self.client.create_role(self.test_role)
             self.roles.append(self.role)
 
+        def setup_test_v3_user(self):
+            """Set up a test v3 user."""
+            self.setup_test_project()
+            self.test_user = rand_name('test_user_')
+            self.test_password = rand_name('pass_')
+            self.test_email = self.test_user + '@testmail.tm'
+            resp, self.v3_user = self.client.create_user(self.test_user,
+                                                         self.test_password,
+                                                         self.project['id'],
+                                                         self.test_email)
+            self.v3_users.append(self.v3_user)
+
+        def setup_test_project(self):
+            """Set up a test project."""
+            self.test_project = rand_name('test_project_')
+            self.test_description = rand_name('desc_')
+            resp, self.project = self.client.create_project(
+                name=self.test_project,
+                description=self.test_description)
+            self.projects.append(self.project)
+
+        def setup_test_v3_role(self):
+            """Set up a test v3 role."""
+            self.test_role = rand_name('role')
+            resp, self.v3_role = self.client.create_role(self.test_role)
+            self.v3_roles.append(self.v3_role)
+
         def teardown_all(self):
             for user in self.users:
                 self.client.delete_user(user['id'])
@@ -119,3 +152,9 @@
                 self.client.delete_tenant(tenant['id'])
             for role in self.roles:
                 self.client.delete_role(role['id'])
+            for v3_user in self.v3_users:
+                self.client.delete_user(v3_user['id'])
+            for v3_project in self.projects:
+                self.client.delete_project(v3_project['id'])
+            for v3_role in self.v3_roles:
+                self.client.delete_role(v3_role['id'])
diff --git a/tempest/api/image/v1/test_image_members.py b/tempest/api/image/v1/test_image_members.py
index fcbde50..9ea9a3d 100644
--- a/tempest/api/image/v1/test_image_members.py
+++ b/tempest/api/image/v1/test_image_members.py
@@ -18,6 +18,8 @@
 
 from tempest.api.image import base
 from tempest import clients
+from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
 from tempest.test import attr
 
 
@@ -26,21 +28,26 @@
     @classmethod
     def setUpClass(cls):
         super(ImageMembersTests, cls).setUpClass()
-        admin = clients.AdminManager(interface='json')
-        cls.admin_client = admin.identity_client
-        cls.tenants = cls._get_tenants()
+        if cls.config.compute.allow_tenant_isolation:
+            creds = cls.isolated_creds.get_alt_creds()
+            username, tenant_name, password = creds
+            cls.os_alt = clients.Manager(username=username,
+                                         password=password,
+                                         tenant_name=tenant_name)
+        else:
+            cls.os_alt = clients.AltManager()
 
-    @classmethod
-    def _get_tenants(cls):
-        resp, tenants = cls.admin_client.list_tenants()
-        tenants = map(lambda x: x['id'], tenants)
-        return tenants
+        alt_tenant_name = cls.os_alt.tenant_name
+        identity_client = cls._get_identity_admin_client()
+        _, tenants = identity_client.list_tenants()
+        cls.alt_tenant_id = [tnt['id'] for tnt in tenants if tnt['name'] ==
+                             alt_tenant_name][0]
 
     def _create_image(self):
         image_file = StringIO.StringIO('*' * 1024)
         resp, image = self.create_image(container_format='bare',
                                         disk_format='raw',
-                                        is_public=True,
+                                        is_public=False,
                                         data=image_file)
         self.assertEqual(201, resp.status)
         image_id = image['id']
@@ -49,23 +56,23 @@
     @attr(type='gate')
     def test_add_image_member(self):
         image = self._create_image()
-        resp = self.client.add_member(self.tenants[0], image)
+        resp = self.client.add_member(self.alt_tenant_id, image)
         self.assertEqual(204, resp.status)
         resp, body = self.client.get_image_membership(image)
         self.assertEqual(200, resp.status)
         members = body['members']
         members = map(lambda x: x['member_id'], members)
-        self.assertIn(self.tenants[0], members)
+        self.assertIn(self.alt_tenant_id, members)
 
     @attr(type='gate')
     def test_get_shared_images(self):
         image = self._create_image()
-        resp = self.client.add_member(self.tenants[0], image)
+        resp = self.client.add_member(self.alt_tenant_id, image)
         self.assertEqual(204, resp.status)
         share_image = self._create_image()
-        resp = self.client.add_member(self.tenants[0], share_image)
+        resp = self.client.add_member(self.alt_tenant_id, share_image)
         self.assertEqual(204, resp.status)
-        resp, body = self.client.get_shared_images(self.tenants[0])
+        resp, body = self.client.get_shared_images(self.alt_tenant_id)
         self.assertEqual(200, resp.status)
         images = body['shared_images']
         images = map(lambda x: x['image_id'], images)
@@ -75,11 +82,33 @@
     @attr(type='gate')
     def test_remove_member(self):
         image_id = self._create_image()
-        resp = self.client.add_member(self.tenants[0], image_id)
+        resp = self.client.add_member(self.alt_tenant_id, image_id)
         self.assertEqual(204, resp.status)
-        resp = self.client.delete_member(self.tenants[0], image_id)
+        resp = self.client.delete_member(self.alt_tenant_id, image_id)
         self.assertEqual(204, resp.status)
         resp, body = self.client.get_image_membership(image_id)
         self.assertEqual(200, resp.status)
         members = body['members']
-        self.assertEqual(0, len(members))
+        self.assertEqual(0, len(members), str(members))
+
+    @attr(type=['negative', 'gate'])
+    def test_add_member_with_non_existing_image(self):
+        # Add member with non existing image.
+        non_exist_image = rand_name('image_')
+        self.assertRaises(exceptions.NotFound, self.client.add_member,
+                          self.alt_tenant_id, non_exist_image)
+
+    @attr(type=['negative', 'gate'])
+    def test_delete_member_with_non_existing_image(self):
+        # Delete member with non existing image.
+        non_exist_image = rand_name('image_')
+        self.assertRaises(exceptions.NotFound, self.client.delete_member,
+                          self.alt_tenant_id, non_exist_image)
+
+    @attr(type=['negative', 'gate'])
+    def test_delete_member_with_non_existing_tenant(self):
+        # Delete member with non existing tenant.
+        image_id = self._create_image()
+        non_exist_tenant = rand_name('tenant_')
+        self.assertRaises(exceptions.NotFound, self.client.delete_member,
+                          non_exist_tenant, image_id)
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index cfac257..c3a66c5 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -56,6 +56,7 @@
         cls.networks = []
         cls.subnets = []
         cls.ports = []
+        cls.routers = []
         cls.pools = []
         cls.vips = []
         cls.members = []
@@ -73,6 +74,8 @@
             cls.client.delete_pool(pool['id'])
         for port in cls.ports:
             cls.client.delete_port(port['id'])
+        for router in cls.routers:
+            cls.client.delete_router(router['id'])
         for subnet in cls.subnets:
             cls.client.delete_subnet(subnet['id'])
         for network in cls.networks:
@@ -125,6 +128,21 @@
         return port
 
     @classmethod
+    def create_router(cls, router_name=None, admin_state_up=False,
+                      external_network_id=None, enable_snat=None):
+        ext_gw_info = {}
+        if external_network_id:
+            ext_gw_info['network_id'] = external_network_id
+        if enable_snat:
+            ext_gw_info['enable_snat'] = enable_snat
+        resp, body = cls.client.create_router(
+            router_name, external_gateway_info=ext_gw_info,
+            admin_state_up=admin_state_up)
+        router = body['router']
+        cls.routers.append(router)
+        return router
+
+    @classmethod
     def create_pool(cls, name, lb_method, protocol, subnet):
         """Wrapper utility that returns a test pool."""
         resp, body = cls.client.create_pool(name, lb_method, protocol,
diff --git a/tempest/api/network/test_extensions.py b/tempest/api/network/test_extensions.py
new file mode 100644
index 0000000..1b27d1b
--- /dev/null
+++ b/tempest/api/network/test_extensions.py
@@ -0,0 +1,79 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 OpenStack, Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+
+from tempest.api.network import base
+from tempest.test import attr
+
+
+class ExtensionsTestJSON(base.BaseNetworkTest):
+    _interface = 'json'
+
+    """
+    Tests the following operations in the Neutron API using the REST client for
+    Neutron:
+
+        List all available extensions
+
+    v2.0 of the Neutron API is assumed. It is also assumed that the following
+    options are defined in the [network] section of etc/tempest.conf:
+
+    """
+
+    @classmethod
+    def setUpClass(cls):
+        super(ExtensionsTestJSON, cls).setUpClass()
+
+    @attr(type='smoke')
+    def test_list_show_extensions(self):
+        # List available extensions for the tenant
+        expected_alias = ['security-group', 'l3_agent_scheduler',
+                          'ext-gw-mode', 'binding', 'quotas',
+                          'agent', 'dhcp_agent_scheduler', 'provider',
+                          'router', 'extraroute', 'external-net',
+                          'allowed-address-pairs', 'extra_dhcp_opt']
+        actual_alias = list()
+        resp, extensions = self.client.list_extensions()
+        self.assertEqual('200', resp['status'])
+        list_extensions = extensions['extensions']
+        # Show and verify the details of the available extensions
+        for ext in list_extensions:
+            ext_name = ext['name']
+            ext_alias = ext['alias']
+            actual_alias.append(ext['alias'])
+            resp, ext_details = self.client.show_extension_details(ext_alias)
+            self.assertEqual('200', resp['status'])
+            ext_details = ext_details['extension']
+
+            self.assertIsNotNone(ext_details)
+            self.assertIn('updated', ext_details.keys())
+            self.assertIn('name', ext_details.keys())
+            self.assertIn('description', ext_details.keys())
+            self.assertIn('namespace', ext_details.keys())
+            self.assertIn('links', ext_details.keys())
+            self.assertIn('alias', ext_details.keys())
+            self.assertEqual(ext_details['name'], ext_name)
+            self.assertEqual(ext_details['alias'], ext_alias)
+            self.assertEqual(ext_details, ext)
+        # Verify if expected extensions are present in the actual list
+        # of extensions returned
+        for e in expected_alias:
+            self.assertIn(e, actual_alias)
+
+
+class ExtensionsTestXML(ExtensionsTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index 017864f..9acb6c5 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -20,7 +20,7 @@
 from tempest.test import attr
 
 
-class FloatingIPTest(base.BaseNetworkTest):
+class FloatingIPTestJSON(base.BaseNetworkTest):
     _interface = 'json'
 
     """
@@ -41,17 +41,15 @@
 
     @classmethod
     def setUpClass(cls):
-        super(FloatingIPTest, cls).setUpClass()
+        super(FloatingIPTestJSON, cls).setUpClass()
         cls.ext_net_id = cls.config.network.public_network_id
 
         # Create network, subnet, router and add interface
         cls.network = cls.create_network()
         cls.subnet = cls.create_subnet(cls.network)
-        resp, router = cls.client.create_router(
+        cls.router = cls.create_router(
             rand_name('router-'),
-            external_gateway_info={"network_id":
-                                   cls.network_cfg.public_network_id})
-        cls.router = router['router']
+            external_network_id=cls.network_cfg.public_network_id)
         resp, _ = cls.client.add_router_interface_with_subnet_id(
             cls.router['id'], cls.subnet['id'])
         cls.port = list()
@@ -66,8 +64,7 @@
                                                           cls.subnet['id'])
         for i in range(2):
             cls.client.delete_port(cls.port[i]['id'])
-        cls.client.delete_router(cls.router['id'])
-        super(FloatingIPTest, cls).tearDownClass()
+        super(FloatingIPTestJSON, cls).tearDownClass()
 
     def _delete_floating_ip(self, floating_ip_id):
         # Deletes a floating IP and verifies if it is deleted or not
@@ -133,3 +130,7 @@
         self.assertIsNone(update_floating_ip['port_id'])
         self.assertIsNone(update_floating_ip['fixed_ip_address'])
         self.assertIsNone(update_floating_ip['router_id'])
+
+
+class FloatingIPTestXML(FloatingIPTestJSON):
+    _interface = 'xml'
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 8b939fe..2cfbf61 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -52,6 +52,8 @@
     @attr(type='smoke')
     def test_create_show_list_update_delete_router(self):
         # Create a router
+        # NOTE(salv-orlando): Do not invoke self.create_router
+        # as we need to check the response code
         name = rand_name('router-')
         resp, create_body = self.client.create_router(
             name, external_gateway_info={
@@ -94,41 +96,37 @@
     def test_add_remove_router_interface_with_subnet_id(self):
         network = self.create_network()
         subnet = self.create_subnet(network)
-        name = rand_name('router-')
-        resp, create_body = self.client.create_router(name)
-        self.addCleanup(self.client.delete_router, create_body['router']['id'])
+        router = self.create_router(rand_name('router-'))
         # Add router interface with subnet id
         resp, interface = self.client.add_router_interface_with_subnet_id(
-            create_body['router']['id'], subnet['id'])
+            router['id'], subnet['id'])
         self.assertEqual('200', resp['status'])
         self.addCleanup(self._remove_router_interface_with_subnet_id,
-                        create_body['router']['id'], subnet['id'])
+                        router['id'], subnet['id'])
         self.assertTrue('subnet_id' in interface.keys())
         self.assertTrue('port_id' in interface.keys())
         # Verify router id is equal to device id in port details
         resp, show_port_body = self.client.show_port(
             interface['port_id'])
         self.assertEqual(show_port_body['port']['device_id'],
-                         create_body['router']['id'])
+                         router['id'])
 
     @attr(type='smoke')
     def test_add_remove_router_interface_with_port_id(self):
         network = self.create_network()
         self.create_subnet(network)
-        name = rand_name('router-')
-        resp, create_body = self.client.create_router(name)
-        self.addCleanup(self.client.delete_router, create_body['router']['id'])
+        router = self.create_router(rand_name('router-'))
         resp, port_body = self.client.create_port(network['id'])
         # add router interface to port created above
         resp, interface = self.client.add_router_interface_with_port_id(
-            create_body['router']['id'], port_body['port']['id'])
+            router['id'], port_body['port']['id'])
         self.assertEqual('200', resp['status'])
         self.addCleanup(self._remove_router_interface_with_port_id,
-                        create_body['router']['id'], port_body['port']['id'])
+                        router['id'], port_body['port']['id'])
         self.assertTrue('subnet_id' in interface.keys())
         self.assertTrue('port_id' in interface.keys())
         # Verify router id is equal to device id in port details
         resp, show_port_body = self.client.show_port(
             interface['port_id'])
         self.assertEqual(show_port_body['port']['device_id'],
-                         create_body['router']['id'])
+                         router['id'])
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index 60ca88a..914dcff 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -16,7 +16,7 @@
 #    under the License.
 
 from tempest.api.network import base
-from tempest.common.utils.data_utils import rand_name
+from tempest.common.utils import data_utils
 from tempest import exceptions
 from tempest.test import attr
 
@@ -66,9 +66,9 @@
         self.assertIsNotNone(found, msg)
 
     @attr(type='smoke')
-    def test_create_show_delete_security_group_and_rule(self):
+    def test_create_show_delete_security_group(self):
         # Create a security group
-        name = rand_name('secgroup-')
+        name = data_utils.rand_name('secgroup-')
         resp, group_create_body = self.client.create_security_group(name)
         self.assertEqual('201', resp['status'])
         self.addCleanup(self._delete_security_group,
@@ -88,14 +88,29 @@
         for secgroup in list_body['security_groups']:
             secgroup_list.append(secgroup['id'])
         self.assertIn(group_create_body['security_group']['id'], secgroup_list)
-        # No Update in security group
-        # Create rule
-        resp, rule_create_body = self.client.create_security_group_rule(
-            group_create_body['security_group']['id']
-        )
+
+    @attr(type='smoke')
+    def test_create_show_delete_security_group_rule(self):
+        # Create a security group
+        name = data_utils.rand_name('secgroup-')
+        resp, group_create_body = self.client.create_security_group(name)
         self.assertEqual('201', resp['status'])
-        self.addCleanup(self._delete_security_group_rule,
-                        rule_create_body['security_group_rule']['id'])
+        self.addCleanup(self._delete_security_group,
+                        group_create_body['security_group']['id'])
+        self.assertEqual(group_create_body['security_group']['name'], name)
+
+        # Create rules for each protocol
+        protocols = ['tcp', 'udp', 'icmp']
+        for protocol in protocols:
+            resp, rule_create_body = self.client.create_security_group_rule(
+                group_create_body['security_group']['id'],
+                protocol=protocol
+            )
+            self.assertEqual('201', resp['status'])
+            self.addCleanup(self._delete_security_group_rule,
+                            rule_create_body['security_group_rule']['id']
+                            )
+
         # Show details of the created security rule
         resp, show_rule_body = self.client.show_security_group_rule(
             rule_create_body['security_group_rule']['id']
@@ -111,13 +126,13 @@
 
     @attr(type=['negative', 'smoke'])
     def test_show_non_existent_security_group(self):
-        non_exist_id = rand_name('secgroup-')
+        non_exist_id = data_utils.rand_name('secgroup-')
         self.assertRaises(exceptions.NotFound, self.client.show_security_group,
                           non_exist_id)
 
     @attr(type=['negative', 'smoke'])
     def test_show_non_existent_security_group_rule(self):
-        non_exist_id = rand_name('rule-')
+        non_exist_id = data_utils.rand_name('rule-')
         self.assertRaises(exceptions.NotFound,
                           self.client.show_security_group_rule,
                           non_exist_id)
diff --git a/tempest/api/object_storage/test_container_sync.py b/tempest/api/object_storage/test_container_sync.py
index a43b2b5..ff9f7bf 100644
--- a/tempest/api/object_storage/test_container_sync.py
+++ b/tempest/api/object_storage/test_container_sync.py
@@ -17,11 +17,10 @@
 
 import time
 
-import testtools
-
 from tempest.api.object_storage import base
 from tempest.common.utils.data_utils import rand_name
 from tempest.test import attr
+from tempest.test import skip_because
 
 
 class ContainerSyncTest(base.BaseObjectTest):
@@ -52,7 +51,7 @@
             cls.delete_containers(cls.containers, client[0], client[1])
         super(ContainerSyncTest, cls).tearDownClass()
 
-    @testtools.skip('Skipped until the Bug #1093743 is resolved.')
+    @skip_because(bug="1093743")
     @attr(type='gate')
     def test_container_synchronization(self):
         # container to container synchronization
diff --git a/tempest/api/object_storage/test_object_expiry.py b/tempest/api/object_storage/test_object_expiry.py
index db38401..cb52d88 100644
--- a/tempest/api/object_storage/test_object_expiry.py
+++ b/tempest/api/object_storage/test_object_expiry.py
@@ -17,13 +17,12 @@
 
 import time
 
-import testtools
-
 from tempest.api.object_storage import base
 from tempest.common.utils.data_utils import arbitrary_string
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
 from tempest.test import attr
+from tempest.test import skip_because
 
 
 class ObjectExpiryTest(base.BaseObjectTest):
@@ -43,7 +42,7 @@
         cls.delete_containers([cls.container_name])
         super(ObjectExpiryTest, cls).tearDownClass()
 
-    @testtools.skip('Skipped until the Bug #1069849 is resolved.')
+    @skip_because(bug="1069849")
     @attr(type='gate')
     def test_get_object_after_expiry_time(self):
         # TODO(harika-vakadi): similar test case has to be created for
diff --git a/tempest/api/object_storage/test_object_services.py b/tempest/api/object_storage/test_object_services.py
index 7c10138..407c3ec 100644
--- a/tempest/api/object_storage/test_object_services.py
+++ b/tempest/api/object_storage/test_object_services.py
@@ -16,7 +16,6 @@
 #    under the License.
 
 import hashlib
-import time
 
 from tempest.api.object_storage import base
 from tempest.common.utils.data_utils import arbitrary_string
@@ -225,44 +224,6 @@
         self.assertEqual(resp[actual_meta_key], meta_value)
 
     @attr(type='gate')
-    def test_get_object_using_temp_url(self):
-        # access object using temporary URL within expiration time
-
-        try:
-            # update account metadata
-            # flag to check if account metadata got updated
-            flag = False
-            key = 'Meta'
-            metadata = {'Temp-URL-Key': key}
-            resp, _ = self.account_client.create_account_metadata(
-                metadata=metadata)
-            self.assertIn(int(resp['status']), HTTP_SUCCESS)
-            flag = True
-            resp, _ = self.account_client.list_account_metadata()
-            self.assertIn('x-account-meta-temp-url-key', resp)
-            self.assertEqual(resp['x-account-meta-temp-url-key'], key)
-
-            # create object
-            object_name = rand_name(name='ObjectTemp')
-            data = arbitrary_string(size=len(object_name),
-                                    base_text=object_name)
-            self.object_client.create_object(self.container_name,
-                                             object_name, data)
-            expires = int(time.time() + 10)
-
-            # trying to get object using temp url with in expiry time
-            _, body = self.object_client.get_object_using_temp_url(
-                self.container_name, object_name,
-                expires, key)
-            self.assertEqual(body, data)
-        finally:
-            if flag:
-                resp, _ = self.account_client.delete_account_metadata(
-                    metadata=metadata)
-                resp, _ = self.account_client.list_account_metadata()
-                self.assertNotIn('x-account-meta-temp-url-key', resp)
-
-    @attr(type='gate')
     def test_object_upload_in_segments(self):
         # create object
         object_name = rand_name(name='LObject')
diff --git a/tempest/api/object_storage/test_object_temp_url.py b/tempest/api/object_storage/test_object_temp_url.py
new file mode 100644
index 0000000..0fd5499
--- /dev/null
+++ b/tempest/api/object_storage/test_object_temp_url.py
@@ -0,0 +1,157 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+# Copyright (C) 2013 eNovance SAS <licensing@enovance.com>
+#
+# Author: Joe H. Rahme <joe.hakim.rahme@enovance.com>
+#
+# Licensed under the Apache License, Version 2.0 (the "License"); you may
+# not use this file except in compliance with the License. You may obtain
+# a copy of the License at
+#
+#      http://www.apache.org/licenses/LICENSE-2.0
+#
+# Unless required by applicable law or agreed to in writing, software
+# distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+# WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+# License for the specific language governing permissions and limitations
+# under the License.
+
+import hashlib
+import hmac
+import time
+import urlparse
+
+from tempest.api.object_storage import base
+from tempest.common.utils.data_utils import arbitrary_string
+from tempest.common.utils.data_utils import rand_name
+from tempest import exceptions
+from tempest.test import attr
+from tempest.test import HTTP_SUCCESS
+
+
+class ObjectTempUrlTest(base.BaseObjectTest):
+
+    @classmethod
+    def setUpClass(cls):
+        super(ObjectTempUrlTest, cls).setUpClass()
+        cls.container_name = rand_name(name='TestContainer')
+        cls.container_client.create_container(cls.container_name)
+        cls.containers = [cls.container_name]
+
+        # update account metadata
+        cls.key = 'Meta'
+        cls.metadata = {'Temp-URL-Key': cls.key}
+        cls.account_client.create_account_metadata(metadata=cls.metadata)
+        cls.account_client_metadata, _ = \
+            cls.account_client.list_account_metadata()
+
+    @classmethod
+    def tearDownClass(cls):
+        resp, _ = cls.account_client.delete_account_metadata(
+            metadata=cls.metadata)
+        resp, _ = cls.account_client.list_account_metadata()
+
+        cls.delete_containers(cls.containers)
+        # delete the user setup created
+        cls.data.teardown_all()
+        super(ObjectTempUrlTest, cls).tearDownClass()
+
+    def setUp(self):
+        super(ObjectTempUrlTest, self).setUp()
+        # make sure the metadata has been set
+        self.assertIn('x-account-meta-temp-url-key',
+                      self.account_client_metadata)
+
+        self.assertEqual(
+            self.account_client_metadata['x-account-meta-temp-url-key'],
+            self.key)
+
+        # create object
+        self.object_name = rand_name(name='ObjectTemp')
+        self.data = arbitrary_string(size=len(self.object_name),
+                                     base_text=self.object_name)
+        self.object_client.create_object(self.container_name,
+                                         self.object_name, self.data)
+
+    def get_temp_url(self, container, object_name, method, expires,
+                     key):
+        """Create the temporary URL."""
+
+        path = "%s/%s/%s" % (
+            urlparse.urlparse(self.object_client.base_url).path,
+            container, object_name)
+
+        hmac_body = '%s\n%s\n%s' % (method, expires, path)
+        sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest()
+
+        url = "%s/%s?temp_url_sig=%s&temp_url_expires=%s" % (container,
+                                                             object_name,
+                                                             sig, expires)
+
+        return url
+
+    @attr(type='gate')
+    def test_get_object_using_temp_url(self):
+        EXPIRATION_TIME = 10000  # high to ensure the test finishes.
+        expires = int(time.time() + EXPIRATION_TIME)
+
+        # get a temp URL for the created object
+        url = self.get_temp_url(self.container_name,
+                                self.object_name, "GET",
+                                expires, self.key)
+
+        # trying to get object using temp url within expiry time
+        _, body = self.object_client.get_object_using_temp_url(url)
+
+        self.assertEqual(body, self.data)
+
+        # Testing a HEAD on this Temp URL
+        resp, body = self.object_client.head(url)
+        self.assertIn(int(resp['status']), HTTP_SUCCESS)
+
+    @attr(type='gate')
+    def test_put_object_using_temp_url(self):
+        # make sure the metadata has been set
+        new_data = arbitrary_string(size=len(self.object_name),
+                                    base_text=rand_name(name="random"))
+
+        EXPIRATION_TIME = 10000  # high to ensure the test finishes.
+        expires = int(time.time() + EXPIRATION_TIME)
+
+        url = self.get_temp_url(self.container_name,
+                                self.object_name, "PUT",
+                                expires, self.key)
+
+        # trying to put random data in the object using temp url
+        resp, body = self.object_client.put_object_using_temp_url(
+            url, new_data)
+
+        self.assertIn(int(resp['status']), HTTP_SUCCESS)
+
+        # Testing a HEAD on this Temp URL
+        resp, body = self.object_client.head(url)
+        self.assertIn(int(resp['status']), HTTP_SUCCESS)
+
+        # Validate that the content of the object has been modified
+        url = self.get_temp_url(self.container_name,
+                                self.object_name, "GET",
+                                expires, self.key)
+
+        _, body = self.object_client.get_object_using_temp_url(url)
+        self.assertEqual(body, new_data)
+
+    @attr(type=['gate', 'negative'])
+    def test_get_object_after_expiration_time(self):
+        EXPIRATION_TIME = 1
+        expires = int(time.time() + EXPIRATION_TIME)
+
+        # get a temp URL for the created object
+        url = self.get_temp_url(self.container_name,
+                                self.object_name, "GET",
+                                expires, self.key)
+
+        # temp URL is valid for 1 seconds, let's wait 3
+        time.sleep(EXPIRATION_TIME + 2)
+
+        self.assertRaises(exceptions.Unauthorized,
+                          self.object_client.get_object_using_temp_url,
+                          url)
diff --git a/tempest/api/orchestration/base.py b/tempest/api/orchestration/base.py
index 2a72c95..7c72991 100644
--- a/tempest/api/orchestration/base.py
+++ b/tempest/api/orchestration/base.py
@@ -31,6 +31,7 @@
         super(BaseOrchestrationTest, cls).setUpClass()
         os = clients.OrchestrationManager()
         cls.orchestration_cfg = os.config.orchestration
+        cls.compute_cfg = os.config.compute
         if not os.config.service_available.heat:
             raise cls.skipException("Heat support is required")
         cls.build_timeout = cls.orchestration_cfg.build_timeout
@@ -40,10 +41,18 @@
         cls.orchestration_client = os.orchestration_client
         cls.servers_client = os.servers_client
         cls.keypairs_client = os.keypairs_client
+        cls.network_client = os.network_client
         cls.stacks = []
         cls.keypairs = []
 
     @classmethod
+    def _get_default_network(cls):
+        resp, networks = cls.network_client.list_networks()
+        for net in networks['networks']:
+            if net['name'] == cls.compute_cfg.fixed_network_name:
+                return net
+
+    @classmethod
     def _get_identity_admin_client(cls):
         """
         Returns an instance of the Identity Admin API client
diff --git a/tempest/api/orchestration/stacks/test_non_empty_stack.py b/tempest/api/orchestration/stacks/test_non_empty_stack.py
index defb910..0ecc5ff 100644
--- a/tempest/api/orchestration/stacks/test_non_empty_stack.py
+++ b/tempest/api/orchestration/stacks/test_non_empty_stack.py
@@ -36,6 +36,8 @@
     Type: String
   ImageId:
     Type: String
+  Subnet:
+    Type: String
 Resources:
   SmokeServer:
     Type: AWS::EC2::Instance
@@ -45,6 +47,7 @@
       ImageId: {Ref: ImageId}
       InstanceType: {Ref: InstanceType}
       KeyName: {Ref: KeyName}
+      SubnetId: {Ref: Subnet}
       UserData:
         Fn::Base64:
           Fn::Join:
@@ -78,13 +81,15 @@
                         cls._create_keypair()['name'])
 
         # create the stack
+        subnet = cls._get_default_network()['subnets'][0]
         cls.stack_identifier = cls.create_stack(
             cls.stack_name,
             cls.template,
             parameters={
                 'KeyName': keypair_name,
                 'InstanceType': cls.orchestration_cfg.instance_type,
-                'ImageId': cls.orchestration_cfg.image_ref
+                'ImageId': cls.orchestration_cfg.image_ref,
+                'Subnet': subnet
             })
         cls.stack_id = cls.stack_identifier.split('/')[1]
         cls.resource_name = 'SmokeServer'
diff --git a/tempest/api/orchestration/stacks/test_server_cfn_init.py b/tempest/api/orchestration/stacks/test_server_cfn_init.py
index 41849d0..ea0bff5 100644
--- a/tempest/api/orchestration/stacks/test_server_cfn_init.py
+++ b/tempest/api/orchestration/stacks/test_server_cfn_init.py
@@ -43,6 +43,8 @@
     Type: String
   image:
     Type: String
+  network:
+    Type: String
 Resources:
   CfnUser:
     Type: AWS::IAM::User
@@ -88,6 +90,8 @@
       key_name: {Ref: key_name}
       security_groups:
       - {Ref: SmokeSecurityGroup}
+      networks:
+      - uuid: {Ref: network}
       user_data:
         Fn::Base64:
           Fn::Join:
@@ -118,7 +122,7 @@
   SmokeServerIp:
     Description: IP address of server
     Value:
-      Fn::GetAtt: [SmokeServer, first_private_address]
+      Fn::GetAtt: [SmokeServer, first_address]
 """
 
     @classmethod
@@ -142,7 +146,8 @@
             parameters={
                 'key_name': keypair_name,
                 'flavor': cls.orchestration_cfg.instance_type,
-                'image': cls.orchestration_cfg.image_ref
+                'image': cls.orchestration_cfg.image_ref,
+                'network': cls._get_default_network()['id']
             })
 
     @attr(type='slow')
diff --git a/tempest/api/volume/test_volumes_actions.py b/tempest/api/volume/test_volumes_actions.py
index 19e3fc6..09131e2 100644
--- a/tempest/api/volume/test_volumes_actions.py
+++ b/tempest/api/volume/test_volumes_actions.py
@@ -32,8 +32,8 @@
         cls.image_client = cls.os.image_client
 
         # Create a test shared instance and volume for attach/detach tests
-        srv_name = rand_name('Instance-')
-        vol_name = rand_name('Volume-')
+        srv_name = rand_name(cls.__name__ + '-Instance-')
+        vol_name = rand_name(cls.__name__ + '-Volume-')
         resp, cls.server = cls.servers_client.create_server(srv_name,
                                                             cls.image_ref,
                                                             cls.flavor_ref)
diff --git a/tempest/api/volume/test_volumes_get.py b/tempest/api/volume/test_volumes_get.py
index 119e3e0..f2915f7 100644
--- a/tempest/api/volume/test_volumes_get.py
+++ b/tempest/api/volume/test_volumes_get.py
@@ -34,6 +34,15 @@
         self.assertEqual(202, resp.status)
         self.client.wait_for_resource_deletion(volume_id)
 
+    def _is_true(self, val):
+        # NOTE(jdg): Temporary conversion method to get cinder patch
+        # merged.  Then we'll make this strict again and
+        #specifically check "true" or "false"
+        if val in ['true', 'True', True]:
+            return True
+        else:
+            return False
+
     def _volume_create_get_update_delete(self, **kwargs):
         # Create a volume, Get it's details and Delete the volume
         volume = {}
@@ -69,10 +78,14 @@
                          fetched_volume['metadata'],
                          'The fetched Volume is different '
                          'from the created Volume')
+
+        # NOTE(jdg): Revert back to strict true/false checking
+        # after fix for bug #1227837 merges
+        boot_flag = self._is_true(fetched_volume['bootable'])
         if 'imageRef' in kwargs:
-            self.assertEqual(fetched_volume['bootable'], True)
+            self.assertEqual(boot_flag, True)
         if 'imageRef' not in kwargs:
-            self.assertEqual(fetched_volume['bootable'], False)
+            self.assertEqual(boot_flag, False)
 
         # Update Volume
         new_v_name = rand_name('new-Volume')
@@ -92,10 +105,14 @@
         self.assertEqual(new_v_name, updated_volume['display_name'])
         self.assertEqual(new_desc, updated_volume['display_description'])
         self.assertEqual(metadata, updated_volume['metadata'])
+
+        # NOTE(jdg): Revert back to strict true/false checking
+        # after fix for bug #1227837 merges
+        boot_flag = self._is_true(updated_volume['bootable'])
         if 'imageRef' in kwargs:
-            self.assertEqual(updated_volume['bootable'], True)
+            self.assertEqual(boot_flag, True)
         if 'imageRef' not in kwargs:
-            self.assertEqual(updated_volume['bootable'], False)
+            self.assertEqual(boot_flag, False)
 
     @attr(type='gate')
     def test_volume_get_metadata_none(self):
diff --git a/tempest/api/volume/test_volumes_list.py b/tempest/api/volume/test_volumes_list.py
index 32eecfb..2aaa71d 100644
--- a/tempest/api/volume/test_volumes_list.py
+++ b/tempest/api/volume/test_volumes_list.py
@@ -1,6 +1,7 @@
 # vim: tabstop=4 shiftwidth=4 softtabstop=4
 
 # Copyright 2012 OpenStack Foundation
+# Copyright 2013 IBM Corp.
 # All Rights Reserved.
 #
 #    Licensed under the Apache License, Version 2.0 (the "License"); you may
@@ -16,6 +17,7 @@
 #    under the License.
 
 from tempest.api.volume import base
+from tempest.common.utils.data_utils import rand_int_id
 from tempest.common.utils.data_utils import rand_name
 from tempest.openstack.common import log as logging
 from tempest.test import attr
@@ -103,6 +105,66 @@
         self.assertEqual(200, resp.status)
         self.assertVolumesIn(fetched_list, self.volume_list)
 
+    @attr(type='gate')
+    def test_volume_list_by_name(self):
+        volume = self.volume_list[rand_int_id(0, 2)]
+        params = {'display_name': volume['display_name']}
+        resp, fetched_vol = self.client.list_volumes(params)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(1, len(fetched_vol), str(fetched_vol))
+        self.assertEqual(fetched_vol[0]['display_name'],
+                         volume['display_name'])
+
+    @attr(type='gate')
+    def test_volume_list_details_by_name(self):
+        volume = self.volume_list[rand_int_id(0, 2)]
+        params = {'display_name': volume['display_name']}
+        resp, fetched_vol = self.client.list_volumes_with_detail(params)
+        self.assertEqual(200, resp.status)
+        self.assertEqual(1, len(fetched_vol), str(fetched_vol))
+        self.assertEqual(fetched_vol[0]['display_name'],
+                         volume['display_name'])
+
+    @attr(type='gate')
+    def test_volumes_list_by_status(self):
+        params = {'status': 'available'}
+        resp, fetched_list = self.client.list_volumes(params)
+        self.assertEqual(200, resp.status)
+        for volume in fetched_list:
+            self.assertEqual('available', volume['status'])
+        self.assertVolumesIn(fetched_list, self.volume_list)
+
+    @attr(type='gate')
+    def test_volumes_list_details_by_status(self):
+        params = {'status': 'available'}
+        resp, fetched_list = self.client.list_volumes_with_detail(params)
+        self.assertEqual(200, resp.status)
+        for volume in fetched_list:
+            self.assertEqual('available', volume['status'])
+        self.assertVolumesIn(fetched_list, self.volume_list)
+
+    @attr(type='gate')
+    def test_volumes_list_by_availability_zone(self):
+        volume = self.volume_list[rand_int_id(0, 2)]
+        zone = volume['availability_zone']
+        params = {'availability_zone': zone}
+        resp, fetched_list = self.client.list_volumes(params)
+        self.assertEqual(200, resp.status)
+        for volume in fetched_list:
+            self.assertEqual(zone, volume['availability_zone'])
+        self.assertVolumesIn(fetched_list, self.volume_list)
+
+    @attr(type='gate')
+    def test_volumes_list_details_by_availability_zone(self):
+        volume = self.volume_list[rand_int_id(0, 2)]
+        zone = volume['availability_zone']
+        params = {'availability_zone': zone}
+        resp, fetched_list = self.client.list_volumes_with_detail(params)
+        self.assertEqual(200, resp.status)
+        for volume in fetched_list:
+            self.assertEqual(zone, volume['availability_zone'])
+        self.assertVolumesIn(fetched_list, self.volume_list)
+
 
 class VolumeListTestXML(VolumesListTest):
     _interface = 'xml'
diff --git a/tempest/api/volume/test_volumes_negative.py b/tempest/api/volume/test_volumes_negative.py
index 7eeb1ee..3e2b6ad 100644
--- a/tempest/api/volume/test_volumes_negative.py
+++ b/tempest/api/volume/test_volumes_negative.py
@@ -15,6 +15,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import uuid
+
 from tempest.api.volume import base
 from tempest.common.utils.data_utils import rand_name
 from tempest import exceptions
@@ -29,39 +31,26 @@
         super(VolumesNegativeTest, cls).setUpClass()
         cls.client = cls.volumes_client
 
-    @attr(type='gate')
+        # Create a test shared instance and volume for attach/detach tests
+        vol_name = rand_name('Volume-')
+
+        cls.volume = cls.create_volume(size=1, display_name=vol_name)
+        cls.client.wait_for_volume_status(cls.volume['id'], 'available')
+        cls.mountpoint = "/dev/vdc"
+
+    @attr(type=['negative', 'gate'])
     def test_volume_get_nonexistant_volume_id(self):
-        # Should not be able to get a non-existent volume
-        # Creating a non-existent volume id
-        volume_id_list = []
-        resp, volumes = self.client.list_volumes()
-        for i in range(len(volumes)):
-            volume_id_list.append(volumes[i]['id'])
-        while True:
-            non_exist_id = rand_name('999')
-            if non_exist_id not in volume_id_list:
-                break
-        # Trying to Get a non-existent volume
+        # Should not be able to get a non-existant volume
         self.assertRaises(exceptions.NotFound, self.client.get_volume,
-                          non_exist_id)
+                          str(uuid.uuid4()))
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
     def test_volume_delete_nonexistant_volume_id(self):
-        # Should not be able to delete a non-existent Volume
-        # Creating non-existent volume id
-        volume_id_list = []
-        resp, volumes = self.client.list_volumes()
-        for i in range(len(volumes)):
-            volume_id_list.append(volumes[i]['id'])
-        while True:
-            non_exist_id = '12345678-abcd-4321-abcd-123456789098'
-            if non_exist_id not in volume_id_list:
-                break
-        # Try to delete a non-existent volume
+        # Should not be able to delete a non-existant Volume
         self.assertRaises(exceptions.NotFound, self.client.delete_volume,
-                          non_exist_id)
+                          str(uuid.uuid4()))
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
     def test_create_volume_with_invalid_size(self):
         # Should not be able to create volume with invalid size
         # in request
@@ -70,7 +59,7 @@
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='#$%', display_name=v_name, metadata=metadata)
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
     def test_create_volume_with_out_passing_size(self):
         # Should not be able to create volume without passing size
         # in request
@@ -79,7 +68,7 @@
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='', display_name=v_name, metadata=metadata)
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
     def test_create_volume_with_size_zero(self):
         # Should not be able to create volume with size zero
         v_name = rand_name('Volume-')
@@ -87,28 +76,80 @@
         self.assertRaises(exceptions.BadRequest, self.client.create_volume,
                           size='0', display_name=v_name, metadata=metadata)
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
+    def test_create_volume_with_size_negative(self):
+        # Should not be able to create volume with size negative
+        v_name = rand_name('Volume-')
+        metadata = {'Type': 'work'}
+        self.assertRaises(exceptions.BadRequest, self.client.create_volume,
+                          size='-1', display_name=v_name, metadata=metadata)
+
+    @attr(type=['negative', 'gate'])
+    def test_update_volume_with_nonexistant_volume_id(self):
+        v_name = rand_name('Volume-')
+        metadata = {'Type': 'work'}
+        self.assertRaises(exceptions.NotFound, self.client.update_volume,
+                          volume_id=str(uuid.uuid4()), display_name=v_name,
+                          metadata=metadata)
+
+    @attr(type=['negative', 'gate'])
+    def test_update_volume_with_invalid_volume_id(self):
+        v_name = rand_name('Volume-')
+        metadata = {'Type': 'work'}
+        self.assertRaises(exceptions.NotFound, self.client.update_volume,
+                          volume_id='#$%%&^&^', display_name=v_name,
+                          metadata=metadata)
+
+    @attr(type=['negative', 'gate'])
+    def test_update_volume_with_empty_volume_id(self):
+        v_name = rand_name('Volume-')
+        metadata = {'Type': 'work'}
+        self.assertRaises(exceptions.NotFound, self.client.update_volume,
+                          volume_id='', display_name=v_name,
+                          metadata=metadata)
+
+    @attr(type=['negative', 'gate'])
     def test_get_invalid_volume_id(self):
         # Should not be able to get volume with invalid id
         self.assertRaises(exceptions.NotFound, self.client.get_volume,
                           '#$%%&^&^')
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
     def test_get_volume_without_passing_volume_id(self):
         # Should not be able to get volume when empty ID is passed
         self.assertRaises(exceptions.NotFound, self.client.get_volume, '')
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
     def test_delete_invalid_volume_id(self):
         # Should not be able to delete volume when invalid ID is passed
         self.assertRaises(exceptions.NotFound, self.client.delete_volume,
                           '!@#$%^&*()')
 
-    @attr(type='gate')
+    @attr(type=['negative', 'gate'])
     def test_delete_volume_without_passing_volume_id(self):
         # Should not be able to delete volume when empty ID is passed
         self.assertRaises(exceptions.NotFound, self.client.delete_volume, '')
 
+    @attr(type=['negative', 'gate'])
+    def test_attach_volumes_with_nonexistent_volume_id(self):
+        srv_name = rand_name('Instance-')
+        resp, server = self.servers_client.create_server(srv_name,
+                                                         self.image_ref,
+                                                         self.flavor_ref)
+        self.addCleanup(self.servers_client.delete_server, server['id'])
+        self.servers_client.wait_for_server_status(server['id'], 'ACTIVE')
+        self.assertRaises(exceptions.NotFound,
+                          self.client.attach_volume,
+                          str(uuid.uuid4()),
+                          server['id'],
+                          self.mountpoint)
+
+    @attr(type=['negative', 'gate'])
+    def test_detach_volumes_with_invalid_volume_id(self):
+        self.assertRaises(exceptions.NotFound,
+                          self.client.detach_volume,
+                          'xxx')
+
 
 class VolumesNegativeTestXML(VolumesNegativeTest):
     _interface = 'xml'
diff --git a/tempest/cli/simple_read_only/test_cinder.py b/tempest/cli/simple_read_only/test_cinder.py
index 3ff997a..25157a4 100644
--- a/tempest/cli/simple_read_only/test_cinder.py
+++ b/tempest/cli/simple_read_only/test_cinder.py
@@ -84,6 +84,24 @@
         roles = self.parser.listing(self.cinder('list-extensions'))
         self.assertTableStruct(roles, ['Name', 'Summary', 'Alias', 'Updated'])
 
+    def test_cinder_credentials(self):
+        self.cinder('credentials')
+
+    def test_cinder_availability_zone_list(self):
+        self.cinder('availability-zone-list')
+
+    def test_cinder_endpoints(self):
+        self.cinder('endpoints')
+
+    def test_cinder_service_list(self):
+        self.cinder('service-list')
+
+    def test_cinder_transfer_list(self):
+        self.cinder('transfer-list')
+
+    def test_cinder_bash_completion(self):
+        self.cinder('bash-completion')
+
     def test_admin_help(self):
         help_text = self.cinder('help')
         lines = help_text.split('\n')
diff --git a/tempest/cli/simple_read_only/test_keystone.py b/tempest/cli/simple_read_only/test_keystone.py
index 4c1c27f..a7e7147 100644
--- a/tempest/cli/simple_read_only/test_keystone.py
+++ b/tempest/cli/simple_read_only/test_keystone.py
@@ -50,7 +50,10 @@
                 self.assertTrue(svc['__label'].startswith('Service:'),
                                 msg=('Invalid beginning of service block: '
                                      '%s' % svc['__label']))
-            self.assertIn('id', svc.keys())
+            # check that region and publicURL exists. One might also
+            # check for adminURL and internalURL. id seems to be optional
+            # and is missing in the catalog backend
+            self.assertIn('publicURL', svc.keys())
             self.assertIn('region', svc.keys())
 
     def test_admin_endpoint_list(self):
diff --git a/tempest/cli/simple_read_only/test_neutron.py b/tempest/cli/simple_read_only/test_neutron.py
index ae3a1a7..3c266be 100644
--- a/tempest/cli/simple_read_only/test_neutron.py
+++ b/tempest/cli/simple_read_only/test_neutron.py
@@ -67,6 +67,12 @@
     def test_neutron_floatingip_list(self):
         self.neutron('floatingip-list')
 
+    def test_neutron_meter_label_list(self):
+        self.neutron('meter-label-list')
+
+    def test_neutron_meter_label_rule_list(self):
+        self.neutron('meter-label-rule-list')
+
     def test_neutron_net_external_list(self):
         self.neutron('net-external-list')
 
diff --git a/tempest/cli/simple_read_only/test_compute.py b/tempest/cli/simple_read_only/test_nova.py
similarity index 97%
rename from tempest/cli/simple_read_only/test_compute.py
rename to tempest/cli/simple_read_only/test_nova.py
index 9b358e6..94415f0 100644
--- a/tempest/cli/simple_read_only/test_compute.py
+++ b/tempest/cli/simple_read_only/test_nova.py
@@ -167,6 +167,10 @@
     def test_admin_net_list(self):
         self.nova('net-list')
 
+    def test_agent_list(self):
+        self.nova('agent-list')
+        self.nova('agent-list', flags='--debug')
+
     # Optional arguments:
 
     def test_admin_version(self):
diff --git a/tempest/cli/simple_read_only/test_compute_manage.py b/tempest/cli/simple_read_only/test_nova_manage.py
similarity index 92%
rename from tempest/cli/simple_read_only/test_compute_manage.py
rename to tempest/cli/simple_read_only/test_nova_manage.py
index 523c65f..9a33556 100644
--- a/tempest/cli/simple_read_only/test_compute_manage.py
+++ b/tempest/cli/simple_read_only/test_nova_manage.py
@@ -81,3 +81,11 @@
 
     def test_db_version(self):
         self.assertNotEqual("", self.nova_manage('db version'))
+
+    def test_cell_list(self):
+        # make sure command doesn't error out
+        self.nova_manage('cell list')
+
+    def test_host_list(self):
+        # make sure command doesn't error out
+        self.nova_manage('host list')
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index d6b4466..8c82ec0 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -14,7 +14,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import keystoneclient.v2_0.client
+import netaddr
+
+import keystoneclient.v2_0.client as keystoneclient
+import neutronclient.v2_0.client as neutronclient
 
 from tempest import clients
 from tempest.common.utils.data_utils import rand_name
@@ -30,97 +33,118 @@
     def __init__(self, name, tempest_client=True, interface='json',
                  password='pass'):
         self.isolated_creds = {}
+        self.isolated_net_resources = {}
+        self.ports = []
         self.name = name
         self.config = config.TempestConfig()
         self.tempest_client = tempest_client
         self.interface = interface
         self.password = password
-        self.admin_client = self._get_identity_admin_client()
+        self.identity_admin_client, self.network_admin_client = (
+            self._get_admin_clients())
 
-    def _get_keystone_client(self):
+    def _get_official_admin_clients(self):
         username = self.config.identity.admin_username
         password = self.config.identity.admin_password
         tenant_name = self.config.identity.admin_tenant_name
         auth_url = self.config.identity.uri
         dscv = self.config.identity.disable_ssl_certificate_validation
-        return keystoneclient.v2_0.client.Client(username=username,
-                                                 password=password,
-                                                 tenant_name=tenant_name,
-                                                 auth_url=auth_url,
-                                                 insecure=dscv)
+        identity_client = keystoneclient.Client(username=username,
+                                                password=password,
+                                                tenant_name=tenant_name,
+                                                auth_url=auth_url,
+                                                insecure=dscv)
+        network_client = neutronclient.Client(username=username,
+                                              password=password,
+                                              tenant_name=tenant_name,
+                                              auth_url=auth_url,
+                                              insecure=dscv)
+        return identity_client, network_client
 
-    def _get_identity_admin_client(self):
+    def _get_admin_clients(self):
         """
-        Returns an instance of the Identity Admin API client
+        Returns a tuple with instances of the following admin clients (in this
+        order):
+            identity
+            network
         """
         if self.tempest_client:
             os = clients.AdminManager(interface=self.interface)
-            admin_client = os.identity_client
+            admin_clients = (os.identity_client,
+                             os.network_client,)
         else:
-            admin_client = self._get_keystone_client()
-        return admin_client
+            admin_clients = self._get_official_admin_clients()
+        return admin_clients
 
     def _create_tenant(self, name, description):
         if self.tempest_client:
-            resp, tenant = self.admin_client.create_tenant(
+            resp, tenant = self.identity_admin_client.create_tenant(
                 name=name, description=description)
         else:
-            tenant = self.admin_client.tenants.create(name,
-                                                      description=description)
+            tenant = self.identity_admin_client.tenants.create(
+                name,
+                description=description)
         return tenant
 
     def _get_tenant_by_name(self, name):
         if self.tempest_client:
-            resp, tenant = self.admin_client.get_tenant_by_name(name)
+            resp, tenant = self.identity_admin_client.get_tenant_by_name(name)
         else:
-            tenants = self.admin_client.tenants.list()
+            tenants = self.identity_admin_client.tenants.list()
             for ten in tenants:
                 if ten['name'] == name:
                     tenant = ten
-            raise exceptions.NotFound('No such tenant')
+                    break
+            else:
+                raise exceptions.NotFound('No such tenant')
         return tenant
 
     def _create_user(self, username, password, tenant, email):
         if self.tempest_client:
-            resp, user = self.admin_client.create_user(username, password,
-                                                       tenant['id'], email)
+            resp, user = self.identity_admin_client.create_user(username,
+                                                                password,
+                                                                tenant['id'],
+                                                                email)
         else:
-            user = self.admin_client.users.create(username, password, email,
-                                                  tenant_id=tenant.id)
+            user = self.identity_admin_client.users.create(username, password,
+                                                           email,
+                                                           tenant_id=tenant.id)
         return user
 
     def _get_user(self, tenant, username):
         if self.tempest_client:
-            resp, user = self.admin_client.get_user_by_username(tenant['id'],
-                                                                username)
+            resp, user = self.identity_admin_client.get_user_by_username(
+                tenant['id'],
+                username)
         else:
-            user = self.admin_client.users.get(username)
+            user = self.identity_admin_client.users.get(username)
         return user
 
     def _list_roles(self):
         if self.tempest_client:
-            resp, roles = self.admin_client.list_roles()
+            resp, roles = self.identity_admin_client.list_roles()
         else:
-            roles = self.admin_client.roles.list()
+            roles = self.identity_admin_client.roles.list()
         return roles
 
     def _assign_user_role(self, tenant, user, role):
         if self.tempest_client:
-            self.admin_client.assign_user_role(tenant, user, role)
+            self.identity_admin_client.assign_user_role(tenant, user, role)
         else:
-            self.admin_client.roles.add_user_role(user, role, tenant=tenant)
+            self.identity_admin_client.roles.add_user_role(user,
+                                                           role, tenant=tenant)
 
     def _delete_user(self, user):
         if self.tempest_client:
-            self.admin_client.delete_user(user)
+            self.identity_admin_client.delete_user(user)
         else:
-            self.admin_client.users.delete(user)
+            self.identity_admin_client.users.delete(user)
 
     def _delete_tenant(self, tenant):
         if self.tempest_client:
-            self.admin_client.delete_tenant(tenant)
+            self.identity_admin_client.delete_tenant(tenant)
         else:
-            self.admin_client.tenants.delete(tenant)
+            self.identity_admin_client.tenants.delete(tenant)
 
     def _create_creds(self, suffix=None, admin=False):
         rand_name_root = rand_name(self.name)
@@ -128,7 +152,6 @@
             rand_name_root += suffix
         tenant_name = rand_name_root + "-tenant"
         tenant_desc = tenant_name + "-desc"
-        rand_name_root = rand_name(self.name)
         tenant = self._create_tenant(name=tenant_name,
                                      description=tenant_desc)
         if suffix:
@@ -164,6 +187,92 @@
             tenant_name = tenant.name
         return username, tenant_name
 
+    def _get_tenant_id(self, tenant):
+        if self.tempest_client:
+            return tenant.get('id')
+        else:
+            return tenant.id
+
+    def _create_network_resources(self, tenant_id):
+        network = None
+        subnet = None
+        router = None
+        rand_name_root = rand_name(self.name)
+        network_name = rand_name_root + "-network"
+        network = self._create_network(network_name, tenant_id)
+        try:
+            subnet_name = rand_name_root + "-subnet"
+            subnet = self._create_subnet(subnet_name, tenant_id, network['id'])
+            router_name = rand_name_root + "-router"
+            router = self._create_router(router_name, tenant_id)
+            self._add_router_interface(router['id'], subnet['id'])
+        except Exception:
+            if router:
+                self._clear_isolated_router(router['id'], router['name'])
+            if subnet:
+                self._clear_isolated_subnet(subnet['id'], subnet['name'])
+            if network:
+                self._clear_isolated_network(network['id'], network['name'])
+            raise
+        return network, subnet, router
+
+    def _create_network(self, name, tenant_id):
+        if self.tempest_client:
+            resp, resp_body = self.network_admin_client.create_network(
+                name, tenant_id=tenant_id)
+        else:
+            body = {'network': {'tenant_id': tenant_id, 'name': name}}
+            resp_body = self.network_admin_client.create_network(body)
+        return resp_body['network']
+
+    def _create_subnet(self, subnet_name, tenant_id, network_id):
+        if not self.tempest_client:
+            body = {'subnet': {'name': subnet_name, 'tenant_id': tenant_id,
+                               'network_id': network_id, 'ip_version': 4}}
+        base_cidr = netaddr.IPNetwork(self.config.network.tenant_network_cidr)
+        mask_bits = self.config.network.tenant_network_mask_bits
+        for subnet_cidr in base_cidr.subnet(mask_bits):
+            try:
+                if self.tempest_client:
+                    resp, resp_body = self.network_admin_client.create_subnet(
+                        network_id, str(subnet_cidr), name=subnet_name,
+                        tenant_id=tenant_id)
+                else:
+                    body['subnet']['cidr'] = str(subnet_cidr)
+                    resp_body = self.network_admin_client.create_subnet(body)
+                break
+            except exceptions.BadRequest as e:
+                if 'overlaps with another subnet' not in str(e):
+                    raise
+        else:
+            e = exceptions.BuildErrorException()
+            e.message = 'Available CIDR for subnet creation could not be found'
+            raise e
+        return resp_body['subnet']
+
+    def _create_router(self, router_name, tenant_id):
+        external_net_id = dict(
+            network_id=self.config.network.public_network_id)
+        if self.tempest_client:
+            resp, resp_body = self.network_admin_client.create_router(
+                router_name,
+                external_gateway_info=external_net_id,
+                tenant_id=tenant_id)
+        else:
+            body = {'router': {'name': router_name, 'tenant_id': tenant_id,
+                               'external_gateway_info': external_net_id,
+                               'admin_state_up': True}}
+            resp_body = self.network_admin_client.create_router(body)
+        return resp_body['router']
+
+    def _add_router_interface(self, router_id, subnet_id):
+        if self.tempest_client:
+            self.network_admin_client.add_router_interface_with_subnet_id(
+                router_id, subnet_id)
+        else:
+            body = {'subnet_id': subnet_id}
+            self.network_admin_client.add_interface_router(router_id, body)
+
     def get_primary_tenant(self):
         return self.isolated_creds.get('primary')[1]
 
@@ -182,6 +291,33 @@
     def get_admin_user(self):
         return self.isolated_creds.get('admin')[0]
 
+    def get_primary_network(self):
+        return self.isolated_net_resources.get('primary')[0]
+
+    def get_primary_subnet(self):
+        return self.isolated_net_resources.get('primary')[1]
+
+    def get_primary_router(self):
+        return self.isolated_net_resources.get('primary')[2]
+
+    def get_admin_network(self):
+        return self.isolated_net_resources.get('admin')[0]
+
+    def get_admin_subnet(self):
+        return self.isolated_net_resources.get('admin')[1]
+
+    def get_admin_router(self):
+        return self.isolated_net_resources.get('admin')[2]
+
+    def get_alt_network(self):
+        return self.isolated_net_resources.get('alt')[0]
+
+    def get_alt_subnet(self):
+        return self.isolated_net_resources.get('alt')[1]
+
+    def get_alt_router(self):
+        return self.isolated_net_resources.get('alt')[2]
+
     def get_primary_creds(self):
         if self.isolated_creds.get('primary'):
             user, tenant = self.isolated_creds['primary']
@@ -190,8 +326,15 @@
             user, tenant = self._create_creds()
             username, tenant_name = self._get_cred_names(user, tenant)
             self.isolated_creds['primary'] = (user, tenant)
-            LOG.info("Aquired isolated creds:\n user: %s, tenant: %s"
+            LOG.info("Acquired isolated creds:\n user: %s, tenant: %s"
                      % (username, tenant_name))
+            if self.config.service_available.neutron:
+                network, subnet, router = self._create_network_resources(
+                    self._get_tenant_id(tenant))
+                self.isolated_net_resources['primary'] = (
+                    network, subnet, router,)
+                LOG.info("Created isolated network resources for : \n"
+                         + " user: %s, tenant: %s" % (username, tenant_name))
         return username, tenant_name, self.password
 
     def get_admin_creds(self):
@@ -202,9 +345,16 @@
             user, tenant = self._create_creds(admin=True)
             username, tenant_name = self._get_cred_names(user, tenant)
             self.isolated_creds['admin'] = (user, tenant)
-            LOG.info("Aquired admin isolated creds:\n user: %s, tenant: %s"
+            LOG.info("Acquired admin isolated creds:\n user: %s, tenant: %s"
                      % (username, tenant_name))
-            return username, tenant_name, self.password
+            if self.config.service_available.neutron:
+                network, subnet, router = self._create_network_resources(
+                    self._get_tenant_id(tenant))
+                self.isolated_net_resources['admin'] = (
+                    network, subnet, router,)
+                LOG.info("Created isolated network resources for : \n"
+                         + " user: %s, tenant: %s" % (username, tenant_name))
+        return username, tenant_name, self.password
 
     def get_alt_creds(self):
         if self.isolated_creds.get('alt'):
@@ -214,13 +364,93 @@
             user, tenant = self._create_creds()
             username, tenant_name = self._get_cred_names(user, tenant)
             self.isolated_creds['alt'] = (user, tenant)
-            LOG.info("Aquired alt isolated creds:\n user: %s, tenant: %s"
+            LOG.info("Acquired alt isolated creds:\n user: %s, tenant: %s"
                      % (username, tenant_name))
+            if self.config.service_available.neutron:
+                network, subnet, router = self._create_network_resources(
+                    self._get_tenant_id(tenant))
+                self.isolated_net_resources['alt'] = (
+                    network, subnet, router,)
+                LOG.info("Created isolated network resources for : \n"
+                         + " user: %s, tenant: %s" % (username, tenant_name))
         return username, tenant_name, self.password
 
+    def _clear_isolated_router(self, router_id, router_name):
+        net_client = self.network_admin_client
+        try:
+            net_client.delete_router(router_id)
+        except exceptions.NotFound:
+            LOG.warn('router with name: %s not found for delete' %
+                     router_name)
+            pass
+
+    def _clear_isolated_subnet(self, subnet_id, subnet_name):
+        net_client = self.network_admin_client
+        try:
+            net_client.delete_subnet(subnet_id)
+        except exceptions.NotFound:
+            LOG.warn('subnet with name: %s not found for delete' %
+                     subnet_name)
+            pass
+
+    def _clear_isolated_network(self, network_id, network_name):
+        net_client = self.network_admin_client
+        try:
+            net_client.delete_network(network_id)
+        except exceptions.NotFound:
+            LOG.warn('network with name: %s not found for delete' %
+                     network_name)
+            pass
+
+    def _cleanup_ports(self, network_id):
+        # TODO(mlavalle) This method will be removed once patch
+        # https://review.openstack.org/#/c/46563/ merges in Neutron
+        if not self.ports:
+            if self.tempest_client:
+                resp, resp_body = self.network_admin_client.list_ports()
+            else:
+                resp_body = self.network_admin_client.list_ports()
+            self.ports = resp_body['ports']
+        ports_to_delete = [
+            port for port in self.ports if port['network_id'] == network_id]
+        for port in ports_to_delete:
+            try:
+                LOG.info('Cleaning up port id %s, name %s' %
+                         (port['id'], port['name']))
+                self.network_admin_client.delete_port(port['id'])
+            except exceptions.NotFound:
+                LOG.warn('Port id: %s, name %s not found for clean-up' %
+                         (port['id'], port['name']))
+
+    def _clear_isolated_net_resources(self):
+        net_client = self.network_admin_client
+        for cred in self.isolated_net_resources:
+            network, subnet, router = self.isolated_net_resources.get(cred)
+            try:
+                if self.tempest_client:
+                    net_client.remove_router_interface_with_subnet_id(
+                        router['id'], subnet['id'])
+                else:
+                    body = {'subnet_id': subnet['id']}
+                    net_client.remove_interface_router(router['id'], body)
+            except exceptions.NotFound:
+                LOG.warn('router with name: %s not found for delete' %
+                         router['name'])
+                pass
+            self._clear_isolated_router(router['id'], router['name'])
+            # TODO(mlavalle) This method call will be removed once patch
+            # https://review.openstack.org/#/c/46563/ merges in Neutron
+            self._cleanup_ports(network['id'])
+            self._clear_isolated_subnet(subnet['id'], subnet['name'])
+            self._clear_isolated_network(network['id'], network['name'])
+            LOG.info("Cleared isolated network resources: \n"
+                     + " network: %s, subnet: %s, router: %s"
+                     % (network['name'], subnet['name'], router['name']))
+
     def clear_isolated_creds(self):
         if not self.isolated_creds:
             return
+        self._clear_isolated_net_resources()
         for cred in self.isolated_creds:
             user, tenant = self.isolated_creds.get(cred)
             try:
diff --git a/tempest/common/rest_client.py b/tempest/common/rest_client.py
index a867a12..4b5127a 100644
--- a/tempest/common/rest_client.py
+++ b/tempest/common/rest_client.py
@@ -80,6 +80,21 @@
         self.http_obj = http.ClosingHttp(
             disable_ssl_certificate_validation=dscv)
 
+    def __str__(self):
+        STRING_LIMIT = 80
+        str_format = ("config:%s, user:%s, password:%s, "
+                      "auth_url:%s, tenant_name:%s, auth_version:%s, "
+                      "service:%s, base_url:%s, region:%s, "
+                      "endpoint_url:%s, build_interval:%s, build_timeout:%s"
+                      "\ntoken:%s..., \nheaders:%s...")
+        return str_format % (self.config, self.user, self.password,
+                             self.auth_url, self.tenant_name,
+                             self.auth_version, self.service,
+                             self.base_url, self.region, self.endpoint_url,
+                             self.build_interval, self.build_timeout,
+                             str(self.token)[0:STRING_LIMIT],
+                             str(self.headers)[0:STRING_LIMIT])
+
     def _set_auth(self):
         """
         Sets the token and base_url used in requests based on the strategy type
@@ -448,8 +463,8 @@
         # NOTE(mtreinish): This is for compatibility with Glance and swift
         # APIs. These are the return content types that Glance api v1
         # (and occasionally swift) are using.
-        TXT_ENC = ['text/plain; charset=UTF-8', 'text/html; charset=UTF-8',
-                   'text/plain; charset=utf-8']
+        TXT_ENC = ['text/plain', 'text/plain; charset=UTF-8',
+                   'text/html; charset=UTF-8', 'text/plain; charset=utf-8']
         XML_ENC = ['application/xml', 'application/xml; charset=UTF-8']
 
         if ctype in JSON_ENC or ctype in XML_ENC:
diff --git a/tempest/common/tempest_fixtures.py b/tempest/common/tempest_fixtures.py
new file mode 100644
index 0000000..ebc9ad3
--- /dev/null
+++ b/tempest/common/tempest_fixtures.py
@@ -0,0 +1,23 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 IBM Corp.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+from tempest.openstack.common import lockutils
+
+
+class LockFixture(lockutils.LockFixture):
+    def __init__(self, name):
+        super(LockFixture, self).__init__(name, 'tempest-')
diff --git a/tempest/config.py b/tempest/config.py
index 71705fb..db923e9 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -27,6 +27,12 @@
 from tempest.openstack.common import log as logging
 
 
+def register_opt_group(conf, opt_group, options):
+    conf.register_group(opt_group)
+    for opt in options:
+        conf.register_opt(opt, group=opt_group.name)
+
+
 identity_group = cfg.OptGroup(name='identity',
                               title="Keystone Configuration Options")
 
@@ -87,13 +93,6 @@
                secret=True),
 ]
 
-
-def register_identity_opts(conf):
-    conf.register_group(identity_group)
-    for opt in IdentityGroup:
-        conf.register_opt(opt, group='identity')
-
-
 compute_group = cfg.OptGroup(name='compute',
                              title='Compute Service Options')
 
@@ -182,8 +181,8 @@
                     "succeed."),
     cfg.IntOpt('ready_wait',
                default=0,
-               help="Additinal wait time for clean state, when there is"
-                    " no OS-EXT-STS extension availiable"),
+               help="Additional wait time for clean state, when there is "
+                    "no OS-EXT-STS extension available"),
     cfg.IntOpt('ssh_channel_timeout',
                default=60,
                help="Timeout in seconds to wait for output from ssh "
@@ -225,12 +224,6 @@
                     "an instance")
 ]
 
-
-def register_compute_opts(conf):
-    conf.register_group(compute_group)
-    for opt in ComputeGroup:
-        conf.register_opt(opt, group='compute')
-
 compute_admin_group = cfg.OptGroup(name='compute-admin',
                                    title="Compute Admin Options")
 
@@ -248,12 +241,6 @@
                secret=True),
 ]
 
-
-def register_compute_admin_opts(conf):
-    conf.register_group(compute_admin_group)
-    for opt in ComputeAdminGroup:
-        conf.register_opt(opt, group='compute-admin')
-
 image_group = cfg.OptGroup(name='image',
                            title="Image Service Options")
 
@@ -273,16 +260,10 @@
     cfg.StrOpt('http_image',
                default='http://download.cirros-cloud.net/0.3.1/'
                'cirros-0.3.1-x86_64-uec.tar.gz',
-               help='http accessable image')
+               help='http accessible image')
 ]
 
 
-def register_image_opts(conf):
-    conf.register_group(image_group)
-    for opt in ImageGroup:
-        conf.register_opt(opt, group='image')
-
-
 network_group = cfg.OptGroup(name='network',
                              title='Network Service Options')
 
@@ -316,12 +297,6 @@
                     "connectivity"),
 ]
 
-
-def register_network_opts(conf):
-    conf.register_group(network_group)
-    for opt in NetworkGroup:
-        conf.register_opt(opt, group='network')
-
 volume_group = cfg.OptGroup(name='volume',
                             title='Block Storage Options')
 
@@ -363,16 +338,10 @@
 ]
 
 
-def register_volume_opts(conf):
-    conf.register_group(volume_group)
-    for opt in VolumeGroup:
-        conf.register_opt(opt, group='volume')
-
-
 object_storage_group = cfg.OptGroup(name='object-storage',
                                     title='Object Storage Service Options')
 
-ObjectStoreConfig = [
+ObjectStoreGroup = [
     cfg.StrOpt('catalog_type',
                default='object-store',
                help="Catalog type of the Object-Storage service."),
@@ -404,12 +373,6 @@
 ]
 
 
-def register_object_storage_opts(conf):
-    conf.register_group(object_storage_group)
-    for opt in ObjectStoreConfig:
-        conf.register_opt(opt, group='object-storage')
-
-
 orchestration_group = cfg.OptGroup(name='orchestration',
                                    title='Orchestration Service Options')
 
@@ -447,17 +410,11 @@
                default=None,
                help="Name of existing keypair to launch servers with."),
     cfg.IntOpt('max_template_size',
-               default=10240,
+               default=32768,
                help="Value must match heat configuration of the same name."),
 ]
 
 
-def register_orchestration_opts(conf):
-    conf.register_group(orchestration_group)
-    for opt in OrchestrationGroup:
-        conf.register_opt(opt, group='orchestration')
-
-
 dashboard_group = cfg.OptGroup(name="dashboard",
                                title="Dashboard options")
 
@@ -471,15 +428,9 @@
 ]
 
 
-def register_dashboard_opts(conf):
-    conf.register_group(scenario_group)
-    for opt in DashboardGroup:
-        conf.register_opt(opt, group='dashboard')
-
-
 boto_group = cfg.OptGroup(name='boto',
                           title='EC2/S3 options')
-BotoConfig = [
+BotoGroup = [
     cfg.StrOpt('ec2_url',
                default="http://localhost:8773/services/Cloud",
                help="EC2 URL"),
@@ -523,12 +474,6 @@
                help="Status Change Test Interval"),
 ]
 
-
-def register_boto_opts(conf):
-    conf.register_group(boto_group)
-    for opt in BotoConfig:
-        conf.register_opt(opt, group='boto')
-
 stress_group = cfg.OptGroup(name='stress', title='Stress Test Options')
 
 StressGroup = [
@@ -563,12 +508,6 @@
 ]
 
 
-def register_stress_opts(conf):
-    conf.register_group(stress_group)
-    for opt in StressGroup:
-        conf.register_opt(opt, group='stress')
-
-
 scenario_group = cfg.OptGroup(name='scenario', title='Scenario Test Options')
 
 ScenarioGroup = [
@@ -596,12 +535,6 @@
 ]
 
 
-def register_scenario_opts(conf):
-    conf.register_group(scenario_group)
-    for opt in ScenarioGroup:
-        conf.register_opt(opt, group='scenario')
-
-
 service_available_group = cfg.OptGroup(name="service_available",
                                        title="Available OpenStack Services")
 
@@ -629,12 +562,6 @@
                 help="Whether or not Horizon is expected to be available"),
 ]
 
-
-def register_service_available_opts(conf):
-    conf.register_group(scenario_group)
-    for opt in ServiceAvailableGroup:
-        conf.register_opt(opt, group='service_available')
-
 debug_group = cfg.OptGroup(name="debug",
                            title="Debug System")
 
@@ -645,12 +572,6 @@
 ]
 
 
-def register_debug_opts(conf):
-    conf.register_group(debug_group)
-    for opt in DebugGroup:
-        conf.register_opt(opt, group='debug')
-
-
 @singleton
 class TempestConfig:
     """Provides OpenStack configuration information."""
@@ -689,19 +610,21 @@
         LOG = logging.getLogger('tempest')
         LOG.info("Using tempest config file %s" % path)
 
-        register_compute_opts(cfg.CONF)
-        register_identity_opts(cfg.CONF)
-        register_image_opts(cfg.CONF)
-        register_network_opts(cfg.CONF)
-        register_volume_opts(cfg.CONF)
-        register_object_storage_opts(cfg.CONF)
-        register_orchestration_opts(cfg.CONF)
-        register_dashboard_opts(cfg.CONF)
-        register_boto_opts(cfg.CONF)
-        register_compute_admin_opts(cfg.CONF)
-        register_stress_opts(cfg.CONF)
-        register_scenario_opts(cfg.CONF)
-        register_service_available_opts(cfg.CONF)
+        register_opt_group(cfg.CONF, compute_group, ComputeGroup)
+        register_opt_group(cfg.CONF, identity_group, IdentityGroup)
+        register_opt_group(cfg.CONF, image_group, ImageGroup)
+        register_opt_group(cfg.CONF, network_group, NetworkGroup)
+        register_opt_group(cfg.CONF, volume_group, VolumeGroup)
+        register_opt_group(cfg.CONF, object_storage_group, ObjectStoreGroup)
+        register_opt_group(cfg.CONF, orchestration_group, OrchestrationGroup)
+        register_opt_group(cfg.CONF, dashboard_group, DashboardGroup)
+        register_opt_group(cfg.CONF, boto_group, BotoGroup)
+        register_opt_group(cfg.CONF, compute_admin_group, ComputeAdminGroup)
+        register_opt_group(cfg.CONF, stress_group, StressGroup)
+        register_opt_group(cfg.CONF, scenario_group, ScenarioGroup)
+        register_opt_group(cfg.CONF, service_available_group,
+                           ServiceAvailableGroup)
+        register_opt_group(cfg.CONF, debug_group, DebugGroup)
         self.compute = cfg.CONF.compute
         self.identity = cfg.CONF.identity
         self.images = cfg.CONF.image
@@ -715,6 +638,7 @@
         self.stress = cfg.CONF.stress
         self.scenario = cfg.CONF.scenario
         self.service_available = cfg.CONF.service_available
+        self.debug = cfg.CONF.debug
         if not self.compute_admin.username:
             self.compute_admin.username = self.identity.admin_username
             self.compute_admin.password = self.identity.admin_password
diff --git a/tempest/hacking/checks.py b/tempest/hacking/checks.py
index aa97211..4c1c107 100644
--- a/tempest/hacking/checks.py
+++ b/tempest/hacking/checks.py
@@ -19,28 +19,11 @@
 
 PYTHON_CLIENTS = ['cinder', 'glance', 'keystone', 'nova', 'swift', 'neutron']
 
-SKIP_DECORATOR_RE = re.compile(r'\s*@testtools.skip\((.*)\)')
-SKIP_STR_RE = re.compile(r'.*Bug #\d+.*')
 PYTHON_CLIENT_RE = re.compile('import (%s)client' % '|'.join(PYTHON_CLIENTS))
 TEST_DEFINITION = re.compile(r'^\s*def test.*')
 SCENARIO_DECORATOR = re.compile(r'\s*@.*services\(')
 
 
-def skip_bugs(physical_line):
-    """Check skip lines for proper bug entries
-
-    T101: skips must contain "Bug #<bug_number>"
-    """
-
-    res = SKIP_DECORATOR_RE.match(physical_line)
-    if res:
-        content = res.group(1)
-        res = SKIP_STR_RE.match(content)
-        if not res:
-            return (physical_line.find(content),
-                    'T101: skips must contain "Bug #<bug_number>"')
-
-
 def import_no_clients_in_api(physical_line, filename):
     """Check for client imports from tempest/api tests
 
@@ -70,6 +53,5 @@
 
 
 def factory(register):
-    register(skip_bugs)
     register(import_no_clients_in_api)
     register(scenario_tests_need_service_tags)
diff --git a/tempest/openstack/common/lockutils.py b/tempest/openstack/common/lockutils.py
index 0abd1a7..a55fd94 100644
--- a/tempest/openstack/common/lockutils.py
+++ b/tempest/openstack/common/lockutils.py
@@ -24,6 +24,7 @@
 import time
 import weakref
 
+import fixtures
 from oslo.config import cfg
 
 from tempest.openstack.common import fileutils
@@ -275,3 +276,36 @@
     """
 
     return functools.partial(synchronized, lock_file_prefix=lock_file_prefix)
+
+
+class LockFixture(fixtures.Fixture):
+    """External locking fixture.
+
+    This fixture is basically an alternative to the synchronized decorator with
+    the external flag so that tearDowns and addCleanups will be included in
+    the lock context for locking between tests. The fixture is recommended to
+    be the first line in a test method, like so::
+
+        def test_method(self):
+            self.useFixture(LockFixture)
+                ...
+
+    or the first line in setUp if all the test methods in the class are
+    required to be serialized. Something like::
+
+        class TestCase(testtools.testcase):
+            def setUp(self):
+                self.useFixture(LockFixture)
+                super(TestCase, self).setUp()
+                    ...
+
+    This is because addCleanups are put on a LIFO queue that gets run after the
+    test method exits. (either by completing or raising an exception)
+    """
+    def __init__(self, name, lock_file_prefix=None):
+        self.mgr = lock(name, lock_file_prefix, True)
+
+    def setUp(self):
+        super(LockFixture, self).setUp()
+        self.addCleanup(self.mgr.__exit__, None, None, None)
+        self.mgr.__enter__()
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index f71ea46..8ccc899 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -280,16 +280,23 @@
         cls.os_resources.remove(thing)
         del cls.resource_keys[key]
 
-    def status_timeout(self, things, thing_id, expected_status):
+    def status_timeout(self, things, thing_id, expected_status,
+                       error_status='ERROR',
+                       not_found_exception=nova_exceptions.NotFound):
         """
         Given a thing and an expected status, do a loop, sleeping
         for a configurable amount of time, checking for the
         expected status to show. At any time, if the returned
         status of the thing is ERROR, fail out.
         """
-        self._status_timeout(things, thing_id, expected_status=expected_status)
+        self._status_timeout(things, thing_id,
+                             expected_status=expected_status,
+                             error_status=error_status,
+                             not_found_exception=not_found_exception)
 
-    def delete_timeout(self, things, thing_id):
+    def delete_timeout(self, things, thing_id,
+                       error_status='ERROR',
+                       not_found_exception=nova_exceptions.NotFound):
         """
         Given a thing, do a loop, sleeping
         for a configurable amount of time, checking for the
@@ -298,13 +305,17 @@
         """
         self._status_timeout(things,
                              thing_id,
-                             allow_notfound=True)
+                             allow_notfound=True,
+                             error_status=error_status,
+                             not_found_exception=not_found_exception)
 
     def _status_timeout(self,
                         things,
                         thing_id,
                         expected_status=None,
-                        allow_notfound=False):
+                        allow_notfound=False,
+                        error_status='ERROR',
+                        not_found_exception=nova_exceptions.NotFound):
 
         log_status = expected_status if expected_status else ''
         if allow_notfound:
@@ -316,16 +327,16 @@
             # for the singular resource to retrieve.
             try:
                 thing = things.get(thing_id)
-            except nova_exceptions.NotFound:
+            except not_found_exception:
                 if allow_notfound:
                     return True
                 else:
                     raise
 
             new_status = thing.status
-            if new_status == 'ERROR':
+            if new_status == error_status:
                 message = "%s failed to get to expected status. \
-                          In ERROR state." % (thing)
+                          In %s state." % (thing, new_status)
                 raise exceptions.BuildErrorException(message)
             elif new_status == expected_status and expected_status is not None:
                 return True  # All good.
@@ -374,8 +385,10 @@
                                                          **ruleset)
             self.set_resource(sg_rule.id, sg_rule)
 
-    def create_server(self, client, name=None, image=None, flavor=None,
+    def create_server(self, client=None, name=None, image=None, flavor=None,
                       create_kwargs={}):
+        if client is None:
+            client = self.compute_client
         if name is None:
             name = rand_name('scenario-server-')
         if image is None:
@@ -476,12 +489,17 @@
     @classmethod
     def setUpClass(cls):
         super(NetworkScenarioTest, cls).setUpClass()
-        cls.tenant_id = cls.manager._get_identity_client(
-            cls.config.identity.username,
-            cls.config.identity.password,
-            cls.config.identity.tenant_name).tenant_id
+        if cls.config.compute.allow_tenant_isolation:
+            cls.tenant_id = cls.isolated_creds.get_primary_tenant().id
+        else:
+            cls.tenant_id = cls.manager._get_identity_client(
+                cls.config.identity.username,
+                cls.config.identity.password,
+                cls.config.identity.tenant_name).tenant_id
 
-    def _create_security_group(self, client, namestart='secgroup-smoke-'):
+    def _create_security_group(self, client=None, namestart='secgroup-smoke-'):
+        if client is None:
+            client = self.compute_client
         # Create security group
         sg_name = rand_name(namestart)
         sg_desc = sg_name + " description"
@@ -649,3 +667,10 @@
     @classmethod
     def _stack_rand_name(cls):
         return rand_name(cls.__name__ + '-')
+
+    @classmethod
+    def _get_default_network(cls):
+        networks = cls.network_client.list_networks()
+        for net in networks['networks']:
+            if net['name'] == cls.config.compute.fixed_network_name:
+                return net
diff --git a/tempest/scenario/orchestration/test_autoscaling.py b/tempest/scenario/orchestration/test_autoscaling.py
index 1a4d802..658e9bb 100644
--- a/tempest/scenario/orchestration/test_autoscaling.py
+++ b/tempest/scenario/orchestration/test_autoscaling.py
@@ -37,11 +37,13 @@
             self.keypair_name = self.keypair.id
 
     def launch_stack(self):
+        net = self._get_default_network()
         self.parameters = {
             'KeyName': self.keypair_name,
             'InstanceType': self.config.orchestration.instance_type,
             'ImageId': self.config.orchestration.image_ref,
-            'StackStart': str(time.time())
+            'StackStart': str(time.time()),
+            'Subnet': net['subnets'][0]
         }
 
         # create the stack
diff --git a/tempest/scenario/orchestration/test_autoscaling.yaml b/tempest/scenario/orchestration/test_autoscaling.yaml
index 045b3bc..745eb05 100644
--- a/tempest/scenario/orchestration/test_autoscaling.yaml
+++ b/tempest/scenario/orchestration/test_autoscaling.yaml
@@ -8,6 +8,8 @@
     Type: String
   ImageId:
     Type: String
+  Subnet:
+    Type: String
   StackStart:
     Description: Epoch seconds when the stack was launched
     Type: Number
@@ -39,6 +41,7 @@
       LaunchConfigurationName: {Ref: LaunchConfig}
       MinSize: '1'
       MaxSize: '3'
+      VPCZoneIdentifier: [{Ref: Subnet}]
   SmokeServerScaleUpPolicy:
     Type: AWS::AutoScaling::ScalingPolicy
     Properties:
diff --git a/tempest/scenario/test_large_ops.py b/tempest/scenario/test_large_ops.py
index 33b7adc..22c543b 100644
--- a/tempest/scenario/test_large_ops.py
+++ b/tempest/scenario/test_large_ops.py
@@ -24,7 +24,7 @@
 LOG = logging.getLogger(__name__)
 
 
-class TestLargeOpsScenario(manager.OfficialClientTest):
+class TestLargeOpsScenario(manager.NetworkScenarioTest):
 
     """
     Test large operations.
@@ -82,19 +82,19 @@
                                         properties=properties)
 
     def nova_boot(self):
-        def delete(servers):
-            [x.delete() for x in servers]
-
         name = rand_name('scenario-server-')
         client = self.compute_client
         flavor_id = self.config.compute.flavor_ref
+        secgroup = self._create_security_group()
         self.servers = client.servers.create(
             name=name, image=self.image,
             flavor=flavor_id,
-            min_count=self.config.scenario.large_ops_number)
+            min_count=self.config.scenario.large_ops_number,
+            security_groups=[secgroup.name])
         # needed because of bug 1199788
         self.servers = [x for x in client.servers.list() if name in x.name]
-        self.addCleanup(delete, self.servers)
+        for server in self.servers:
+            self.set_resource(server.name, server)
         self._wait_for_server_status('ACTIVE')
 
     @services('compute', 'image')
diff --git a/tempest/scenario/test_minimum_basic.py b/tempest/scenario/test_minimum_basic.py
index ce4d1bd..752ff6f 100644
--- a/tempest/scenario/test_minimum_basic.py
+++ b/tempest/scenario/test_minimum_basic.py
@@ -87,8 +87,7 @@
 
     def nova_boot(self):
         create_kwargs = {'key_name': self.keypair.name}
-        self.server = self.create_server(self.compute_client,
-                                         image=self.image,
+        self.server = self.create_server(image=self.image,
                                          create_kwargs=create_kwargs)
 
     def nova_list(self):
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 2aa5de3..6cd9fe8 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -110,10 +110,6 @@
     def setUpClass(cls):
         super(TestNetworkBasicOps, cls).setUpClass()
         cls.check_preconditions()
-        cls.tenant_id = cls.manager._get_identity_client(
-            cls.config.identity.username,
-            cls.config.identity.password,
-            cls.config.identity.tenant_name).tenant_id
         # TODO(mnewby) Consider looking up entities as needed instead
         # of storing them as collections on the class.
         cls.keypairs = {}
@@ -168,8 +164,7 @@
             name=rand_name('keypair-smoke-'))
 
     def _create_security_groups(self):
-        self.security_groups[self.tenant_id] = self._create_security_group(
-            self.compute_client)
+        self.security_groups[self.tenant_id] = self._create_security_group()
 
     def _create_networks(self):
         network = self._create_network(self.tenant_id)
@@ -214,8 +209,7 @@
             'key_name': keypair_name,
             'security_groups': security_groups,
         }
-        server = self.create_server(self.compute_client, name=name,
-                                    create_kwargs=create_kwargs)
+        server = self.create_server(name=name, create_kwargs=create_kwargs)
         return server
 
     def _create_servers(self):
diff --git a/tempest/scenario/test_server_advanced_ops.py b/tempest/scenario/test_server_advanced_ops.py
index 26bc95e..853b1ba 100644
--- a/tempest/scenario/test_server_advanced_ops.py
+++ b/tempest/scenario/test_server_advanced_ops.py
@@ -48,7 +48,7 @@
     @services('compute')
     def test_resize_server_confirm(self):
         # We create an instance for use in this test
-        instance = self.create_server(self.compute_client)
+        instance = self.create_server()
         instance_id = instance.id
         resize_flavor = self.config.compute.flavor_ref_alt
         LOG.debug("Resizing instance %s from flavor %s to flavor %s",
@@ -66,7 +66,7 @@
     @services('compute')
     def test_server_sequence_suspend_resume(self):
         # We create an instance for use in this test
-        instance = self.create_server(self.compute_client)
+        instance = self.create_server()
         instance_id = instance.id
         LOG.debug("Suspending instance %s. Current status: %s",
                   instance_id, instance.status)
diff --git a/tempest/scenario/test_server_basic_ops.py b/tempest/scenario/test_server_basic_ops.py
index 03e6e41..c32d49d 100644
--- a/tempest/scenario/test_server_basic_ops.py
+++ b/tempest/scenario/test_server_basic_ops.py
@@ -56,8 +56,7 @@
         create_kwargs = {
             'key_name': self.keypair.id
         }
-        instance = self.create_server(self.compute_client,
-                                      create_kwargs=create_kwargs)
+        instance = self.create_server(create_kwargs=create_kwargs)
         self.set_resource('instance', instance)
 
     def pause_server(self):
diff --git a/tempest/scenario/test_snapshot_pattern.py b/tempest/scenario/test_snapshot_pattern.py
index 8c2cc76..ba347e0 100644
--- a/tempest/scenario/test_snapshot_pattern.py
+++ b/tempest/scenario/test_snapshot_pattern.py
@@ -34,8 +34,7 @@
         create_kwargs = {
             'key_name': self.keypair.name
         }
-        return self.create_server(self.compute_client, image=image_id,
-                                  create_kwargs=create_kwargs)
+        return self.create_server(image=image_id, create_kwargs=create_kwargs)
 
     def _add_keypair(self):
         self.keypair = self.create_keypair()
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index ab464e3..4f49d65 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -58,8 +58,7 @@
         create_kwargs = {
             'key_name': self.keypair.name
         }
-        return self.create_server(self.compute_client, image=image_id,
-                                  create_kwargs=create_kwargs)
+        return self.create_server(image=image_id, create_kwargs=create_kwargs)
 
     def _add_keypair(self):
         self.keypair = self.create_keypair()
diff --git a/tempest/scenario/test_volume_boot_pattern.py b/tempest/scenario/test_volume_boot_pattern.py
index 3572166..d12cd56 100644
--- a/tempest/scenario/test_volume_boot_pattern.py
+++ b/tempest/scenario/test_volume_boot_pattern.py
@@ -49,8 +49,7 @@
             'block_device_mapping': bd_map,
             'key_name': keypair.name
         }
-        return self.create_server(self.compute_client,
-                                  create_kwargs=create_kwargs)
+        return self.create_server(create_kwargs=create_kwargs)
 
     def _create_snapshot_from_volume(self, vol_id):
         volume_snapshots = self.volume_client.volume_snapshots
diff --git a/tempest/services/compute/json/aggregates_client.py b/tempest/services/compute/json/aggregates_client.py
index 7ae1eee..75ce9ff 100644
--- a/tempest/services/compute/json/aggregates_client.py
+++ b/tempest/services/compute/json/aggregates_client.py
@@ -52,6 +52,19 @@
         body = json.loads(body)
         return resp, body['aggregate']
 
+    def update_aggregate(self, aggregate_id, name, availability_zone=None):
+        """Update a aggregate."""
+        put_body = {
+            'name': name,
+            'availability_zone': availability_zone
+        }
+        put_body = json.dumps({'aggregate': put_body})
+        resp, body = self.put('os-aggregates/%s' % str(aggregate_id),
+                              put_body, self.headers)
+
+        body = json.loads(body)
+        return resp, body['aggregate']
+
     def delete_aggregate(self, aggregate_id):
         """Deletes the given aggregate."""
         return self.delete("os-aggregates/%s" % str(aggregate_id))
diff --git a/tempest/services/compute/json/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index 769c538..8349263 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -94,3 +94,13 @@
         except exceptions.NotFound:
             return True
         return False
+
+    def list_floating_ip_pools(self, params=None):
+        """Returns a list of all floating IP Pools."""
+        url = 'os-floating-ip-pools'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url)
+        body = json.loads(body)
+        return resp, body['floating_ip_pools']
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index 851041b..dfbc01c 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -369,6 +369,11 @@
         """Unrescue the provided server."""
         return self.action(server_id, 'unrescue', None)
 
+    def get_server_diagnostics(self, server_id):
+        """Get the usage data for a server."""
+        resp, body = self.get("servers/%s/diagnostics" % str(server_id))
+        return resp, json.loads(body)
+
     def list_instance_actions(self, server_id):
         """List the provided server action."""
         resp, body = self.get("servers/%s/os-instance-actions" %
diff --git a/tempest/services/compute/xml/aggregates_client.py b/tempest/services/compute/xml/aggregates_client.py
index 0ef8e22..8ef0af6 100644
--- a/tempest/services/compute/xml/aggregates_client.py
+++ b/tempest/services/compute/xml/aggregates_client.py
@@ -72,6 +72,17 @@
         aggregate = self._format_aggregate(etree.fromstring(body))
         return resp, aggregate
 
+    def update_aggregate(self, aggregate_id, name, availability_zone=None):
+        """Update a aggregate."""
+        put_body = Element("aggregate",
+                           name=name,
+                           availability_zone=availability_zone)
+        resp, body = self.put('os-aggregates/%s' % str(aggregate_id),
+                              str(Document(put_body)),
+                              self.headers)
+        aggregate = self._format_aggregate(etree.fromstring(body))
+        return resp, aggregate
+
     def delete_aggregate(self, aggregate_id):
         """Deletes the given aggregate."""
         return self.delete("os-aggregates/%s" % str(aggregate_id),
diff --git a/tempest/services/compute/xml/common.py b/tempest/services/compute/xml/common.py
index cb24917..84b56c2 100644
--- a/tempest/services/compute/xml/common.py
+++ b/tempest/services/compute/xml/common.py
@@ -15,6 +15,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+import collections
+
 XMLNS_11 = "http://docs.openstack.org/compute/api/v1.1"
 
 
@@ -110,3 +112,19 @@
             ns, tag = tag.split("}", 1)
         json[tag] = xml_to_json(child)
     return json
+
+
+def deep_dict_to_xml(dest, source):
+    """Populates the ``dest`` xml element with the ``source`` ``Mapping``
+       elements, if the source Mapping's value is also a ``Mapping``
+       they will be recursively added as a child elements.
+       :param source: A python ``Mapping`` (dict)
+       :param dest: XML child element will be added to the ``dest``
+    """
+    for element, content in source.iteritems():
+        if isinstance(content, collections.Mapping):
+            xml_element = Element(element)
+            deep_dict_to_xml(xml_element, content)
+            dest.append(xml_element)
+        else:
+            dest.append(Element(element, content))
diff --git a/tempest/services/compute/xml/floating_ips_client.py b/tempest/services/compute/xml/floating_ips_client.py
index 278cc88..2fffaa2 100644
--- a/tempest/services/compute/xml/floating_ips_client.py
+++ b/tempest/services/compute/xml/floating_ips_client.py
@@ -107,3 +107,13 @@
         except exceptions.NotFound:
             return True
         return False
+
+    def list_floating_ip_pools(self, params=None):
+        """Returns a list of all floating IP Pools."""
+        url = 'os-floating-ip-pools'
+        if params:
+            url += '?%s' % urllib.urlencode(params)
+
+        resp, body = self.get(url, self.headers)
+        body = self._parse_array(etree.fromstring(body))
+        return resp, body
diff --git a/tempest/services/compute/xml/servers_client.py b/tempest/services/compute/xml/servers_client.py
index da993ab..ada0398 100644
--- a/tempest/services/compute/xml/servers_client.py
+++ b/tempest/services/compute/xml/servers_client.py
@@ -193,6 +193,14 @@
         server = self._parse_server(etree.fromstring(body))
         return resp, server
 
+    def lock_server(self, server_id, **kwargs):
+        """Locks the given server."""
+        return self.action(server_id, 'lock', None, **kwargs)
+
+    def unlock_server(self, server_id, **kwargs):
+        """Unlocks the given server."""
+        return self.action(server_id, 'unlock', None, **kwargs)
+
     def suspend_server(self, server_id, **kwargs):
         """Suspends the provided server."""
         return self.action(server_id, 'suspend', None, **kwargs)
@@ -209,6 +217,10 @@
         """Un-pauses the provided server."""
         return self.action(server_id, 'unpause', None, **kwargs)
 
+    def reset_state(self, server_id, state='error'):
+        """Resets the state of a server to active/error."""
+        return self.action(server_id, 'os-resetState', None, state=state)
+
     def delete_server(self, server_id):
         """Deletes the given server."""
         return self.delete("servers/%s" % str(server_id))
@@ -564,6 +576,13 @@
                                  (server_id, volume_id), headers)
         return resp, body
 
+    def get_server_diagnostics(self, server_id):
+        """Get the usage data for a server."""
+        resp, body = self.get("servers/%s/diagnostics" % server_id,
+                              self.headers)
+        body = xml_to_json(etree.fromstring(body))
+        return resp, body
+
     def list_instance_actions(self, server_id):
         """List the provided server action."""
         resp, body = self.get("servers/%s/os-instance-actions" % server_id,
diff --git a/tempest/services/identity/json/identity_client.py b/tempest/services/identity/json/identity_client.py
index 18132ed..94045b8 100644
--- a/tempest/services/identity/json/identity_client.py
+++ b/tempest/services/identity/json/identity_client.py
@@ -139,7 +139,7 @@
         body = json.loads(body)
         return resp, body['tenant']
 
-    def create_user(self, name, password, tenant_id, email):
+    def create_user(self, name, password, tenant_id, email, **kwargs):
         """Create a user."""
         post_body = {
             'name': name,
@@ -147,6 +147,8 @@
             'tenantId': tenant_id,
             'email': email
         }
+        if kwargs.get('enabled') is not None:
+            post_body['enabled'] = kwargs.get('enabled')
         post_body = json.dumps({'user': post_body})
         resp, body = self.post('users', post_body, self.headers)
         body = json.loads(body)
diff --git a/tempest/services/identity/v3/json/identity_client.py b/tempest/services/identity/v3/json/identity_client.py
index 0a56e84..ec99d37 100644
--- a/tempest/services/identity/v3/json/identity_client.py
+++ b/tempest/services/identity/v3/json/identity_client.py
@@ -123,6 +123,30 @@
         body = json.loads(body)
         return resp, body['project']
 
+    def list_projects(self):
+        resp, body = self.get("projects")
+        body = json.loads(body)
+        return resp, body['projects']
+
+    def update_project(self, project_id, **kwargs):
+        resp, body = self.get_project(project_id)
+        name = kwargs.get('name', body['name'])
+        desc = kwargs.get('description', body['description'])
+        en = kwargs.get('enabled', body['enabled'])
+        domain_id = kwargs.get('domain_id', body['domain_id'])
+        post_body = {
+            'id': project_id,
+            'name': name,
+            'description': desc,
+            'enabled': en,
+            'domain_id': domain_id,
+        }
+        post_body = json.dumps({'project': post_body})
+        resp, body = self.patch('projects/%s' % project_id, post_body,
+                                self.headers)
+        body = json.loads(body)
+        return resp, body['project']
+
     def get_project(self, project_id):
         """GET a Project."""
         resp, body = self.get("projects/%s" % project_id)
diff --git a/tempest/services/identity/v3/xml/identity_client.py b/tempest/services/identity/v3/xml/identity_client.py
index 03e06dc..3fffc1f 100644
--- a/tempest/services/identity/v3/xml/identity_client.py
+++ b/tempest/services/identity/v3/xml/identity_client.py
@@ -163,6 +163,31 @@
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
+    def list_projects(self):
+        """Get the list of projects."""
+        resp, body = self.get("projects", self.headers)
+        body = self._parse_projects(etree.fromstring(body))
+        return resp, body
+
+    def update_project(self, project_id, **kwargs):
+        """Updates a Project."""
+        resp, body = self.get_project(project_id)
+        name = kwargs.get('name', body['name'])
+        desc = kwargs.get('description', body['description'])
+        en = kwargs.get('enabled', body['enabled'])
+        domain_id = kwargs.get('domain_id', body['domain_id'])
+        post_body = Element("project",
+                            xmlns=XMLNS,
+                            name=name,
+                            description=desc,
+                            enabled=str(en).lower(),
+                            domain_id=domain_id)
+        resp, body = self.patch('projects/%s' % project_id,
+                                str(Document(post_body)),
+                                self.headers)
+        body = self._parse_body(etree.fromstring(body))
+        return resp, body
+
     def get_project(self, project_id):
         """GET a Project."""
         resp, body = self.get("projects/%s" % project_id, self.headers)
diff --git a/tempest/services/identity/xml/identity_client.py b/tempest/services/identity/xml/identity_client.py
index 9d44826..9c0a72c 100644
--- a/tempest/services/identity/xml/identity_client.py
+++ b/tempest/services/identity/xml/identity_client.py
@@ -159,7 +159,7 @@
         body = self._parse_body(etree.fromstring(body))
         return resp, body
 
-    def create_user(self, name, password, tenant_id, email):
+    def create_user(self, name, password, tenant_id, email, **kwargs):
         """Create a user."""
         create_user = Element("user",
                               xmlns=XMLNS,
@@ -167,6 +167,9 @@
                               password=password,
                               tenantId=tenant_id,
                               email=email)
+        if 'enabled' in kwargs:
+            create_user.add_attr('enabled', str(kwargs['enabled']).lower())
+
         resp, body = self.post('users', str(Document(create_user)),
                                self.headers)
         body = self._parse_body(etree.fromstring(body))
diff --git a/tempest/services/network/json/network_client.py b/tempest/services/network/json/network_client.py
index 369dd81..4b87b91 100644
--- a/tempest/services/network/json/network_client.py
+++ b/tempest/services/network/json/network_client.py
@@ -45,12 +45,9 @@
         body = json.loads(body)
         return resp, body
 
-    def create_network(self, name):
-        post_body = {
-            'network': {
-                'name': name,
-            }
-        }
+    def create_network(self, name, **kwargs):
+        post_body = {'network': kwargs}
+        post_body['network']['name'] = name
         body = json.dumps(post_body)
         uri = '%s/networks' % (self.uri_prefix)
         resp, body = self.post(uri, headers=self.headers, body=body)
@@ -79,12 +76,11 @@
         resp, body = self.delete(uri, self.headers)
         return resp, body
 
-    def create_subnet(self, net_uuid, cidr):
-        post_body = dict(
-            subnet=dict(
-                ip_version=4,
-                network_id=net_uuid,
-                cidr=cidr),)
+    def create_subnet(self, net_uuid, cidr, ip_version=4, **kwargs):
+        post_body = {'subnet': kwargs}
+        post_body['subnet']['ip_version'] = ip_version
+        post_body['subnet']['network_id'] = net_uuid
+        post_body['subnet']['cidr'] = cidr
         body = json.dumps(post_body)
         uri = '%s/subnets' % (self.uri_prefix)
         resp, body = self.post(uri, headers=self.headers, body=body)
@@ -206,16 +202,10 @@
         body = json.loads(body)
         return resp, body
 
-    def create_router(self, name, **kwargs):
-        post_body = {
-            'router': {
-                'name': name,
-            }
-        }
-        post_body['router']['admin_state_up'] = kwargs.get(
-            'admin_state_up', True)
-        post_body['router']['external_gateway_info'] = kwargs.get(
-            'external_gateway_info', None)
+    def create_router(self, name, admin_state_up=True, **kwargs):
+        post_body = {'router': kwargs}
+        post_body['router']['name'] = name
+        post_body['router']['admin_state_up'] = admin_state_up
         body = json.dumps(post_body)
         uri = '%s/routers' % (self.uri_prefix)
         resp, body = self.post(uri, headers=self.headers, body=body)
@@ -598,3 +588,15 @@
                                                      health_monitor_id)
         resp, body = self.delete(uri, headers=self.headers)
         return resp, body
+
+    def list_extensions(self):
+        uri = '%s/extensions' % (self.uri_prefix)
+        resp, body = self.get(uri, self.headers)
+        body = json.loads(body)
+        return resp, body
+
+    def show_extension_details(self, ext_alias):
+        uri = '%s/extensions/%s' % (self.uri_prefix, ext_alias)
+        resp, body = self.get(uri, headers=self.headers)
+        body = json.loads(body)
+        return resp, body
diff --git a/tempest/services/network/xml/network_client.py b/tempest/services/network/xml/network_client.py
index a9b5512..cf8154a 100755
--- a/tempest/services/network/xml/network_client.py
+++ b/tempest/services/network/xml/network_client.py
@@ -16,6 +16,7 @@
 import xml.etree.ElementTree as ET
 
 from tempest.common.rest_client import RestClientXML
+from tempest.services.compute.xml.common import deep_dict_to_xml
 from tempest.services.compute.xml.common import Document
 from tempest.services.compute.xml.common import Element
 from tempest.services.compute.xml.common import xml_to_json
@@ -428,6 +429,124 @@
                                                      health_monitor_id)
         return self.delete(uri, self.headers)
 
+    def list_extensions(self):
+        url = '%s/extensions' % (self.uri_prefix)
+        resp, body = self.get(url, self.headers)
+        extensions = self._parse_array(etree.fromstring(body))
+        extensions = {"extensions": extensions}
+        return resp, extensions
+
+    def show_extension_details(self, ext_alias):
+        uri = '%s/extensions/%s' % (self.uri_prefix, str(ext_alias))
+        resp, body = self.get(uri, self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def create_router(self, name, **kwargs):
+        uri = '%s/routers' % (self.uri_prefix)
+        router = Element("router")
+        router.append(Element("name", name))
+        deep_dict_to_xml(router, kwargs)
+        resp, body = self.post(uri, str(Document(router)), self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def delete_router(self, router_id):
+        uri = '%s/routers/%s' % (self.uri_prefix, router_id)
+        resp, body = self.delete(uri, self.headers)
+        return resp, body
+
+    def show_router(self, router_id):
+        uri = '%s/routers/%s' % (self.uri_prefix, router_id)
+        resp, body = self.get(uri, self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def update_router(self, router_id, **kwargs):
+        uri = '%s/routers/%s' % (self.uri_prefix, router_id)
+        router = Element("router")
+        for element, content in kwargs.iteritems():
+            router.append(Element(element, content))
+        resp, body = self.put(uri, str(Document(router)), self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def add_router_interface_with_subnet_id(self, router_id, subnet_id):
+        uri = '%s/routers/%s/add_router_interface' % (self.uri_prefix,
+              router_id)
+        subnet = Element("subnet_id", subnet_id)
+        resp, body = self.put(uri, str(Document(subnet)), self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def add_router_interface_with_port_id(self, router_id, port_id):
+        uri = '%s/routers/%s/add_router_interface' % (self.uri_prefix,
+              router_id)
+        port = Element("port_id", port_id)
+        resp, body = self.put(uri, str(Document(port)), self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def remove_router_interface_with_subnet_id(self, router_id, subnet_id):
+        uri = '%s/routers/%s/remove_router_interface' % (self.uri_prefix,
+              router_id)
+        subnet = Element("subnet_id", subnet_id)
+        resp, body = self.put(uri, str(Document(subnet)), self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def remove_router_interface_with_port_id(self, router_id, port_id):
+        uri = '%s/routers/%s/remove_router_interface' % (self.uri_prefix,
+              router_id)
+        port = Element("port_id", port_id)
+        resp, body = self.put(uri, str(Document(port)), self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def create_floating_ip(self, ext_network_id, **kwargs):
+        uri = '%s/floatingips' % (self.uri_prefix)
+        floatingip = Element('floatingip')
+        floatingip.append(Element("floating_network_id", ext_network_id))
+        for element, content in kwargs.iteritems():
+            floatingip.append(Element(element, content))
+        resp, body = self.post(uri, str(Document(floatingip)), self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def show_floating_ip(self, floating_ip_id):
+        uri = '%s/floatingips/%s' % (self.uri_prefix, floating_ip_id)
+        resp, body = self.get(uri, self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
+    def list_floating_ips(self):
+        uri = '%s/floatingips' % (self.uri_prefix)
+        resp, body = self.get(uri, self.headers)
+        floatingips = self._parse_array(etree.fromstring(body))
+        floatingips = {"floatingips": floatingips}
+        return resp, floatingips
+
+    def delete_floating_ip(self, floating_ip_id):
+        uri = '%s/floatingips/%s' % (self.uri_prefix, floating_ip_id)
+        resp, body = self.delete(uri, self.headers)
+        return resp, body
+
+    def update_floating_ip(self, floating_ip_id, **kwargs):
+        uri = '%s/floatingips/%s' % (self.uri_prefix, floating_ip_id)
+        floatingip = Element('floatingip')
+        floatingip.add_attr('xmlns:xsi',
+                            'http://www.w3.org/2001/XMLSchema-instance')
+        for element, content in kwargs.iteritems():
+            if content is None:
+                xml_elem = Element(element)
+                xml_elem.add_attr("xsi:nil", "true")
+                floatingip.append(xml_elem)
+            else:
+                floatingip.append(Element(element, content))
+        resp, body = self.put(uri, str(Document(floatingip)), self.headers)
+        body = _root_tag_fetcher_and_xml_to_json_parse(body)
+        return resp, body
+
 
 def _root_tag_fetcher_and_xml_to_json_parse(xml_returned_body):
     body = ET.fromstring(xml_returned_body)
@@ -435,5 +554,10 @@
     if root_tag.startswith("{"):
         ns, root_tag = root_tag.split("}", 1)
     body = xml_to_json(etree.fromstring(xml_returned_body))
+    nil = '{http://www.w3.org/2001/XMLSchema-instance}nil'
+    for key, val in body.iteritems():
+        if isinstance(val, dict):
+            if (nil in val and val[nil] == 'true'):
+                body[key] = None
     body = {root_tag: body}
     return body
diff --git a/tempest/services/object_storage/object_client.py b/tempest/services/object_storage/object_client.py
index d338d45..2fee042 100644
--- a/tempest/services/object_storage/object_client.py
+++ b/tempest/services/object_storage/object_client.py
@@ -15,10 +15,6 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import hashlib
-import hmac
-import urlparse
-
 from tempest.common import http
 from tempest.common.rest_client import RestClient
 from tempest import exceptions
@@ -125,29 +121,20 @@
         resp, body = self.copy(url, headers=headers)
         return resp, body
 
-    def get_object_using_temp_url(self, container, object_name, expires, key):
-        """Retrieve object's data using temporary URL."""
-
-        self._set_auth()
-        method = 'GET'
-        path = "%s/%s/%s" % (urlparse.urlparse(self.base_url).path, container,
-                             object_name)
-        hmac_body = '%s\n%s\n%s' % (method, expires, path)
-        sig = hmac.new(key, hmac_body, hashlib.sha1).hexdigest()
-
-        url = "%s/%s?temp_url_sig=%s&temp_url_expires=%s" % (container,
-                                                             object_name,
-                                                             sig, expires)
-
-        resp, body = self.get(url)
-        return resp, body
-
     def create_object_segments(self, container, object_name, segment, data):
         """Creates object segments."""
         url = "{0}/{1}/{2}".format(container, object_name, segment)
         resp, body = self.put(url, data, self.headers)
         return resp, body
 
+    def get_object_using_temp_url(self, url):
+        """Retrieve object's data using temp URL."""
+        return self.get(url)
+
+    def put_object_using_temp_url(self, url, data):
+        """Put data in an object using temp URL."""
+        return self.put(url, data, None)
+
 
 class ObjectClientCustomizedHeader(RestClient):
 
diff --git a/tempest/stress/README.rst b/tempest/stress/README.rst
index 7c180f6..ae86f6e 100644
--- a/tempest/stress/README.rst
+++ b/tempest/stress/README.rst
@@ -31,7 +31,7 @@
 
 To test installation, do the following (from the tempest/stress directory):
 
-	./run_stress.py etc/server-create-destroy-test.json -d 30
+	./run_stress.py -t etc/server-create-destroy-test.json -d 30
 
 This sample test tries to create a few VMs and kill a few VMs.
 
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index e518d28..b5cab68 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -13,6 +13,7 @@
 #    limitations under the License.
 
 import multiprocessing
+import os
 import signal
 import time
 
@@ -34,11 +35,14 @@
     username = admin_manager.config.stress.target_ssh_user
     key_filename = admin_manager.config.stress.target_private_key_path
     if not (username and key_filename):
+        LOG.error('username and key_filename should not be empty')
         return None
     ssh_client = ssh.Client(host, username, key_filename=key_filename)
     try:
         return ssh_client.exec_command(command)
     except exceptions.SSHExecCommandFailed:
+        LOG.error('do_ssh raise exception. command:%s, host:%s.'
+                  % (command, host))
         return None
 
 
@@ -61,19 +65,20 @@
     return nodes
 
 
-def _error_in_logs(logfiles, nodes):
+def _has_error_in_logs(logfiles, nodes, stop_on_error=False):
     """
     Detect errors in the nova log files on the controller and compute nodes.
     """
     grep = 'egrep "ERROR|TRACE" %s' % logfiles
+    ret = False
     for node in nodes:
         errors = do_ssh(grep, node)
-        if not errors:
-            return None
         if len(errors) > 0:
             LOG.error('%s: %s' % (node, errors))
-            return errors
-    return None
+            ret = True
+            if stop_on_error:
+                break
+    return ret
 
 
 def sigchld_handler(signal, frame):
@@ -87,12 +92,22 @@
     """
     Goes through the process list and terminates all child processes.
     """
+    log_check_interval = int(admin_manager.config.stress.log_check_interval)
     for process in processes:
         if process['process'].is_alive():
             try:
                 process['process'].terminate()
             except Exception:
                 pass
+    time.sleep(log_check_interval)
+    for process in processes:
+        if process['process'].is_alive():
+            try:
+                pid = process['process'].pid
+                LOG.warn("Process %d hangs. Send SIGKILL." % pid)
+                os.kill(pid, signal.SIGKILL)
+            except Exception:
+                pass
         process['process'].join()
 
 
@@ -181,8 +196,7 @@
 
         if not logfiles:
             continue
-        errors = _error_in_logs(logfiles, computes)
-        if errors:
+        if _has_error_in_logs(logfiles, computes, stop_on_error):
             had_errors = True
             break
 
diff --git a/tempest/stress/run_stress.py b/tempest/stress/run_stress.py
index 886d94b..e5cc281 100755
--- a/tempest/stress/run_stress.py
+++ b/tempest/stress/run_stress.py
@@ -23,14 +23,20 @@
 from testtools.testsuite import iterate_tests
 from unittest import loader
 
+from tempest.openstack.common import log as logging
+
+LOG = logging.getLogger(__name__)
+
 
 def discover_stress_tests(path="./", filter_attr=None, call_inherited=False):
     """Discovers all tempest tests and create action out of them
     """
+    LOG.info("Start test discovery")
     tests = []
     testloader = loader.TestLoader()
     list = testloader.discover(path)
     for func in (iterate_tests(list)):
+        attrs = []
         try:
             method_name = getattr(func, '_testMethodName')
             full_name = "%s.%s.%s" % (func.__module__,
@@ -106,4 +112,8 @@
                    help="Name of the file with test description")
 
 if __name__ == "__main__":
-    sys.exit(main(parser.parse_args()))
+    try:
+        sys.exit(main(parser.parse_args()))
+    except Exception:
+        LOG.exception("Failure in the stress test framework")
+        sys.exit(1)
diff --git a/tempest/stress/stressaction.py b/tempest/stress/stressaction.py
index 45a628d..61e46fa 100644
--- a/tempest/stress/stressaction.py
+++ b/tempest/stress/stressaction.py
@@ -30,7 +30,10 @@
         self.stop_on_error = stop_on_error
 
     def _shutdown_handler(self, signal, frame):
-        self.tearDown()
+        try:
+            self.tearDown()
+        except Exception:
+            self.logger.exception("Error while tearDown")
         sys.exit(0)
 
     @property
diff --git a/tempest/test.py b/tempest/test.py
index 6acb1c9..8ce7af8 100644
--- a/tempest/test.py
+++ b/tempest/test.py
@@ -16,6 +16,7 @@
 #    under the License.
 
 import atexit
+import functools
 import os
 import time
 
@@ -103,6 +104,24 @@
     return decorator
 
 
+def skip_because(*args, **kwargs):
+    """A decorator useful to skip tests hitting known bugs
+
+    @param bug: bug number causing the test to skip
+    @param condition: optional condition to be True for the skip to have place
+    """
+    def decorator(f):
+        @functools.wraps(f)
+        def wrapper(*func_args, **func_kwargs):
+            if "bug" in kwargs:
+                if "condition" not in kwargs or kwargs["condition"] is True:
+                    msg = "Skipped until Bug: %s is resolved." % kwargs["bug"]
+                    raise testtools.TestCase.skipException(msg)
+            return f(*func_args, **func_kwargs)
+        return wrapper
+    return decorator
+
+
 # there is a mis-match between nose and testtools for older pythons.
 # testtools will set skipException to be either
 # unittest.case.SkipTest, unittest2.case.SkipTest or an internal skip
diff --git a/tempest/tests/test_wrappers.py b/tempest/tests/test_wrappers.py
index 1a5af00..dbe3420 100644
--- a/tempest/tests/test_wrappers.py
+++ b/tempest/tests/test_wrappers.py
@@ -20,8 +20,6 @@
 import tempfile
 import testtools
 
-from tempest.test import attr
-
 DEVNULL = open(os.devnull, 'wb')
 
 
@@ -46,7 +44,6 @@
         shutil.copy('tempest/tests/files/setup.cfg', self.setup_cfg_file)
         shutil.copy('tempest/tests/files/__init__.py', self.init_file)
 
-    @attr(type='smoke')
     def test_pretty_tox(self):
         # Copy wrapper script and requirements:
         pretty_tox = os.path.join(self.directory, 'pretty_tox.sh')
@@ -62,7 +59,6 @@
                                     shell=True, stdout=DEVNULL, stderr=DEVNULL)
         self.assertEqual(exit_code, 0)
 
-    @attr(type='smoke')
     def test_pretty_tox_fails(self):
         # Copy wrapper script and requirements:
         pretty_tox = os.path.join(self.directory, 'pretty_tox.sh')
@@ -78,7 +74,6 @@
                                     stdout=DEVNULL, stderr=DEVNULL)
         self.assertEqual(exit_code, 1)
 
-    @attr(type='smoke')
     def test_pretty_tox_serial(self):
         # Copy wrapper script and requirements:
         pretty_tox = os.path.join(self.directory, 'pretty_tox_serial.sh')
@@ -90,7 +85,6 @@
                                     shell=True, stdout=DEVNULL, stderr=DEVNULL)
         self.assertEqual(exit_code, 0)
 
-    @attr(type='smoke')
     def test_pretty_tox_serial_fails(self):
         # Copy wrapper script and requirements:
         pretty_tox = os.path.join(self.directory, 'pretty_tox_serial.sh')
diff --git a/tempest/thirdparty/boto/test_ec2_instance_run.py b/tempest/thirdparty/boto/test_ec2_instance_run.py
index 486e0a0..0f455e1 100644
--- a/tempest/thirdparty/boto/test_ec2_instance_run.py
+++ b/tempest/thirdparty/boto/test_ec2_instance_run.py
@@ -16,7 +16,6 @@
 #    under the License.
 
 from boto import exception
-import testtools
 
 from tempest import clients
 from tempest.common.utils.data_utils import rand_name
@@ -24,6 +23,7 @@
 from tempest import exceptions
 from tempest.openstack.common import log as logging
 from tempest.test import attr
+from tempest.test import skip_because
 from tempest.thirdparty.boto.test import BotoTestCase
 from tempest.thirdparty.boto.utils.s3 import s3_upload_dir
 from tempest.thirdparty.boto.utils.wait import re_search_wait
@@ -188,13 +188,13 @@
         self.assertEqual(tags[0].value, 'value1')
 
         tags = self.ec2_client.get_all_tags(filters={'key': 'value2'})
-        self.assertEqual(len(tags), 0)
+        self.assertEqual(len(tags), 0, str(tags))
 
         for instance in reservation.instances:
             instance.remove_tag('key1', value='value1')
 
         tags = self.ec2_client.get_all_tags()
-        self.assertEqual(len(tags), 0)
+        self.assertEqual(len(tags), 0, str(tags))
 
         for instance in reservation.instances:
             instance.stop()
@@ -206,8 +206,8 @@
             instance.terminate()
         self.cancelResourceCleanUp(rcuk)
 
+    @skip_because(bug="1098891")
     @attr(type='smoke')
-    @testtools.skip("Skipped until the Bug #1098891 is resolved")
     def test_run_terminate_instance(self):
         # EC2 run, terminate immediately
         image_ami = self.ec2_client.get_image(self.images["ami"]
@@ -233,7 +233,7 @@
 
     # NOTE(afazekas): doctored test case,
     # with normal validation it would fail
-    @testtools.skip("Skipped until the Bug #1182679 is resolved.")
+    @skip_because(bug="1182679")
     @attr(type='smoke')
     def test_integration_1(self):
         # EC2 1. integration test (not strict)
diff --git a/tempest/thirdparty/boto/test_ec2_keys.py b/tempest/thirdparty/boto/test_ec2_keys.py
index 85a99c0..5592d8c 100644
--- a/tempest/thirdparty/boto/test_ec2_keys.py
+++ b/tempest/thirdparty/boto/test_ec2_keys.py
@@ -15,11 +15,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
-
 from tempest import clients
 from tempest.common.utils.data_utils import rand_name
 from tempest.test import attr
+from tempest.test import skip_because
 from tempest.thirdparty.boto.test import BotoTestCase
 
 
@@ -47,8 +46,8 @@
         self.assertTrue(compare_key_pairs(keypair,
                         self.client.get_key_pair(key_name)))
 
+    @skip_because(bug="1072318")
     @attr(type='smoke')
-    @testtools.skip("Skipped until the Bug #1072318 is resolved")
     def test_delete_ec2_keypair(self):
         # EC2 delete KeyPair
         key_name = rand_name("keypair-")
diff --git a/tempest/thirdparty/boto/test_ec2_network.py b/tempest/thirdparty/boto/test_ec2_network.py
index ae8c3c2..b4949c8 100644
--- a/tempest/thirdparty/boto/test_ec2_network.py
+++ b/tempest/thirdparty/boto/test_ec2_network.py
@@ -15,10 +15,9 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
-
 from tempest import clients
 from tempest.test import attr
+from tempest.test import skip_because
 from tempest.thirdparty.boto.test import BotoTestCase
 
 
@@ -30,8 +29,8 @@
         cls.os = clients.Manager()
         cls.client = cls.os.ec2api_client
 
-# Note(afazekas): these tests for things duable without an instance
-    @testtools.skip("Skipped until the Bug #1080406 is resolved")
+    # Note(afazekas): these tests for things duable without an instance
+    @skip_because(bug="1080406")
     @attr(type='smoke')
     def test_disassociate_not_associated_floating_ip(self):
         # EC2 disassociate not associated floating ip
diff --git a/tempest/thirdparty/boto/test_s3_buckets.py b/tempest/thirdparty/boto/test_s3_buckets.py
index e43cbaa..1a8fbe0 100644
--- a/tempest/thirdparty/boto/test_s3_buckets.py
+++ b/tempest/thirdparty/boto/test_s3_buckets.py
@@ -15,11 +15,10 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
-import testtools
-
 from tempest import clients
 from tempest.common.utils.data_utils import rand_name
 from tempest.test import attr
+from tempest.test import skip_because
 from tempest.thirdparty.boto.test import BotoTestCase
 
 
@@ -31,7 +30,7 @@
         cls.os = clients.Manager()
         cls.client = cls.os.s3_client
 
-    @testtools.skip("Skipped until the Bug #1076965 is resolved")
+    @skip_because(bug="1076965")
     @attr(type='smoke')
     def test_create_and_get_delete_bucket(self):
         # S3 Create, get and delete bucket
diff --git a/test-requirements.txt b/test-requirements.txt
index 1ede25e..8aa6ed9 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -3,3 +3,4 @@
 docutils==0.9.1
 sphinx>=1.1.2
 python-subunit
+oslo.sphinx
diff --git a/tools/check_logs.py b/tools/check_logs.py
new file mode 100755
index 0000000..2ad4f70
--- /dev/null
+++ b/tools/check_logs.py
@@ -0,0 +1,155 @@
+#!/usr/bin/env python
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2013 Red Hat, Inc.
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+import argparse
+import gzip
+import os
+import re
+import StringIO
+import sys
+import urllib2
+import yaml
+
+
+def process_files(file_specs, url_specs, whitelists):
+    regexp = re.compile(r"^.*(ERROR|CRITICAL).*\[.*\-.*\]")
+    had_errors = False
+    for (name, filename) in file_specs:
+        whitelist = whitelists.get(name, [])
+        with open(filename) as content:
+            if scan_content(name, content, regexp, whitelist):
+                had_errors = True
+    for (name, url) in url_specs:
+        whitelist = whitelists.get(name, [])
+        req = urllib2.Request(url)
+        req.add_header('Accept-Encoding', 'gzip')
+        page = urllib2.urlopen(req)
+        buf = StringIO.StringIO(page.read())
+        f = gzip.GzipFile(fileobj=buf)
+        if scan_content(name, f.read().splitlines(), regexp, whitelist):
+            had_errors = True
+    return had_errors
+
+
+def scan_content(name, content, regexp, whitelist):
+    had_errors = False
+    for line in content:
+        if not line.startswith("Stderr:") and regexp.match(line):
+            whitelisted = False
+            for w in whitelist:
+                pat = ".*%s.*%s.*" % (w['module'].replace('.', '\\.'),
+                                      w['message'])
+                if re.match(pat, line):
+                    whitelisted = True
+                    break
+            if not whitelisted:
+                if not had_errors:
+                    print("Log File: %s" % name)
+                had_errors = True
+                print(line)
+    return had_errors
+
+
+def collect_url_logs(url):
+    page = urllib2.urlopen(url)
+    content = page.read()
+    logs = re.findall('(screen-[\w-]+\.txt\.gz)</a>', content)
+    return logs
+
+
+def main(opts):
+    if opts.directory and opts.url or not (opts.directory or opts.url):
+        print("Must provide exactly one of -d or -u")
+        exit(1)
+    print("Checking logs...")
+    WHITELIST_FILE = os.path.join(
+        os.path.abspath(os.path.dirname(os.path.dirname(__file__))),
+        "etc", "whitelist.yaml")
+
+    file_matcher = re.compile(r".*screen-([\w-]+)\.log")
+    files = []
+    if opts.directory:
+        d = opts.directory
+        for f in os.listdir(d):
+            files.append(os.path.join(d, f))
+    files_to_process = []
+    for f in files:
+        m = file_matcher.match(f)
+        if m:
+            files_to_process.append((m.group(1), f))
+
+    url_matcher = re.compile(r".*screen-([\w-]+)\.txt\.gz")
+    urls = []
+    if opts.url:
+        for logfile in collect_url_logs(opts.url):
+            urls.append("%s/%s" % (opts.url, logfile))
+    urls_to_process = []
+    for u in urls:
+        m = url_matcher.match(u)
+        if m:
+            urls_to_process.append((m.group(1), u))
+
+    whitelists = {}
+    with open(WHITELIST_FILE) as stream:
+        loaded = yaml.safe_load(stream)
+        if loaded:
+            for (name, l) in loaded.iteritems():
+                for w in l:
+                    assert 'module' in w, 'no module in %s' % name
+                    assert 'message' in w, 'no message in %s' % name
+            whitelists = loaded
+    if process_files(files_to_process, urls_to_process, whitelists):
+        print("Logs have errors")
+        # Return non-zero to start failing builds
+        return 0
+    else:
+        print("ok")
+        return 0
+
+usage = """
+Find non-white-listed log errors in log files from a devstack-gate run.
+Log files will be searched for ERROR or CRITICAL messages. If any
+error messages do not match any of the whitelist entries contained in
+etc/whitelist.yaml, those messages will be printed to the console and
+failure will be returned. A file directory containing logs or a url to the
+log files of an OpenStack gate job can be provided.
+
+The whitelist yaml looks like:
+
+log-name:
+    - module: "a.b.c"
+      message: "regexp"
+    - module: "a.b.c"
+      message: "regexp"
+
+repeated for each log file with a whitelist.
+"""
+
+parser = argparse.ArgumentParser(description=usage)
+parser.add_argument('-d', '--directory',
+                    help="Directory containing log files")
+parser.add_argument('-u', '--url',
+                    help="url containing logs from an OpenStack gate job")
+
+if __name__ == "__main__":
+    try:
+        sys.exit(main(parser.parse_args()))
+    except Exception as e:
+        print("Failure in script: %s" % e)
+        # Don't fail if there is a problem with the script.
+        sys.exit(0)
diff --git a/tools/find_stack_traces.py b/tools/find_stack_traces.py
index 0ce1500..52a5a66 100755
--- a/tools/find_stack_traces.py
+++ b/tools/find_stack_traces.py
@@ -65,7 +65,9 @@
 
 def hunt_for_stacktrace(url):
     """Return TRACE or ERROR lines out of logs."""
-    page = urllib2.urlopen(url)
+    req = urllib2.Request(url)
+    req.add_header('Accept-Encoding', 'gzip')
+    page = urllib2.urlopen(req)
     buf = StringIO.StringIO(page.read())
     f = gzip.GzipFile(fileobj=buf)
     content = f.read()
diff --git a/tools/install_venv_common.py b/tools/install_venv_common.py
index 0999e2c..92d66ae 100644
--- a/tools/install_venv_common.py
+++ b/tools/install_venv_common.py
@@ -119,8 +119,7 @@
         self.pip_install('setuptools')
         self.pip_install('pbr')
 
-        self.pip_install('-r', self.requirements)
-        self.pip_install('-r', self.test_requirements)
+        self.pip_install('-r', self.requirements, '-r', self.test_requirements)
 
     def post_process(self):
         self.get_distro().post_process()
diff --git a/tools/skip_tracker.py b/tools/skip_tracker.py
index c38ccdb..ffaf134 100755
--- a/tools/skip_tracker.py
+++ b/tools/skip_tracker.py
@@ -61,8 +61,8 @@
     """
     Return the skip tuples in a test file
     """
-    BUG_RE = re.compile(r'.*skip.*bug:*\s*\#*(\d+)', re.IGNORECASE)
-    DEF_RE = re.compile(r'.*def (\w+)\(')
+    BUG_RE = re.compile(r'\s*@.*skip_because\(bug=[\'"](\d+)[\'"]')
+    DEF_RE = re.compile(r'\s*def (\w+)\(')
     bug_found = False
     results = []
     lines = open(path, 'rb').readlines()
diff --git a/tools/tempest_auto_config.py b/tools/tempest_auto_config.py
new file mode 100644
index 0000000..aef6a1f
--- /dev/null
+++ b/tools/tempest_auto_config.py
@@ -0,0 +1,234 @@
+# vim: tabstop=4 shiftwidth=4 softtabstop=4
+
+# Copyright 2012 OpenStack Foundation
+# All Rights Reserved.
+#
+#    Licensed under the Apache License, Version 2.0 (the "License"); you may
+#    not use this file except in compliance with the License. You may obtain
+#    a copy of the License at
+#
+#         http://www.apache.org/licenses/LICENSE-2.0
+#
+#    Unless required by applicable law or agreed to in writing, software
+#    distributed under the License is distributed on an "AS IS" BASIS, WITHOUT
+#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the
+#    License for the specific language governing permissions and limitations
+#    under the License.
+
+# Config
+import ConfigParser
+import os
+
+# Default client libs
+import keystoneclient.v2_0.client as keystone_client
+
+# Import Openstack exceptions
+import keystoneclient.exceptions as keystone_exception
+
+
+DEFAULT_CONFIG_DIR = "%s/etc" % os.path.abspath(os.path.pardir)
+DEFAULT_CONFIG_FILE = "tempest.conf"
+DEFAULT_CONFIG_SAMPLE = "tempest.conf.sample"
+
+# Environment variables override defaults
+TEMPEST_CONFIG_DIR = os.environ.get('TEMPEST_CONFIG_DIR') or DEFAULT_CONFIG_DIR
+TEMPEST_CONFIG = os.environ.get('TEMPEST_CONFIG') or "%s/%s" % \
+    (TEMPEST_CONFIG_DIR, DEFAULT_CONFIG_FILE)
+TEMPEST_CONFIG_SAMPLE = os.environ.get('TEMPEST_CONFIG_SAMPLE') or "%s/%s" % \
+    (TEMPEST_CONFIG_DIR, DEFAULT_CONFIG_SAMPLE)
+
+# Admin credentials
+OS_USERNAME = os.environ.get('OS_USERNAME')
+OS_PASSWORD = os.environ.get('OS_PASSWORD')
+OS_TENANT_NAME = os.environ.get('OS_TENANT_NAME')
+OS_AUTH_URL = os.environ.get('OS_AUTH_URL')
+
+# Image references
+IMAGE_ID = os.environ.get('IMAGE_ID')
+IMAGE_ID_ALT = os.environ.get('IMAGE_ID_ALT')
+
+
+class ClientManager(object):
+    """
+    Manager that provides access to the official python clients for
+    calling various OpenStack APIs.
+    """
+    def __init__(self):
+        self.identity_client = None
+        self.image_client = None
+        self.network_client = None
+        self.compute_client = None
+        self.volume_client = None
+
+    def get_identity_client(self, **kwargs):
+        """
+        Returns the openstack identity python client
+        :param username: a string representing the username
+        :param password: a string representing the user's password
+        :param tenant_name: a string representing the tenant name of the user
+        :param auth_url: a string representing the auth url of the identity
+        :param insecure: True if we wish to disable ssl certificate validation,
+        False otherwise
+        :returns an instance of openstack identity python client
+        """
+        if not self.identity_client:
+            self.identity_client = keystone_client.Client(**kwargs)
+
+        return self.identity_client
+
+
+def getTempestConfigSample():
+    """
+    Gets the tempest configuration file as a ConfigParser object
+    :return: the tempest configuration file
+    """
+    # get the sample config file from the sample
+    config_sample = ConfigParser.ConfigParser()
+    config_sample.readfp(open(TEMPEST_CONFIG_SAMPLE))
+
+    return config_sample
+
+
+def update_config_admin_credentials(config, config_section):
+    """
+    Updates the tempest config with the admin credentials
+    :param config: an object representing the tempest config file
+    :param config_section: the section name where the admin credentials are
+    """
+    # Check if credentials are present
+    if not (OS_AUTH_URL and
+            OS_USERNAME and
+            OS_PASSWORD and
+            OS_TENANT_NAME):
+        raise Exception("Admin environment variables not found.")
+
+    # TODO(tkammer): Add support for uri_v3
+    config_identity_params = {'uri': OS_AUTH_URL,
+                              'admin_username': OS_USERNAME,
+                              'admin_password': OS_PASSWORD,
+                              'admin_tenant_name': OS_TENANT_NAME}
+
+    update_config_section_with_params(config,
+                                      config_section,
+                                      config_identity_params)
+
+
+def update_config_section_with_params(config, section, params):
+    """
+    Updates a given config object with given params
+    :param config: the object representing the config file of tempest
+    :param section: the section we would like to update
+    :param params: the parameters we wish to update for that section
+    """
+    for option, value in params.items():
+        config.set(section, option, value)
+
+
+def get_identity_client_kwargs(config, section_name):
+    """
+    Get the required arguments for the identity python client
+    :param config: the tempest configuration file
+    :param section_name: the section name in the configuration where the
+    arguments can be found
+    :return: a dictionary representing the needed arguments for the identity
+    client
+    """
+    username = config.get(section_name, 'admin_username')
+    password = config.get(section_name, 'admin_password')
+    tenant_name = config.get(section_name, 'admin_tenant_name')
+    auth_url = config.get(section_name, 'uri')
+    dscv = config.get(section_name, 'disable_ssl_certificate_validation')
+    kwargs = {'username': username,
+              'password': password,
+              'tenant_name': tenant_name,
+              'auth_url': auth_url,
+              'insecure': dscv}
+
+    return kwargs
+
+
+def create_user_with_tenant(identity_client, username, password, tenant_name):
+    """
+    Creates a user using a given identity client
+    :param identity_client: openstack identity python client
+    :param username: a string representing the username
+    :param password: a string representing the user's password
+    :param tenant_name: a string representing the tenant name of the user
+    """
+    # Try to create the necessary tenant
+    tenant_id = None
+    try:
+        tenant_description = "Tenant for Tempest %s user" % username
+        tenant = identity_client.tenants.create(tenant_name,
+                                                tenant_description)
+        tenant_id = tenant.id
+    except keystone_exception.Conflict:
+
+        # if already exist, use existing tenant
+        tenant_list = identity_client.tenants.list()
+        for tenant in tenant_list:
+            if tenant.name == tenant_name:
+                tenant_id = tenant.id
+
+    # Try to create the user
+    try:
+        email = "%s@test.com" % username
+        identity_client.users.create(name=username,
+                                     password=password,
+                                     email=email,
+                                     tenant_id=tenant_id)
+    except keystone_exception.Conflict:
+
+        # if already exist, use existing user
+        pass
+
+
+def create_users_and_tenants(identity_client,
+                             config,
+                             identity_section):
+    """
+    Creates the two non admin users and tenants for tempest
+    :param identity_client: openstack identity python client
+    :param config: tempest configuration file
+    :param identity_section: the section name of identity in the config
+    """
+    # Get the necessary params from the config file
+    tenant_name = config.get(identity_section, 'tenant_name')
+    username = config.get(identity_section, 'username')
+    password = config.get(identity_section, 'password')
+
+    alt_tenant_name = config.get(identity_section, 'alt_tenant_name')
+    alt_username = config.get(identity_section, 'alt_username')
+    alt_password = config.get(identity_section, 'alt_password')
+
+    # Create the necessary users for the test runs
+    create_user_with_tenant(identity_client, username, password, tenant_name)
+    create_user_with_tenant(identity_client, alt_username, alt_password,
+                            alt_tenant_name)
+
+
+def main():
+    """
+    Main module to control the script
+    """
+    # TODO(tkammer): add support for existing config file
+    config_sample = getTempestConfigSample()
+    update_config_admin_credentials(config_sample, 'identity')
+
+    client_manager = ClientManager()
+
+    # Set the identity related info for tempest
+    identity_client_kwargs = get_identity_client_kwargs(config_sample,
+                                                        'identity')
+    identity_client = client_manager.get_identity_client(
+        **identity_client_kwargs)
+
+    # Create the necessary users and tenants for tempest run
+    create_users_and_tenants(identity_client,
+                             config_sample,
+                             'identity')
+
+    # TODO(tkammer): add image implementation
+
+if __name__ == "__main__":
+    main()
diff --git a/tox.ini b/tox.ini
index 1b8a0fd..d93112c 100644
--- a/tox.ini
+++ b/tox.ini
@@ -1,11 +1,23 @@
 [tox]
 envlist = pep8
+minversion = 1.6
+skipsdist = True
 
 [testenv]
 setenv = VIRTUAL_ENV={envdir}
          LANG=en_US.UTF-8
          LANGUAGE=en_US:en
          LC_ALL=C
+usedevelop = True
+
+[testenv:py26]
+commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
+
+[testenv:py33]
+commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
+
+[testenv:py27]
+commands = python setup.py test --slowest --testr-arg='tempest\.tests {posargs}'
 
 [testenv:all]
 sitepackages = True
@@ -15,29 +27,25 @@
 
 [testenv:full]
 sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
 # The regex below is used to select which tests to run and exclude the slow tag:
 # See the testrepostiory bug: https://bugs.launchpad.net/testrepository/+bug/1208610
 commands =
-  sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli|tests)) {posargs}'
+  sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli)) {posargs}'
 
 [testenv:testr-full]
 sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
 commands =
-  sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli|tests)) {posargs}'
+  sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli)) {posargs}'
 
 [testenv:heat-slow]
 sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
-         OS_TEST_TIMEOUT=1200
+setenv = OS_TEST_TIMEOUT=1200
 # The regex below is used to select heat api/scenario tests tagged as slow.
 commands =
   sh tools/pretty_tox_serial.sh '(?=.*\[.*\bslow\b.*\])(^tempest\.(api|scenario)\.orchestration) {posargs}'
 
 [testenv:large-ops]
 sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
 commands =
   python setup.py testr --slowest --testr-args='tempest.scenario.test_large_ops {posargs}'
 
@@ -51,8 +59,9 @@
          NOSE_OPENSTACK_YELLOW=3
          NOSE_OPENSTACK_SHOW_ELAPSED=1
          NOSE_OPENSTACK_STDOUT=1
+         TEMPEST_PY26_NOSE_COMPAT=1
 commands =
-  nosetests --logging-format '%(asctime)-15s %(message)s' --with-xunit -sv --xunit-file=nosetests-full.xml tempest/api tempest/scenario tempest/thirdparty tempest/cli tempest/tests {posargs}
+  nosetests --logging-format '%(asctime)-15s %(message)s' --with-xunit -sv --xunit-file=nosetests-full.xml tempest/api tempest/scenario tempest/thirdparty tempest/cli {posargs}
 
 [testenv:py26-smoke]
 setenv = VIRTUAL_ENV={envdir}
@@ -62,12 +71,12 @@
          NOSE_OPENSTACK_YELLOW=3
          NOSE_OPENSTACK_SHOW_ELAPSED=1
          NOSE_OPENSTACK_STDOUT=1
+         TEMPEST_PY26_NOSE_COMPAT=1
 commands =
   nosetests --logging-format '%(asctime)-15s %(message)s' --with-xunit -sv --attr=type=smoke --xunit-file=nosetests-smoke.xml tempest {posargs}
 
 [testenv:smoke]
 sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
 # This is still serial because neutron doesn't work with parallel. See:
 # https://bugs.launchpad.net/tempest/+bug/1216076 so the neutron smoke
 # job would fail if we moved it to parallel.
@@ -76,17 +85,15 @@
 
 [testenv:coverage]
 sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
 commands =
    python -m tools/tempest_coverage -c start --combine
-   sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli|tests))'
+   sh tools/pretty_tox.sh '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario|thirdparty|cli))'
    python -m tools/tempest_coverage -c report --html {posargs}
 
 [testenv:stress]
 sitepackages = True
-setenv = VIRTUAL_ENV={envdir}
 commands =
-    python -m tempest/stress/run_stress -a -d 3600
+    python -m tempest/stress/run_stress -a -d 3600 -S
 
 [testenv:venv]
 commands = {posargs}