Add tests for new tainted field in nodes

- Added API tests for nodes returning tainted fields in v1.13+
- Fixed missing and duplicate idempotent ids.

Depends-On: https://review.opendev.org/#/c/689606/
Change-Id: I283467b3dc4a6f32b1c7b81c2e97a52d8c0c9f1e
This commit is contained in:
Duc Truong 2019-10-22 20:03:03 +00:00
parent e8c68ffb74
commit 01aa3de05f
15 changed files with 154 additions and 29 deletions

View File

@ -255,7 +255,8 @@ def list_nodes(base):
def update_a_node(base, node_id, profile_id=None, name=None,
metadata=None, role=None, wait_timeout=None):
metadata=None, tainted=None, role=None,
wait_timeout=None):
"""Utility function that updates a Senlin node.
Update a node and return it after it is ACTIVE.
@ -268,6 +269,9 @@ def update_a_node(base, node_id, profile_id=None, name=None,
'role': role
}
}
if tainted is not None:
params['node']['tainted'] = tainted
res = base.client.update_obj('nodes', node_id, params)
action_id = res['location'].split('/actions/')[1]
base.client.wait_for_status('actions', action_id, 'SUCCEEDED',

View File

@ -71,8 +71,8 @@ class TestClusterCollectNegative(base.BaseSenlinAPITest):
self.assertEqual("API version '1.1' is not supported on this method.",
str(message))
@decorators.idempotent_id('1b080a66-9c76-4321-9d88-74e38eb44df7')
@utils.api_microversion('1.2')
@decorators.idempotent_id('a3d59666-93be-47ee-a484-c248ed2f49fe')
def test_cluster_collect_failed_path(self):
# Collect on a basic path
ex = self.assertRaises(exceptions.BadRequest,

View File

@ -146,6 +146,7 @@ class TestClusterScaleOutNegativeResourceIsLocked(base.BaseSenlinAPITest):
self.cluster_id = utils.create_a_cluster(self, profile_id)
self.addCleanup(utils.delete_a_cluster, self, self.cluster_id)
@decorators.idempotent_id('3ecc8a73-03b2-4937-bb98-5b49554baf06')
def test_cluster_action_scale_out_locked_cluster(self):
params = {
"scale_out": {

View File

@ -97,7 +97,7 @@ class TestEventListNegativeBadRequest(base.BaseSenlinAPITest):
str(message))
@decorators.attr(type=['negative'])
@decorators.idempotent_id('72e0fd48-2dc7-47ce-abad-299e508fabd4')
@decorators.idempotent_id('7a6c1133-733b-481f-98d0-3e4a2d55e027')
def test_event_list_unsupported_action(self):
ex = self.assertRaises(exceptions.BadRequest,
self.client.list_objs,

View File

@ -27,8 +27,26 @@ class TestNodeCreate(base.BaseSenlinAPITest):
config={'node.name.format': 'test-node'})
self.addCleanup(utils.delete_a_cluster, self, self.cluster_id)
@utils.api_microversion('1.12')
@decorators.idempotent_id('14d06753-7f0a-4ad2-84be-37fce7114a8f')
def test_node_create_all_attrs_defined(self):
expected_keys = ['cluster_id', 'created_at', 'data', 'domain', 'id',
'index', 'init_at', 'metadata', 'name', 'physical_id',
'profile_id', 'profile_name', 'project', 'role',
'status', 'status_reason', 'updated_at', 'user']
self._create_node(expected_keys)
@decorators.idempotent_id('b678a196-01bf-42cb-a079-9595d937d211')
@utils.api_microversion('1.13')
def test_node_create_all_attrs_defined_v1_13(self):
expected_keys = ['cluster_id', 'created_at', 'data', 'domain', 'id',
'index', 'init_at', 'metadata', 'name', 'physical_id',
'profile_id', 'profile_name', 'project', 'role',
'status', 'status_reason', 'tainted',
'updated_at', 'user']
self._create_node(expected_keys)
def _create_node(self, expected_keys):
params = {
'node': {
'profile_id': self.profile_id,
@ -46,10 +64,7 @@ class TestNodeCreate(base.BaseSenlinAPITest):
self.assertIn('actions', res['location'])
node = res['body']
self.addCleanup(utils.delete_a_node, self, node['id'])
for key in ['cluster_id', 'created_at', 'data', 'domain', 'id',
'index', 'init_at', 'metadata', 'name', 'physical_id',
'profile_id', 'profile_name', 'project', 'role',
'status', 'status_reason', 'updated_at', 'user']:
for key in expected_keys:
self.assertIn(key, node)
self.assertIn('test-node', node['name'])
self.assertEqual(self.profile_id, node['profile_id'])

View File

@ -26,8 +26,27 @@ class TestNodeList(base.BaseSenlinAPITest):
self.node_id = utils.create_a_node(self, profile_id)
self.addCleanup(utils.delete_a_node, self, self.node_id)
@utils.api_microversion('1.12')
@decorators.idempotent_id('cd086dcb-7509-4125-adfc-6beb63b10d0a')
def test_node_list(self):
expected_keys = ['cluster_id', 'created_at', 'data', 'domain',
'id', 'index', 'init_at', 'metadata', 'name',
'physical_id', 'profile_id', 'profile_name',
'project', 'role', 'status', 'status_reason',
'updated_at', 'user']
self._list_node(expected_keys)
@decorators.idempotent_id('f7cc5f8a-8aed-468f-ad03-883071371c5d')
@utils.api_microversion('1.13')
def test_node_list_v1_13(self):
expected_keys = ['cluster_id', 'created_at', 'data', 'domain',
'id', 'index', 'init_at', 'metadata', 'name',
'physical_id', 'profile_id', 'profile_name',
'project', 'role', 'status', 'status_reason',
'updated_at', 'user']
self._list_node(expected_keys)
def _list_node(self, expected_keys):
res = self.client.list_objs('nodes')
# Verify resp of node list API
@ -37,11 +56,7 @@ class TestNodeList(base.BaseSenlinAPITest):
nodes = res['body']
node_ids = []
for node in nodes:
for key in ['cluster_id', 'created_at', 'data', 'domain',
'id', 'index', 'init_at', 'metadata', 'name',
'physical_id', 'profile_id', 'profile_name',
'project', 'role', 'status', 'status_reason',
'updated_at', 'user']:
for key in expected_keys:
self.assertIn(key, node)
node_ids.append(node['id'])

View File

@ -26,8 +26,27 @@ class TestNodeShow(base.BaseSenlinAPITest):
self.node_id = utils.create_a_node(self, profile_id)
self.addCleanup(utils.delete_a_node, self, self.node_id)
@utils.api_microversion('1.12')
@decorators.idempotent_id('302372e8-efa2-4348-88dd-8a1829e5e26c')
def test_node_show(self):
expected_keys = ['cluster_id', 'created_at', 'data', 'domain',
'id', 'index', 'init_at', 'metadata', 'name',
'physical_id', 'profile_id', 'profile_name',
'project', 'role', 'status', 'status_reason',
'updated_at', 'user']
self._show_node(expected_keys)
@decorators.idempotent_id('81e65048-c68b-44a1-b351-d572bd68bf06')
@utils.api_microversion('1.13')
def test_node_show_v1_13(self):
expected_keys = ['cluster_id', 'created_at', 'data', 'domain',
'id', 'index', 'init_at', 'metadata', 'name',
'physical_id', 'profile_id', 'profile_name',
'project', 'role', 'status', 'status_reason',
'tainted', 'updated_at', 'user']
self._show_node(expected_keys)
def _show_node(self, expected_keys):
res = self.client.get_obj('nodes', self.node_id)
# Verify resp of node get API
@ -35,9 +54,5 @@ class TestNodeShow(base.BaseSenlinAPITest):
self.assertIsNone(res['location'])
self.assertIsNotNone(res['body'])
node = res['body']
for key in ['cluster_id', 'created_at', 'data', 'domain',
'id', 'index', 'init_at', 'metadata', 'name',
'physical_id', 'profile_id', 'profile_name',
'project', 'role', 'status', 'status_reason',
'updated_at', 'user']:
for key in expected_keys:
self.assertIn(key, node)

View File

@ -28,6 +28,7 @@ class TestNodeUpdate(base.BaseSenlinAPITest):
role='member')
self.addCleanup(utils.delete_a_node, self, self.node_id)
@utils.api_microversion('1.12')
@decorators.idempotent_id('bd8a39bf-eee0-4056-aec0-0d8f8706efea')
def test_node_update_basic_properties(self):
# Update basic properties of node
@ -54,3 +55,32 @@ class TestNodeUpdate(base.BaseSenlinAPITest):
# Wait for node update to be done before moving on
action_id = res['location'].split('/actions/')[1]
self.client.wait_for_status('actions', action_id, 'SUCCEEDED')
@decorators.idempotent_id('f8816054-6864-4c55-8770-6fdd66239fda')
@utils.api_microversion('1.13')
def test_node_update_basic_properties_v1_13(self):
# Update basic properties of node
params = {
'node': {
'name': 'node_new_name',
'role': 'admin',
'metadata': {'k2': 'v2'},
'tainted': True
}
}
res = self.client.update_obj('nodes', self.node_id, params)
# Verify resp of node update API
self.assertEqual(202, res['status'])
self.assertIsNotNone(res['body'])
self.assertIn('actions', res['location'])
node = res['body']
for key in ['cluster_id', 'created_at', 'data', 'domain', 'id',
'index', 'init_at', 'metadata', 'name', 'physical_id',
'profile_id', 'profile_name', 'project', 'role', 'status',
'status_reason', 'tainted', 'updated_at', 'user']:
self.assertIn(key, node)
# Wait for node update to be done before moving on
action_id = res['location'].split('/actions/')[1]
self.client.wait_for_status('actions', action_id, 'SUCCEEDED')

View File

@ -30,8 +30,8 @@ class TestPolicyTypeList(base.BaseSenlinAPITest):
for policy_type in policy_types:
self.assertIn('name', policy_type)
@decorators.idempotent_id('35efa810-ef80-4a8a-b73f-55d62434108d')
@utils.api_microversion('1.5')
@decorators.idempotent_id('1900b22a-012d-41f0-85a2-8aa6b65ec2ca')
def test_policy_type_list_v1_5(self):
res = self.client.list_objs('policy-types')

View File

@ -35,8 +35,8 @@ class TestProfileTypeList(base.BaseSenlinAPITest):
for profile_type in expected_profile_types:
self.assertIn(profile_type, profile_types)
@decorators.idempotent_id('646a1f96-e1c6-4ba4-a96b-2f4a5a9efdb3')
@utils.api_microversion('1.5')
@decorators.idempotent_id('778d41df-0ce0-421f-98e5-2efdcec6d995')
def test_profile_type_list_v1_5(self):
res = self.client.list_objs('profile-types')

View File

@ -43,7 +43,7 @@ class TestProfileDeleteNegativeConflict(base.BaseSenlinAPITest):
class TestProfileDeleteNegativeNotFound(base.BaseSenlinAPITest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('b6e7911d-5f65-4ec6-a08b-b88809fe2b9e')
@decorators.idempotent_id('41990227-e75c-4fc3-9503-87aa7ac06e7e')
def test_profile_delete_not_found(self):
# Verify notfound exception(404) is raised.
ex = self.assertRaises(exceptions.NotFound,

View File

@ -19,14 +19,14 @@ from senlin_tempest_plugin.tests.api import base
class TestProfileListNegativeBadRequest(base.BaseSenlinAPITest):
@decorators.attr(type=['negative'])
@decorators.idempotent_id('b936b936-f891-4389-bbeb-f81b7dc3c688')
@decorators.idempotent_id('0747310b-6d97-47d3-a7d6-c3d6121cee75')
def test_profile_list_invalid_params(self):
self.assertRaises(exceptions.BadRequest,
self.client.list_objs,
'profiles', {'bogus': 'foo'})
@decorators.attr(type=['negative'])
@decorators.idempotent_id('04ce3766-acf9-4549-91c8-e6ffdf7bafbd')
@decorators.idempotent_id('5dcb1ec1-e870-4e25-a0b8-4b596f0607c0')
def test_profile_list_limit_not_int(self):
ex = self.assertRaises(exceptions.BadRequest,
self.client.list_objs,
@ -37,7 +37,7 @@ class TestProfileListNegativeBadRequest(base.BaseSenlinAPITest):
str(message))
@decorators.attr(type=['negative'])
@decorators.idempotent_id('cfd50d13-5ed8-48d9-b03f-95480ba06fad')
@decorators.idempotent_id('7e389aa6-039d-4d5d-8d4a-ac33c6d471a3')
def test_profile_list_global_project_false(self):
ex = self.assertRaises(exceptions.Forbidden,
self.client.list_objs,
@ -48,7 +48,7 @@ class TestProfileListNegativeBadRequest(base.BaseSenlinAPITest):
str(message))
@decorators.attr(type=['negative'])
@decorators.idempotent_id('ab477cf8-6c37-4762-bd85-d55b46444d8f')
@decorators.idempotent_id('6891a01f-e8ab-4e95-bc74-4260745a8fe5')
def test_profile_list_global_project_not_bool(self):
ex = self.assertRaises(exceptions.BadRequest,
self.client.list_objs,
@ -59,7 +59,7 @@ class TestProfileListNegativeBadRequest(base.BaseSenlinAPITest):
"'global_project'", str(message))
@decorators.attr(type=['negative'])
@decorators.idempotent_id('f5bd7807-2b3e-43b2-8ed6-7bdb5e9af46b')
@decorators.idempotent_id('b0bc73b2-dff8-416a-b0e5-8d1389468201')
def test_profile_list_invalid_sort(self):
ex = self.assertRaises(exceptions.BadRequest,
self.client.list_objs,
@ -70,7 +70,7 @@ class TestProfileListNegativeBadRequest(base.BaseSenlinAPITest):
str(message))
@decorators.attr(type=['negative'])
@decorators.idempotent_id('077f39f0-bb2a-4de8-9568-2ed49e99b720')
@decorators.idempotent_id('d84461d1-fc0d-4983-8030-3096cf360d45')
def test_profile_list_invalid_marker(self):
ex = self.assertRaises(exceptions.BadRequest,
self.client.list_objs,

View File

@ -33,7 +33,7 @@ class TestProfileUpdateNegativeNotFound(base.BaseSenlinAPITest):
"could not be found.", str(message))
@decorators.attr(type=['negative'])
@decorators.idempotent_id('5fe90195-aaed-4c1f-a73a-806b3f044bf8')
@decorators.idempotent_id('12a6772b-baea-47cc-a689-528a8e48ae22')
def test_profile_update_profile_no_param(self):
ex = self.assertRaises(exceptions.BadRequest,
self.client.update_obj, 'profiles',
@ -56,7 +56,7 @@ class TestProfileUpdateNegativeBadRequest(base.BaseSenlinAPITest):
self.profile_id = profile_id
@decorators.attr(type=['negative'])
@decorators.idempotent_id('31242de5-55ac-4589-87a1-a9940e4beca2')
@decorators.idempotent_id('45df7339-8fff-459a-b4e3-0aeafbcb4232')
def test_profile_update_no_property_updated(self):
# No property is updated
params = {
@ -72,7 +72,7 @@ class TestProfileUpdateNegativeBadRequest(base.BaseSenlinAPITest):
str(message))
@decorators.attr(type=['negative'])
@decorators.idempotent_id('d2ca7de6-0069-48c9-b3de-ee975a2428dc')
@decorators.idempotent_id('0f4edfc0-78fa-414e-b995-100b67544410')
def test_profile_update_spec_not_updatable(self):
# Try to update spec of profile which is not allowed.
params = {

View File

@ -87,6 +87,7 @@ class TestNodeUpdate(base.BaseSenlinFunctionalTest):
self.node_id = utils.create_a_node(self, self.profile_id)
self.addCleanup(utils.delete_a_node, self, self.node_id)
@utils.api_microversion('1.12')
@decorators.attr(type=['functional'])
@decorators.idempotent_id('d373fb1d-33a1-434f-a850-fb78eff15d18')
def test_node_update_basic_properties(self):
@ -103,6 +104,46 @@ class TestNodeUpdate(base.BaseSenlinFunctionalTest):
self.assertEqual(name, node['name'])
self.assertEqual(metadata, node['metadata'])
self.assertEqual(role, node['role'])
self.assertNotIn('tainted', node)
@decorators.idempotent_id('eac6704f-9a2c-4ed4-9d26-9a5eb4d20bb3')
@utils.api_microversion('1.13')
@decorators.attr(type=['functional'])
def test_node_update_basic_properties_v1_13(self):
name = 'new-name'
role = 'new-role'
metadata = {'k2': 'v2'}
# Update node
utils.update_a_node(self, self.node_id, name=name, metadata=metadata,
role=role)
# Verify update result
node = utils.get_a_node(self, self.node_id)
self.assertEqual(name, node['name'])
self.assertEqual(metadata, node['metadata'])
self.assertEqual(role, node['role'])
self.assertEqual(False, node['tainted'])
@decorators.idempotent_id('598f3a1f-d4f1-4ee1-bae3-c1df23f93398')
@utils.api_microversion('1.13')
@decorators.attr(type=['functional'])
def test_node_update_basic_properties__with_tainted_v1_13(self):
name = 'new-name'
role = 'new-role'
metadata = {'k2': 'v2'}
tainted = True
# Update node
utils.update_a_node(self, self.node_id, name=name, metadata=metadata,
role=role, tainted=tainted)
# Verify update result
node = utils.get_a_node(self, self.node_id)
self.assertEqual(name, node['name'])
self.assertEqual(metadata, node['metadata'])
self.assertEqual(role, node['role'])
self.assertEqual(tainted, node['tainted'])
@decorators.attr(type=['functional'])
@decorators.idempotent_id('361e051d-b55b-4943-8a01-462f6fc5be43')

View File

@ -49,6 +49,7 @@ class TestHealthPolicy(base.BaseSenlinIntegrationTest):
pass
@decorators.attr(type=['integration'])
@decorators.idempotent_id('d40ae276-2cbc-4073-b71d-0854ddf8c6a1')
def test_health_policy(self):
# Create a health policy
spec = constants.spec_health_policy
@ -81,6 +82,7 @@ class TestHealthPolicy(base.BaseSenlinIntegrationTest):
return list(nodes.keys())[index], list(nodes.values())[index]
@decorators.attr(type=['integration'])
@decorators.idempotent_id('94b0c88a-2cd0-4fff-abbd-331e8369b7b4')
def test_multiple_detection_modes_any(self):
# Create a health policy
spec = constants.spec_health_policy
@ -122,6 +124,7 @@ class TestHealthPolicy(base.BaseSenlinIntegrationTest):
self.compute_client.get_obj, 'servers', old_server_id)
@decorators.attr(type=['integration'])
@decorators.idempotent_id('7ce88abb-0a7c-48a8-91ce-59463b75c1e5')
def test_multiple_detection_modes_all(self):
# Create a health policy
spec = constants.spec_health_policy
@ -179,6 +182,7 @@ class TestHealthPolicy(base.BaseSenlinIntegrationTest):
self.compute_client.get_obj, 'servers', old_server_id)
@decorators.attr(type=['integration'])
@decorators.idempotent_id('e78e0590-2df7-423b-8f71-8037e03598f3')
def test_multiple_detection_modes_all_poll_url_fail(self):
# Create a health policy
spec = constants.spec_health_policy