Merge "Remove extra "?expanded=" from api link"
diff --git a/README.rst b/README.rst
index 281516b..9d19c23 100644
--- a/README.rst
+++ b/README.rst
@@ -263,9 +263,7 @@
 
     $ testr run tempest.api.compute.servers.test_servers_negative.ServersNegativeTestJSON.test_reboot_non_existent_server
 
-Alternatively, you can use the run_tempest.sh script which will create a venv
-and run the tests or use tox to do the same. Tox also contains several existing
-job configurations. For example::
+Tox also contains several existing job configurations. For example::
 
     $ tox -efull
 
diff --git a/doc/source/test-removal.rst b/doc/source/test-removal.rst
index 79a5846..4757dc4 100644
--- a/doc/source/test-removal.rst
+++ b/doc/source/test-removal.rst
@@ -38,8 +38,10 @@
  #. The test proposed for removal has a failure rate <  0.50% in the gate over
     the past release (the value and interval will likely be adjusted in the
     future)
- #. There must not be an external user/consumer of tempest that depends on the
-    test proposed for removal
+
+    .. _`prong #3`:
+ #. There must not be an external user/consumer of tempest
+    that depends on the test proposed for removal
 
 The answers to 1 and 2 are easy to verify. For 1 just provide a link to the new
 test location. If you are linking to the tempest removal patch please also put
