Merge "Support v3 in credential providers and subclasses"
diff --git a/README.rst b/README.rst
index 9aaea24..ba93712 100644
--- a/README.rst
+++ b/README.rst
@@ -54,13 +54,13 @@
.. note::
- If you have a running devstack environment, tempest will be
+ If you have a running devstack environment, Tempest will be
automatically configured and placed in ``/opt/stack/tempest``. It
will have a configuration file already set up to work with your
devstack installation.
Tempest is not tied to any single test runner, but `testr`_ is the most commonly
-used tool. Also, the nosetests test runner is **not** recommended to run tempest.
+used tool. Also, the nosetests test runner is **not** recommended to run Tempest.
After setting up your configuration file, you can execute the set of Tempest
tests by using ``testr`` ::
@@ -80,7 +80,7 @@
$> tox -efull
which will run the same set of tests as the OpenStack gate. (it's exactly how
-the gate invokes tempest) Or::
+the gate invokes Tempest) Or::
$> tox -esmoke
@@ -90,13 +90,13 @@
Configuration
-------------
-Detailed configuration of tempest is beyond the scope of this
+Detailed configuration of Tempest is beyond the scope of this
document see :ref:`tempest-configuration` for more details on configuring
-tempest. The etc/tempest.conf.sample attempts to be a self documenting version
+Tempest. The etc/tempest.conf.sample attempts to be a self documenting version
of the configuration.
You can generate a new sample tempest.conf file, run the following
-command from the top level of the tempest directory:
+command from the top level of the Tempest directory:
tox -egenconfig
@@ -106,7 +106,7 @@
Unit Tests
----------
-Tempest also has a set of unit tests which test the tempest code itself. These
+Tempest also has a set of unit tests which test the Tempest code itself. These
tests can be run by specifing the test discovery path::
$> OS_TEST_PATH=./tempest/tests testr run --parallel
@@ -114,7 +114,7 @@
By setting OS_TEST_PATH to ./tempest/tests it specifies that test discover
should only be run on the unit test directory. The default value of OS_TEST_PATH
is OS_TEST_PATH=./tempest/test_discover which will only run test discover on the
-tempest suite.
+Tempest suite.
Alternatively, you can use the run_tests.sh script which will create a venv and
run the unit tests. There are also the py26, py27, or py33 tox jobs which will
@@ -124,10 +124,10 @@
----------
Starting in the kilo release the OpenStack services dropped all support for
-python 2.6. This change has been mirrored in tempest, starting after the
-tempest-2 tag. This means that proposed changes to tempest which only fix
+python 2.6. This change has been mirrored in Tempest, starting after the
+tempest-2 tag. This means that proposed changes to Tempest which only fix
python 2.6 compatibility will be rejected, and moving forward more features not
-present in python 2.6 will be used. If you're running you're OpenStack services
-on an earlier release with python 2.6 you can easily run tempest against it
+present in python 2.6 will be used. If you're running your OpenStack services
+on an earlier release with python 2.6 you can easily run Tempest against it
from a remote system running python 2.7. (or deploy a cloud guest in your cloud
that has python 2.7)
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index d01024b..2e57007 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -427,6 +427,11 @@
# Does the test environment have the ec2 api running? (boolean value)
#ec2_api = true
+# Does Nova preserve preexisting ports from Neutron when deleting an
+# instance? This should be set to True if testing Kilo+ Nova. (boolean
+# value)
+#preserve_ports = false
+
[dashboard]
diff --git a/requirements.txt b/requirements.txt
index e6fc09b..35b5144 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -9,22 +9,20 @@
boto>=2.32.1
paramiko>=1.13.0
netaddr>=0.7.12
-python-ceilometerclient>=1.0.6
python-glanceclient>=0.15.0
python-cinderclient>=1.1.0
python-heatclient>=0.3.0
-python-ironicclient>=0.2.1
-python-saharaclient>=0.7.6
+python-saharaclient>=0.8.0
python-swiftclient>=2.2.0
testrepository>=0.0.18
-oslo.concurrency>=1.4.1 # Apache-2.0
-oslo.config>=1.6.0 # Apache-2.0
-oslo.i18n>=1.3.0 # Apache-2.0
-oslo.log>=0.4.0 # Apache-2.0
-oslo.serialization>=1.2.0 # Apache-2.0
-oslo.utils>=1.2.0 # Apache-2.0
+oslo.concurrency>=1.8.0,<1.9.0 # Apache-2.0
+oslo.config>=1.9.3,<1.10.0 # Apache-2.0
+oslo.i18n>=1.5.0,<1.6.0 # Apache-2.0
+oslo.log>=1.0.0,<1.1.0 # Apache-2.0
+oslo.serialization>=1.4.0,<1.5.0 # Apache-2.0
+oslo.utils>=1.4.0,<1.5.0 # Apache-2.0
six>=1.9.0
iso8601>=0.1.9
fixtures>=0.3.14
testscenarios>=0.4
-tempest-lib>=0.3.0
+tempest-lib>=0.4.0
diff --git a/tempest/api/compute/admin/test_security_groups.py b/tempest/api/compute/admin/test_security_groups.py
index 578f73b..6d79a77 100644
--- a/tempest/api/compute/admin/test_security_groups.py
+++ b/tempest/api/compute/admin/test_security_groups.py
@@ -39,7 +39,7 @@
@test.idempotent_id('49667619-5af9-4c63-ab5d-2cfdd1c8f7f1')
@testtools.skipIf(CONF.service_available.neutron,
- "Skipped because neutron do not support all_tenants"
+ "Skipped because neutron does not support all_tenants "
"search filter.")
@test.attr(type='smoke')
@test.services('network')
diff --git a/tempest/api_schema/response/compute/agents.py b/tempest/api_schema/response/compute/agents.py
deleted file mode 100644
index e5f3a8d..0000000
--- a/tempest/api_schema/response/compute/agents.py
+++ /dev/null
@@ -1,61 +0,0 @@
-# Copyright 2014 NEC Corporation. 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.
-
-list_agents = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'agents': {
- 'type': 'array',
- 'items': {
- 'type': 'object',
- 'properties': {
- 'agent_id': {'type': 'integer'},
- 'hypervisor': {'type': 'string'},
- 'os': {'type': 'string'},
- 'architecture': {'type': 'string'},
- 'version': {'type': 'string'},
- 'url': {'type': 'string', 'format': 'uri'},
- 'md5hash': {'type': 'string'}
- },
- 'required': ['agent_id', 'hypervisor', 'os',
- 'architecture', 'version', 'url', 'md5hash']
- }
- }
- },
- 'required': ['agents']
- }
-}
-
-common_create_agent = {
- 'type': 'object',
- 'properties': {
- 'agent': {
- 'type': 'object',
- 'properties': {
- 'agent_id': {'type': ['integer', 'string']},
- 'hypervisor': {'type': 'string'},
- 'os': {'type': 'string'},
- 'architecture': {'type': 'string'},
- 'version': {'type': 'string'},
- 'url': {'type': 'string', 'format': 'uri'},
- 'md5hash': {'type': 'string'}
- },
- 'required': ['agent_id', 'hypervisor', 'os', 'architecture',
- 'version', 'url', 'md5hash']
- }
- },
- 'required': ['agent']
-}
diff --git a/tempest/api_schema/response/compute/v2/agents.py b/tempest/api_schema/response/compute/v2/agents.py
deleted file mode 100644
index d827377..0000000
--- a/tempest/api_schema/response/compute/v2/agents.py
+++ /dev/null
@@ -1,24 +0,0 @@
-# Copyright 2014 NEC Corporation. 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_schema.response.compute import agents
-
-create_agent = {
- 'status_code': [200],
- 'response_body': agents.common_create_agent
-}
-
-delete_agent = {
- 'status_code': [200]
-}
diff --git a/tempest/api_schema/response/compute/v2/certificates.py b/tempest/api_schema/response/compute/v2/certificates.py
deleted file mode 100644
index bda6075..0000000
--- a/tempest/api_schema/response/compute/v2/certificates.py
+++ /dev/null
@@ -1,19 +0,0 @@
-# Copyright 2014 NEC Corporation. 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 copy
-
-from tempest.api_schema.response.compute import certificates
-
-create_certificate = copy.deepcopy(certificates._common_schema)
diff --git a/tempest/api_schema/response/compute/v2/interfaces.py b/tempest/api_schema/response/compute/v2/interfaces.py
deleted file mode 100644
index 64d161d..0000000
--- a/tempest/api_schema/response/compute/v2/interfaces.py
+++ /dev/null
@@ -1,29 +0,0 @@
-# Copyright 2014 NEC Corporation. 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_schema.response.compute import interfaces as common_schema
-
-list_interfaces = {
- 'status_code': [200],
- 'response_body': {
- 'type': 'object',
- 'properties': {
- 'interfaceAttachments': {
- 'type': 'array',
- 'items': common_schema.interface_common_info
- }
- },
- 'required': ['interfaceAttachments']
- }
-}
diff --git a/tempest/api_schema/response/compute/v2/__init__.py b/tempest/api_schema/response/compute/v2_1/__init__.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/__init__.py
rename to tempest/api_schema/response/compute/v2_1/__init__.py
diff --git a/tempest/api_schema/response/compute/v2_1/agents.py b/tempest/api_schema/response/compute/v2_1/agents.py
new file mode 100644
index 0000000..84c5fd3
--- /dev/null
+++ b/tempest/api_schema/response/compute/v2_1/agents.py
@@ -0,0 +1,57 @@
+# Copyright 2014 NEC Corporation. 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.
+
+common_agent_info = {
+ 'type': 'object',
+ 'properties': {
+ 'agent_id': {'type': ['integer', 'string']},
+ 'hypervisor': {'type': 'string'},
+ 'os': {'type': 'string'},
+ 'architecture': {'type': 'string'},
+ 'version': {'type': 'string'},
+ 'url': {'type': 'string', 'format': 'uri'},
+ 'md5hash': {'type': 'string'}
+ },
+ 'required': ['agent_id', 'hypervisor', 'os', 'architecture',
+ 'version', 'url', 'md5hash']
+}
+
+list_agents = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'agents': {
+ 'type': 'array',
+ 'items': common_agent_info
+ }
+ },
+ 'required': ['agents']
+ }
+}
+
+create_agent = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'agent': common_agent_info
+ },
+ 'required': ['agent']
+ }
+}
+
+delete_agent = {
+ 'status_code': [200]
+}
diff --git a/tempest/api_schema/response/compute/v2/aggregates.py b/tempest/api_schema/response/compute/v2_1/aggregates.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/aggregates.py
rename to tempest/api_schema/response/compute/v2_1/aggregates.py
diff --git a/tempest/api_schema/response/compute/v2/availability_zone.py b/tempest/api_schema/response/compute/v2_1/availability_zone.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/availability_zone.py
rename to tempest/api_schema/response/compute/v2_1/availability_zone.py
diff --git a/tempest/api_schema/response/compute/certificates.py b/tempest/api_schema/response/compute/v2_1/certificates.py
similarity index 89%
rename from tempest/api_schema/response/compute/certificates.py
rename to tempest/api_schema/response/compute/v2_1/certificates.py
index caac2ab..35445d8 100644
--- a/tempest/api_schema/response/compute/certificates.py
+++ b/tempest/api_schema/response/compute/v2_1/certificates.py
@@ -25,13 +25,15 @@
'data': {'type': 'string'},
'private_key': {'type': 'string'},
},
- 'required': ['data', 'private_key'],
+ 'required': ['data', 'private_key']
}
},
- 'required': ['certificate'],
+ 'required': ['certificate']
}
}
get_certificate = copy.deepcopy(_common_schema)
get_certificate['response_body']['properties']['certificate'][
'properties']['private_key'].update({'type': 'null'})
+
+create_certificate = copy.deepcopy(_common_schema)
diff --git a/tempest/api_schema/response/compute/v2/extensions.py b/tempest/api_schema/response/compute/v2_1/extensions.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/extensions.py
rename to tempest/api_schema/response/compute/v2_1/extensions.py
diff --git a/tempest/api_schema/response/compute/v2/fixed_ips.py b/tempest/api_schema/response/compute/v2_1/fixed_ips.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/fixed_ips.py
rename to tempest/api_schema/response/compute/v2_1/fixed_ips.py
diff --git a/tempest/api_schema/response/compute/v2/flavors.py b/tempest/api_schema/response/compute/v2_1/flavors.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/flavors.py
rename to tempest/api_schema/response/compute/v2_1/flavors.py
diff --git a/tempest/api_schema/response/compute/v2/floating_ips.py b/tempest/api_schema/response/compute/v2_1/floating_ips.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/floating_ips.py
rename to tempest/api_schema/response/compute/v2_1/floating_ips.py
diff --git a/tempest/api_schema/response/compute/v2/hosts.py b/tempest/api_schema/response/compute/v2_1/hosts.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/hosts.py
rename to tempest/api_schema/response/compute/v2_1/hosts.py
diff --git a/tempest/api_schema/response/compute/v2/hypervisors.py b/tempest/api_schema/response/compute/v2_1/hypervisors.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/hypervisors.py
rename to tempest/api_schema/response/compute/v2_1/hypervisors.py
diff --git a/tempest/api_schema/response/compute/v2/images.py b/tempest/api_schema/response/compute/v2_1/images.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/images.py
rename to tempest/api_schema/response/compute/v2_1/images.py
diff --git a/tempest/api_schema/response/compute/v2/instance_usage_audit_logs.py b/tempest/api_schema/response/compute/v2_1/instance_usage_audit_logs.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/instance_usage_audit_logs.py
rename to tempest/api_schema/response/compute/v2_1/instance_usage_audit_logs.py
diff --git a/tempest/api_schema/response/compute/interfaces.py b/tempest/api_schema/response/compute/v2_1/interfaces.py
similarity index 74%
rename from tempest/api_schema/response/compute/interfaces.py
rename to tempest/api_schema/response/compute/v2_1/interfaces.py
index fd53eb3..4de3309 100644
--- a/tempest/api_schema/response/compute/interfaces.py
+++ b/tempest/api_schema/response/compute/v2_1/interfaces.py
@@ -14,10 +14,6 @@
from tempest.api_schema.response.compute import parameter_types
-delete_interface = {
- 'status_code': [202]
-}
-
interface_common_info = {
'type': 'object',
'properties': {
@@ -45,3 +41,32 @@
},
'required': ['port_state', 'fixed_ips', 'port_id', 'net_id', 'mac_addr']
}
+
+get_create_interfaces = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'interfaceAttachment': interface_common_info
+ },
+ 'required': ['interfaceAttachment']
+ }
+}
+
+list_interfaces = {
+ 'status_code': [200],
+ 'response_body': {
+ 'type': 'object',
+ 'properties': {
+ 'interfaceAttachments': {
+ 'type': 'array',
+ 'items': interface_common_info
+ }
+ },
+ 'required': ['interfaceAttachments']
+ }
+}
+
+delete_interface = {
+ 'status_code': [202]
+}
diff --git a/tempest/api_schema/response/compute/v2/keypairs.py b/tempest/api_schema/response/compute/v2_1/keypairs.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/keypairs.py
rename to tempest/api_schema/response/compute/v2_1/keypairs.py
diff --git a/tempest/api_schema/response/compute/v2/limits.py b/tempest/api_schema/response/compute/v2_1/limits.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/limits.py
rename to tempest/api_schema/response/compute/v2_1/limits.py
diff --git a/tempest/api_schema/response/compute/v2/quota_classes.py b/tempest/api_schema/response/compute/v2_1/quota_classes.py
similarity index 95%
rename from tempest/api_schema/response/compute/v2/quota_classes.py
rename to tempest/api_schema/response/compute/v2_1/quota_classes.py
index 5474a89..a7374df 100644
--- a/tempest/api_schema/response/compute/v2/quota_classes.py
+++ b/tempest/api_schema/response/compute/v2_1/quota_classes.py
@@ -15,7 +15,7 @@
import copy
-from tempest.api_schema.response.compute.v2 import quotas
+from tempest.api_schema.response.compute.v2_1 import quotas
# NOTE(mriedem): os-quota-class-sets responses are the same as os-quota-sets
# except for the key in the response body is quota_class_set instead of
diff --git a/tempest/api_schema/response/compute/v2/quotas.py b/tempest/api_schema/response/compute/v2_1/quotas.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/quotas.py
rename to tempest/api_schema/response/compute/v2_1/quotas.py
diff --git a/tempest/api_schema/response/compute/v2/security_group_default_rule.py b/tempest/api_schema/response/compute/v2_1/security_group_default_rule.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/security_group_default_rule.py
rename to tempest/api_schema/response/compute/v2_1/security_group_default_rule.py
diff --git a/tempest/api_schema/response/compute/v2/security_groups.py b/tempest/api_schema/response/compute/v2_1/security_groups.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/security_groups.py
rename to tempest/api_schema/response/compute/v2_1/security_groups.py
diff --git a/tempest/api_schema/response/compute/v2/servers.py b/tempest/api_schema/response/compute/v2_1/servers.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/servers.py
rename to tempest/api_schema/response/compute/v2_1/servers.py
diff --git a/tempest/api_schema/response/compute/v2/tenant_networks.py b/tempest/api_schema/response/compute/v2_1/tenant_networks.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/tenant_networks.py
rename to tempest/api_schema/response/compute/v2_1/tenant_networks.py
diff --git a/tempest/api_schema/response/compute/v2/tenant_usages.py b/tempest/api_schema/response/compute/v2_1/tenant_usages.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/tenant_usages.py
rename to tempest/api_schema/response/compute/v2_1/tenant_usages.py
diff --git a/tempest/api_schema/response/compute/v2/volumes.py b/tempest/api_schema/response/compute/v2_1/volumes.py
similarity index 100%
rename from tempest/api_schema/response/compute/v2/volumes.py
rename to tempest/api_schema/response/compute/v2_1/volumes.py
diff --git a/tempest/cli/simple_read_only/telemetry/__init__.py b/tempest/cli/simple_read_only/telemetry/__init__.py
deleted file mode 100644
index e69de29..0000000
--- a/tempest/cli/simple_read_only/telemetry/__init__.py
+++ /dev/null
diff --git a/tempest/cli/simple_read_only/telemetry/test_ceilometer.py b/tempest/cli/simple_read_only/telemetry/test_ceilometer.py
deleted file mode 100644
index b5e570b..0000000
--- a/tempest/cli/simple_read_only/telemetry/test_ceilometer.py
+++ /dev/null
@@ -1,62 +0,0 @@
-# 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 oslo_log import log as logging
-
-from tempest import cli
-from tempest import config
-from tempest import test
-
-CONF = config.CONF
-
-LOG = logging.getLogger(__name__)
-
-
-class SimpleReadOnlyCeilometerClientTest(cli.ClientTestBase):
- """Basic, read-only tests for Ceilometer CLI client.
-
- Checks return values and output of read-only commands.
- These tests do not presume any content, nor do they create
- their own. They only verify the structure of output if present.
- """
-
- @classmethod
- def resource_setup(cls):
- if (not CONF.service_available.ceilometer):
- msg = ("Skipping all Ceilometer cli tests because it is "
- "not available")
- raise cls.skipException(msg)
- super(SimpleReadOnlyCeilometerClientTest, cls).resource_setup()
-
- def ceilometer(self, *args, **kwargs):
- return self.clients.ceilometer(
- *args, endpoint_type=CONF.telemetry.endpoint_type, **kwargs)
-
- @test.idempotent_id('ab717d43-a9c4-4dcf-bad8-c4777933a970')
- def test_ceilometer_meter_list(self):
- self.ceilometer('meter-list')
-
- @test.attr(type='slow')
- @test.idempotent_id('fe2e52a4-a99b-426e-a52d-d0bde50f3e4c')
- def test_ceilometer_resource_list(self):
- self.ceilometer('resource-list')
-
- @test.idempotent_id('eede695c-f3bf-449f-a420-02f3cc426d52')
- def test_ceilometermeter_alarm_list(self):
- self.ceilometer('alarm-list')
-
- @test.idempotent_id('0586bcc4-8e35-415f-8f23-77b590042684')
- def test_ceilometer_version(self):
- self.ceilometer('', flags='--version')
diff --git a/tempest/common/accounts.py b/tempest/common/accounts.py
index 6125149..8e9a018 100644
--- a/tempest/common/accounts.py
+++ b/tempest/common/accounts.py
@@ -45,13 +45,7 @@
accounts = {}
self.use_default_creds = True
self.hash_dict = self.get_hash_dict(accounts)
- # FIXME(dhellmann): The configuration option is not part of
- # the API of the library, because if we change the option name
- # or group it will break this use. Tempest needs to set this
- # value somewhere that it owns, and then use
- # lockutils.set_defaults() to tell oslo.concurrency what value
- # to use.
- self.accounts_dir = os.path.join(CONF.oslo_concurrency.lock_path,
+ self.accounts_dir = os.path.join(lockutils.get_lock_path(CONF),
'test_accounts')
self.isolated_creds = {}
diff --git a/tempest/config.py b/tempest/config.py
index b8976b4..4ee4669 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -357,7 +357,13 @@
'images of running instances?'),
cfg.BoolOpt('ec2_api',
default=True,
- help='Does the test environment have the ec2 api running?')
+ help='Does the test environment have the ec2 api running?'),
+ # TODO(mriedem): Remove preserve_ports once juno-eol happens.
+ cfg.BoolOpt('preserve_ports',
+ default=False,
+ help='Does Nova preserve preexisting ports from Neutron '
+ 'when deleting an instance? This should be set to True '
+ 'if testing Kilo+ Nova.')
]
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index bb668f7..3d6abff 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -15,7 +15,6 @@
from oslo_log import log as logging
from tempest_lib.common.utils import data_utils
-from tempest_lib import decorators
import testtools
from tempest import config
@@ -94,8 +93,8 @@
self.servers_client.wait_for_server_status(self.server['id'], 'ACTIVE')
self._check_network_connectivity()
- @decorators.skip_because(bug="1323658")
@test.idempotent_id('61f1aa9a-1573-410e-9054-afa557cab021')
+ @test.stresstest(class_setup_per='process')
@test.services('compute', 'network')
def test_server_connectivity_stop_start(self):
self._setup_network_and_servers()
@@ -147,7 +146,6 @@
self.servers_client.resume_server(self.server['id'])
self._wait_server_status_and_check_network_connectivity()
- @decorators.skip_because(bug="1323658")
@test.idempotent_id('719eb59d-2f42-4b66-b8b1-bb1254473967')
@testtools.skipUnless(CONF.compute_feature_enabled.resize,
'Resize is not available.')
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index af7b683..bb19853 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -101,13 +101,19 @@
self.servers = []
def _setup_network_and_servers(self, **kwargs):
+ boot_with_port = kwargs.pop('boot_with_port', False)
self.security_group = \
self._create_security_group(tenant_id=self.tenant_id)
self.network, self.subnet, self.router = self.create_networks(**kwargs)
self.check_networks()
+ self.port_id = None
+ if boot_with_port:
+ # create a port on the network and boot with that
+ self.port_id = self._create_port(self.network['id']).id
+
name = data_utils.rand_name('server-smoke')
- server = self._create_server(name, self.network)
+ server = self._create_server(name, self.network, self.port_id)
self._check_tenant_network_connectivity()
floating_ip = self.create_floating_ip(server)
@@ -141,7 +147,7 @@
self.assertIn(self.router.id,
seen_router_ids)
- def _create_server(self, name, network):
+ def _create_server(self, name, network, port_id=None):
keypair = self.create_keypair()
self.keypairs[keypair['name']] = keypair
security_groups = [{'name': self.security_group['name']}]
@@ -152,6 +158,8 @@
'key_name': keypair['name'],
'security_groups': security_groups,
}
+ if port_id is not None:
+ create_kwargs['networks'][0]['port'] = port_id
server = self.create_server(name=name, create_kwargs=create_kwargs)
self.servers.append(server)
return server
@@ -605,3 +613,39 @@
self.check_public_network_connectivity(
should_connect=True, msg="after updating "
"admin_state_up of instance port to True")
+
+ @test.idempotent_id('759462e1-8535-46b0-ab3a-33aa45c55aaa')
+ @testtools.skipUnless(CONF.compute_feature_enabled.preserve_ports,
+ 'Preserving ports on instance delete may not be '
+ 'supported in the version of Nova being tested.')
+ @test.attr(type='smoke')
+ @test.services('compute', 'network')
+ def test_preserve_preexisting_port(self):
+ """Tests that a pre-existing port provided on server boot is not
+ deleted if the server is deleted.
+
+ Nova should unbind the port from the instance on delete if the port was
+ not created by Nova as part of the boot request.
+ """
+ # Setup the network, create a port and boot the server from that port.
+ self._setup_network_and_servers(boot_with_port=True)
+ _, server = self.floating_ip_tuple
+ self.assertIsNotNone(self.port_id,
+ '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'])
+ self.assertEqual(1, len(port_list),
+ 'There should only be one port created for '
+ 'server %s.' % server['id'])
+ self.assertEqual(self.port_id, port_list[0]['id'])
+ # Delete the server.
+ self.servers_client.delete_server(server['id'])
+ self.servers_client.wait_for_server_termination(server['id'])
+ # Assert the port still exists on the network but is unbound from
+ # the deleted server.
+ port = self.network_client.show_port(self.port_id)['port']
+ self.assertEqual(self.network['id'], port['network_id'])
+ self.assertEqual('', port['device_id'])
+ self.assertEqual('', port['device_owner'])
diff --git a/tempest/services/compute/json/agents_client.py b/tempest/services/compute/json/agents_client.py
index e17495f..403437d 100644
--- a/tempest/services/compute/json/agents_client.py
+++ b/tempest/services/compute/json/agents_client.py
@@ -15,8 +15,7 @@
import json
import urllib
-from tempest.api_schema.response.compute import agents as common_schema
-from tempest.api_schema.response.compute.v2 import agents as schema
+from tempest.api_schema.response.compute.v2_1 import agents as schema
from tempest.common import service_client
@@ -32,7 +31,7 @@
url += '?%s' % urllib.urlencode(params)
resp, body = self.get(url)
body = json.loads(body)
- self.validate_response(common_schema.list_agents, resp, body)
+ self.validate_response(schema.list_agents, resp, body)
return service_client.ResponseBodyList(resp, body['agents'])
def create_agent(self, **kwargs):
diff --git a/tempest/services/compute/json/aggregates_client.py b/tempest/services/compute/json/aggregates_client.py
index 10955fd..7f1c162 100644
--- a/tempest/services/compute/json/aggregates_client.py
+++ b/tempest/services/compute/json/aggregates_client.py
@@ -18,7 +18,7 @@
from tempest_lib import exceptions as lib_exc
from tempest.api_schema.response.compute import aggregates as schema
-from tempest.api_schema.response.compute.v2 import aggregates as v2_schema
+from tempest.api_schema.response.compute.v2_1 import aggregates as v2_schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/availability_zone_client.py b/tempest/services/compute/json/availability_zone_client.py
index 343c412..b541a2c 100644
--- a/tempest/services/compute/json/availability_zone_client.py
+++ b/tempest/services/compute/json/availability_zone_client.py
@@ -15,7 +15,8 @@
import json
-from tempest.api_schema.response.compute.v2 import availability_zone as schema
+from tempest.api_schema.response.compute.v2_1 import availability_zone \
+ as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/certificates_client.py b/tempest/services/compute/json/certificates_client.py
index 4a30f1e..e6b72bb 100644
--- a/tempest/services/compute/json/certificates_client.py
+++ b/tempest/services/compute/json/certificates_client.py
@@ -15,8 +15,7 @@
import json
-from tempest.api_schema.response.compute import certificates as schema
-from tempest.api_schema.response.compute.v2 import certificates as v2schema
+from tempest.api_schema.response.compute.v2_1 import certificates as schema
from tempest.common import service_client
@@ -34,5 +33,5 @@
url = "os-certificates"
resp, body = self.post(url, None)
body = json.loads(body)
- self.validate_response(v2schema.create_certificate, resp, body)
+ self.validate_response(schema.create_certificate, resp, body)
return service_client.ResponseBody(resp, body['certificate'])
diff --git a/tempest/services/compute/json/extensions_client.py b/tempest/services/compute/json/extensions_client.py
index 09561b3..5c69085 100644
--- a/tempest/services/compute/json/extensions_client.py
+++ b/tempest/services/compute/json/extensions_client.py
@@ -15,7 +15,7 @@
import json
-from tempest.api_schema.response.compute.v2 import extensions as schema
+from tempest.api_schema.response.compute.v2_1 import extensions as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/fixed_ips_client.py b/tempest/services/compute/json/fixed_ips_client.py
index 31cf5b2..dda940c 100644
--- a/tempest/services/compute/json/fixed_ips_client.py
+++ b/tempest/services/compute/json/fixed_ips_client.py
@@ -15,7 +15,7 @@
import json
-from tempest.api_schema.response.compute.v2 import fixed_ips as schema
+from tempest.api_schema.response.compute.v2_1 import fixed_ips as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/flavors_client.py b/tempest/services/compute/json/flavors_client.py
index 433c325..25b1869 100644
--- a/tempest/services/compute/json/flavors_client.py
+++ b/tempest/services/compute/json/flavors_client.py
@@ -20,7 +20,7 @@
from tempest.api_schema.response.compute import flavors_access as schema_access
from tempest.api_schema.response.compute import flavors_extra_specs \
as schema_extra_specs
-from tempest.api_schema.response.compute.v2 import flavors as v2schema
+from tempest.api_schema.response.compute.v2_1 import flavors as v2schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/floating_ips_client.py b/tempest/services/compute/json/floating_ips_client.py
index 0354ba4..5bad527 100644
--- a/tempest/services/compute/json/floating_ips_client.py
+++ b/tempest/services/compute/json/floating_ips_client.py
@@ -18,7 +18,7 @@
from tempest_lib import exceptions as lib_exc
-from tempest.api_schema.response.compute.v2 import floating_ips as schema
+from tempest.api_schema.response.compute.v2_1 import floating_ips as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/hosts_client.py b/tempest/services/compute/json/hosts_client.py
index b06378b..de925a9 100644
--- a/tempest/services/compute/json/hosts_client.py
+++ b/tempest/services/compute/json/hosts_client.py
@@ -16,7 +16,7 @@
import urllib
from tempest.api_schema.response.compute import hosts as schema
-from tempest.api_schema.response.compute.v2 import hosts as v2_schema
+from tempest.api_schema.response.compute.v2_1 import hosts as v2_schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/hypervisor_client.py b/tempest/services/compute/json/hypervisor_client.py
index 380b5ce..bf4bc7f 100644
--- a/tempest/services/compute/json/hypervisor_client.py
+++ b/tempest/services/compute/json/hypervisor_client.py
@@ -16,7 +16,7 @@
import json
from tempest.api_schema.response.compute import hypervisors as common_schema
-from tempest.api_schema.response.compute.v2 import hypervisors as v2schema
+from tempest.api_schema.response.compute.v2_1 import hypervisors as v2schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/images_client.py b/tempest/services/compute/json/images_client.py
index 0ceb6d1..1223fef 100644
--- a/tempest/services/compute/json/images_client.py
+++ b/tempest/services/compute/json/images_client.py
@@ -18,7 +18,7 @@
from tempest_lib import exceptions as lib_exc
-from tempest.api_schema.response.compute.v2 import images as schema
+from tempest.api_schema.response.compute.v2_1 import images as schema
from tempest.common import service_client
from tempest.common import waiters
diff --git a/tempest/services/compute/json/instance_usage_audit_log_client.py b/tempest/services/compute/json/instance_usage_audit_log_client.py
index 551d751..33ba76f 100644
--- a/tempest/services/compute/json/instance_usage_audit_log_client.py
+++ b/tempest/services/compute/json/instance_usage_audit_log_client.py
@@ -15,8 +15,8 @@
import json
-from tempest.api_schema.response.compute.v2 import instance_usage_audit_logs \
- as schema
+from tempest.api_schema.response.compute.v2_1 import \
+ instance_usage_audit_logs as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/interfaces_client.py b/tempest/services/compute/json/interfaces_client.py
index 0c5516c..c3bfa99 100644
--- a/tempest/services/compute/json/interfaces_client.py
+++ b/tempest/services/compute/json/interfaces_client.py
@@ -16,9 +16,8 @@
import json
import time
-from tempest.api_schema.response.compute import interfaces as common_schema
from tempest.api_schema.response.compute import servers as servers_schema
-from tempest.api_schema.response.compute.v2 import interfaces as schema
+from tempest.api_schema.response.compute.v2_1 import interfaces as schema
from tempest.common import service_client
from tempest import exceptions
@@ -46,17 +45,19 @@
resp, body = self.post('servers/%s/os-interface' % server,
body=post_body)
body = json.loads(body)
+ self.validate_response(schema.get_create_interfaces, resp, body)
return service_client.ResponseBody(resp, body['interfaceAttachment'])
def show_interface(self, server, port_id):
resp, body = self.get('servers/%s/os-interface/%s' % (server, port_id))
body = json.loads(body)
+ self.validate_response(schema.get_create_interfaces, resp, body)
return service_client.ResponseBody(resp, body['interfaceAttachment'])
def delete_interface(self, server, port_id):
resp, body = self.delete('servers/%s/os-interface/%s' % (server,
port_id))
- self.validate_response(common_schema.delete_interface, resp, body)
+ self.validate_response(schema.delete_interface, resp, body)
return service_client.ResponseBody(resp, body)
def wait_for_interface_status(self, server, port_id, status):
diff --git a/tempest/services/compute/json/keypairs_client.py b/tempest/services/compute/json/keypairs_client.py
index 18729c3..722aefa 100644
--- a/tempest/services/compute/json/keypairs_client.py
+++ b/tempest/services/compute/json/keypairs_client.py
@@ -16,7 +16,7 @@
import json
from tempest.api_schema.response.compute import keypairs as common_schema
-from tempest.api_schema.response.compute.v2 import keypairs as schema
+from tempest.api_schema.response.compute.v2_1 import keypairs as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/limits_client.py b/tempest/services/compute/json/limits_client.py
index 8769906..d2aaec6 100644
--- a/tempest/services/compute/json/limits_client.py
+++ b/tempest/services/compute/json/limits_client.py
@@ -15,7 +15,7 @@
import json
-from tempest.api_schema.response.compute.v2 import limits as schema
+from tempest.api_schema.response.compute.v2_1 import limits as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/quotas_client.py b/tempest/services/compute/json/quotas_client.py
index ea0f423..89f4acd 100644
--- a/tempest/services/compute/json/quotas_client.py
+++ b/tempest/services/compute/json/quotas_client.py
@@ -15,9 +15,9 @@
import json
-from tempest.api_schema.response.compute.v2\
+from tempest.api_schema.response.compute.v2_1\
import quota_classes as classes_schema
-from tempest.api_schema.response.compute.v2 import quotas as schema
+from tempest.api_schema.response.compute.v2_1 import quotas as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/security_group_default_rules_client.py b/tempest/services/compute/json/security_group_default_rules_client.py
index b370e00..3bf3263 100644
--- a/tempest/services/compute/json/security_group_default_rules_client.py
+++ b/tempest/services/compute/json/security_group_default_rules_client.py
@@ -15,7 +15,7 @@
import json
-from tempest.api_schema.response.compute.v2 import \
+from tempest.api_schema.response.compute.v2_1 import \
security_group_default_rule as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/security_groups_client.py b/tempest/services/compute/json/security_groups_client.py
index 5aefa7b..d8c8d63 100644
--- a/tempest/services/compute/json/security_groups_client.py
+++ b/tempest/services/compute/json/security_groups_client.py
@@ -18,7 +18,7 @@
from tempest_lib import exceptions as lib_exc
-from tempest.api_schema.response.compute.v2 import security_groups as schema
+from tempest.api_schema.response.compute.v2_1 import security_groups as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/servers_client.py b/tempest/services/compute/json/servers_client.py
index bd4fd0e..bd27668 100644
--- a/tempest/services/compute/json/servers_client.py
+++ b/tempest/services/compute/json/servers_client.py
@@ -21,7 +21,7 @@
from tempest_lib import exceptions as lib_exc
from tempest.api_schema.response.compute import servers as common_schema
-from tempest.api_schema.response.compute.v2 import servers as schema
+from tempest.api_schema.response.compute.v2_1 import servers as schema
from tempest.common import service_client
from tempest.common import waiters
from tempest import exceptions
diff --git a/tempest/services/compute/json/tenant_networks_client.py b/tempest/services/compute/json/tenant_networks_client.py
index c86c817..11251f6 100644
--- a/tempest/services/compute/json/tenant_networks_client.py
+++ b/tempest/services/compute/json/tenant_networks_client.py
@@ -14,7 +14,7 @@
import json
-from tempest.api_schema.response.compute.v2 import tenant_networks as schema
+from tempest.api_schema.response.compute.v2_1 import tenant_networks as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/tenant_usages_client.py b/tempest/services/compute/json/tenant_usages_client.py
index bbc1051..ff6e7a2 100644
--- a/tempest/services/compute/json/tenant_usages_client.py
+++ b/tempest/services/compute/json/tenant_usages_client.py
@@ -16,7 +16,7 @@
import json
import urllib
-from tempest.api_schema.response.compute.v2 import tenant_usages as schema
+from tempest.api_schema.response.compute.v2_1 import tenant_usages as schema
from tempest.common import service_client
diff --git a/tempest/services/compute/json/volumes_extensions_client.py b/tempest/services/compute/json/volumes_extensions_client.py
index b2d5cf9..ba5921e 100644
--- a/tempest/services/compute/json/volumes_extensions_client.py
+++ b/tempest/services/compute/json/volumes_extensions_client.py
@@ -19,7 +19,7 @@
from tempest_lib import exceptions as lib_exc
-from tempest.api_schema.response.compute.v2 import volumes as schema
+from tempest.api_schema.response.compute.v2_1 import volumes as schema
from tempest.common import service_client
from tempest import exceptions
diff --git a/tempest/stress/driver.py b/tempest/stress/driver.py
index d095b53..e84d627 100644
--- a/tempest/stress/driver.py
+++ b/tempest/stress/driver.py
@@ -132,7 +132,14 @@
computes = _get_compute_nodes(controller, ssh_user, ssh_key)
for node in computes:
do_ssh("rm -f %s" % logfiles, node, ssh_user, ssh_key)
+ skip = False
for test in tests:
+ for service in test.get('required_services', []):
+ if not CONF.service_available.get(service):
+ skip = True
+ break
+ if skip:
+ break
if test.get('use_admin', False):
manager = admin_manager
else:
diff --git a/tempest/stress/etc/stress-tox-job.json b/tempest/stress/etc/stress-tox-job.json
index dffc469..9cee316 100644
--- a/tempest/stress/etc/stress-tox-job.json
+++ b/tempest/stress/etc/stress-tox-job.json
@@ -15,5 +15,14 @@
"use_admin": false,
"use_isolated_tenants": false,
"kwargs": {}
+ },
+ {"action": "tempest.stress.actions.unit_test.UnitTest",
+ "threads": 4,
+ "use_admin": false,
+ "use_isolated_tenants": false,
+ "required_services": ["neutron"],
+ "kwargs": {"test_method": "tempest.scenario.test_network_advanced_server_ops.TestNetworkAdvancedServerOps.test_server_connectivity_stop_start",
+ "class_setup_per": "process"}
}
]
+
diff --git a/tempest/tests/common/test_accounts.py b/tempest/tests/common/test_accounts.py
index 4003eb4..2a98a06 100644
--- a/tempest/tests/common/test_accounts.py
+++ b/tempest/tests/common/test_accounts.py
@@ -17,6 +17,7 @@
import mock
from oslo_concurrency.fixture import lockutils as lockutils_fixtures
+from oslo_concurrency import lockutils
from oslo_config import cfg
from oslotest import mockpatch
@@ -126,13 +127,7 @@
with mock.patch('__builtin__.open', mock.mock_open(),
create=True) as open_mock:
test_account_class._get_free_hash(hash_list)
- # FIXME(dhellmann): The configuration option is not part
- # of the API of the library, because if we change the
- # option name or group it will break this use. Tempest
- # needs to set this value somewhere that it owns, and then
- # use lockutils.set_defaults() to tell oslo.concurrency
- # what value to use.
- lock_path = os.path.join(accounts.CONF.oslo_concurrency.lock_path,
+ lock_path = os.path.join(lockutils.get_lock_path(accounts.CONF),
'test_accounts',
hash_list[0])
open_mock.assert_called_once_with(lock_path, 'w')
@@ -170,13 +165,7 @@
with mock.patch('__builtin__.open', mock.mock_open(),
create=True) as open_mock:
test_account_class._get_free_hash(hash_list)
- # FIXME(dhellmann): The configuration option is not part
- # of the API of the library, because if we change the
- # option name or group it will break this use. Tempest
- # needs to set this value somewhere that it owns, and then
- # use lockutils.set_defaults() to tell oslo.concurrency
- # what value to use.
- lock_path = os.path.join(accounts.CONF.oslo_concurrency.lock_path,
+ lock_path = os.path.join(lockutils.get_lock_path(accounts.CONF),
'test_accounts',
hash_list[3])
open_mock.assert_has_calls([mock.call(lock_path, 'w')])
@@ -192,13 +181,7 @@
remove_mock = self.useFixture(mockpatch.Patch('os.remove'))
rmdir_mock = self.useFixture(mockpatch.Patch('os.rmdir'))
test_account_class.remove_hash(hash_list[2])
- # FIXME(dhellmann): The configuration option is not part of
- # the API of the library, because if we change the option name
- # or group it will break this use. Tempest needs to set this
- # value somewhere that it owns, and then use
- # lockutils.set_defaults() to tell oslo.concurrency what value
- # to use.
- hash_path = os.path.join(accounts.CONF.oslo_concurrency.lock_path,
+ hash_path = os.path.join(lockutils.get_lock_path(accounts.CONF),
'test_accounts',
hash_list[2])
lock_path = os.path.join(accounts.CONF.oslo_concurrency.lock_path,
@@ -218,13 +201,7 @@
remove_mock = self.useFixture(mockpatch.Patch('os.remove'))
rmdir_mock = self.useFixture(mockpatch.Patch('os.rmdir'))
test_account_class.remove_hash(hash_list[2])
- # FIXME(dhellmann): The configuration option is not part of
- # the API of the library, because if we change the option name
- # or group it will break this use. Tempest needs to set this
- # value somewhere that it owns, and then use
- # lockutils.set_defaults() to tell oslo.concurrency what value
- # to use.
- hash_path = os.path.join(accounts.CONF.oslo_concurrency.lock_path,
+ hash_path = os.path.join(lockutils.get_lock_path(accounts.CONF),
'test_accounts',
hash_list[2])
remove_mock.mock.assert_called_once_with(hash_path)
diff --git a/test-requirements.txt b/test-requirements.txt
index 6a9111e..76ae521 100644
--- a/test-requirements.txt
+++ b/test-requirements.txt
@@ -5,9 +5,9 @@
# needed for doc build
sphinx>=1.1.2,!=1.2.0,!=1.3b1,<1.3
python-subunit>=0.0.18
-oslosphinx>=2.2.0 # Apache-2.0
+oslosphinx>=2.5.0,<2.6.0 # Apache-2.0
mox>=0.5.3
mock>=1.0
coverage>=3.6
-oslotest>=1.2.0 # Apache-2.0
-stevedore>=1.1.0 # Apache-2.0
+oslotest>=1.5.1,<1.6.0 # Apache-2.0
+stevedore>=1.3.0,<1.4.0 # Apache-2.0