Merge "Add return one value to volume delete methods"
diff --git a/etc/tempest.conf.sample b/etc/tempest.conf.sample
index 234273b..02609ae 100644
--- a/etc/tempest.conf.sample
+++ b/etc/tempest.conf.sample
@@ -135,6 +135,9 @@
# concurrent test processes. (boolean value)
#locking_credentials_provider = false
+# Roles to assign to all users created by tempest (list value)
+#tempest_roles =
+
[baremetal]
@@ -582,9 +585,6 @@
# applies to user and project (string value)
#admin_domain_name = <None>
-# Roles to assign to all users created by tempest (list value)
-#tempest_roles =
-
[identity-feature-enabled]
@@ -920,6 +920,11 @@
# operations testing. (integer value)
#large_ops_number = 0
+# DHCP client used by images to renew DCHP lease. If left empty,
+# update operation will be skipped. Supported clients: "udhcpc",
+# "dhclient" (string value)
+#dhcp_client = udhcpc
+
[service_available]
diff --git a/tempest/api/compute/admin/test_agents.py b/tempest/api/compute/admin/test_agents.py
index 3bdcfd6..425ce13 100644
--- a/tempest/api/compute/admin/test_agents.py
+++ b/tempest/api/compute/admin/test_agents.py
@@ -37,8 +37,7 @@
hypervisor='common', os='linux', architecture='x86_64',
version='7.0', url='xxx://xxxx/xxx/xxx',
md5hash='add6bb58e139be103324d04d82d8f545')
- resp, body = self.client.create_agent(**params)
- self.assertEqual(200, resp.status)
+ body = self.client.create_agent(**params)
self.agent_id = body['agent_id']
def tearDown(self):
@@ -67,8 +66,7 @@
hypervisor='kvm', os='win', architecture='x86',
version='7.0', url='xxx://xxxx/xxx/xxx',
md5hash='add6bb58e139be103324d04d82d8f545')
- resp, body = self.client.create_agent(**params)
- self.assertEqual(200, resp.status)
+ body = self.client.create_agent(**params)
self.addCleanup(self.client.delete_agent, body['agent_id'])
for expected_item, value in params.items():
self.assertEqual(value, body[expected_item])
@@ -79,27 +77,23 @@
params = self._param_helper(
version='8.0', url='xxx://xxxx/xxx/xxx2',
md5hash='add6bb58e139be103324d04d82d8f547')
- resp, body = self.client.update_agent(self.agent_id, **params)
- self.assertEqual(200, resp.status)
+ body = self.client.update_agent(self.agent_id, **params)
for expected_item, value in params.items():
self.assertEqual(value, body[expected_item])
@test.attr(type='gate')
def test_delete_agent(self):
# Delete an agent.
- resp, _ = self.client.delete_agent(self.agent_id)
- self.assertEqual(200, resp.status)
+ self.client.delete_agent(self.agent_id)
# Verify the list doesn't contain the deleted agent.
- resp, agents = self.client.list_agents()
- self.assertEqual(200, resp.status)
+ agents = self.client.list_agents()
self.assertNotIn(self.agent_id, map(lambda x: x['agent_id'], agents))
@test.attr(type='gate')
def test_list_agents(self):
# List all agents.
- resp, agents = self.client.list_agents()
- self.assertEqual(200, resp.status)
+ agents = self.client.list_agents()
self.assertTrue(len(agents) > 0, 'Cannot get any agents.(%s)' % agents)
self.assertIn(self.agent_id, map(lambda x: x['agent_id'], agents))
@@ -110,14 +104,12 @@
hypervisor='xen', os='linux', architecture='x86',
version='7.0', url='xxx://xxxx/xxx/xxx1',
md5hash='add6bb58e139be103324d04d82d8f546')
- resp, agent_xen = self.client.create_agent(**params)
- self.assertEqual(200, resp.status)
+ agent_xen = self.client.create_agent(**params)
self.addCleanup(self.client.delete_agent, agent_xen['agent_id'])
agent_id_xen = agent_xen['agent_id']
params_filter = {'hypervisor': agent_xen['hypervisor']}
- resp, agents = self.client.list_agents(params_filter)
- self.assertEqual(200, resp.status)
+ agents = self.client.list_agents(params_filter)
self.assertTrue(len(agents) > 0, 'Cannot get any agents.(%s)' % agents)
self.assertIn(agent_id_xen, map(lambda x: x['agent_id'], agents))
self.assertNotIn(self.agent_id, map(lambda x: x['agent_id'], agents))
diff --git a/tempest/api/compute/admin/test_aggregates.py b/tempest/api/compute/admin/test_aggregates.py
index 7c2e604..a866ede 100644
--- a/tempest/api/compute/admin/test_aggregates.py
+++ b/tempest/api/compute/admin/test_aggregates.py
@@ -35,7 +35,7 @@
cls.aggregate_name_prefix = 'test_aggregate_'
cls.az_name_prefix = 'test_az_'
- resp, hosts_all = cls.os_adm.hosts_client.list_hosts()
+ hosts_all = cls.os_adm.hosts_client.list_hosts()
hosts = map(lambda x: x['host_name'],
filter(lambda y: y['service'] == 'compute', hosts_all))
cls.host = hosts[0]
@@ -52,14 +52,12 @@
def test_aggregate_create_delete(self):
# Create and delete an aggregate.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = self.client.create_aggregate(name=aggregate_name)
self.addCleanup(self._try_delete_aggregate, aggregate['id'])
- self.assertEqual(200, resp.status)
self.assertEqual(aggregate_name, aggregate['name'])
self.assertIsNone(aggregate['availability_zone'])
- resp, _ = self.client.delete_aggregate(aggregate['id'])
- self.assertEqual(200, resp.status)
+ self.client.delete_aggregate(aggregate['id'])
self.client.wait_for_resource_deletion(aggregate['id'])
@test.attr(type='gate')
@@ -67,26 +65,23 @@
# Create and delete an aggregate.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
az_name = data_utils.rand_name(self.az_name_prefix)
- resp, aggregate = self.client.create_aggregate(
+ aggregate = self.client.create_aggregate(
name=aggregate_name, availability_zone=az_name)
self.addCleanup(self._try_delete_aggregate, aggregate['id'])
- self.assertEqual(200, resp.status)
self.assertEqual(aggregate_name, aggregate['name'])
self.assertEqual(az_name, aggregate['availability_zone'])
- resp, _ = self.client.delete_aggregate(aggregate['id'])
- self.assertEqual(200, resp.status)
+ self.client.delete_aggregate(aggregate['id'])
self.client.wait_for_resource_deletion(aggregate['id'])
@test.attr(type='gate')
def test_aggregate_create_verify_entry_in_list(self):
# Create an aggregate and ensure it is listed.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = self.client.create_aggregate(name=aggregate_name)
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
- resp, aggregates = self.client.list_aggregates()
- self.assertEqual(200, resp.status)
+ aggregates = self.client.list_aggregates()
self.assertIn((aggregate['id'], aggregate['availability_zone']),
map(lambda x: (x['id'], x['availability_zone']),
aggregates))
@@ -95,11 +90,10 @@
def test_aggregate_create_update_metadata_get_details(self):
# Create an aggregate and ensure its details are returned.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = self.client.create_aggregate(name=aggregate_name)
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
- resp, body = self.client.get_aggregate(aggregate['id'])
- self.assertEqual(200, resp.status)
+ body = self.client.get_aggregate(aggregate['id'])
self.assertEqual(aggregate['name'], body['name'])
self.assertEqual(aggregate['availability_zone'],
body['availability_zone'])
@@ -107,13 +101,11 @@
# set the metadata of the aggregate
meta = {"key": "value"}
- resp, body = self.client.set_metadata(aggregate['id'], meta)
- self.assertEqual(200, resp.status)
+ body = self.client.set_metadata(aggregate['id'], meta)
self.assertEqual(meta, body["metadata"])
# verify the metadata has been set
- resp, body = self.client.get_aggregate(aggregate['id'])
- self.assertEqual(200, resp.status)
+ body = self.client.get_aggregate(aggregate['id'])
self.assertEqual(meta, body["metadata"])
@test.attr(type='gate')
@@ -121,11 +113,10 @@
# Update an aggregate and ensure properties are updated correctly
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
az_name = data_utils.rand_name(self.az_name_prefix)
- resp, aggregate = self.client.create_aggregate(
+ aggregate = self.client.create_aggregate(
name=aggregate_name, availability_zone=az_name)
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
- self.assertEqual(200, resp.status)
self.assertEqual(aggregate_name, aggregate['name'])
self.assertEqual(az_name, aggregate['availability_zone'])
self.assertIsNotNone(aggregate['id'])
@@ -134,15 +125,13 @@
new_aggregate_name = aggregate_name + '_new'
new_az_name = az_name + '_new'
- resp, resp_aggregate = self.client.update_aggregate(aggregate_id,
- new_aggregate_name,
- new_az_name)
- self.assertEqual(200, resp.status)
+ resp_aggregate = self.client.update_aggregate(aggregate_id,
+ new_aggregate_name,
+ new_az_name)
self.assertEqual(new_aggregate_name, resp_aggregate['name'])
self.assertEqual(new_az_name, resp_aggregate['availability_zone'])
- resp, aggregates = self.client.list_aggregates()
- self.assertEqual(200, resp.status)
+ aggregates = self.client.list_aggregates()
self.assertIn((aggregate_id, new_aggregate_name, new_az_name),
map(lambda x:
(x['id'], x['name'], x['availability_zone']),
@@ -153,18 +142,16 @@
# Add an host to the given aggregate and remove.
self.useFixture(fixtures.LockFixture('availability_zone'))
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = self.client.create_aggregate(name=aggregate_name)
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
- resp, body = self.client.add_host(aggregate['id'], self.host)
- self.assertEqual(200, resp.status)
+ body = self.client.add_host(aggregate['id'], self.host)
self.assertEqual(aggregate_name, body['name'])
self.assertEqual(aggregate['availability_zone'],
body['availability_zone'])
self.assertIn(self.host, body['hosts'])
- resp, body = self.client.remove_host(aggregate['id'], self.host)
- self.assertEqual(200, resp.status)
+ body = self.client.remove_host(aggregate['id'], self.host)
self.assertEqual(aggregate_name, body['name'])
self.assertEqual(aggregate['availability_zone'],
body['availability_zone'])
@@ -175,12 +162,12 @@
# Add an host to the given aggregate and list.
self.useFixture(fixtures.LockFixture('availability_zone'))
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = self.client.create_aggregate(name=aggregate_name)
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.client.add_host(aggregate['id'], self.host)
self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
- resp, aggregates = self.client.list_aggregates()
+ aggregates = self.client.list_aggregates()
aggs = filter(lambda x: x['id'] == aggregate['id'], aggregates)
self.assertEqual(1, len(aggs))
agg = aggs[0]
@@ -193,12 +180,12 @@
# Add an host to the given aggregate and get details.
self.useFixture(fixtures.LockFixture('availability_zone'))
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = self.client.create_aggregate(name=aggregate_name)
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.client.add_host(aggregate['id'], self.host)
self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
- resp, body = self.client.get_aggregate(aggregate['id'])
+ body = self.client.get_aggregate(aggregate['id'])
self.assertEqual(aggregate_name, body['name'])
self.assertIsNone(body['availability_zone'])
self.assertIn(self.host, body['hosts'])
@@ -209,7 +196,7 @@
self.useFixture(fixtures.LockFixture('availability_zone'))
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
az_name = data_utils.rand_name(self.az_name_prefix)
- resp, aggregate = self.client.create_aggregate(
+ aggregate = self.client.create_aggregate(
name=aggregate_name, availability_zone=az_name)
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.client.add_host(aggregate['id'], self.host)
diff --git a/tempest/api/compute/admin/test_aggregates_negative.py b/tempest/api/compute/admin/test_aggregates_negative.py
index 219d12e..a450e5d 100644
--- a/tempest/api/compute/admin/test_aggregates_negative.py
+++ b/tempest/api/compute/admin/test_aggregates_negative.py
@@ -34,7 +34,7 @@
cls.aggregate_name_prefix = 'test_aggregate_'
cls.az_name_prefix = 'test_az_'
- resp, hosts_all = cls.os_adm.hosts_client.list_hosts()
+ hosts_all = cls.os_adm.hosts_client.list_hosts()
hosts = map(lambda x: x['host_name'],
filter(lambda y: y['service'] == 'compute', hosts_all))
cls.host = hosts[0]
@@ -66,8 +66,7 @@
def test_aggregate_create_with_existent_aggregate_name(self):
# creating an aggregate with existent aggregate name is forbidden
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.assertEqual(200, resp.status)
+ aggregate = self.client.create_aggregate(name=aggregate_name)
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.assertRaises(exceptions.Conflict,
@@ -78,8 +77,7 @@
def test_aggregate_delete_as_user(self):
# Regular user is not allowed to delete an aggregate.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.assertEqual(200, resp.status)
+ aggregate = self.client.create_aggregate(name=aggregate_name)
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.assertRaises(exceptions.Unauthorized,
@@ -96,8 +94,7 @@
def test_aggregate_get_details_as_user(self):
# Regular user is not allowed to get aggregate details.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.assertEqual(200, resp.status)
+ aggregate = self.client.create_aggregate(name=aggregate_name)
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.assertRaises(exceptions.Unauthorized,
@@ -119,7 +116,7 @@
@test.attr(type=['negative', 'gate'])
def test_aggregate_add_non_exist_host(self):
# Adding a non-exist host to an aggregate should raise exceptions.
- resp, hosts_all = self.os_adm.hosts_client.list_hosts()
+ hosts_all = self.os_adm.hosts_client.list_hosts()
hosts = map(lambda x: x['host_name'], hosts_all)
while True:
non_exist_host = data_utils.rand_name('nonexist_host_')
@@ -127,7 +124,7 @@
break
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
+ aggregate = self.client.create_aggregate(name=aggregate_name)
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.assertRaises(exceptions.NotFound, self.client.add_host,
@@ -137,8 +134,7 @@
def test_aggregate_add_host_as_user(self):
# Regular user is not allowed to add a host to an aggregate.
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.assertEqual(200, resp.status)
+ aggregate = self.client.create_aggregate(name=aggregate_name)
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.assertRaises(exceptions.Unauthorized,
@@ -149,12 +145,10 @@
def test_aggregate_add_existent_host(self):
self.useFixture(fixtures.LockFixture('availability_zone'))
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.assertEqual(200, resp.status)
+ aggregate = self.client.create_aggregate(name=aggregate_name)
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
- resp, body = self.client.add_host(aggregate['id'], self.host)
- self.assertEqual(200, resp.status)
+ self.client.add_host(aggregate['id'], self.host)
self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
self.assertRaises(exceptions.Conflict, self.client.add_host,
@@ -165,11 +159,9 @@
# Regular user is not allowed to remove a host from an aggregate.
self.useFixture(fixtures.LockFixture('availability_zone'))
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.assertEqual(200, resp.status)
+ aggregate = self.client.create_aggregate(name=aggregate_name)
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
- resp, body = self.client.add_host(aggregate['id'], self.host)
- self.assertEqual(200, resp.status)
+ self.client.add_host(aggregate['id'], self.host)
self.addCleanup(self.client.remove_host, aggregate['id'], self.host)
self.assertRaises(exceptions.Unauthorized,
@@ -180,8 +172,7 @@
def test_aggregate_remove_nonexistent_host(self):
non_exist_host = data_utils.rand_name('nonexist_host_')
aggregate_name = data_utils.rand_name(self.aggregate_name_prefix)
- resp, aggregate = self.client.create_aggregate(name=aggregate_name)
- self.assertEqual(200, resp.status)
+ aggregate = self.client.create_aggregate(name=aggregate_name)
self.addCleanup(self.client.delete_aggregate, aggregate['id'])
self.assertRaises(exceptions.NotFound, self.client.remove_host,
diff --git a/tempest/api/compute/admin/test_hosts.py b/tempest/api/compute/admin/test_hosts.py
index 25965fd..b9d47bb 100644
--- a/tempest/api/compute/admin/test_hosts.py
+++ b/tempest/api/compute/admin/test_hosts.py
@@ -30,19 +30,17 @@
@test.attr(type='gate')
def test_list_hosts(self):
- resp, hosts = self.client.list_hosts()
- self.assertEqual(200, resp.status)
+ hosts = self.client.list_hosts()
self.assertTrue(len(hosts) >= 2, str(hosts))
@test.attr(type='gate')
def test_list_hosts_with_zone(self):
self.useFixture(fixtures.LockFixture('availability_zone'))
- resp, hosts = self.client.list_hosts()
+ hosts = self.client.list_hosts()
host = hosts[0]
zone_name = host['zone']
params = {'zone': zone_name}
- resp, hosts = self.client.list_hosts(params)
- self.assertEqual(200, resp.status)
+ hosts = self.client.list_hosts(params)
self.assertTrue(len(hosts) >= 1)
self.assertIn(host, hosts)
@@ -51,31 +49,27 @@
# If send the request with a blank zone, the request will be successful
# and it will return all the hosts list
params = {'zone': ''}
- resp, hosts = self.client.list_hosts(params)
+ hosts = self.client.list_hosts(params)
self.assertNotEqual(0, len(hosts))
- self.assertEqual(200, resp.status)
@test.attr(type='gate')
def test_list_hosts_with_nonexistent_zone(self):
# If send the request with a nonexistent zone, the request will be
# successful and no hosts will be retured
params = {'zone': 'xxx'}
- resp, hosts = self.client.list_hosts(params)
+ hosts = self.client.list_hosts(params)
self.assertEqual(0, len(hosts))
- self.assertEqual(200, resp.status)
@test.attr(type='gate')
def test_show_host_detail(self):
- resp, hosts = self.client.list_hosts()
- self.assertEqual(200, resp.status)
+ hosts = self.client.list_hosts()
hosts = [host for host in hosts if host['service'] == 'compute']
self.assertTrue(len(hosts) >= 1)
for host in hosts:
hostname = host['host_name']
- resp, resources = self.client.show_host_detail(hostname)
- self.assertEqual(200, resp.status)
+ resources = self.client.show_host_detail(hostname)
self.assertTrue(len(resources) >= 1)
host_resource = resources[0]['resource']
self.assertIsNotNone(host_resource)
diff --git a/tempest/api/compute/admin/test_hosts_negative.py b/tempest/api/compute/admin/test_hosts_negative.py
index 055219f..fc918a3 100644
--- a/tempest/api/compute/admin/test_hosts_negative.py
+++ b/tempest/api/compute/admin/test_hosts_negative.py
@@ -31,8 +31,7 @@
cls.non_admin_client = cls.os.hosts_client
def _get_host_name(self):
- resp, hosts = self.client.list_hosts()
- self.assertEqual(200, resp.status)
+ hosts = self.client.list_hosts()
self.assertTrue(len(hosts) >= 1)
hostname = hosts[0]['host_name']
return hostname
diff --git a/tempest/api/compute/admin/test_hypervisor.py b/tempest/api/compute/admin/test_hypervisor.py
index de3debb..fbfef87 100644
--- a/tempest/api/compute/admin/test_hypervisor.py
+++ b/tempest/api/compute/admin/test_hypervisor.py
@@ -30,8 +30,7 @@
def _list_hypervisors(self):
# List of hypervisors
- resp, hypers = self.client.get_hypervisor_list()
- self.assertEqual(200, resp.status)
+ hypers = self.client.get_hypervisor_list()
return hypers
def assertHypervisors(self, hypers):
@@ -46,8 +45,7 @@
@test.attr(type='gate')
def test_get_hypervisor_list_details(self):
# Display the details of the all hypervisor
- resp, hypers = self.client.get_hypervisor_list_details()
- self.assertEqual(200, resp.status)
+ hypers = self.client.get_hypervisor_list_details()
self.assertHypervisors(hypers)
@test.attr(type='gate')
@@ -56,9 +54,7 @@
hypers = self._list_hypervisors()
self.assertHypervisors(hypers)
- resp, details = (self.client.
- get_hypervisor_show_details(hypers[0]['id']))
- self.assertEqual(200, resp.status)
+ details = self.client.get_hypervisor_show_details(hypers[0]['id'])
self.assertTrue(len(details) > 0)
self.assertEqual(details['hypervisor_hostname'],
hypers[0]['hypervisor_hostname'])
@@ -70,15 +66,13 @@
self.assertHypervisors(hypers)
hostname = hypers[0]['hypervisor_hostname']
- resp, hypervisors = self.client.get_hypervisor_servers(hostname)
- self.assertEqual(200, resp.status)
+ hypervisors = self.client.get_hypervisor_servers(hostname)
self.assertTrue(len(hypervisors) > 0)
@test.attr(type='gate')
def test_get_hypervisor_stats(self):
# Verify the stats of the all hypervisor
- resp, stats = self.client.get_hypervisor_stats()
- self.assertEqual(200, resp.status)
+ stats = self.client.get_hypervisor_stats()
self.assertTrue(len(stats) > 0)
@test.attr(type='gate')
@@ -94,9 +88,7 @@
ironic_only = True
hypers_without_ironic = []
for hyper in hypers:
- resp, details = (self.client.
- get_hypervisor_show_details(hypers[0]['id']))
- self.assertEqual(200, resp.status)
+ details = self.client.get_hypervisor_show_details(hypers[0]['id'])
if details['hypervisor_type'] != 'ironic':
hypers_without_ironic.append(hyper)
ironic_only = False
@@ -110,8 +102,8 @@
# because hypervisors might be disabled, this loops looking
# for any good hit.
try:
- resp, uptime = self.client.get_hypervisor_uptime(hyper['id'])
- if (resp.status == 200) and (len(uptime) > 0):
+ uptime = self.client.get_hypervisor_uptime(hyper['id'])
+ if len(uptime) > 0:
has_valid_uptime = True
break
except Exception:
@@ -124,7 +116,6 @@
def test_search_hypervisor(self):
hypers = self._list_hypervisors()
self.assertHypervisors(hypers)
- resp, hypers = self.client.search_hypervisor(
+ hypers = self.client.search_hypervisor(
hypers[0]['hypervisor_hostname'])
- self.assertEqual(200, resp.status)
self.assertHypervisors(hypers)
diff --git a/tempest/api/compute/admin/test_hypervisor_negative.py b/tempest/api/compute/admin/test_hypervisor_negative.py
index b1f2351..a137a61 100644
--- a/tempest/api/compute/admin/test_hypervisor_negative.py
+++ b/tempest/api/compute/admin/test_hypervisor_negative.py
@@ -35,8 +35,7 @@
def _list_hypervisors(self):
# List of hypervisors
- resp, hypers = self.client.get_hypervisor_list()
- self.assertEqual(200, resp.status)
+ hypers = self.client.get_hypervisor_list()
return hypers
@test.attr(type=['negative', 'gate'])
diff --git a/tempest/api/compute/admin/test_services.py b/tempest/api/compute/admin/test_services.py
index e7a39f8..5cf4a31 100644
--- a/tempest/api/compute/admin/test_services.py
+++ b/tempest/api/compute/admin/test_services.py
@@ -31,29 +31,27 @@
@test.attr(type='gate')
def test_list_services(self):
- resp, services = self.client.list_services()
- self.assertEqual(200, resp.status)
+ services = self.client.list_services()
self.assertNotEqual(0, len(services))
@test.attr(type='gate')
def test_get_service_by_service_binary_name(self):
binary_name = 'nova-compute'
params = {'binary': binary_name}
- resp, services = self.client.list_services(params)
- self.assertEqual(200, resp.status)
+ services = self.client.list_services(params)
self.assertNotEqual(0, len(services))
for service in services:
self.assertEqual(binary_name, service['binary'])
@test.attr(type='gate')
def test_get_service_by_host_name(self):
- resp, services = self.client.list_services()
+ services = self.client.list_services()
host_name = services[0]['host']
services_on_host = [service for service in services if
service['host'] == host_name]
params = {'host': host_name}
- resp, services = self.client.list_services(params)
+ services = self.client.list_services(params)
# we could have a periodic job checkin between the 2 service
# lookups, so only compare binary lists.
@@ -66,13 +64,12 @@
@test.attr(type='gate')
def test_get_service_by_service_and_host_name(self):
- resp, services = self.client.list_services()
+ services = self.client.list_services()
host_name = services[0]['host']
binary_name = services[0]['binary']
params = {'host': host_name, 'binary': binary_name}
- resp, services = self.client.list_services(params)
- self.assertEqual(200, resp.status)
+ services = self.client.list_services(params)
self.assertEqual(1, len(services))
self.assertEqual(host_name, services[0]['host'])
self.assertEqual(binary_name, services[0]['binary'])
diff --git a/tempest/api/compute/admin/test_services_negative.py b/tempest/api/compute/admin/test_services_negative.py
index 534afc5..bb19a39 100644
--- a/tempest/api/compute/admin/test_services_negative.py
+++ b/tempest/api/compute/admin/test_services_negative.py
@@ -37,26 +37,23 @@
@test.attr(type=['negative', 'gate'])
def test_get_service_by_invalid_params(self):
# return all services if send the request with invalid parameter
- resp, services = self.client.list_services()
+ services = self.client.list_services()
params = {'xxx': 'nova-compute'}
- resp, services_xxx = self.client.list_services(params)
- self.assertEqual(200, resp.status)
+ services_xxx = self.client.list_services(params)
self.assertEqual(len(services), len(services_xxx))
@test.attr(type=['negative', 'gate'])
def test_get_service_by_invalid_service_and_valid_host(self):
- resp, services = self.client.list_services()
+ services = self.client.list_services()
host_name = services[0]['host']
params = {'host': host_name, 'binary': 'xxx'}
- resp, services = self.client.list_services(params)
- self.assertEqual(200, resp.status)
+ services = self.client.list_services(params)
self.assertEqual(0, len(services))
@test.attr(type=['negative', 'gate'])
def test_get_service_with_valid_service_and_invalid_host(self):
- resp, services = self.client.list_services()
+ services = self.client.list_services()
binary_name = services[0]['binary']
params = {'host': 'xxx', 'binary': binary_name}
- resp, services = self.client.list_services(params)
- self.assertEqual(200, resp.status)
+ services = self.client.list_services(params)
self.assertEqual(0, len(services))
diff --git a/tempest/api/compute/test_live_block_migration.py b/tempest/api/compute/test_live_block_migration.py
index cb75d07..e04439f 100644
--- a/tempest/api/compute/test_live_block_migration.py
+++ b/tempest/api/compute/test_live_block_migration.py
@@ -36,7 +36,7 @@
cls.created_server_ids = []
def _get_compute_hostnames(self):
- _resp, body = self.admin_hosts_client.list_hosts()
+ body = self.admin_hosts_client.list_hosts()
return [
host_record['host_name']
for host_record in body
diff --git a/tempest/api/network/test_networks.py b/tempest/api/network/test_networks.py
index e70519e..65aeb24 100644
--- a/tempest/api/network/test_networks.py
+++ b/tempest/api/network/test_networks.py
@@ -15,7 +15,6 @@
import itertools
import netaddr
-import testtools
from tempest.api.network import base
from tempest.common import custom_matchers
@@ -571,9 +570,16 @@
test_subnet_ids,
'Subnet are not in the same network')
- @testtools.skipUnless(CONF.network_feature_enabled.ipv6_subnet_attributes,
- "IPv6 extended attributes for subnets not "
- "available")
+
+class NetworksIpV6TestAttrs(NetworksIpV6TestJSON):
+
+ @classmethod
+ def resource_setup(cls):
+ if not CONF.network_feature_enabled.ipv6_subnet_attributes:
+ raise cls.skipException("IPv6 extended attributes for "
+ "subnets not available")
+ super(NetworksIpV6TestAttrs, cls).resource_setup()
+
@test.attr(type='smoke')
def test_create_delete_subnet_with_v6_attributes_stateful(self):
self._create_verify_delete_subnet(
@@ -581,20 +587,54 @@
ipv6_ra_mode='dhcpv6-stateful',
ipv6_address_mode='dhcpv6-stateful')
- @testtools.skipUnless(CONF.network_feature_enabled.ipv6_subnet_attributes,
- "IPv6 extended attributes for subnets not "
- "available")
@test.attr(type='smoke')
def test_create_delete_subnet_with_v6_attributes_slaac(self):
self._create_verify_delete_subnet(
ipv6_ra_mode='slaac',
ipv6_address_mode='slaac')
- @testtools.skipUnless(CONF.network_feature_enabled.ipv6_subnet_attributes,
- "IPv6 extended attributes for subnets not "
- "available")
@test.attr(type='smoke')
def test_create_delete_subnet_with_v6_attributes_stateless(self):
self._create_verify_delete_subnet(
ipv6_ra_mode='dhcpv6-stateless',
ipv6_address_mode='dhcpv6-stateless')
+
+ def _test_delete_subnet_with_ports(self, mode):
+ """Create subnet and delete it with existing ports"""
+ slaac_network = self.create_network()
+ subnet_slaac = self.create_subnet(slaac_network,
+ **{'ipv6_ra_mode': mode,
+ 'ipv6_address_mode': mode})
+ port = self.create_port(slaac_network)
+ self.assertIsNotNone(port['fixed_ips'][0]['ip_address'])
+ self.client.delete_subnet(subnet_slaac['id'])
+ self.subnets.pop()
+ subnets = self.client.list_subnets()
+ subnet_ids = [subnet['id'] for subnet in subnets['subnets']]
+ self.assertNotIn(subnet_slaac['id'], subnet_ids,
+ "Subnet wasn't deleted")
+ self.assertRaisesRegexp(
+ exceptions.Conflict,
+ "There are one or more ports still in use on the network",
+ self.client.delete_network,
+ slaac_network['id'])
+
+ @test.attr(type='smoke')
+ def test_create_delete_slaac_subnet_with_ports(self):
+ """Test deleting subnet with SLAAC ports
+
+ Create subnet with SLAAC, create ports in network
+ and then you shall be able to delete subnet without port
+ deletion. But you still can not delete the network.
+ """
+ self._test_delete_subnet_with_ports("slaac")
+
+ @test.attr(type='smoke')
+ def test_create_delete_stateless_subnet_with_ports(self):
+ """Test deleting subnet with DHCPv6 stateless ports
+
+ Create subnet with DHCPv6 stateless, create ports in network
+ and then you shall be able to delete subnet without port
+ deletion. But you still can not delete the network.
+ """
+ self._test_delete_subnet_with_ports("dhcpv6-stateless")
diff --git a/tempest/api/network/test_ports.py b/tempest/api/network/test_ports.py
index ee0e4c8..bf85e90 100644
--- a/tempest/api/network/test_ports.py
+++ b/tempest/api/network/test_ports.py
@@ -17,6 +17,7 @@
import socket
from tempest.api.network import base
+from tempest.api.network import base_security_groups as sec_base
from tempest.common import custom_matchers
from tempest.common.utils import data_utils
from tempest import config
@@ -25,7 +26,7 @@
CONF = config.CONF
-class PortsTestJSON(base.BaseNetworkTest):
+class PortsTestJSON(sec_base.BaseSecGroupTest):
_interface = 'json'
"""
@@ -102,7 +103,8 @@
address = self._get_ipaddress_from_tempest_conf()
allocation_pools = {'allocation_pools': [{'start': str(address + 4),
'end': str(address + 6)}]}
- self.create_subnet(network, **allocation_pools)
+ subnet = self.create_subnet(network, **allocation_pools)
+ self.addCleanup(self.client.delete_subnet, subnet['id'])
body = self.client.create_port(network_id=net_id)
self.addCleanup(self.client.delete_port, body['port']['id'])
port = body['port']
@@ -148,8 +150,11 @@
def test_port_list_filter_by_router_id(self):
# Create a router
network = self.create_network()
- self.create_subnet(network)
+ self.addCleanup(self.client.delete_network, network['id'])
+ subnet = self.create_subnet(network)
+ self.addCleanup(self.client.delete_subnet, subnet['id'])
router = self.create_router(data_utils.rand_name('router-'))
+ self.addCleanup(self.client.delete_router, router['id'])
port = self.client.create_port(network_id=network['id'])
# Add router interface to port created above
self.client.add_router_interface_with_port_id(
@@ -175,31 +180,41 @@
self.assertEqual(sorted(fields), sorted(port.keys()))
@test.attr(type='smoke')
- def test_update_port_with_second_ip(self):
+ def test_create_update_port_with_second_ip(self):
# Create a network with two subnets
network = self.create_network()
+ self.addCleanup(self.client.delete_network, network['id'])
subnet_1 = self.create_subnet(network)
+ self.addCleanup(self.client.delete_subnet, subnet_1['id'])
subnet_2 = self.create_subnet(network)
+ self.addCleanup(self.client.delete_subnet, subnet_2['id'])
fixed_ip_1 = [{'subnet_id': subnet_1['id']}]
fixed_ip_2 = [{'subnet_id': subnet_2['id']}]
- # Create a port with a single IP address from first subnet
- port = self.create_port(network,
- fixed_ips=fixed_ip_1)
- self.assertEqual(1, len(port['fixed_ips']))
-
- # Update the port with a second IP address from second subnet
fixed_ips = fixed_ip_1 + fixed_ip_2
- port = self.update_port(port, fixed_ips=fixed_ips)
+
+ # Create a port with multiple IP addresses
+ port = self.create_port(network,
+ fixed_ips=fixed_ips)
+ self.addCleanup(self.client.delete_port, port['id'])
self.assertEqual(2, len(port['fixed_ips']))
+ check_fixed_ips = [subnet_1['id'], subnet_2['id']]
+ for item in port['fixed_ips']:
+ self.assertIn(item['subnet_id'], check_fixed_ips)
# Update the port to return to a single IP address
port = self.update_port(port, fixed_ips=fixed_ip_1)
self.assertEqual(1, len(port['fixed_ips']))
+ # Update the port with a second IP address from second subnet
+ port = self.update_port(port, fixed_ips=fixed_ips)
+ self.assertEqual(2, len(port['fixed_ips']))
+
def _update_port_with_security_groups(self, security_groups_names):
- post_body = {"network_id": self.network['id']}
- self.create_subnet(self.network)
+ subnet_1 = self.create_subnet(self.network)
+ self.addCleanup(self.client.delete_subnet, subnet_1['id'])
+ fixed_ip_1 = [{'subnet_id': subnet_1['id']}]
+
security_groups_list = list()
for name in security_groups_names:
group_create_body = self.client.create_security_group(
@@ -209,24 +224,48 @@
security_groups_list.append(group_create_body['security_group']
['id'])
# Create a port
+ sec_grp_name = data_utils.rand_name('secgroup')
+ security_group = self.client.create_security_group(name=sec_grp_name)
+ self.addCleanup(self.client.delete_security_group,
+ security_group['security_group']['id'])
+ post_body = {
+ "name": data_utils.rand_name('port-'),
+ "security_groups": [security_group['security_group']['id']],
+ "network_id": self.network['id'],
+ "admin_state_up": True,
+ "fixed_ips": fixed_ip_1}
body = self.client.create_port(**post_body)
self.addCleanup(self.client.delete_port, body['port']['id'])
port = body['port']
+
# Update the port with security groups
- update_body = {"security_groups": security_groups_list}
+ subnet_2 = self.create_subnet(self.network)
+ fixed_ip_2 = [{'subnet_id': subnet_2['id']}]
+ update_body = {"name": data_utils.rand_name('port-'),
+ "admin_state_up": False,
+ "fixed_ips": fixed_ip_2,
+ "security_groups": security_groups_list}
body = self.client.update_port(port['id'], **update_body)
- # Verify the security groups updated to port
port_show = body['port']
+ # Verify the security groups and other attributes updated to port
+ exclude_keys = set(port_show).symmetric_difference(update_body)
+ exclude_keys.add('fixed_ips')
+ exclude_keys.add('security_groups')
+ self.assertThat(port_show, custom_matchers.MatchesDictExceptForKeys(
+ update_body, exclude_keys))
+ self.assertEqual(fixed_ip_2[0]['subnet_id'],
+ port_show['fixed_ips'][0]['subnet_id'])
+
for security_group in security_groups_list:
self.assertIn(security_group, port_show['security_groups'])
@test.attr(type='smoke')
- def test_update_port_with_security_group(self):
+ def test_update_port_with_security_group_and_extra_attributes(self):
self._update_port_with_security_groups(
[data_utils.rand_name('secgroup')])
@test.attr(type='smoke')
- def test_update_port_with_two_security_groups(self):
+ def test_update_port_with_two_security_groups_and_extra_attributes(self):
self._update_port_with_security_groups(
[data_utils.rand_name('secgroup'),
data_utils.rand_name('secgroup')])
@@ -251,23 +290,14 @@
@test.attr(type='smoke')
def test_create_port_with_no_securitygroups(self):
network = self.create_network()
- self.create_subnet(network)
+ self.addCleanup(self.client.delete_network, network['id'])
+ subnet = self.create_subnet(network)
+ self.addCleanup(self.client.delete_subnet, subnet['id'])
port = self.create_port(network, security_groups=[])
+ self.addCleanup(self.client.delete_port, port['id'])
self.assertIsNotNone(port['security_groups'])
self.assertEmpty(port['security_groups'])
- @test.attr(type='smoke')
- def test_update_port_with_no_securitygroups(self):
- network = self.create_network()
- self.create_subnet(network)
- port = self.create_port(network)
- # Verify that port is created with default security group
- self.assertIsNotNone(port['security_groups'])
- self.assertNotEmpty(port['security_groups'])
- updated_port = self.update_port(port, security_groups=[])
- self.assertIsNotNone(updated_port['security_groups'])
- self.assertEmpty(updated_port['security_groups'])
-
class PortsAdminExtendedAttrsTestJSON(base.BaseAdminNetworkTest):
_interface = 'json'
diff --git a/tempest/clients.py b/tempest/clients.py
index 8d59742..de03f1d 100644
--- a/tempest/clients.py
+++ b/tempest/clients.py
@@ -139,9 +139,9 @@
# super cares for credentials validation
super(Manager, self).__init__(credentials=credentials)
- self._set_compute_clients(self.interface)
- self._set_identity_clients(self.interface)
- self._set_volume_clients(self.interface)
+ self._set_compute_clients()
+ self._set_identity_clients()
+ self._set_volume_clients()
self.baremetal_client = BaremetalClientJSON(self.auth_provider)
self.network_client = NetworkClientJSON(self.auth_provider)
@@ -176,17 +176,12 @@
self.data_processing_client = DataProcessingClient(
self.auth_provider)
- def _set_compute_clients(self, type):
- self._set_compute_json_clients()
-
- # Common compute clients
+ def _set_compute_clients(self):
self.agents_client = AgentsClientJSON(self.auth_provider)
self.networks_client = NetworksClientJSON(self.auth_provider)
self.migrations_client = MigrationsClientJSON(self.auth_provider)
self.security_group_default_rules_client = (
SecurityGroupDefaultRulesClientJSON(self.auth_provider))
-
- def _set_compute_json_clients(self):
self.certificates_client = CertificatesClientJSON(self.auth_provider)
self.servers_client = ServersClientJSON(self.auth_provider)
self.limits_client = LimitsClientJSON(self.auth_provider)
@@ -213,10 +208,7 @@
self.instance_usages_audit_log_client = \
InstanceUsagesAuditLogClientJSON(self.auth_provider)
- def _set_identity_clients(self, type):
- self._set_identity_json_clients()
-
- def _set_identity_json_clients(self):
+ def _set_identity_clients(self):
self.identity_client = IdentityClientJSON(self.auth_provider)
self.identity_v3_client = IdentityV3ClientJSON(self.auth_provider)
self.endpoints_client = EndPointClientJSON(self.auth_provider)
@@ -228,20 +220,12 @@
self.token_v3_client = V3TokenClientJSON()
self.credentials_client = CredentialsClientJSON(self.auth_provider)
- def _set_volume_clients(self, type):
- self._set_volume_json_clients()
- # Common volume clients
- # NOTE : As XML clients are not implemented for Qos-specs.
- # So, setting the qos_client here. Once client are implemented,
- # qos_client would be moved to its respective if/else.
- # Bug : 1312553
+ def _set_volume_clients(self):
self.volume_qos_client = QosSpecsClientJSON(self.auth_provider)
self.volume_qos_v2_client = QosSpecsV2ClientJSON(
self.auth_provider)
self.volume_services_v2_client = VolumesServicesV2ClientJSON(
self.auth_provider)
-
- def _set_volume_json_clients(self):
self.backups_client = BackupsClientJSON(self.auth_provider)
self.backups_v2_client = BackupsClientV2JSON(self.auth_provider)
self.snapshots_client = SnapshotsClientJSON(self.auth_provider)
diff --git a/tempest/common/isolated_creds.py b/tempest/common/isolated_creds.py
index e7590b7..a663931 100644
--- a/tempest/common/isolated_creds.py
+++ b/tempest/common/isolated_creds.py
@@ -124,7 +124,7 @@
self._assign_user_role(tenant, user, swift_operator_role)
if admin:
self._assign_user_role(tenant, user, CONF.identity.admin_role)
- for role in CONF.identity.tempest_roles:
+ for role in CONF.auth.tempest_roles:
self._assign_user_role(tenant, user, role)
return self._get_credentials(user, tenant)
diff --git a/tempest/common/utils/linux/remote_client.py b/tempest/common/utils/linux/remote_client.py
index d8bfef8..6e61c55 100644
--- a/tempest/common/utils/linux/remote_client.py
+++ b/tempest/common/utils/linux/remote_client.py
@@ -97,6 +97,10 @@
cmd = "/bin/ip addr | awk '/ether/ {print $2}'"
return self.exec_command(cmd)
+ def get_nic_name(self, address):
+ cmd = "/bin/ip -o addr | awk '/%s/ {print $2}'" % address
+ return self.exec_command(cmd)
+
def get_ip_list(self):
cmd = "/bin/ip address"
return self.exec_command(cmd)
@@ -116,3 +120,47 @@
# Get pid(s) of a process/program
cmd = "ps -ef | grep %s | grep -v 'grep' | awk {'print $1'}" % pr_name
return self.exec_command(cmd).split('\n')
+
+ def get_dns_servers(self):
+ cmd = 'cat /etc/resolv.conf'
+ resolve_file = self.exec_command(cmd).strip().split('\n')
+ entries = (l.split() for l in resolve_file)
+ dns_servers = [l[1] for l in entries
+ if len(l) and l[0] == 'nameserver']
+ return dns_servers
+
+ def send_signal(self, pid, signum):
+ cmd = 'sudo /bin/kill -{sig} {pid}'.format(pid=pid, sig=signum)
+ return self.exec_command(cmd)
+
+ def _renew_lease_udhcpc(self, fixed_ip=None):
+ """Renews DHCP lease via udhcpc client. """
+ file_path = '/var/run/udhcpc.'
+ nic_name = self.get_nic_name(fixed_ip)
+ nic_name = nic_name.strip().lower()
+ pid = self.exec_command('cat {path}{nic}.pid'.
+ format(path=file_path, nic=nic_name))
+ pid = pid.strip()
+ self.send_signal(pid, 'USR1')
+
+ def _renew_lease_dhclient(self, fixed_ip=None):
+ """Renews DHCP lease via dhclient client. """
+ cmd = "sudo /sbin/dhclient -r && /sbin/dhclient"
+ self.exec_command(cmd)
+
+ def renew_lease(self, fixed_ip=None):
+ """Wrapper method for renewing DHCP lease via given client
+
+ Supporting:
+ * udhcpc
+ * dhclient
+ """
+ # TODO(yfried): add support for dhcpcd
+ suported_clients = ['udhcpc', 'dhclient']
+ dhcp_client = CONF.scenario.dhcp_client
+ if dhcp_client not in suported_clients:
+ raise exceptions.InvalidConfiguration('%s DHCP client unsupported'
+ % dhcp_client)
+ if dhcp_client == 'udhcpc' and not fixed_ip:
+ raise ValueError("need to set 'fixed_ip' for udhcpc client")
+ return getattr(self, '_renew_lease_' + dhcp_client)(fixed_ip=fixed_ip)
\ No newline at end of file
diff --git a/tempest/config.py b/tempest/config.py
index 4858fda..dd693e5 100644
--- a/tempest/config.py
+++ b/tempest/config.py
@@ -59,6 +59,9 @@
"It requires at least `2 * CONC` distinct accounts "
"configured in `test_accounts_file`, with CONC == the "
"number of concurrent test processes."),
+ cfg.ListOpt('tempest_roles',
+ help="Roles to assign to all users created by tempest",
+ default=[])
]
identity_group = cfg.OptGroup(name='identity',
@@ -131,9 +134,6 @@
cfg.StrOpt('admin_domain_name',
help="Admin domain name for authentication (Keystone V3)."
"The same domain applies to user and project"),
- cfg.ListOpt('tempest_roles',
- help="Roles to assign to all users created by tempest",
- default=[])
]
identity_feature_group = cfg.OptGroup(name='identity-feature-enabled',
@@ -860,7 +860,14 @@
'large_ops_number',
default=0,
help="specifies how many resources to request at once. Used "
- "for large operations testing.")
+ "for large operations testing."),
+ # TODO(yfried): add support for dhcpcd
+ cfg.StrOpt('dhcp_client',
+ default='udhcpc',
+ choices=["udhcpc", "dhclient"],
+ help='DHCP client used by images to renew DCHP lease. '
+ 'If left empty, update operation will be skipped. '
+ 'Supported clients: "udhcpc", "dhclient"')
]
diff --git a/tempest/scenario/manager.py b/tempest/scenario/manager.py
index 220a7e7..1fdd26a 100644
--- a/tempest/scenario/manager.py
+++ b/tempest/scenario/manager.py
@@ -1012,12 +1012,16 @@
router.update(admin_state_up=admin_state_up)
self.assertEqual(admin_state_up, router.admin_state_up)
- def create_networks(self, client=None, tenant_id=None):
+ def create_networks(self, client=None, tenant_id=None,
+ dns_nameservers=None):
"""Create a network with a subnet connected to a router.
The baremetal driver is a special case since all nodes are
on the same shared network.
+ :param client: network client to create resources with.
+ :param tenant_id: id of tenant to create resources in.
+ :param dns_nameservers: list of dns servers to send to subnet.
:returns: network, subnet, router
"""
if CONF.baremetal.driver_enabled:
@@ -1033,7 +1037,12 @@
else:
network = self._create_network(client=client, tenant_id=tenant_id)
router = self._get_router(client=client, tenant_id=tenant_id)
- subnet = self._create_subnet(network=network, client=client)
+
+ subnet_kwargs = dict(network=network, client=client)
+ # use explicit check because empty list is a valid option
+ if dns_nameservers is not None:
+ subnet_kwargs['dns_nameservers'] = dns_nameservers
+ subnet = self._create_subnet(**subnet_kwargs)
subnet.add_to_router(router.id)
return network, subnet, router
diff --git a/tempest/scenario/test_aggregates_basic_ops.py b/tempest/scenario/test_aggregates_basic_ops.py
index 75769ce..469ac4a 100644
--- a/tempest/scenario/test_aggregates_basic_ops.py
+++ b/tempest/scenario/test_aggregates_basic_ops.py
@@ -43,7 +43,7 @@
return cls.admin_credentials()
def _create_aggregate(self, **kwargs):
- _, aggregate = self.aggregates_client.create_aggregate(**kwargs)
+ aggregate = self.aggregates_client.create_aggregate(**kwargs)
self.addCleanup(self._delete_aggregate, aggregate)
aggregate_name = kwargs['name']
availability_zone = kwargs['availability_zone']
@@ -55,23 +55,23 @@
self.aggregates_client.delete_aggregate(aggregate['id'])
def _get_host_name(self):
- _, hosts = self.hosts_client.list_hosts()
+ hosts = self.hosts_client.list_hosts()
self.assertTrue(len(hosts) >= 1)
computes = [x for x in hosts if x['service'] == 'compute']
return computes[0]['host_name']
def _add_host(self, aggregate_id, host):
- _, aggregate = self.aggregates_client.add_host(aggregate_id, host)
+ aggregate = self.aggregates_client.add_host(aggregate_id, host)
self.addCleanup(self._remove_host, aggregate['id'], host)
self.assertIn(host, aggregate['hosts'])
def _remove_host(self, aggregate_id, host):
- _, aggregate = self.aggregates_client.remove_host(aggregate_id, host)
+ aggregate = self.aggregates_client.remove_host(aggregate_id, host)
self.assertNotIn(host, aggregate['hosts'])
def _check_aggregate_details(self, aggregate, aggregate_name, azone,
hosts, metadata):
- _, aggregate = self.aggregates_client.get_aggregate(aggregate['id'])
+ aggregate = self.aggregates_client.get_aggregate(aggregate['id'])
self.assertEqual(aggregate_name, aggregate['name'])
self.assertEqual(azone, aggregate['availability_zone'])
self.assertEqual(hosts, aggregate['hosts'])
@@ -81,15 +81,15 @@
aggregate['metadata'][meta_key])
def _set_aggregate_metadata(self, aggregate, meta):
- _, aggregate = self.aggregates_client.set_metadata(aggregate['id'],
- meta)
+ aggregate = self.aggregates_client.set_metadata(aggregate['id'],
+ meta)
for key, value in meta.items():
self.assertEqual(meta[key], aggregate['metadata'][key])
def _update_aggregate(self, aggregate, aggregate_name,
availability_zone):
- _, aggregate = self.aggregates_client.update_aggregate(
+ aggregate = self.aggregates_client.update_aggregate(
aggregate['id'], name=aggregate_name,
availability_zone=availability_zone)
self.assertEqual(aggregate['name'], aggregate_name)
diff --git a/tempest/scenario/test_network_basic_ops.py b/tempest/scenario/test_network_basic_ops.py
index 30c3b9d..2cfec14 100644
--- a/tempest/scenario/test_network_basic_ops.py
+++ b/tempest/scenario/test_network_basic_ops.py
@@ -100,10 +100,10 @@
self.keypairs = {}
self.servers = []
- def _setup_network_and_servers(self):
+ def _setup_network_and_servers(self, **kwargs):
self.security_group = \
self._create_security_group(tenant_id=self.tenant_id)
- self.network, self.subnet, self.router = self.create_networks()
+ self.network, self.subnet, self.router = self.create_networks(**kwargs)
self.check_networks()
name = data_utils.rand_name('server-smoke')
@@ -425,3 +425,62 @@
self.check_public_network_connectivity(
should_connect=True, msg="after updating "
"admin_state_up of router to True")
+
+ def _check_dns_server(self, ssh_client, dns_servers):
+ servers = ssh_client.get_dns_servers()
+ self.assertEqual(set(dns_servers), set(servers),
+ 'Looking for servers: {trgt_serv}. '
+ 'Retrieved DNS nameservers: {act_serv} '
+ 'From host: {host}.'
+ .format(host=ssh_client.ssh_client.host,
+ act_serv=servers,
+ trgt_serv=dns_servers))
+
+ @testtools.skipUnless(CONF.scenario.dhcp_client,
+ "DHCP client is not available.")
+ @test.attr(type='smoke')
+ @test.services('compute', 'network')
+ def test_subnet_details(self):
+ """Tests that subnet's extra configuration details are affecting
+ the VMs
+
+ NOTE: Neutron subnets push data to servers via dhcp-agent, so any
+ update in subnet requires server to actively renew its DHCP lease.
+
+ 1. Configure subnet with dns nameserver
+ 2. retrieve the VM's configured dns and verify it matches the one
+ configured for the subnet.
+ 3. update subnet's dns
+ 4. retrieve the VM's configured dns and verify it matches the new one
+ configured for the subnet.
+
+ TODO(yfried): add host_routes
+
+ any resolution check would be testing either:
+ * l3 forwarding (tested in test_network_basic_ops)
+ * Name resolution of an external DNS nameserver - out of scope for
+ Tempest
+ """
+ # this test check only updates (no actual resolution) so using
+ # arbitrary ip addresses as nameservers, instead of parsing CONF
+ initial_dns_server = '1.2.3.4'
+ alt_dns_server = '9.8.7.6'
+ self._setup_network_and_servers(dns_nameservers=[initial_dns_server])
+ self.check_public_network_connectivity(should_connect=True)
+
+ floating_ip, server = self.floating_ip_tuple
+ ip_address = floating_ip.floating_ip_address
+ private_key = self._get_server_key(server)
+ ssh_client = self._ssh_to_server(ip_address, private_key)
+
+ self._check_dns_server(ssh_client, [initial_dns_server])
+
+ self.subnet.update(dns_nameservers=[alt_dns_server])
+ # asserts that Neutron DB has updated the nameservers
+ self.assertEqual([alt_dns_server], self.subnet.dns_nameservers,
+ "Failed to update subnet's nameservers")
+
+ # server needs to renew its dhcp lease in order to get the new dns
+ # definitions from subnet
+ ssh_client.renew_lease(fixed_ip=floating_ip['fixed_ip_address'])
+ self._check_dns_server(ssh_client, [alt_dns_server])
diff --git a/tempest/services/compute/json/agents_client.py b/tempest/services/compute/json/agents_client.py
index eacd367..95d7880 100644
--- a/tempest/services/compute/json/agents_client.py
+++ b/tempest/services/compute/json/agents_client.py
@@ -17,6 +17,7 @@
from tempest.api_schema.response.compute import agents as common_schema
from tempest.api_schema.response.compute.v2 import agents as schema
+from tempest.common import service_client
from tempest.services.compute.json import base
@@ -33,7 +34,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(common_schema.list_agents, resp, body)
- return resp, body['agents']
+ return service_client.ResponseBodyList(resp, body['agents'])
def create_agent(self, **kwargs):
"""Create an agent build."""
@@ -41,16 +42,16 @@
resp, body = self.post('os-agents', post_body)
body = json.loads(body)
self.validate_response(schema.create_agent, resp, body)
- return resp, body['agent']
+ return service_client.ResponseBody(resp, body['agent'])
def delete_agent(self, agent_id):
"""Delete an existing agent build."""
resp, body = self.delete("os-agents/%s" % str(agent_id))
self.validate_response(schema.delete_agent, resp, body)
- return resp, body
+ return service_client.ResponseBody(resp, body)
def update_agent(self, agent_id, **kwargs):
"""Update an agent build."""
put_body = json.dumps({'para': kwargs})
resp, body = self.put('os-agents/%s' % str(agent_id), put_body)
- return resp, self._parse_resp(body)
+ return service_client.ResponseBody(resp, self._parse_resp(body))
diff --git a/tempest/services/compute/json/aggregates_client.py b/tempest/services/compute/json/aggregates_client.py
index 1539259..47dd401 100644
--- a/tempest/services/compute/json/aggregates_client.py
+++ b/tempest/services/compute/json/aggregates_client.py
@@ -17,6 +17,7 @@
from tempest.api_schema.response.compute import aggregates as schema
from tempest.api_schema.response.compute.v2 import aggregates as v2_schema
+from tempest.common import service_client
from tempest import exceptions
from tempest.services.compute.json import base
@@ -28,14 +29,14 @@
resp, body = self.get("os-aggregates")
body = json.loads(body)
self.validate_response(schema.list_aggregates, resp, body)
- return resp, body['aggregates']
+ return service_client.ResponseBodyList(resp, body['aggregates'])
def get_aggregate(self, aggregate_id):
"""Get details of the given aggregate."""
resp, body = self.get("os-aggregates/%s" % str(aggregate_id))
body = json.loads(body)
self.validate_response(schema.get_aggregate, resp, body)
- return resp, body['aggregate']
+ return service_client.ResponseBody(resp, body['aggregate'])
def create_aggregate(self, **kwargs):
"""Creates a new aggregate."""
@@ -44,7 +45,7 @@
body = json.loads(body)
self.validate_response(v2_schema.create_aggregate, resp, body)
- return resp, body['aggregate']
+ return service_client.ResponseBody(resp, body['aggregate'])
def update_aggregate(self, aggregate_id, name, availability_zone=None):
"""Update a aggregate."""
@@ -57,13 +58,13 @@
body = json.loads(body)
self.validate_response(schema.update_aggregate, resp, body)
- return resp, body['aggregate']
+ return service_client.ResponseBody(resp, body['aggregate'])
def delete_aggregate(self, aggregate_id):
"""Deletes the given aggregate."""
resp, body = self.delete("os-aggregates/%s" % str(aggregate_id))
self.validate_response(v2_schema.delete_aggregate, resp, body)
- return resp, body
+ return service_client.ResponseBody(resp, body)
def is_resource_deleted(self, id):
try:
@@ -87,7 +88,7 @@
post_body)
body = json.loads(body)
self.validate_response(schema.aggregate_add_remove_host, resp, body)
- return resp, body['aggregate']
+ return service_client.ResponseBody(resp, body['aggregate'])
def remove_host(self, aggregate_id, host):
"""Removes a host from the given aggregate."""
@@ -99,7 +100,7 @@
post_body)
body = json.loads(body)
self.validate_response(schema.aggregate_add_remove_host, resp, body)
- return resp, body['aggregate']
+ return service_client.ResponseBody(resp, body['aggregate'])
def set_metadata(self, aggregate_id, meta):
"""Replaces the aggregate's existing metadata with new metadata."""
@@ -111,4 +112,4 @@
post_body)
body = json.loads(body)
self.validate_response(schema.aggregate_set_metadata, resp, body)
- return resp, body['aggregate']
+ return service_client.ResponseBody(resp, body['aggregate'])
diff --git a/tempest/services/compute/json/hosts_client.py b/tempest/services/compute/json/hosts_client.py
index 5d306f9..f4e1f12 100644
--- a/tempest/services/compute/json/hosts_client.py
+++ b/tempest/services/compute/json/hosts_client.py
@@ -17,6 +17,7 @@
from tempest.api_schema.response.compute import hosts as schema
from tempest.api_schema.response.compute.v2 import hosts as v2_schema
+from tempest.common import service_client
from tempest.services.compute.json import base
@@ -32,7 +33,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.list_hosts, resp, body)
- return resp, body['hosts']
+ return service_client.ResponseBodyList(resp, body['hosts'])
def show_host_detail(self, hostname):
"""Show detail information for the host."""
@@ -40,7 +41,7 @@
resp, body = self.get("os-hosts/%s" % str(hostname))
body = json.loads(body)
self.validate_response(schema.show_host_detail, resp, body)
- return resp, body['host']
+ return service_client.ResponseBodyList(resp, body['host'])
def update_host(self, hostname, **kwargs):
"""Update a host."""
@@ -55,7 +56,7 @@
resp, body = self.put("os-hosts/%s" % str(hostname), request_body)
body = json.loads(body)
self.validate_response(v2_schema.update_host, resp, body)
- return resp, body
+ return service_client.ResponseBody(resp, body)
def startup_host(self, hostname):
"""Startup a host."""
@@ -63,7 +64,7 @@
resp, body = self.get("os-hosts/%s/startup" % str(hostname))
body = json.loads(body)
self.validate_response(v2_schema.startup_host, resp, body)
- return resp, body['host']
+ return service_client.ResponseBody(resp, body['host'])
def shutdown_host(self, hostname):
"""Shutdown a host."""
@@ -71,7 +72,7 @@
resp, body = self.get("os-hosts/%s/shutdown" % str(hostname))
body = json.loads(body)
self.validate_response(v2_schema.shutdown_host, resp, body)
- return resp, body['host']
+ return service_client.ResponseBody(resp, body['host'])
def reboot_host(self, hostname):
"""reboot a host."""
@@ -79,4 +80,4 @@
resp, body = self.get("os-hosts/%s/reboot" % str(hostname))
body = json.loads(body)
self.validate_response(v2_schema.reboot_host, resp, body)
- return resp, body['host']
+ return service_client.ResponseBody(resp, body['host'])
diff --git a/tempest/services/compute/json/hypervisor_client.py b/tempest/services/compute/json/hypervisor_client.py
index 52b50c8..37be874 100644
--- a/tempest/services/compute/json/hypervisor_client.py
+++ b/tempest/services/compute/json/hypervisor_client.py
@@ -17,6 +17,7 @@
from tempest.api_schema.response.compute import hypervisors as common_schema
from tempest.api_schema.response.compute.v2 import hypervisors as v2schema
+from tempest.common import service_client
from tempest.services.compute.json import base
@@ -28,7 +29,7 @@
body = json.loads(body)
self.validate_response(common_schema.common_hypervisors_detail,
resp, body)
- return resp, body['hypervisors']
+ return service_client.ResponseBodyList(resp, body['hypervisors'])
def get_hypervisor_list_details(self):
"""Show detailed hypervisors information."""
@@ -36,7 +37,7 @@
body = json.loads(body)
self.validate_response(common_schema.common_list_hypervisors_detail,
resp, body)
- return resp, body['hypervisors']
+ return service_client.ResponseBodyList(resp, body['hypervisors'])
def get_hypervisor_show_details(self, hyper_id):
"""Display the details of the specified hypervisor."""
@@ -44,28 +45,28 @@
body = json.loads(body)
self.validate_response(common_schema.common_show_hypervisor,
resp, body)
- return resp, body['hypervisor']
+ return service_client.ResponseBody(resp, body['hypervisor'])
def get_hypervisor_servers(self, hyper_name):
"""List instances belonging to the specified hypervisor."""
resp, body = self.get('os-hypervisors/%s/servers' % hyper_name)
body = json.loads(body)
self.validate_response(v2schema.hypervisors_servers, resp, body)
- return resp, body['hypervisors']
+ return service_client.ResponseBodyList(resp, body['hypervisors'])
def get_hypervisor_stats(self):
"""Get hypervisor statistics over all compute nodes."""
resp, body = self.get('os-hypervisors/statistics')
body = json.loads(body)
self.validate_response(common_schema.hypervisor_statistics, resp, body)
- return resp, body['hypervisor_statistics']
+ return service_client.ResponseBody(resp, body['hypervisor_statistics'])
def get_hypervisor_uptime(self, hyper_id):
"""Display the uptime of the specified hypervisor."""
resp, body = self.get('os-hypervisors/%s/uptime' % hyper_id)
body = json.loads(body)
self.validate_response(common_schema.hypervisor_uptime, resp, body)
- return resp, body['hypervisor']
+ return service_client.ResponseBody(resp, body['hypervisor'])
def search_hypervisor(self, hyper_name):
"""Search specified hypervisor."""
@@ -73,4 +74,4 @@
body = json.loads(body)
self.validate_response(common_schema.common_hypervisors_detail,
resp, body)
- return resp, body['hypervisors']
+ return service_client.ResponseBodyList(resp, body['hypervisors'])
diff --git a/tempest/services/compute/json/services_client.py b/tempest/services/compute/json/services_client.py
index 8d73c37..52662fa 100644
--- a/tempest/services/compute/json/services_client.py
+++ b/tempest/services/compute/json/services_client.py
@@ -18,6 +18,7 @@
import urllib
from tempest.api_schema.response.compute import services as schema
+from tempest.common import service_client
from tempest.services.compute.json import base
@@ -31,7 +32,7 @@
resp, body = self.get(url)
body = json.loads(body)
self.validate_response(schema.list_services, resp, body)
- return resp, body['services']
+ return service_client.ResponseBodyList(resp, body['services'])
def enable_service(self, host_name, binary):
"""
@@ -43,7 +44,7 @@
resp, body = self.put('os-services/enable', post_body)
body = json.loads(body)
self.validate_response(schema.enable_service, resp, body)
- return resp, body['service']
+ return service_client.ResponseBody(resp, body['service'])
def disable_service(self, host_name, binary):
"""
@@ -54,4 +55,4 @@
post_body = json.dumps({'binary': binary, 'host': host_name})
resp, body = self.put('os-services/disable', post_body)
body = json.loads(body)
- return resp, body['service']
+ return service_client.ResponseBody(resp, body['service'])
diff --git a/tempest/services/network/resources.py b/tempest/services/network/resources.py
index 513d2cf..4d45515 100644
--- a/tempest/services/network/resources.py
+++ b/tempest/services/network/resources.py
@@ -82,8 +82,10 @@
self._router_ids = set()
def update(self, *args, **kwargs):
- result = self.client.update_subnet(subnet=self.id, *args, **kwargs)
- super(DeletableSubnet, self).update(**result['subnet'])
+ result = self.client.update_subnet(self.id,
+ *args,
+ **kwargs)
+ return super(DeletableSubnet, self).update(**result['subnet'])
def add_to_router(self, router_id):
self._router_ids.add(router_id)