@@ -133,6 +135,10 @@
  #. A revert for a patch which added a broken test, or testing which didn't
     actually run in the gate (basically any revert for something which
     shouldn't have been added)
+ #. Tests that would become out of scope as a consequence of an API change,
+    as described in `API Compatibility`_.
+    Such tests cannot live in Tempest because of the branchless nature of
+    Tempest. Such test must still honor `prong #3`_.
 
 For the first exception type the only types of testing in tree which have been
 declared out of scope at this point are:
@@ -149,7 +155,7 @@
 Tempest Scope
 ^^^^^^^^^^^^^
 
-Also starting in the liberty cycle tempest has defined a set of projects which
+Starting in the liberty cycle tempest has defined a set of projects which
 are defined as in scope for direct testing in tempest. As of today that list
 is:
 
@@ -166,3 +172,17 @@
 to maintain continuity after migrating the tests out of tempest.
 
 .. _tempest plugin mechanism: http://docs.openstack.org/developer/tempest/plugin.html
+
+API Compatibility
+"""""""""""""""""
+
+If an API introduces a non-discoverable, backward incompatible change, and
+such change is not backported to all versions supported by Tempest, tests for
+that API cannot live in Tempest anymore.
+This is because tests would not be able to know or control which API response
+to expect, and thus would not be able to enforce a specific behavior.
+
+If a test exists in Tempest that would meet this criteria as consequence of a
+change, the test must be removed according to the procedure discussed into
+this document. The API change should not be merged until all conditions
+required for test removal can be met.
\ No newline at end of file
diff --git a/run_tempest.sh b/run_tempest.sh
deleted file mode 100755
index 414146b..0000000
--- a/run_tempest.sh
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/usr/bin/env bash
-
-echo "WARNING: This script is deprecated and will be removed in the near future. Please migrate to tempest run or another method of launching a test runner"
-
-function usage {
-  echo "Usage: $0 [OPTION]..."
-  echo "Run Tempest test suite"
-  echo ""
-  echo "  -V, --virtual-env        Always use virtualenv.  Install automatically if not present"
-  echo "  -N, --no-virtual-env     Don't use virtualenv.  Run tests in local environment"
-  echo "  -n, --no-site-packages   Isolate the virtualenv from the global Python environment"
-  echo "  -f, --force              Force a clean re-build of the virtual environment. Useful when dependencies have been added."
-  echo "  -u, --update             Update the virtual environment with any newer package versions"
-  echo "  -s, --smoke              Only run smoke tests"
-  echo "  -t, --serial             Run testr serially"
-  echo "  -C, --config             Config file location"
-  echo "  -h, --help               Print this usage message"
-  echo "  -d, --debug              Run tests with testtools instead of testr. This allows you to use PDB"
-  echo "  -- [TESTROPTIONS]        After the first '--' you can pass arbitrary arguments to testr "
-}
-
-testrargs=""
-venv=${VENV:-.venv}
-with_venv=tools/with_venv.sh
-serial=0
-always_venv=0
-never_venv=0
-no_site_packages=0
-debug=0
-force=0
-wrapper=""
-config_file=""
-update=0
-
-if ! options=$(getopt -o VNnfusthdC:lL: -l virtual-env,no-virtual-env,no-site-packages,force,update,smoke,serial,help,debug,config: -- "$@")
-then
-    # parse error
-    usage
-    exit 1
-fi
-
-eval set -- $options
-first_uu=yes
-while [ $# -gt 0 ]; do
-  case "$1" in
-    -h|--help) usage; exit;;
-    -V|--virtual-env) always_venv=1; never_venv=0;;
-    -N|--no-virtual-env) always_venv=0; never_venv=1;;
-    -n|--no-site-packages) no_site_packages=1;;
-    -f|--force) force=1;;
-    -u|--update) update=1;;
-    -d|--debug) debug=1;;
-    -C|--config) config_file=$2; shift;;
-    -s|--smoke) testrargs+="smoke";;
-    -t|--serial) serial=1;;
-    --) [ "yes" == "$first_uu" ] || testrargs="$testrargs $1"; first_uu=no  ;;
-    *) testrargs="$testrargs $1";;
-  esac
-  shift
-done
-
-if [ -n "$config_file" ]; then
-    config_file=`readlink -f "$config_file"`
-    export TEMPEST_CONFIG_DIR=`dirname "$config_file"`
-    export TEMPEST_CONFIG=`basename "$config_file"`
-fi
-
-cd `dirname "$0"`
-
-if [ $no_site_packages -eq 1 ]; then
-  installvenvopts="--no-site-packages"
-fi
-
-function testr_init {
-  if [ ! -d .testrepository ]; then
-      ${wrapper} testr init
-  fi
-}
-
-function run_tests {
-  testr_init
-  ${wrapper} find . -type f -name "*.pyc" -delete
-  export OS_TEST_PATH=./tempest/test_discover
-  if [ $debug -eq 1 ]; then
-      if [ "$testrargs" = "" ]; then
-           testrargs="discover ./tempest/test_discover"
-      fi
-      ${wrapper} python -m testtools.run $testrargs
-      return $?
-  fi
-
-  if [ $serial -eq 1 ]; then
-      ${wrapper} testr run --subunit $testrargs | ${wrapper} subunit-trace -n -f
-  else
-      ${wrapper} testr run --parallel --subunit $testrargs | ${wrapper} subunit-trace -n -f
-  fi
-}
-
-if [ $never_venv -eq 0 ]
-then
-  # Remove the virtual environment if --force used
-  if [ $force -eq 1 ]; then
-    echo "Cleaning virtualenv..."
-    rm -rf ${venv}
-  fi
-  if [ $update -eq 1 ]; then
-      echo "Updating virtualenv..."
-      virtualenv $installvenvopts $venv
-      $venv/bin/pip install -U -r requirements.txt
-  fi
-  if [ -e ${venv} ]; then
-    wrapper="${with_venv}"
-  else
-    if [ $always_venv -eq 1 ]; then
-      # Automatically install the virtualenv
-      virtualenv $installvenvopts $venv
-      wrapper="${with_venv}"
-      ${wrapper} pip install -U -r requirements.txt
-    else
-      echo -e "No virtual environment found...create one? (Y/n) \c"
-      read use_ve
-      if [ "x$use_ve" = "xY" -o "x$use_ve" = "x" -o "x$use_ve" = "xy" ]; then
-        # Install the virtualenv and run the test suite in it
-        virtualenv $installvenvopts $venv
-        wrapper=${with_venv}
-        ${wrapper} pip install -U -r requirements.txt
-      fi
-    fi
-  fi
-fi
-
-run_tests
-retval=$?
-
-exit $retval
diff --git a/run_tests.sh b/run_tests.sh
deleted file mode 100755
index a856bb4..0000000
--- a/run_tests.sh
+++ /dev/null
@@ -1,193 +0,0 @@
-#!/usr/bin/env bash
-
-function usage {
-  echo "Usage: $0 [OPTION]..."
-  echo "Run Tempest unit tests"
-  echo ""
-  echo "  -V, --virtual-env        Always use virtualenv.  Install automatically if not present"
-  echo "  -N, --no-virtual-env     Don't use virtualenv.  Run tests in local environment"
-  echo "  -n, --no-site-packages   Isolate the virtualenv from the global Python environment"
-  echo "  -f, --force              Force a clean re-build of the virtual environment. Useful when dependencies have been added."
-  echo "  -u, --update             Update the virtual environment with any newer package versions"
-  echo "  -t, --serial             Run testr serially"
-  echo "  -p, --pep8               Just run pep8"
-  echo "  -c, --coverage           Generate coverage report"
-  echo "  -h, --help               Print this usage message"
-  echo "  -d, --debug              Run tests with testtools instead of testr. This allows you to use PDB"
-  echo "  -- [TESTROPTIONS]        After the first '--' you can pass arbitrary arguments to testr "
-}
-
-function deprecation_warning {
-  cat <<EOF
--------------------------------------------------------------------------
-WARNING: run_tests.sh is deprecated and this script will be removed after
-the Newton release. All tests should be run through testr/ostestr or tox.
-
-To run style checks:
-
- tox -e pep8
-
-To run python 2.7 unit tests
-
- tox -e py27
-
-To run unit tests and generate coverage report
-
- tox -e cover
-
-To run a subset of any of these tests:
-
- tox -e py27 someregex
-
- i.e.: tox -e py27 test_servers
-
-Additional tox targets are available in tox.ini. For more information
-see:
-http://docs.openstack.org/project-team-guide/project-setup/python.html
-
-NOTE: if you want to use testr to run tests, you can instead use:
-
- OS_TEST_PATH=./tempest/tests testr run
-
-Documentation on using testr directly can be found at
-http://testrepository.readthedocs.org/en/latest/MANUAL.html
--------------------------------------------------------------------------
-EOF
-}
-
-testrargs=""
-just_pep8=0
-venv=${VENV:-.venv}
-with_venv=tools/with_venv.sh
-serial=0
-always_venv=0
-never_venv=0
-no_site_packages=0
-debug=0
-force=0
-coverage=0
-wrapper=""
-config_file=""
-update=0
-
-deprecation_warning
-
-if ! options=$(getopt -o VNnfuctphd -l virtual-env,no-virtual-env,no-site-packages,force,update,serial,coverage,pep8,help,debug -- "$@")
-then
-    # parse error
-    usage
-    exit 1
-fi
-
-eval set -- $options
-first_uu=yes
-while [ $# -gt 0 ]; do
-  case "$1" in
-    -h|--help) usage; exit;;
-    -V|--virtual-env) always_venv=1; never_venv=0;;
-    -N|--no-virtual-env) always_venv=0; never_venv=1;;
-    -n|--no-site-packages) no_site_packages=1;;
-    -f|--force) force=1;;
-    -u|--update) update=1;;
-    -d|--debug) debug=1;;
-    -p|--pep8) let just_pep8=1;;
-    -c|--coverage) coverage=1;;
-    -t|--serial) serial=1;;
-    --) [ "yes" == "$first_uu" ] || testrargs="$testrargs $1"; first_uu=no  ;;
-    *) testrargs="$testrargs $1";;
-  esac
-  shift
-done
-
-
-cd `dirname "$0"`
-
-if [ $no_site_packages -eq 1 ]; then
-  installvenvopts="--no-site-packages"
-fi
-
-function testr_init {
-  if [ ! -d .testrepository ]; then
-      ${wrapper} testr init
-  fi
-}
-
-function run_tests {
-  testr_init
-  ${wrapper} find . -type f -name "*.pyc" -delete
-  export OS_TEST_PATH=./tempest/tests
-  if [ $debug -eq 1 ]; then
-      if [ "$testrargs" = "" ]; then
-          testrargs="discover ./tempest/tests"
-      fi
-      ${wrapper} python -m testtools.run $testrargs
-      return $?
-  fi
-
-  if [ $coverage -eq 1 ]; then
-      ${wrapper} python setup.py test --coverage
-      return $?
-  fi
-
-  if [ $serial -eq 1 ]; then
-      ${wrapper} testr run --subunit $testrargs | ${wrapper} subunit-trace -n -f
-  else
-      ${wrapper} testr run --parallel --subunit $testrargs | ${wrapper} subunit-trace -n -f
-  fi
-}
-
-function run_pep8 {
-  echo "Running flake8 ..."
-  if [ $never_venv -eq 1 ]; then
-      echo "**WARNING**:" >&2
-      echo "Running flake8 without virtual env may miss OpenStack HACKING detection" >&2
-  fi
-  ${wrapper} flake8
-}
-
-if [ $never_venv -eq 0 ]
-then
-  # Remove the virtual environment if --force used
-  if [ $force -eq 1 ]; then
-    echo "Cleaning virtualenv..."
-    rm -rf ${venv}
-  fi
-  if [ $update -eq 1 ]; then
-      echo "Updating virtualenv..."
-      virtualenv $installvenvopts $venv
-      $venv/bin/pip install -U -r requirements.txt -r test-requirements.txt
-  fi
-  if [ -e ${venv} ]; then
-    wrapper="${with_venv}"
-  else
-    if [ $always_venv -eq 1 ]; then
-      # Automatically install the virtualenv
-      virtualenv $installvenvopts $venv
-      wrapper="${with_venv}"
-      ${wrapper} pip install -U -r requirements.txt -r test-requirements.txt
-    else
-      echo -e "No virtual environment found...create one? (Y/n) \c"
-      read use_ve
-      if [ "x$use_ve" = "xY" -o "x$use_ve" = "x" -o "x$use_ve" = "xy" ]; then
-        # Install the virtualenv and run the test suite in it
-        virtualenv $installvenvopts $venv
-        wrapper=${with_venv}
-        ${wrapper} pip install -U -r requirements.txt -r test-requirements.txt
-      fi
-    fi
-  fi
-fi
-
-if [ $just_pep8 -eq 1 ]; then
-    run_pep8
-    exit
-fi
-
-run_tests
-retval=$?
-
-if [ -z "$testrargs" ]; then
-    run_pep8
-fi
-
-exit $retval
diff --git a/tempest/api/compute/admin/test_flavors_access_negative.py b/tempest/api/compute/admin/test_flavors_access_negative.py
index bd72d13..9fe1f74 100644
--- a/tempest/api/compute/admin/test_flavors_access_negative.py
+++ b/tempest/api/compute/admin/test_flavors_access_negative.py
@@ -26,6 +26,8 @@
     Add and remove Flavor Access require admin privileges.
     """
 
+    credentials = ['primary', 'admin', 'alt']
+
     @classmethod
     def skip_checks(cls):
         super(FlavorsAccessNegativeTestJSON, cls).skip_checks()
@@ -151,4 +153,4 @@
         self.assertRaises(lib_exc.NotFound,
                           self.admin_flavors_client.remove_flavor_access,
                           new_flavor['id'],
-                          data_utils.rand_uuid())
+                          self.os_alt.servers_client.tenant_id)
diff --git a/tempest/api/compute/admin/test_servers_negative.py b/tempest/api/compute/admin/test_servers_negative.py
index 5220c97..13a411b 100644
--- a/tempest/api/compute/admin/test_servers_negative.py
+++ b/tempest/api/compute/admin/test_servers_negative.py
@@ -45,16 +45,6 @@
         server = cls.create_test_server(wait_until='ACTIVE')
         cls.s1_id = server['id']
 
