Merge "Add test for list snapshots with offset param"
diff --git a/.mailmap b/.mailmap
index 3ea6ab0..7898e69 100644
--- a/.mailmap
+++ b/.mailmap
@@ -13,9 +13,10 @@
Ken'ichi Ohmichi <ken-oomichi@wx.jp.nec.com> <oomichi@mxs.nes.nec.co.jp>
Ken'ichi Ohmichi <ken-oomichi@wx.jp.nec.com> <ken1ohmichi@gmail.com>
Marc Koderer <marc@koderer.com> <m.koderer@telekom.de>
-Masayuki Igawa <masayuki@igawa.me> <igawa@mxs.nes.nec.co.jp>
-Masayuki Igawa <masayuki@igawa.me> <mas-igawa@ut.jp.nec.com>
-Masayuki Igawa <masayuki@igawa.me> <masayuki.igawa@gmail.com>
+Masayuki Igawa <masayuki@igawa.io> <igawa@mxs.nes.nec.co.jp>
+Masayuki Igawa <masayuki@igawa.io> <mas-igawa@ut.jp.nec.com>
+Masayuki Igawa <masayuki@igawa.io> <masayuki.igawa@gmail.com>
+Masayuki Igawa <masayuki@igawa.io> <masayuki@igawa.me>
Matthew Treinish <mtreinish@kortar.org> <treinish@linux.vnet.ibm.com>
Nayna Patel <nayna.patel@hp.com> <nayna.patel@hp.com>
ravikumar-venkatesan <ravikumar.venkatesan@hp.com> <ravikumar.venkatesan@hp.com>
diff --git a/.zuul.yaml b/.zuul.yaml
index ee0ae9c..17ec1fc 100644
--- a/.zuul.yaml
+++ b/.zuul.yaml
@@ -164,6 +164,16 @@
tempest_concurrency: 2
- job:
+ name: tempest-full-rocky
+ parent: tempest-full
+ override-checkout: stable/rocky
+
+- job:
+ name: tempest-full-rocky-py3
+ parent: tempest-full-py3
+ override-checkout: stable/rocky
+
+- job:
name: tempest-full-queens
parent: tempest-full
override-checkout: stable/queens
@@ -314,6 +324,26 @@
- ^setup.cfg$
- ^tempest/hacking/.*$
- ^tempest/tests/.*$
+ - tempest-full-rocky:
+ irrelevant-files:
+ - ^(test-|)requirements.txt$
+ - ^.*\.rst$
+ - ^doc/.*$
+ - ^etc/.*$
+ - ^releasenotes/.*$
+ - ^setup.cfg$
+ - ^tempest/hacking/.*$
+ - ^tempest/tests/.*$
+ - tempest-full-rocky-py3:
+ irrelevant-files:
+ - ^(test-|)requirements.txt$
+ - ^.*\.rst$
+ - ^doc/.*$
+ - ^etc/.*$
+ - ^releasenotes/.*$
+ - ^setup.cfg$
+ - ^tempest/hacking/.*$
+ - ^tempest/tests/.*$
- tempest-full-queens:
irrelevant-files:
- ^(test-|)requirements.txt$
@@ -422,6 +452,8 @@
- ^tempest/tests/.*$
periodic-stable:
jobs:
+ - tempest-full-rocky
+ - tempest-full-rocky-py3
- tempest-full-queens
- tempest-full-queens-py3
- tempest-full-pike
diff --git a/README.rst b/README.rst
index c93e19f..0a130dc 100644
--- a/README.rst
+++ b/README.rst
@@ -111,15 +111,18 @@
$ tempest run --workspace cloud-01
- There is also the option to use testr directly, or any `testr`_ based test
- runner, like `ostestr`_. For example, from the workspace dir run::
+ There is also the option to use `stestr`_ directly. For example, from
+ the workspace dir run::
- $ ostestr --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario))'
+ $ stestr run --black-regex '\[.*\bslow\b.*\]' '^tempest\.(api|scenario)'
- will run the same set of tests as the default gate jobs.
+ will run the same set of tests as the default gate jobs. Or you can
+ use `unittest`_ compatible test runners such as `testr`_, `pytest`_ etc.
+.. _unittest: https://docs.python.org/3/library/unittest.html
.. _testr: https://testrepository.readthedocs.org/en/latest/MANUAL.html
-.. _ostestr: https://docs.openstack.org/os-testr/latest/
+.. _stestr: https://stestr.readthedocs.org/en/latest/MANUAL.html
+.. _pytest: https://docs.pytest.org/en/latest/
Library
-------
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index c9d5733..7a3bfdf 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -209,26 +209,27 @@
az_name = data_utils.rand_name(self.az_name_prefix)
aggregate = self._create_test_aggregate(availability_zone=az_name)
- # Find a host that has not been added to other zone,
- # for one host can't be added to different zones.
+ # Find a host that has not been added to other availability zone,
+ # for one host can't be added to different availability zones.
aggregates = self.client.list_aggregates()['aggregates']
hosts_in_zone = []
- for v in aggregates:
- if v['availability_zone']:
- hosts_in_zone.extend(v['hosts'])
+ for agg in aggregates:
+ if agg['availability_zone']:
+ hosts_in_zone.extend(agg['hosts'])
hosts = [v for v in self.hosts_available if v not in hosts_in_zone]
if not hosts:
- raise self.skipException("All hosts are already in other zones, "
- "so can't add host to aggregate.")
+ raise self.skipException("All hosts are already in other "
+ "availability zones, so can't add "
+ "host to aggregate. \nAggregates list: "
+ "%s" % aggregates)
host = hosts[0]
self.client.add_host(aggregate['id'], host=host)
self.addCleanup(self.client.remove_host, aggregate['id'], host=host)
- admin_servers_client = self.os_admin.servers_client
server = self.create_test_server(availability_zone=az_name,
wait_until='ACTIVE')
- body = admin_servers_client.show_server(server['id'])['server']
- self.assertEqual(host, body['OS-EXT-SRV-ATTR:host'])
+ server_host = self.get_host_for_server(server['id'])
+ self.assertEqual(host, server_host)
class AggregatesAdminTestV241(AggregatesAdminTestBase):
diff --git a/tempest/api/compute/admin/test_delete_server.py b/tempest/api/compute/admin/test_delete_server.py
index 83444b9..58cac57 100644
--- a/tempest/api/compute/admin/test_delete_server.py
+++ b/tempest/api/compute/admin/test_delete_server.py
@@ -15,11 +15,8 @@
from tempest.api.compute import base
from tempest.common import waiters
-from tempest import config
from tempest.lib import decorators
-CONF = config.CONF
-
class DeleteServersAdminTestJSON(base.BaseV2ComputeAdminTest):
# NOTE: Server creations of each test class should be under 10
diff --git a/tempest/api/compute/admin/test_live_migration.py b/tempest/api/compute/admin/test_live_migration.py
index 8350f7c..5a60dc6 100644
--- a/tempest/api/compute/admin/test_live_migration.py
+++ b/tempest/api/compute/admin/test_live_migration.py
@@ -29,13 +29,11 @@
LOG = logging.getLogger(__name__)
-class LiveMigrationTest(base.BaseV2ComputeAdminTest):
- max_microversion = '2.24'
- block_migration = None
+class LiveMigrationTestBase(base.BaseV2ComputeAdminTest):
@classmethod
def skip_checks(cls):
- super(LiveMigrationTest, cls).skip_checks()
+ super(LiveMigrationTestBase, cls).skip_checks()
if not CONF.compute_feature_enabled.live_migration:
skip_msg = ("%s skipped as live-migration is "
@@ -55,11 +53,11 @@
# TODO(mriedem): SSH validation before and after the instance is
# live migrated would be a nice test wrinkle addition.
cls.set_network_resources(network=True, subnet=True)
- super(LiveMigrationTest, cls).setup_credentials()
+ super(LiveMigrationTestBase, cls).setup_credentials()
@classmethod
def setup_clients(cls):
- super(LiveMigrationTest, cls).setup_clients()
+ super(LiveMigrationTestBase, cls).setup_clients()
cls.admin_migration_client = cls.os_admin.migrations_client
def _migrate_server_to(self, server_id, dest_host, volume_backed=False):
@@ -91,6 +89,11 @@
self.assertEqual(target_host, self.get_host_for_server(server_id),
msg)
+
+class LiveMigrationTest(LiveMigrationTestBase):
+ max_microversion = '2.24'
+ block_migration = None
+
def _test_live_migration(self, state='ACTIVE', volume_backed=False):
"""Tests live migration between two hosts.
@@ -168,7 +171,7 @@
self.assertEqual(volume_id1, volume_id2)
-class LiveMigrationRemoteConsolesV26Test(LiveMigrationTest):
+class LiveMigrationRemoteConsolesV26Test(LiveMigrationTestBase):
min_microversion = '2.6'
max_microversion = 'latest'
diff --git a/tempest/api/compute/admin/test_migrations.py b/tempest/api/compute/admin/test_migrations.py
index e030575..83f2e61 100644
--- a/tempest/api/compute/admin/test_migrations.py
+++ b/tempest/api/compute/admin/test_migrations.py
@@ -114,8 +114,7 @@
raise self.skipException(msg)
server = self.create_test_server(wait_until="ACTIVE")
- src_host = self.admin_servers_client.show_server(
- server['id'])['server']['OS-EXT-SRV-ATTR:host']
+ src_host = self.get_host_for_server(server['id'])
self.admin_servers_client.migrate_server(server['id'])
@@ -131,8 +130,7 @@
waiters.wait_for_server_status(self.servers_client,
server['id'], 'ACTIVE')
- dst_host = self.admin_servers_client.show_server(
- server['id'])['server']['OS-EXT-SRV-ATTR:host']
+ dst_host = self.get_host_for_server(server['id'])
assert_func(src_host, dst_host)
@decorators.idempotent_id('4bf0be52-3b6f-4746-9a27-3143636fe30d')
diff --git a/tempest/api/compute/admin/test_server_diagnostics_negative.py b/tempest/api/compute/admin/test_server_diagnostics_negative.py
index d5b6674..6215c37 100644
--- a/tempest/api/compute/admin/test_server_diagnostics_negative.py
+++ b/tempest/api/compute/admin/test_server_diagnostics_negative.py
@@ -18,8 +18,6 @@
class ServerDiagnosticsNegativeTest(base.BaseV2ComputeAdminTest):
- min_microversion = None
- max_microversion = '2.47'
@classmethod
def setup_clients(cls):
@@ -33,8 +31,3 @@
server_id = self.create_test_server(wait_until='ACTIVE')['id']
self.assertRaises(lib_exc.Forbidden,
self.client.show_server_diagnostics, server_id)
-
-
-class ServerDiagnosticsNegativeV248Test(ServerDiagnosticsNegativeTest):
- min_microversion = '2.48'
- max_microversion = 'latest'
diff --git a/tempest/api/compute/admin/test_servers_on_multinodes.py b/tempest/api/compute/admin/test_servers_on_multinodes.py
index d32a5b4..5cd98f4 100644
--- a/tempest/api/compute/admin/test_servers_on_multinodes.py
+++ b/tempest/api/compute/admin/test_servers_on_multinodes.py
@@ -28,7 +28,7 @@
def resource_setup(cls):
super(ServersOnMultiNodesTest, cls).resource_setup()
cls.server01 = cls.create_test_server(wait_until='ACTIVE')['id']
- cls.host01 = cls._get_host(cls.server01)
+ cls.host01 = cls.get_host_for_server(cls.server01)
@classmethod
def skip_checks(cls):
@@ -38,11 +38,6 @@
raise cls.skipException(
"Less than 2 compute nodes, skipping multi-nodes test.")
- @classmethod
- def _get_host(cls, server_id):
- return cls.os_admin.servers_client.show_server(
- server_id)['server']['OS-EXT-SRV-ATTR:host']
-
def _create_servers_with_group(self, policy):
group_id = self.create_test_server_group(policy=[policy])['id']
hints = {'group': group_id}
@@ -61,7 +56,7 @@
hosts = {}
for server in servers:
self.assertIn(server['id'], server_group['members'])
- hosts[server['id']] = self._get_host(server['id'])
+ hosts[server['id']] = self.get_host_for_server(server['id'])
return hosts
@@ -73,7 +68,7 @@
hints = {'same_host': self.server01}
server02 = self.create_test_server(scheduler_hints=hints,
wait_until='ACTIVE')['id']
- host02 = self._get_host(server02)
+ host02 = self.get_host_for_server(server02)
self.assertEqual(self.host01, host02)
@decorators.idempotent_id('cc7ca884-6e3e-42a3-a92f-c522fcf25e8e')
@@ -84,7 +79,7 @@
hints = {'different_host': self.server01}
server02 = self.create_test_server(scheduler_hints=hints,
wait_until='ACTIVE')['id']
- host02 = self._get_host(server02)
+ host02 = self.get_host_for_server(server02)
self.assertNotEqual(self.host01, host02)
@decorators.idempotent_id('7869cc84-d661-4e14-9f00-c18cdc89cf57')
@@ -96,7 +91,7 @@
hints = {'different_host': [self.server01]}
server02 = self.create_test_server(scheduler_hints=hints,
wait_until='ACTIVE')['id']
- host02 = self._get_host(server02)
+ host02 = self.get_host_for_server(server02)
self.assertNotEqual(self.host01, host02)
@decorators.idempotent_id('f8bd0867-e459-45f5-ba53-59134552fe04')
diff --git a/tempest/api/compute/base.py b/tempest/api/compute/base.py
index 834983b..ff2f99c 100644
--- a/tempest/api/compute/base.py
+++ b/tempest/api/compute/base.py
@@ -591,8 +591,9 @@
self.addCleanup(client.delete_flavor, flavor['id'])
return flavor
- def get_host_for_server(self, server_id):
- server_details = self.admin_servers_client.show_server(server_id)
+ @classmethod
+ def get_host_for_server(cls, server_id):
+ server_details = cls.admin_servers_client.show_server(server_id)
return server_details['server']['OS-EXT-SRV-ATTR:host']
def get_host_other_than(self, server_id):
diff --git a/tempest/api/identity/admin/v3/test_application_credentials.py b/tempest/api/identity/admin/v3/test_application_credentials.py
index 4a74ef8..7e802c6 100644
--- a/tempest/api/identity/admin/v3/test_application_credentials.py
+++ b/tempest/api/identity/admin/v3/test_application_credentials.py
@@ -15,13 +15,9 @@
# under the License.
from tempest.api.identity import base
-from tempest import config
from tempest.lib import decorators
-CONF = config.CONF
-
-
class ApplicationCredentialsV3AdminTest(base.BaseApplicationCredentialsV3Test,
base.BaseIdentityV3AdminTest):
diff --git a/tempest/api/identity/admin/v3/test_projects.py b/tempest/api/identity/admin/v3/test_projects.py
index bc94a8e..6ddf42e 100644
--- a/tempest/api/identity/admin/v3/test_projects.py
+++ b/tempest/api/identity/admin/v3/test_projects.py
@@ -14,12 +14,9 @@
# under the License.
from tempest.api.identity import base
-from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
-CONF = config.CONF
-
class ProjectsTestJSON(base.BaseIdentityV3AdminTest):
diff --git a/tempest/api/identity/admin/v3/test_roles.py b/tempest/api/identity/admin/v3/test_roles.py
index 62ced19..47f663c 100644
--- a/tempest/api/identity/admin/v3/test_roles.py
+++ b/tempest/api/identity/admin/v3/test_roles.py
@@ -14,14 +14,11 @@
# under the License.
from tempest.api.identity import base
-from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib.common.utils import test_utils
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
-CONF = config.CONF
-
class RolesV3TestJSON(base.BaseIdentityV3AdminTest):
diff --git a/tempest/api/identity/v3/test_application_credentials.py b/tempest/api/identity/v3/test_application_credentials.py
index caf0b1e..1cee902 100644
--- a/tempest/api/identity/v3/test_application_credentials.py
+++ b/tempest/api/identity/v3/test_application_credentials.py
@@ -19,13 +19,9 @@
from oslo_utils import timeutils
from tempest.api.identity import base
-from tempest import config
from tempest.lib import decorators
-CONF = config.CONF
-
-
class ApplicationCredentialsV3Test(base.BaseApplicationCredentialsV3Test):
def _list_app_creds(self, name=None):
diff --git a/tempest/api/network/admin/test_dhcp_agent_scheduler.py b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
index 8315c5d..4631ea9 100644
--- a/tempest/api/network/admin/test_dhcp_agent_scheduler.py
+++ b/tempest/api/network/admin/test_dhcp_agent_scheduler.py
@@ -63,7 +63,6 @@
def test_add_remove_network_from_dhcp_agent(self):
# The agent is now bound to the network, we can free the port
self.ports_client.delete_port(self.port['id'])
- self.ports.remove(self.port)
agent = dict()
agent['agent_type'] = None
body = self.admin_agents_client.list_agents()
diff --git a/tempest/api/network/admin/test_l3_agent_scheduler.py b/tempest/api/network/admin/test_l3_agent_scheduler.py
index 206d867..033bf55 100644
--- a/tempest/api/network/admin/test_l3_agent_scheduler.py
+++ b/tempest/api/network/admin/test_l3_agent_scheduler.py
@@ -14,11 +14,9 @@
from tempest.api.network import base
from tempest.common import utils
-from tempest import config
from tempest.lib import decorators
from tempest.lib import exceptions
-CONF = config.CONF
AGENT_TYPE = 'L3 agent'
AGENT_MODES = (
'legacy',
diff --git a/tempest/api/network/admin/test_ports.py b/tempest/api/network/admin/test_ports.py
index 483b405..05363db 100644
--- a/tempest/api/network/admin/test_ports.py
+++ b/tempest/api/network/admin/test_ports.py
@@ -14,11 +14,8 @@
# under the License.
from tempest.api.network import base
-from tempest import config
from tempest.lib import decorators
-CONF = config.CONF
-
class PortsAdminExtendedAttrsTestJSON(base.BaseAdminNetworkTest):
diff --git a/tempest/api/network/admin/test_routers.py b/tempest/api/network/admin/test_routers.py
index 8cdb41e..a7355f3 100644
--- a/tempest/api/network/admin/test_routers.py
+++ b/tempest/api/network/admin/test_routers.py
@@ -32,7 +32,6 @@
def _cleanup_router(self, router):
self.delete_router(router)
- self.routers.remove(router)
def _create_router(self, name=None, admin_state_up=False,
external_network_id=None, enable_snat=None):
diff --git a/tempest/api/network/base.py b/tempest/api/network/base.py
index 8670165..9032fdc 100644
--- a/tempest/api/network/base.py
+++ b/tempest/api/network/base.py
@@ -88,9 +88,6 @@
@classmethod
def resource_setup(cls):
super(BaseNetworkTest, cls).resource_setup()
- cls.subnets = []
- cls.ports = []
- cls.routers = []
cls.ethertype = "IPv" + str(cls._ip_version)
if cls._ip_version == 4:
cls.cidr = netaddr.IPNetwork(CONF.network.project_network_cidr)
@@ -155,7 +152,6 @@
cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc,
cls.subnets_client.delete_subnet,
subnet['id'])
- cls.subnets.append(subnet)
return subnet
@classmethod
@@ -166,7 +162,6 @@
port = body['port']
cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc,
cls.ports_client.delete_port, port['id'])
- cls.ports.append(port)
return port
@classmethod
@@ -194,7 +189,6 @@
router = body['router']
cls.addClassResourceCleanup(test_utils.call_and_ignore_notfound_exc,
cls.delete_router, router)
- cls.routers.append(router)
return router
@classmethod
diff --git a/tempest/api/network/test_allowed_address_pair.py b/tempest/api/network/test_allowed_address_pair.py
index 3075047..dec3413 100644
--- a/tempest/api/network/test_allowed_address_pair.py
+++ b/tempest/api/network/test_allowed_address_pair.py
@@ -17,11 +17,8 @@
from tempest.api.network import base
from tempest.common import utils
-from tempest import config
from tempest.lib import decorators
-CONF = config.CONF
-
class AllowedAddressPairTestJSON(base.BaseNetworkTest):
"""Tests the Neutron Allowed Address Pair API extension
diff --git a/tempest/api/network/test_dhcp_ipv6.py b/tempest/api/network/test_dhcp_ipv6.py
index 9d6d700..0730d58 100644
--- a/tempest/api/network/test_dhcp_ipv6.py
+++ b/tempest/api/network/test_dhcp_ipv6.py
@@ -56,6 +56,9 @@
def resource_setup(cls):
super(NetworksTestDHCPv6, cls).resource_setup()
cls.network = cls.create_network()
+ cls.ports = []
+ cls.subnets = []
+ cls.routers = []
def _remove_from_list_by_index(self, things_list, elem):
for index, i in enumerate(things_list):
@@ -90,8 +93,10 @@
def _get_ips_from_subnet(self, **kwargs):
subnet = self.create_subnet(self.network, **kwargs)
+ self.subnets.append(subnet)
port_mac = data_utils.rand_mac_address()
port = self.create_port(self.network, mac_address=port_mac)
+ self.ports.append(port)
real_ip = next(iter(port['fixed_ips']), None)['ip_address']
eui_ip = str(netutils.get_ipv6_addr_by_EUI64(
subnet['cidr'], port_mac))
@@ -182,16 +187,21 @@
kwargs_dhcp = {'ipv6_address_mode': 'dhcpv6-stateful'}
if order == "slaac_first":
subnet_slaac = self.create_subnet(self.network, **kwargs)
+ self.subnets.append(subnet_slaac)
subnet_dhcp = self.create_subnet(
self.network, **kwargs_dhcp)
+ self.subnets.append(subnet_dhcp)
else:
subnet_dhcp = self.create_subnet(
self.network, **kwargs_dhcp)
+ self.subnets.append(subnet_dhcp)
subnet_slaac = self.create_subnet(self.network, **kwargs)
+ self.subnets.append(subnet_slaac)
port_mac = data_utils.rand_mac_address()
eui_ip = str(netutils.get_ipv6_addr_by_EUI64(
subnet_slaac['cidr'], port_mac))
port = self.create_port(self.network, mac_address=port_mac)
+ self.ports.append(port)
real_ips = dict([(k['subnet_id'], k['ip_address'])
for k in port['fixed_ips']])
real_dhcp_ip, real_eui_ip = [real_ips[sub['id']]
@@ -228,16 +238,21 @@
'ipv6_address_mode': add_mode}
if order == "slaac_first":
subnet_slaac = self.create_subnet(self.network, **kwargs)
+ self.subnets.append(subnet_slaac)
subnet_dhcp = self.create_subnet(
self.network, ip_version=4)
+ self.subnets.append(subnet_dhcp)
else:
subnet_dhcp = self.create_subnet(
self.network, ip_version=4)
+ self.subnets.append(subnet_dhcp)
subnet_slaac = self.create_subnet(self.network, **kwargs)
+ self.subnets.append(subnet_slaac)
port_mac = data_utils.rand_mac_address()
eui_ip = str(netutils.get_ipv6_addr_by_EUI64(
subnet_slaac['cidr'], port_mac))
port = self.create_port(self.network, mac_address=port_mac)
+ self.ports.append(port)
real_ips = dict([(k['subnet_id'], k['ip_address'])
for k in port['fixed_ips']])
real_dhcp_ip, real_eui_ip = [real_ips[sub['id']]
@@ -267,7 +282,9 @@
'ipv6_address_mode': add_mode}
kwargs = dict((k, v) for k, v in kwargs.items() if v)
subnet = self.create_subnet(self.network, **kwargs)
+ self.subnets.append(subnet)
port = self.create_port(self.network)
+ self.ports.append(port)
port_ip = next(iter(port['fixed_ips']), None)['ip_address']
self._clean_network()
msg = ('Real IP address is {0} and it is NOT on '
@@ -289,6 +306,7 @@
'ipv6_address_mode': add_mode}
kwargs = dict((k, v) for k, v in kwargs.items() if v)
subnet = self.create_subnet(self.network, **kwargs)
+ self.subnets.append(subnet)
ip_range = netaddr.IPRange(subnet["allocation_pools"][0]["start"],
subnet["allocation_pools"][0]["end"])
ip = netaddr.IPAddress(random.randrange(ip_range.first,
@@ -296,6 +314,7 @@
port = self.create_port(self.network,
fixed_ips=[{'subnet_id': subnet['id'],
'ip_address': ip}])
+ self.ports.append(port)
port_ip = next(iter(port['fixed_ips']), None)['ip_address']
self._clean_network()
self.assertEqual(port_ip, ip,
@@ -310,6 +329,7 @@
kwargs = {'ipv6_ra_mode': 'dhcpv6-stateful',
'ipv6_address_mode': 'dhcpv6-stateful'}
subnet = self.create_subnet(self.network, **kwargs)
+ self.subnets.append(subnet)
ip_range = netaddr.IPRange(subnet["allocation_pools"][0]["start"],
subnet["allocation_pools"][0]["end"])
ip = netaddr.IPAddress(random.randrange(
@@ -327,14 +347,16 @@
kwargs = {'ipv6_ra_mode': 'dhcpv6-stateful',
'ipv6_address_mode': 'dhcpv6-stateful'}
subnet = self.create_subnet(self.network, **kwargs)
+ self.subnets.append(subnet)
ip_range = netaddr.IPRange(subnet["allocation_pools"][0]["start"],
subnet["allocation_pools"][0]["end"])
ip = netaddr.IPAddress(random.randrange(
ip_range.first, ip_range.last)).format()
- self.create_port(self.network,
- fixed_ips=[
- {'subnet_id': subnet['id'],
- 'ip_address': ip}])
+ port = self.create_port(self.network,
+ fixed_ips=[
+ {'subnet_id': subnet['id'],
+ 'ip_address': ip}])
+ self.ports.append(port)
self.assertRaisesRegex(lib_exc.Conflict,
"IpAddressAlreadyAllocated|IpAddressInUse",
self.create_port,
@@ -344,7 +366,9 @@
def _create_subnet_router(self, kwargs):
subnet = self.create_subnet(self.network, **kwargs)
+ self.subnets.append(subnet)
router = self.create_router(admin_state_up=True)
+ self.routers.append(router)
port = self.create_router_interface(router['id'],
subnet['id'])
body = self.ports_client.show_port(port['port_id'])
diff --git a/tempest/api/network/test_floating_ips.py b/tempest/api/network/test_floating_ips.py
index b4bb88e..504bfa8 100644
--- a/tempest/api/network/test_floating_ips.py
+++ b/tempest/api/network/test_floating_ips.py
@@ -64,8 +64,10 @@
cls.router = cls.create_router(external_network_id=cls.ext_net_id)
cls.create_router_interface(cls.router['id'], cls.subnet['id'])
# Create two ports one each for Creation and Updating of floatingIP
+ cls.ports = []
for i in range(2):
- cls.create_port(cls.network)
+ port = cls.create_port(cls.network)
+ cls.ports.append(port)
@decorators.attr(type='smoke')
@decorators.idempotent_id('62595970-ab1c-4b7f-8fcc-fddfe55e8718')
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index 246a5c3..2c9159c 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -22,13 +22,10 @@
from tempest.api.network import base_security_groups as sec_base
from tempest.common import custom_matchers
from tempest.common import utils
-from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions
-CONF = config.CONF
-
class PortsTestJSON(sec_base.BaseSecGroupTest):
"""Test the following operations for ports:
diff --git a/tempest/api/network/test_routers.py b/tempest/api/network/test_routers.py
index 3ff12e4..8b03631 100644
--- a/tempest/api/network/test_routers.py
+++ b/tempest/api/network/test_routers.py
@@ -29,7 +29,6 @@
def _cleanup_router(self, router):
self.delete_router(router)
- self.routers.remove(router)
def _create_router(self, name=None, admin_state_up=False,
external_network_id=None, enable_snat=None):
diff --git a/tempest/api/network/test_routers_negative.py b/tempest/api/network/test_routers_negative.py
index ddd7d3a..0b61860 100644
--- a/tempest/api/network/test_routers_negative.py
+++ b/tempest/api/network/test_routers_negative.py
@@ -15,13 +15,10 @@
from tempest.api.network import base
from tempest.common import utils
-from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
from tempest.lib import exceptions as lib_exc
-CONF = config.CONF
-
class RoutersNegativeTest(base.BaseNetworkTest):
diff --git a/tempest/api/network/test_security_groups.py b/tempest/api/network/test_security_groups.py
index 24bd8ea..ffc1fca 100644
--- a/tempest/api/network/test_security_groups.py
+++ b/tempest/api/network/test_security_groups.py
@@ -15,12 +15,9 @@
from tempest.api.network import base_security_groups as base
from tempest.common import utils
-from tempest import config
from tempest.lib.common.utils import data_utils
from tempest.lib import decorators
-CONF = config.CONF
-
class SecGroupTest(base.BaseSecGroupTest):
diff --git a/tempest/api/volume/admin/test_volume_quotas.py b/tempest/api/volume/admin/test_volume_quotas.py
index 61a6df4..f746f8e 100644
--- a/tempest/api/volume/admin/test_volume_quotas.py
+++ b/tempest/api/volume/admin/test_volume_quotas.py
@@ -22,28 +22,28 @@
QUOTA_USAGE_KEYS = ['reserved', 'limit', 'in_use']
-class BaseVolumeQuotasAdminTestJSON(base.BaseVolumeAdminTest):
+class VolumeQuotasAdminTestJSON(base.BaseVolumeAdminTest):
credentials = ['primary', 'alt', 'admin']
def setUp(self):
# NOTE(jeremy.zhang): Avoid conflicts with volume quota class tests.
self.useFixture(fixtures.LockFixture('volume_quotas'))
- super(BaseVolumeQuotasAdminTestJSON, self).setUp()
+ super(VolumeQuotasAdminTestJSON, self).setUp()
@classmethod
def setup_credentials(cls):
- super(BaseVolumeQuotasAdminTestJSON, cls).setup_credentials()
+ super(VolumeQuotasAdminTestJSON, cls).setup_credentials()
cls.demo_tenant_id = cls.os_primary.credentials.tenant_id
@classmethod
def setup_clients(cls):
- super(BaseVolumeQuotasAdminTestJSON, cls).setup_clients()
+ super(VolumeQuotasAdminTestJSON, cls).setup_clients()
cls.transfer_client = cls.os_primary.volume_transfers_client_latest
cls.alt_transfer_client = cls.os_alt.volume_transfers_client_latest
@classmethod
def resource_setup(cls):
- super(BaseVolumeQuotasAdminTestJSON, cls).resource_setup()
+ super(VolumeQuotasAdminTestJSON, cls).resource_setup()
# Save the current set of quotas so that some tests may use it
# to restore the quotas to their original values after they are
diff --git a/tempest/api/volume/admin/test_volume_quotas_negative.py b/tempest/api/volume/admin/test_volume_quotas_negative.py
index f50f336..d2fe304 100644
--- a/tempest/api/volume/admin/test_volume_quotas_negative.py
+++ b/tempest/api/volume/admin/test_volume_quotas_negative.py
@@ -23,16 +23,16 @@
'backup_gigabytes', 'per_volume_gigabytes']
-class BaseVolumeQuotasNegativeTestJSON(base.BaseVolumeAdminTest):
+class VolumeQuotasNegativeTestJSON(base.BaseVolumeAdminTest):
@classmethod
def setup_credentials(cls):
- super(BaseVolumeQuotasNegativeTestJSON, cls).setup_credentials()
+ super(VolumeQuotasNegativeTestJSON, cls).setup_credentials()
cls.demo_tenant_id = cls.os_primary.credentials.tenant_id
@classmethod
def resource_setup(cls):
- super(BaseVolumeQuotasNegativeTestJSON, cls).resource_setup()
+ super(VolumeQuotasNegativeTestJSON, cls).resource_setup()
# Save the current set of quotas, then set up the cleanup method
# to restore the quotas to their original values after the tests
diff --git a/tempest/api/volume/test_volumes_snapshots.py b/tempest/api/volume/test_volumes_snapshots.py
index 4b97b80..1855386 100644
--- a/tempest/api/volume/test_volumes_snapshots.py
+++ b/tempest/api/volume/test_volumes_snapshots.py
@@ -130,54 +130,39 @@
# Delete the snapshot
self.delete_snapshot(snapshot['id'])
+ def _create_volume_from_snapshot(self, extra_size=0):
+ src_size = CONF.volume.volume_size
+ size = src_size + extra_size
+
+ src_vol = self.create_volume(size=src_size)
+ src_snap = self.create_snapshot(src_vol['id'])
+
+ dst_vol = self.create_volume(snapshot_id=src_snap['id'],
+ size=size)
+ # NOTE(zhufl): dst_vol is created based on snapshot, so dst_vol
+ # should be deleted before deleting snapshot, otherwise deleting
+ # snapshot will end with status 'error-deleting'. This depends on
+ # the implementation mechanism of vendors, generally speaking,
+ # some verdors will use "virtual disk clone" which will promote
+ # disk clone speed, and in this situation the "disk clone"
+ # is just a relationship between volume and snapshot.
+ self.addCleanup(self.delete_volume, self.volumes_client, dst_vol['id'])
+
+ volume = self.volumes_client.show_volume(dst_vol['id'])['volume']
+ # Should allow
+ self.assertEqual(volume['snapshot_id'], src_snap['id'])
+ self.assertEqual(volume['size'], size)
+
@decorators.idempotent_id('677863d1-3142-456d-b6ac-9924f667a7f4')
def test_volume_from_snapshot(self):
# Creates a volume from a snapshot passing a size
# different from the source
- src_size = CONF.volume.volume_size
-
- src_vol = self.create_volume(size=src_size)
- src_snap = self.create_snapshot(src_vol['id'])
- # Destination volume bigger than source snapshot
- dst_vol = self.create_volume(snapshot_id=src_snap['id'],
- size=src_size + 1)
- # NOTE(zhufl): dst_vol is created based on snapshot, so dst_vol
- # should be deleted before deleting snapshot, otherwise deleting
- # snapshot will end with status 'error-deleting'. This depends on
- # the implementation mechanism of vendors, generally speaking,
- # some verdors will use "virtual disk clone" which will promote
- # disk clone speed, and in this situation the "disk clone"
- # is just a relationship between volume and snapshot.
- self.addCleanup(self.delete_volume, self.volumes_client, dst_vol['id'])
-
- volume = self.volumes_client.show_volume(dst_vol['id'])['volume']
- # Should allow
- self.assertEqual(volume['snapshot_id'], src_snap['id'])
- self.assertEqual(volume['size'], src_size + 1)
+ self._create_volume_from_snapshot(extra_size=1)
@decorators.idempotent_id('053d8870-8282-4fff-9dbb-99cb58bb5e0a')
def test_volume_from_snapshot_no_size(self):
# Creates a volume from a snapshot defaulting to original size
- src_size = CONF.volume.volume_size
-
- src_vol = self.create_volume(size=src_size)
- src_snap = self.create_snapshot(src_vol['id'])
- # Destination volume without specifying a size
- dst_vol = self.create_volume(snapshot_id=src_snap['id'])
-
- # NOTE(zhufl): dst_vol is created based on snapshot, so dst_vol
- # should be deleted before deleting snapshot, otherwise deleting
- # snapshot will end with status 'error-deleting'. This depends on
- # the implementation mechanism of vendors, generally speaking,
- # some verdors will use "virtual disk clone" which will promote
- # disk clone speed, and in this situation the "disk clone"
- # is just a relationship between volume and snapshot.
- self.addCleanup(self.delete_volume, self.volumes_client, dst_vol['id'])
-
- volume = self.volumes_client.show_volume(dst_vol['id'])['volume']
- # Should allow
- self.assertEqual(volume['snapshot_id'], src_snap['id'])
- self.assertEqual(volume['size'], src_size)
+ self._create_volume_from_snapshot()
@decorators.idempotent_id('bbcfa285-af7f-479e-8c1a-8c34fc16543c')
@testtools.skipUnless(CONF.volume_feature_enabled.backup,
diff --git a/tempest/cmd/run.py b/tempest/cmd/run.py
index a27425c..84c6d9a 100644
--- a/tempest/cmd/run.py
+++ b/tempest/cmd/run.py
@@ -160,8 +160,6 @@
sys.exit(2)
if parsed_args.state:
self._init_state()
- else:
- pass
regex = self._build_regex(parsed_args)
return_code = 0
diff --git a/tempest/cmd/verify_tempest_config.py b/tempest/cmd/verify_tempest_config.py
index 50691ad..6c2fee8 100644
--- a/tempest/cmd/verify_tempest_config.py
+++ b/tempest/cmd/verify_tempest_config.py
@@ -279,6 +279,9 @@
if not results.get(service):
results[service] = {}
extensions_opt = get_enabled_extensions(service)
+ if not extensions_opt:
+ LOG.info("'%s' has no api_extensions set.", service)
+ return results
if extensions_opt[0] == 'all':
results[service]['extensions'] = extensions
return results
diff --git a/tempest/config.py b/tempest/config.py
index 8314e1e..a8a3bc3 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -470,7 +470,7 @@
"entry 'all' indicates all filters that are included "
"with nova are enabled. Empty list indicates all filters "
"are disabled. The full list of available filters is in "
- "nova.conf: DEFAULT.scheduler_available_filters. If the "
+ "nova.conf: filter_scheduler.enabled_filters. If the "
"default value is overridden in nova.conf by the test "
"environment (which means that a different set of "
"filters is enabled than what is included in Nova by "
diff --git a/tempest/lib/services/volume/v3/snapshots_client.py b/tempest/lib/services/volume/v3/snapshots_client.py
index 0cb5e54..cae65b2 100644
--- a/tempest/lib/services/volume/v3/snapshots_client.py
+++ b/tempest/lib/services/volume/v3/snapshots_client.py
@@ -22,7 +22,6 @@
class SnapshotsClient(rest_client.RestClient):
"""Client class to send CRUD Volume Snapshot V3 API requests."""
- create_resp = 202
def list_snapshots(self, detail=False, **params):
"""List all the snapshot.
@@ -66,7 +65,7 @@
post_body = json.dumps({'snapshot': kwargs})
resp, body = self.post('snapshots', post_body)
body = json.loads(body)
- self.expected_success(self.create_resp, resp.status)
+ self.expected_success(202, resp.status)
return rest_client.ResponseBody(resp, body)
def update_snapshot(self, snapshot_id, **kwargs):
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index cdc30b9..dff50a9 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -704,6 +704,11 @@
else:
raise lib_exc.InvalidConfiguration()
+ @classmethod
+ def get_host_for_server(cls, server_id):
+ server_details = cls.os_admin.servers_client.show_server(server_id)
+ return server_details['server']['OS-EXT-SRV-ATTR:host']
+
class NetworkScenarioTest(ScenarioTest):
"""Base class for network scenario tests.
diff --git a/tempest/scenario/test_network_advanced_server_ops.py b/tempest/scenario/test_network_advanced_server_ops.py
index 7452ee6..8827610 100644
--- a/tempest/scenario/test_network_advanced_server_ops.py
+++ b/tempest/scenario/test_network_advanced_server_ops.py
@@ -102,10 +102,6 @@
'ACTIVE')
self._check_network_connectivity(server, keypair, floating_ip)
- def _get_host_for_server(self, server_id):
- body = self.admin_servers_client.show_server(server_id)['server']
- return body['OS-EXT-SRV-ATTR:host']
-
@decorators.idempotent_id('61f1aa9a-1573-410e-9054-afa557cab021')
@decorators.attr(type='slow')
@utils.services('compute', 'network')
@@ -220,7 +216,7 @@
keypair = self.create_keypair()
server = self._setup_server(keypair)
floating_ip = self._setup_network(server, keypair)
- src_host = self._get_host_for_server(server['id'])
+ src_host = self.get_host_for_server(server['id'])
self._wait_server_status_and_check_network_connectivity(
server, keypair, floating_ip)
@@ -230,7 +226,7 @@
self.servers_client.confirm_resize_server(server['id'])
self._wait_server_status_and_check_network_connectivity(
server, keypair, floating_ip)
- dst_host = self._get_host_for_server(server['id'])
+ dst_host = self.get_host_for_server(server['id'])
self.assertNotEqual(src_host, dst_host)
@@ -246,7 +242,7 @@
keypair = self.create_keypair()
server = self._setup_server(keypair)
floating_ip = self._setup_network(server, keypair)
- src_host = self._get_host_for_server(server['id'])
+ src_host = self.get_host_for_server(server['id'])
self._wait_server_status_and_check_network_connectivity(
server, keypair, floating_ip)
@@ -256,6 +252,6 @@
self.servers_client.revert_resize_server(server['id'])
self._wait_server_status_and_check_network_connectivity(
server, keypair, floating_ip)
- dst_host = self._get_host_for_server(server['id'])
+ dst_host = self.get_host_for_server(server['id'])
self.assertEqual(src_host, dst_host)
diff --git a/tempest/scenario/test_security_groups_basic_ops.py b/tempest/scenario/test_security_groups_basic_ops.py
index f5805ef..28a2d64 100644
--- a/tempest/scenario/test_security_groups_basic_ops.py
+++ b/tempest/scenario/test_security_groups_basic_ops.py
@@ -282,11 +282,8 @@
# Verify servers are on different compute nodes
if self.multi_node:
- adm_get_server = self.os_admin.servers_client.show_server
- new_host = adm_get_server(server["id"])["server"][
- "OS-EXT-SRV-ATTR:host"]
- host_list = [adm_get_server(s)["server"]["OS-EXT-SRV-ATTR:host"]
- for s in self.servers]
+ new_host = self.get_host_for_server(server["id"])
+ host_list = [self.get_host_for_server(s) for s in self.servers]
self.assertNotIn(new_host, host_list,
message="Failed to boot servers on different "
"Compute nodes.")
diff --git a/tempest/tests/cmd/test_tempest_init.py b/tempest/tests/cmd/test_tempest_init.py
index 5f39ac9..9042b12 100644
--- a/tempest/tests/cmd/test_tempest_init.py
+++ b/tempest/tests/cmd/test_tempest_init.py
@@ -22,7 +22,7 @@
class TestTempestInit(base.TestCase):
- def test_generate_testr_conf(self):
+ def test_generate_stestr_conf(self):
# Create fake conf dir
conf_dir = self.useFixture(fixtures.TempDir())
diff --git a/tempest/tests/cmd/test_verify_tempest_config.py b/tempest/tests/cmd/test_verify_tempest_config.py
index 32d6224..c260343 100644
--- a/tempest/tests/cmd/test_verify_tempest_config.py
+++ b/tempest/tests/cmd/test_verify_tempest_config.py
@@ -343,6 +343,24 @@
self.assertEqual(sorted(['fake1', 'fake2', 'not_fake']),
sorted(results['neutron']['extensions']))
+ def test_verify_extensions_neutron_none(self):
+ def fake_list_extensions():
+ return {'extensions': []}
+ fake_os = mock.MagicMock()
+ fake_client = mock.MagicMock()
+ fake_client.list_extensions = fake_list_extensions
+ self.useFixture(fixtures.MockPatchObject(
+ verify_tempest_config, 'get_extension_client',
+ return_value=fake_client))
+ self.useFixture(fixtures.MockPatchObject(
+ verify_tempest_config, 'get_enabled_extensions',
+ return_value=(['all'])))
+ results = verify_tempest_config.verify_extensions(fake_os,
+ 'neutron', {})
+ self.assertIn('neutron', results)
+ self.assertIn('extensions', results['neutron'])
+ self.assertEqual([], results['neutron']['extensions'])
+
def test_verify_extensions_cinder(self):
def fake_list_extensions():
return {'extensions': [{'alias': 'fake1'},
@@ -391,6 +409,24 @@
self.assertEqual(sorted(['fake1', 'fake2', 'not_fake']),
sorted(results['cinder']['extensions']))
+ def test_verify_extensions_cinder_none(self):
+ def fake_list_extensions():
+ return {'extensions': []}
+ fake_os = mock.MagicMock()
+ fake_client = mock.MagicMock()
+ fake_client.list_extensions = fake_list_extensions
+ self.useFixture(fixtures.MockPatchObject(
+ verify_tempest_config, 'get_extension_client',
+ return_value=fake_client))
+ self.useFixture(fixtures.MockPatchObject(
+ verify_tempest_config, 'get_enabled_extensions',
+ return_value=(['all'])))
+ results = verify_tempest_config.verify_extensions(fake_os,
+ 'cinder', {})
+ self.assertIn('cinder', results)
+ self.assertIn('extensions', results['cinder'])
+ self.assertEqual([], results['cinder']['extensions'])
+
def test_verify_extensions_nova(self):
def fake_list_extensions():
return ([{'alias': 'fake1'}, {'alias': 'fake2'},
@@ -437,6 +473,24 @@
self.assertEqual(sorted(['fake1', 'fake2', 'not_fake']),
sorted(results['nova']['extensions']))
+ def test_verify_extensions_nova_none(self):
+ def fake_list_extensions():
+ return ({'extensions': []})
+ fake_os = mock.MagicMock()
+ fake_client = mock.MagicMock()
+ fake_client.list_extensions = fake_list_extensions
+ self.useFixture(fixtures.MockPatchObject(
+ verify_tempest_config, 'get_extension_client',
+ return_value=fake_client))
+ self.useFixture(fixtures.MockPatchObject(
+ verify_tempest_config, 'get_enabled_extensions',
+ return_value=(['all'])))
+ results = verify_tempest_config.verify_extensions(fake_os,
+ 'nova', {})
+ self.assertIn('nova', results)
+ self.assertIn('extensions', results['nova'])
+ self.assertEqual([], results['nova']['extensions'])
+
def test_verify_extensions_swift(self):
def fake_list_extensions():
return {'fake1': 'metadata',
@@ -485,6 +539,24 @@
self.assertEqual(sorted(['not_fake', 'fake1', 'fake2']),
sorted(results['swift']['extensions']))
+ def test_verify_extensions_swift_none(self):
+ def fake_list_extensions():
+ return {'swift': 'metadata'}
+ fake_os = mock.MagicMock()
+ fake_client = mock.MagicMock()
+ fake_client.list_capabilities = fake_list_extensions
+ self.useFixture(fixtures.MockPatchObject(
+ verify_tempest_config, 'get_extension_client',
+ return_value=fake_client))
+ self.useFixture(fixtures.MockPatchObject(
+ verify_tempest_config, 'get_enabled_extensions',
+ return_value=(['all'])))
+ results = verify_tempest_config.verify_extensions(fake_os,
+ 'swift', {})
+ self.assertIn('swift', results)
+ self.assertIn('extensions', results['swift'])
+ self.assertEqual([], results['swift']['extensions'])
+
def test_get_extension_client(self):
creds = credentials_factory.get_credentials(
fill_in=False, username='fake_user', project_name='fake_project',
diff --git a/tox.ini b/tox.ini
index d61a7fe..970f415 100644
--- a/tox.ini
+++ b/tox.ini
@@ -78,6 +78,7 @@
deps = {[tempestenv]deps}
# The regex below is used to select which tests to run and exclude the slow tag:
# See the testrepository bug: https://bugs.launchpad.net/testrepository/+bug/1208610
+# FIXME: We can replace it with the `--black-regex` option to exclude tests now.
commands =
find . -type f -name "*.pyc" -delete
tempest run --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.api)' {posargs}
@@ -100,6 +101,7 @@
deps = {[tempestenv]deps}
# The regex below is used to select which tests to run and exclude the slow tag:
# See the testrepository bug: https://bugs.launchpad.net/testrepository/+bug/1208610
+# FIXME: We can replace it with the `--black-regex` option to exclude tests now.
commands =
find . -type f -name "*.pyc" -delete
tempest run --serial --regex '(?!.*\[.*\bslow\b.*\])(^tempest\.(api|scenario))' {posargs}