-    def _get_unused_flavor_id(self):
-        flavor_id = data_utils.rand_int_id(start=1000)
-        while True:
-            try:
-                self.flavors_client.show_flavor(flavor_id)
-            except lib_exc.NotFound:
-                break
-            flavor_id = data_utils.rand_int_id(start=1000)
-        return flavor_id
-
     @decorators.idempotent_id('28dcec23-f807-49da-822c-56a92ea3c687')
     @testtools.skipUnless(CONF.compute_feature_enabled.resize,
                           'Resize not available.')
@@ -62,8 +52,6 @@
     def test_resize_server_using_overlimit_ram(self):
         # NOTE(mriedem): Avoid conflicts with os-quota-class-sets tests.
         self.useFixture(fixtures.LockFixture('compute_quotas'))
-        flavor_name = data_utils.rand_name("flavor")
-        flavor_id = self._get_unused_flavor_id()
         quota_set = self.quotas_client.show_quota_set(
             self.tenant_id)['quota_set']
         ram = quota_set['ram']
@@ -73,11 +61,7 @@
         ram += 1
         vcpus = 1
         disk = 5
-        flavor_ref = self.flavors_client.create_flavor(name=flavor_name,
-                                                       ram=ram, vcpus=vcpus,
-                                                       disk=disk,
-                                                       id=flavor_id)['flavor']
-        self.addCleanup(self.flavors_client.delete_flavor, flavor_id)
+        flavor_ref = self.create_flavor(ram=ram, vcpus=vcpus, disk=disk)
         self.assertRaises((lib_exc.Forbidden, lib_exc.OverLimit),
                           self.client.resize_server,
                           self.servers[0]['id'],
@@ -90,8 +74,6 @@
     def test_resize_server_using_overlimit_vcpus(self):
         # NOTE(mriedem): Avoid conflicts with os-quota-class-sets tests.
         self.useFixture(fixtures.LockFixture('compute_quotas'))
-        flavor_name = data_utils.rand_name("flavor")
-        flavor_id = self._get_unused_flavor_id()
         quota_set = self.quotas_client.show_quota_set(
             self.tenant_id)['quota_set']
         vcpus = quota_set['cores']
@@ -101,11 +83,7 @@
         vcpus += 1
         ram = 512
         disk = 5
-        flavor_ref = self.flavors_client.create_flavor(name=flavor_name,
-                                                       ram=ram, vcpus=vcpus,
-                                                       disk=disk,
-                                                       id=flavor_id)['flavor']
-        self.addCleanup(self.flavors_client.delete_flavor, flavor_id)
+        flavor_ref = self.create_flavor(ram=ram, vcpus=vcpus, disk=disk)
         self.assertRaises((lib_exc.Forbidden, lib_exc.OverLimit),
                           self.client.resize_server,
                           self.servers[0]['id'],
diff --git a/tempest/api/compute/flavors/test_flavors_negative.py b/tempest/api/compute/flavors/test_flavors_negative.py
index a70c0a9..b313f44 100644
--- a/tempest/api/compute/flavors/test_flavors_negative.py
+++ b/tempest/api/compute/flavors/test_flavors_negative.py
@@ -21,6 +21,7 @@
 from tempest.common import image as common_image
 from tempest.common.utils import data_utils
 from tempest import config
+from tempest.lib import decorators
 from tempest.lib import exceptions as lib_exc
 from tempest import test
 
@@ -43,7 +44,7 @@
 
     @test.attr(type=['negative'])
     @test.services('image')
-    @test.idempotent_id('90f0d93a-91c1-450c-91e6-07d18172cefe')
+    @decorators.idempotent_id('90f0d93a-91c1-450c-91e6-07d18172cefe')
     def test_boot_with_low_ram(self):
         """Try boot a vm with lower than min ram
 
diff --git a/tempest/api/compute/security_groups/test_security_groups.py b/tempest/api/compute/security_groups/test_security_groups.py
index 349bfda..e90a1fc 100644
--- a/tempest/api/compute/security_groups/test_security_groups.py
+++ b/tempest/api/compute/security_groups/test_security_groups.py
@@ -145,7 +145,7 @@
         self.assertEqual(s_new_name, fetched_group['name'])
         self.assertEqual(s_new_des, fetched_group['description'])
 
-    @test.idempotent_id('79517d60-535a-438f-af3d-e6feab1cbea7')
+    @decorators.idempotent_id('79517d60-535a-438f-af3d-e6feab1cbea7')
     @test.services('network')
     def test_list_security_groups_by_server(self):
         # Create a couple security groups that we will use
diff --git a/tempest/api/compute/servers/test_create_server.py b/tempest/api/compute/servers/test_create_server.py
index a94c20b..20646d1 100644
--- a/tempest/api/compute/servers/test_create_server.py
+++ b/tempest/api/compute/servers/test_create_server.py
@@ -254,7 +254,6 @@
             self.flavor_ref)['flavor']
 
         def create_flavor_with_ephemeral(ephem_disk):
-            flavor_id = data_utils.rand_int_id(start=1000)
             name = 'flavor_with_ephemeral_%s' % ephem_disk
             flavor_name = data_utils.rand_name(name)
 
@@ -263,17 +262,10 @@
             disk = flavor_base['disk']
 
             # Create a flavor with ephemeral disk
-            flavor = self.flavor_client.create_flavor(
-                name=flavor_name, ram=ram, vcpus=vcpus, disk=disk,
-                id=flavor_id, ephemeral=ephem_disk)['flavor']
-            self.addCleanup(flavor_clean_up, flavor['id'])
-
+            flavor = self.create_flavor(name=flavor_name, ram=ram, vcpus=vcpus,
+                                        disk=disk, ephemeral=ephem_disk)
             return flavor['id']
 
-        def flavor_clean_up(flavor_id):
-            self.flavor_client.delete_flavor(flavor_id)
-            self.flavor_client.wait_for_resource_deletion(flavor_id)
-
         flavor_with_eph_disk_id = create_flavor_with_ephemeral(ephem_disk=1)
         flavor_no_eph_disk_id = create_flavor_with_ephemeral(ephem_disk=0)
 
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 9f4ce95..19cd98f 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -10,6 +10,8 @@
 #    License for the specific language governing permissions and limitations
 #    under the License.
 
+from testtools import matchers
+
 from tempest.api.volume import base
 from tempest.common.utils import data_utils
 from tempest import config
@@ -95,8 +97,12 @@
 
     @decorators.idempotent_id('2a8abbe4-d871-46db-b049-c41f5af8216e')
     def test_snapshot_create_get_list_update_delete(self):
-        # Create a snapshot
-        snapshot = self.create_snapshot(self.volume_origin['id'])
+        # Create a snapshot with metadata
+        metadata = {"snap-meta1": "value1",
+                    "snap-meta2": "value2",
+                    "snap-meta3": "value3"}
+        snapshot = self.create_snapshot(self.volume_origin['id'],
+                                        metadata=metadata)
 
         # Get the snap and check for some of its details
         snap_get = self.snapshots_client.show_snapshot(
@@ -105,6 +111,10 @@
                          snap_get['volume_id'],
                          "Referred volume origin mismatch")
 
+        # Verify snapshot metadata
+        self.assertThat(snap_get['metadata'].items(),
+                        matchers.ContainsAll(metadata.items()))
+
         # Compare also with the output from the list action
         tracking_data = (snapshot['id'], snapshot[self.name_field])
         snaps_list = self.snapshots_client.list_snapshots()['snapshots']
diff --git a/tempest/api/volume/test_volumes_snapshots_negative.py b/tempest/api/volume/test_volumes_snapshots_negative.py
index a3d91b0..9e44379 100644
--- a/tempest/api/volume/test_volumes_snapshots_negative.py
+++ b/tempest/api/volume/test_volumes_snapshots_negative.py
@@ -62,6 +62,13 @@
                           size=src_size - 1,
                           snapshot_id=src_snap['id'])
 
+    @test.attr(type=['negative'])
+    @decorators.idempotent_id('8fd92339-e22f-4591-86b4-1e2215372a40')
+    def test_list_snapshot_invalid_param_limit(self):
+        self.assertRaises(lib_exc.BadRequest,
+                          self.snapshots_client.list_snapshots,
+                          limit='invalid')
+
 
 class VolumesV1SnapshotNegativeTestJSON(VolumesV2SnapshotNegativeTestJSON):
     _api_version = 1
diff --git a/tempest/api/volume/v2/test_volumes_list.py b/tempest/api/volume/v2/test_volumes_list.py
index 8b51e64..d2328c8 100644
--- a/tempest/api/volume/v2/test_volumes_list.py
+++ b/tempest/api/volume/v2/test_volumes_list.py
@@ -37,13 +37,12 @@
         super(VolumesV2ListTestJSON, cls).resource_setup()
 
         # Create 3 test volumes
-        metadata = {'Type': 'work'}
         # NOTE(zhufl): When using pre-provisioned credentials, the project
         # may have volumes other than those created below.
         existing_volumes = cls.volumes_client.list_volumes()['volumes']
         cls.volume_id_list = [vol['id'] for vol in existing_volumes]
         for _ in range(3):
-            volume = cls.create_volume(metadata=metadata)
+            volume = cls.create_volume()
             cls.volume_id_list.append(volume['id'])
 
     @decorators.idempotent_id('2a7064eb-b9c3-429b-b888-33928fc5edd3')
diff --git a/tempest/api/volume/v2/test_volumes_snapshots_negative.py b/tempest/api/volume/v2/test_volumes_snapshots_negative.py
new file mode 100644
index 0000000..e5581b9
--- /dev/null
+++ b/tempest/api/volume/v2/test_volumes_snapshots_negative.py
@@ -0,0 +1,46 @@
+# Copyright 2017 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.
+
+from tempest.api.volume import base
+from tempest.common.utils import data_utils
+from tempest import config
+from tempest.lib import decorators
+from tempest.lib import exceptions as lib_exc
+from tempest import test
+
+CONF = config.CONF
+
+
+class VolumesV2SnapshotNegativeTest(base.BaseVolumeTest):
+
+    @classmethod
+    def skip_checks(cls):
+        super(VolumesV2SnapshotNegativeTest, cls).skip_checks()
+        if not CONF.volume_feature_enabled.snapshot:
+            raise cls.skipException("Cinder volume snapshots are disabled")
+
+    @test.attr(type=['negative'])
+    @decorators.idempotent_id('27b5f37f-bf69-4e8c-986e-c44f3d6819b8')
+    def test_list_snapshots_invalid_param_sort(self):
+        self.assertRaises(lib_exc.BadRequest,
+                          self.snapshots_client.list_snapshots,
+                          sort_key='invalid')
+
+    @test.attr(type=['negative'])
+    @decorators.idempotent_id('b68deeda-ca79-4a32-81af-5c51179e553a')
+    def test_list_snapshots_invalid_param_marker(self):
+        self.assertRaises(lib_exc.NotFound,
+                          self.snapshots_client.list_snapshots,
+                          marker=data_utils.rand_uuid())
diff --git a/tempest/config.py b/tempest/config.py
index b4d88c5..bd19967 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -15,12 +15,14 @@
 
 from __future__ import print_function
 
+import functools
 import os
 import tempfile
 
 from oslo_concurrency import lockutils
 from oslo_config import cfg
 from oslo_log import log as logging
+import testtools
 
 from tempest.lib import exceptions
 from tempest.lib.services import clients
@@ -1189,6 +1191,75 @@
 CONF = TempestConfigProxy()
 
 
+def skip_unless_config(*args):
+    """Decorator to raise a skip if a config opt doesn't exist or is False
+
+    :param str group: The first arg, the option group to check
+    :param str name: The second arg, the option name to check
+    :param str msg: Optional third arg, the skip msg to use if a skip is raised
+    :raises testtools.TestCaseskipException: If the specified config option
+        doesn't exist or it exists and evaluates to False
+    """
+    def decorator(f):
+        group = args[0]
+        name = args[1]
+
+        @functools.wraps(f)
+        def wrapper(self, *func_args, **func_kwargs):
+            if not hasattr(CONF, group):
+                msg = "Config group %s doesn't exist" % group
+                raise testtools.TestCase.skipException(msg)
+
+            conf_group = getattr(CONF, group)
+            if not hasattr(conf_group, name):
+                msg = "Config option %s.%s doesn't exist" % (group,
+                                                             name)
+                raise testtools.TestCase.skipException(msg)
+
+            value = getattr(conf_group, name)
+            if not value:
+                if len(args) == 3:
+                    msg = args[2]
+                else:
+                    msg = "Config option %s.%s is false" % (group,
+                                                            name)
+                raise testtools.TestCase.skipException(msg)
+            return f(self, *func_args, **func_kwargs)
+        return wrapper
+    return decorator
+
+
+def skip_if_config(*args):
+    """Raise a skipException if a config exists and is True
+
+    :param str group: The first arg, the option group to check
+    :param str name: The second arg, the option name to check
+    :param str msg: Optional third arg, the skip msg to use if a skip is raised
+    :raises testtools.TestCase.skipException: If the specified config option
+        exists and evaluates to True
+    """
+    def decorator(f):
+        group = args[0]
+        name = args[1]
+
+        @functools.wraps(f)
+        def wrapper(self, *func_args, **func_kwargs):
+            if hasattr(CONF, group):
+                conf_group = getattr(CONF, group)
+                if hasattr(conf_group, name):
+                    value = getattr(conf_group, name)
+                    if value:
+                        if len(args) == 3:
+                            msg = args[2]
+                        else:
+                            msg = "Config option %s.%s is false" % (group,
+                                                                    name)
+                        raise testtools.TestCase.skipException(msg)
+            return f(self, *func_args, **func_kwargs)
+        return wrapper
+    return decorator
+
+
 def service_client_config(service_client_name=None):
     """Return a dict with the parameters to init service clients
 
diff --git a/tempest/lib/services/image/v2/namespace_tags_client.py b/tempest/lib/services/image/v2/namespace_tags_client.py
index ac8b569..a7f8c39 100644
--- a/tempest/lib/services/image/v2/namespace_tags_client.py
+++ b/tempest/lib/services/image/v2/namespace_tags_client.py
@@ -115,5 +115,11 @@
         """
         url = 'metadefs/namespaces/%s/tags' % namespace
         resp, _ = self.delete(url)
-        self.expected_success(200, resp.status)
+
+        # NOTE(rosmaita): Bug 1656183 fixed the success response code for
+        # this call to make it consistent with the other metadefs delete
+        # calls.  Accept both codes in case tempest is being run against
+        # an old Glance.
+        self.expected_success([200, 204], resp.status)
+
         return rest_client.ResponseBody(resp)
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index e670216..e58031b 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -731,36 +731,6 @@
                         network['id'])
         return network
 
-    def _list_networks(self, *args, **kwargs):
-        """List networks using admin creds """
-        networks_list = self.admin_manager.networks_client.list_networks(
-            *args, **kwargs)
-        return networks_list['networks']
-
-    def _list_subnets(self, *args, **kwargs):
-        """List subnets using admin creds """
-        subnets_list = self.admin_manager.subnets_client.list_subnets(
-            *args, **kwargs)
-        return subnets_list['subnets']
-
-    def _list_routers(self, *args, **kwargs):
-        """List routers using admin creds """
-        routers_list = self.admin_manager.routers_client.list_routers(
-            *args, **kwargs)
-        return routers_list['routers']
-
-    def _list_ports(self, *args, **kwargs):
-        """List ports using admin creds """
-        ports_list = self.admin_manager.ports_client.list_ports(
-            *args, **kwargs)
-        return ports_list['ports']
-
-    def _list_agents(self, *args, **kwargs):
-        """List agents using admin creds """
-        agents_list = self.admin_manager.network_agents_client.list_agents(
-            *args, **kwargs)
-        return agents_list['agents']
-
     def _create_subnet(self, network, subnets_client=None,
                        routers_client=None, namestart='subnet-smoke',
                        **kwargs):
@@ -779,7 +749,8 @@
             :returns: True if subnet with cidr already exist in tenant
                   False else
             """
-            cidr_in_use = self._list_subnets(tenant_id=tenant_id, cidr=cidr)
+            cidr_in_use = self.admin_manager.subnets_client.list_subnets(
+                tenant_id=tenant_id, cidr=cidr)['subnets']
             return len(cidr_in_use) != 0
 
         ip_version = kwargs.pop('ip_version', 4)
@@ -827,7 +798,8 @@
         return subnet
 
     def _get_server_port_id_and_ip4(self, server, ip_addr=None):
-        ports = self._list_ports(device_id=server['id'], fixed_ip=ip_addr)
+        ports = self.admin_manager.ports_client.list_ports(
+            device_id=server['id'], fixed_ip=ip_addr)['ports']
         # A port can have more than one IP address in some cases.
         # If the network is dual-stack (IPv4 + IPv6), this port is associated
         # with 2 subnets
@@ -856,7 +828,8 @@
         return port_map[0]
 
     def _get_network_by_name(self, network_name):
-        net = self._list_networks(name=network_name)
+        net = self.admin_manager.networks_client.list_networks(
+            name=network_name)['networks']
         self.assertNotEqual(len(net), 0,
                             "Unable to get network by name: %s" % network_name)
         return net[0]
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 4dae564..d8c8d4a 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -127,23 +127,23 @@
         via checking the result of list_[networks,routers,subnets]
         """
 
-        seen_nets = self._list_networks()
-        seen_names = [n['name'] for n in seen_nets]
-        seen_ids = [n['id'] for n in seen_nets]
+        seen_nets = self.admin_manager.networks_client.list_networks()
+        seen_names = [n['name'] for n in seen_nets['networks']]
+        seen_ids = [n['id'] for n in seen_nets['networks']]
         self.assertIn(self.network['name'], seen_names)
         self.assertIn(self.network['id'], seen_ids)
 
         if self.subnet:
-            seen_subnets = self._list_subnets()
-            seen_net_ids = [n['network_id'] for n in seen_subnets]
-            seen_subnet_ids = [n['id'] for n in seen_subnets]
+            seen_subnets = self.admin_manager.subnets_client.list_subnets()
+            seen_net_ids = [n['network_id'] for n in seen_subnets['subnets']]
+            seen_subnet_ids = [n['id'] for n in seen_subnets['subnets']]
             self.assertIn(self.network['id'], seen_net_ids)
             self.assertIn(self.subnet['id'], seen_subnet_ids)
 
         if self.router:
-            seen_routers = self._list_routers()
-            seen_router_ids = [n['id'] for n in seen_routers]
-            seen_router_names = [n['name'] for n in seen_routers]
+            seen_routers = self.admin_manager.routers_client.list_routers()
+            seen_router_ids = [n['id'] for n in seen_routers['routers']]
+            seen_router_names = [n['name'] for n in seen_routers['routers']]
             self.assertIn(self.router['name'],
                           seen_router_names)
             self.assertIn(self.router['id'],
@@ -240,7 +240,8 @@
             ip_address, private_key=private_key)
         old_nic_list = self._get_server_nics(ssh_client)
         # get a port from a list of one item
-        port_list = self._list_ports(device_id=server['id'])
+        port_list = self.admin_manager.ports_client.list_ports(
+            device_id=server['id'])['ports']
         self.assertEqual(1, len(port_list))
         old_port = port_list[0]
         interface = self.interface_client.create_interface(
@@ -253,9 +254,12 @@
                         server['id'], interface['port_id'])
 
         def check_ports():
-            self.new_port_list = [port for port in
-                                  self._list_ports(device_id=server['id'])
-                                  if port['id'] != old_port['id']]
+            self.new_port_list = [
+                port for port in
+                self.admin_manager.ports_client.list_ports(
+                    device_id=server['id'])['ports']
+                if port['id'] != old_port['id']
+            ]
             return len(self.new_port_list) == 1
 
         if not test_utils.call_until_true(
@@ -301,10 +305,13 @@
         floating_ip, server = self.floating_ip_tuple
         # get internal ports' ips:
         # get all network ports in the new network
-        internal_ips = (p['fixed_ips'][0]['ip_address'] for p in
-                        self._list_ports(tenant_id=server['tenant_id'],
-                                         network_id=network['id'])
-                        if p['device_owner'].startswith('network'))
+        internal_ips = (
+            p['fixed_ips'][0]['ip_address'] for p in
+            self.admin_manager.ports_client.list_ports(
+                tenant_id=server['tenant_id'],
+                network_id=network['id'])['ports']
+            if p['device_owner'].startswith('network')
+        )
 
         self._check_server_connectivity(floating_ip,
                                         internal_ips,
@@ -320,8 +327,11 @@
         # We ping the external IP from the instance using its floating IP
         # which is always IPv4, so we must only test connectivity to
         # external IPv4 IPs if the external network is dualstack.
-        v4_subnets = [s for s in self._list_subnets(
-            network_id=CONF.network.public_network_id) if s['ip_version'] == 4]
+        v4_subnets = [
+            s for s in self.admin_manager.subnets_client.list_subnets(
+                network_id=CONF.network.public_network_id)['subnets']
+            if s['ip_version'] == 4
+        ]
         self.assertEqual(1, len(v4_subnets),
                          "Found %d IPv4 subnets" % len(v4_subnets))
 
@@ -624,7 +634,8 @@
         self._setup_network_and_servers()
         floating_ip, server = self.floating_ip_tuple
         server_id = server['id']
-        port_id = self._list_ports(device_id=server_id)[0]['id']
+        port_id = self.admin_manager.ports_client.list_ports(
+            device_id=server_id)['ports'][0]['id']
         server_pip = server['addresses'][self.network['name']][0]['addr']
 
         server2 = self._create_server(self.network)
@@ -677,8 +688,8 @@
                              'Server should have been created from a '
                              'pre-existing port.')
         # Assert the port is bound to the server.
-        port_list = self._list_ports(device_id=server['id'],
-                                     network_id=self.network['id'])
+        port_list = self.admin_manager.ports_client.list_ports(
+            device_id=server['id'], network_id=self.network['id'])['ports']
         self.assertEqual(1, len(port_list),
                          'There should only be one port created for '
                          'server %s.' % server['id'])
@@ -696,8 +707,8 @@
         # Boot another server with the same port to make sure nothing was
         # left around that could cause issues.
         server = self._create_server(self.network, port['id'])
-        port_list = self._list_ports(device_id=server['id'],
-                                     network_id=self.network['id'])
+        port_list = self.admin_manager.ports_client.list_ports(
+            device_id=server['id'], network_id=self.network['id'])['ports']
         self.assertEqual(1, len(port_list),
                          'There should only be one port created for '
                          'server %s.' % server['id'])
@@ -727,9 +738,11 @@
         unschedule_router = (self.admin_manager.network_agents_client.
                              delete_router_from_l3_agent)
 
-        agent_list_alive = set(a["id"] for a in
-                               self._list_agents(agent_type="L3 agent") if
-                               a["alive"] is True)
+        agent_list_alive = set(
+            a["id"] for a in
+            self.admin_manager.network_agents_client.list_agents(
+                agent_type="L3 agent")['agents'] if a["alive"] is True
+        )
         self._setup_network_and_servers()
 
         # NOTE(kevinbenton): we have to use the admin credentials to check
@@ -811,8 +824,8 @@
         self._create_new_network()
         self._hotplug_server()
         fip, server = self.floating_ip_tuple
-        new_ports = self._list_ports(device_id=server["id"],
-                                     network_id=self.new_net["id"])
+        new_ports = self.admin_manager.ports_client.list_ports(
+            device_id=server["id"], network_id=self.new_net["id"])['ports']
         spoof_port = new_ports[0]
         private_key = self._get_server_key(server)
         ssh_client = self.get_remote_client(fip['floating_ip_address'],
diff --git a/tempest/scenario/test_network_v6.py b/tempest/scenario/test_network_v6.py
index 2d6ea75..f33784e 100644
--- a/tempest/scenario/test_network_v6.py
+++ b/tempest/scenario/test_network_v6.py
@@ -143,9 +143,11 @@
         @param ssh: RemoteClient ssh instance to server
         @param sid: server uuid
         """
-        ports = [p["mac_address"] for p in
-                 self._list_ports(device_id=sid,
-                                  network_id=self.network_v6['id'])]
+        ports = [
+            p["mac_address"] for p in
+            self.admin_manager.ports_client.list_ports(
+                device_id=sid, network_id=self.network_v6['id'])['ports']
+        ]
         self.assertEqual(1, len(ports),
                          message=("Multiple IPv6 ports found on network %s. "
                                   "ports: %s")
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index 5565cb8..a01124d 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -220,22 +220,24 @@
         # Checks that we see the newly created network/subnet/router via
         # checking the result of list_[networks,routers,subnets]
         # Check that (router, subnet) couple exist in port_list
-        seen_nets = self._list_networks()
-        seen_names = [n['name'] for n in seen_nets]
-        seen_ids = [n['id'] for n in seen_nets]
+        seen_nets = self.admin_manager.networks_client.list_networks()
+        seen_names = [n['name'] for n in seen_nets['networks']]
+        seen_ids = [n['id'] for n in seen_nets['networks']]
 
         self.assertIn(tenant.network['name'], seen_names)
         self.assertIn(tenant.network['id'], seen_ids)
 
-        seen_subnets = [(n['id'], n['cidr'], n['network_id'])
-                        for n in self._list_subnets()]
+        seen_subnets = [
+            (n['id'], n['cidr'], n['network_id']) for n in
+            self.admin_manager.subnets_client.list_subnets()['subnets']
+        ]
         mysubnet = (tenant.subnet['id'], tenant.subnet['cidr'],
                     tenant.network['id'])
         self.assertIn(mysubnet, seen_subnets)
 
-        seen_routers = self._list_routers()
-        seen_router_ids = [n['id'] for n in seen_routers]
-        seen_router_names = [n['name'] for n in seen_routers]
+        seen_routers = self.admin_manager.routers_client.list_routers()
+        seen_router_ids = [n['id'] for n in seen_routers['routers']]
+        seen_router_names = [n['name'] for n in seen_routers['routers']]
 
         self.assertIn(tenant.router['name'], seen_router_names)
         self.assertIn(tenant.router['id'], seen_router_ids)
@@ -243,9 +245,11 @@
         myport = (tenant.router['id'], tenant.subnet['id'])
         router_ports = [
             (i['device_id'], f['subnet_id'])
-            for i in self._list_ports(device_id=tenant.router['id'])
+            for i in self.admin_manager.ports_client.list_ports(
+                device_id=tenant.router['id'])['ports']
             if net_info.is_router_interface_port(i)
-            for f in i['fixed_ips']]
+            for f in i['fixed_ips']
+        ]
 
         self.assertIn(myport, router_ports)
 
@@ -450,7 +454,8 @@
         mac_addr = mac_addr.strip().lower()
         # Get the fixed_ips and mac_address fields of all ports. Select
         # only those two columns to reduce the size of the response.
-        port_list = self._list_ports(fields=['fixed_ips', 'mac_address'])
+        port_list = self.admin_manager.ports_client.list_ports(
+            fields=['fixed_ips', 'mac_address'])['ports']
         port_detail_list = [
             (port['fixed_ips'][0]['subnet_id'],
              port['fixed_ips'][0]['ip_address'],
@@ -536,7 +541,8 @@
                                      ip=self._get_server_ip(server),
                                      should_succeed=False)
             server_id = server['id']
-            port_id = self._list_ports(device_id=server_id)[0]['id']
+            port_id = self.admin_manager.ports_client.list_ports(
+                device_id=server_id)['ports'][0]['id']
 
             # update port with new security group and check connectivity
             self.ports_client.update_port(port_id, security_groups=[
@@ -598,7 +604,8 @@
 
         access_point_ssh = self._connect_to_access_point(new_tenant)
         server_id = server['id']
-        port_id = self._list_ports(device_id=server_id)[0]['id']
+        port_id = self.admin_manager.ports_client.list_ports(
+            device_id=server_id)['ports'][0]['id']
 
         # Flip the port's port security and check connectivity
         try:
@@ -642,7 +649,8 @@
         sec_groups = []
         server = self._create_server(name, tenant, sec_groups)
         server_id = server['id']
-        ports = self._list_ports(device_id=server_id)
+        ports = self.admin_manager.ports_client.list_ports(
+            device_id=server_id)['ports']
         self.assertEqual(1, len(ports))
         for port in ports:
             self.assertEmpty(port['security_groups'],
diff --git a/tempest/scenario/test_stamp_pattern.py b/tempest/scenario/test_stamp_pattern.py
index ef9664d..716c0bf 100644
--- a/tempest/scenario/test_stamp_pattern.py
+++ b/tempest/scenario/test_stamp_pattern.py
@@ -88,6 +88,7 @@
                                           CONF.compute.build_interval):
             raise lib_exc.TimeoutException
 
+    @decorators.skip_because(bug="1664793")
     @decorators.idempotent_id('10fd234a-515c-41e5-b092-8323060598c5')
     @testtools.skipUnless(CONF.compute_feature_enabled.snapshot,
                           'Snapshotting is not available.')
diff --git a/tempest/tests/test_decorators.py b/tempest/tests/test_decorators.py
index a069a81..ae2f2a3 100644
--- a/tempest/tests/test_decorators.py
+++ b/tempest/tests/test_decorators.py
@@ -199,3 +199,96 @@
                           self._test_requires_ext_helper,
                           extension='enabled_ext',
                           service='bad_service')
+
+
+class TestConfigDecorators(BaseDecoratorsTest):
+    def setUp(self):
+        super(TestConfigDecorators, self).setUp()
+        cfg.CONF.set_default('nova', True, 'service_available')
+        cfg.CONF.set_default('glance', False, 'service_available')
+
+    def _assert_skip_message(self, func, skip_msg):
+        try:
+            func()
+            self.fail()
+        except testtools.TestCase.skipException as skip_exc:
+            self.assertEqual(skip_exc.args[0], skip_msg)
+
+    def _test_skip_unless_config(self, expected_to_skip=True, *decorator_args):
+
+        class TestFoo(test.BaseTestCase):
+            @config.skip_unless_config(*decorator_args)
+            def test_bar(self):
+                return 0
+
+        t = TestFoo('test_bar')
+        if expected_to_skip:
+            self.assertRaises(testtools.TestCase.skipException, t.test_bar)
+            if (len(decorator_args) >= 3):
+                # decorator_args[2]: skip message specified
+                self._assert_skip_message(t.test_bar, decorator_args[2])
+        else:
+            try:
+                self.assertEqual(t.test_bar(), 0)
+            except testtools.TestCase.skipException:
+                # We caught a skipException but we didn't expect to skip
+                # this test so raise a hard test failure instead.
+                raise testtools.TestCase.failureException(
+                    "Not supposed to skip")
+
+    def _test_skip_if_config(self, expected_to_skip=True,
+                             *decorator_args):
+
+        class TestFoo(test.BaseTestCase):
+            @config.skip_if_config(*decorator_args)
+            def test_bar(self):
+                return 0
+
+        t = TestFoo('test_bar')
+        if expected_to_skip:
+            self.assertRaises(testtools.TestCase.skipException, t.test_bar)
+            if (len(decorator_args) >= 3):
+                # decorator_args[2]: skip message specified
+                self._assert_skip_message(t.test_bar, decorator_args[2])
+        else:
+            try:
+                self.assertEqual(t.test_bar(), 0)
+            except testtools.TestCase.skipException:
+                # We caught a skipException but we didn't expect to skip
+                # this test so raise a hard test failure instead.
+                raise testtools.TestCase.failureException(
+                    "Not supposed to skip")
+
+    def test_skip_unless_no_group(self):
+        self._test_skip_unless_config(True, 'fake_group', 'an_option')
+
+    def test_skip_unless_no_option(self):
+        self._test_skip_unless_config(True, 'service_available',
+                                      'not_an_option')
+
+    def test_skip_unless_false_option(self):
+        self._test_skip_unless_config(True, 'service_available', 'glance')
+
+    def test_skip_unless_false_option_msg(self):
+        self._test_skip_unless_config(True, 'service_available', 'glance',
+                                      'skip message')
+
+    def test_skip_unless_true_option(self):
+        self._test_skip_unless_config(False,
+                                      'service_available', 'nova')
+
+    def test_skip_if_no_group(self):
+        self._test_skip_if_config(False, 'fake_group', 'an_option')
+
+    def test_skip_if_no_option(self):
+        self._test_skip_if_config(False, 'service_available', 'not_an_option')
+
+    def test_skip_if_false_option(self):
+        self._test_skip_if_config(False, 'service_available', 'glance')
+
+    def test_skip_if_true_option(self):
+        self._test_skip_if_config(True, 'service_available', 'nova')
+
+    def test_skip_if_true_option_msg(self):
+        self._test_skip_if_config(True, 'service_available', 'nova',
+                                  'skip message')
diff --git a/tempest/tests/test_wrappers.py b/tempest/tests/test_wrappers.py
deleted file mode 100644
index a4ef699..0000000
--- a/tempest/tests/test_wrappers.py
+++ /dev/null
@@ -1,88 +0,0 @@
-# Copyright 2013 IBM Corp.
-#
-#    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 os
-import shutil
-import subprocess
-import tempfile
-
-import six
-
-from tempest.tests import base
-
-DEVNULL = open(os.devnull, 'wb')
-
-
-class TestWrappers(base.TestCase):
-    def setUp(self):
-        super(TestWrappers, self).setUp()
-        # Setup test dirs
-        self.directory = tempfile.mkdtemp(prefix='tempest-unit')
-        self.addCleanup(shutil.rmtree, self.directory)
-        self.test_dir = os.path.join(self.directory, 'tests')
-        os.mkdir(self.test_dir)
-        # Setup Test files
-        self.testr_conf_file = os.path.join(self.directory, '.testr.conf')
-        self.setup_cfg_file = os.path.join(self.directory, 'setup.cfg')
-        self.passing_file = os.path.join(self.test_dir, 'test_passing.py')
-        self.failing_file = os.path.join(self.test_dir, 'test_failing.py')
-        self.init_file = os.path.join(self.test_dir, '__init__.py')
-        self.setup_py = os.path.join(self.directory, 'setup.py')
-        shutil.copy('tempest/tests/files/testr-conf', self.testr_conf_file)
-        shutil.copy('tempest/tests/files/passing-tests', self.passing_file)
-        shutil.copy('tempest/tests/files/failing-tests', self.failing_file)
-        shutil.copy('setup.py', self.setup_py)
-        shutil.copy('tempest/tests/files/setup.cfg', self.setup_cfg_file)
-        shutil.copy('tempest/tests/files/__init__.py', self.init_file)
-        # copy over the pretty_tox scripts
-        shutil.copy('tools/pretty_tox.sh',
-                    os.path.join(self.directory, 'pretty_tox.sh'))
-        shutil.copy('tools/pretty_tox_serial.sh',
-                    os.path.join(self.directory, 'pretty_tox_serial.sh'))
-
-        self.stdout = six.StringIO()
-        self.stderr = six.StringIO()
-        # Change directory, run wrapper and check result
-        self.addCleanup(os.chdir, os.path.abspath(os.curdir))
-        os.chdir(self.directory)
-
-    def assertRunExit(self, cmd, expected):
-        p = subprocess.Popen(
-            "bash %s" % cmd, shell=True,
-            stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-        out, err = p.communicate()
-
-        self.assertEqual(
-            p.returncode, expected,
-            "Stdout: %s; Stderr: %s" % (out, err))
-
-    def test_pretty_tox(self):
-        # Git init is required for the pbr testr command. pbr requires a git
-        # version or an sdist to work. so make the test directory a git repo
-        # too.
-        subprocess.call(['git', 'init'], stderr=DEVNULL)
-        self.assertRunExit('pretty_tox.sh passing', 0)
-
-    def test_pretty_tox_fails(self):
-        # Git init is required for the pbr testr command. pbr requires a git
-        # version or an sdist to work. so make the test directory a git repo
-        # too.
-        subprocess.call(['git', 'init'], stderr=DEVNULL)
-        self.assertRunExit('pretty_tox.sh', 1)
-
-    def test_pretty_tox_serial(self):
-        self.assertRunExit('pretty_tox_serial.sh passing', 0)
-
-    def test_pretty_tox_serial_fails(self):
-        self.assertRunExit('pretty_tox_serial.sh', 1)
diff --git a/tools/pretty_tox.sh b/tools/pretty_tox.sh
deleted file mode 100755
index 0b83b91..0000000
--- a/tools/pretty_tox.sh
+++ /dev/null
@@ -1,14 +0,0 @@
-#!/usr/bin/env bash
-
-echo "WARNING: This script is deprecated and will be removed in the near future. Please migrate to tempest run or another method of launching a test runner"
-
-set -o pipefail
-
-TESTRARGS=$1
-python setup.py testr --testr-args="--subunit $TESTRARGS" | subunit-trace --no-failure-debug -f
-retval=$?
-# NOTE(mtreinish) The pipe above would eat the slowest display from pbr's testr
-# wrapper so just manually print the slowest tests.
-echo -e "\nSlowest Tests:\n"
-testr slowest
-exit $retval
diff --git a/tools/pretty_tox_serial.sh b/tools/pretty_tox_serial.sh
deleted file mode 100755
index 1f8204e..0000000
--- a/tools/pretty_tox_serial.sh
+++ /dev/null
@@ -1,16 +0,0 @@
-#!/usr/bin/env bash
-
-echo "WARNING: This script is deprecated and will be removed in the near future. Please migrate to tempest run or another method of launching a test runner"
-
-set -o pipefail
-
-TESTRARGS=$@
-
-if [ ! -d .testrepository ]; then
-    testr init
-fi
-testr run --subunit $TESTRARGS | subunit-trace -f -n
-retval=$?
-testr slowest
-
-exit $retval