def test_resume_allocations(self, mock_allocate): another_conductor = obj_utils.create_test_conductor( self.context, id=42, hostname='another-host') self._start_service() obj_utils.create_test_allocation( self.context, state='active', conductor_affinity=self.service.conductor.id) obj_utils.create_test_allocation( self.context, state='allocating', conductor_affinity=another_conductor.id) allocation = obj_utils.create_test_allocation( self.context, state='allocating', conductor_affinity=self.service.conductor.id) self.service._resume_allocations(self.context) mock_allocate.assert_called_once_with(self.context, mock.ANY) actual = mock_allocate.call_args[0][1] self.assertEqual(allocation.uuid, actual.uuid) self.assertIsInstance(allocation, objects.Allocation)
def test_get_by_node_resource_invalid_api_version(self): obj_utils.create_test_allocation(self.context, node_id=self.node.id) response = self.get_json( '/nodes/%s/allocation' % self.node.uuid, headers={api_base.Version.string: str(api_v1.min_version())}, expect_errors=True) self.assertEqual(http_client.NOT_FOUND, response.status_int)
def test_get_by_node_resource_invalid_api_version(self): obj_utils.create_test_allocation(self.context, node_id=self.node.id) response = self.get_json( '/nodes/%s/allocation' % self.node.uuid, headers={api_base.Version.string: str(api_v1.min_version())}, expect_errors=True) self.assertEqual(http_client.NOT_FOUND, response.status_int)
def test_get_all_by_non_existing_node(self): obj_utils.create_test_allocation(self.context, node_id=self.node.id) response = self.get_json('/allocations?node=banana', headers=self.headers, expect_errors=True) self.assertEqual('application/json', response.content_type) self.assertEqual(http_client.BAD_REQUEST, response.status_int)
def test_check_orphaned_allocations(self, mock_allocate): alive_conductor = obj_utils.create_test_conductor(self.context, id=42, hostname='alive') dead_conductor = obj_utils.create_test_conductor(self.context, id=43, hostname='dead') obj_utils.create_test_allocation(self.context, state='allocating', conductor_affinity=alive_conductor.id) allocation = obj_utils.create_test_allocation( self.context, state='allocating', conductor_affinity=dead_conductor.id) self._start_service() with mock.patch.object(self.dbapi, 'get_offline_conductors', autospec=True) as mock_conds: mock_conds.return_value = [dead_conductor.id] self.service._check_orphan_allocations(self.context) mock_allocate.assert_called_once_with(self.context, mock.ANY) actual = mock_allocate.call_args[0][1] self.assertEqual(allocation.uuid, actual.uuid) self.assertIsInstance(allocation, objects.Allocation) allocation = self.dbapi.get_allocation_by_id(allocation.id) self.assertEqual(self.service.conductor.id, allocation.conductor_affinity)
def test_check_orphaned_allocations(self, mock_allocate): alive_conductor = obj_utils.create_test_conductor( self.context, id=42, hostname='alive') dead_conductor = obj_utils.create_test_conductor( self.context, id=43, hostname='dead') obj_utils.create_test_allocation( self.context, state='allocating', conductor_affinity=alive_conductor.id) allocation = obj_utils.create_test_allocation( self.context, state='allocating', conductor_affinity=dead_conductor.id) self._start_service() with mock.patch.object(self.dbapi, 'get_offline_conductors', autospec=True) as mock_conds: mock_conds.return_value = [dead_conductor.id] self.service._check_orphan_allocations(self.context) mock_allocate.assert_called_once_with(self.context, mock.ANY) actual = mock_allocate.call_args[0][1] self.assertEqual(allocation.uuid, actual.uuid) self.assertIsInstance(allocation, objects.Allocation) allocation = self.dbapi.get_allocation_by_id(allocation.id) self.assertEqual(self.service.conductor.id, allocation.conductor_affinity)
def test_resume_allocations(self, mock_allocate): another_conductor = obj_utils.create_test_conductor( self.context, id=42, hostname='another-host') self._start_service() obj_utils.create_test_allocation( self.context, state='active', conductor_affinity=self.service.conductor.id) obj_utils.create_test_allocation( self.context, state='allocating', conductor_affinity=another_conductor.id) allocation = obj_utils.create_test_allocation( self.context, state='allocating', conductor_affinity=self.service.conductor.id) self.service._resume_allocations(self.context) mock_allocate.assert_called_once_with(self.context, mock.ANY) actual = mock_allocate.call_args[0][1] self.assertEqual(allocation.uuid, actual.uuid) self.assertIsInstance(allocation, objects.Allocation)
def test_get_by_node_resource_with_fields(self): obj_utils.create_test_allocation(self.context, node_id=self.node.id) data = self.get_json('/nodes/%s/allocation?fields=name,extra' % self.node.uuid, headers=self.headers) self.assertNotIn('uuid', data) self.assertIn('name', data) self.assertEqual({}, data["extra"])
def test_allocation_get_all_invalid_api_version(self): obj_utils.create_test_allocation( self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(), name='allocation_1') response = self.get_json('/allocations', headers={api_base.Version.string: '1.14'}, expect_errors=True) self.assertEqual(http_client.NOT_FOUND, response.status_int)
def test_delete_allocation_by_node_invalid_api_version(self, mock_destroy): obj_utils.create_test_allocation(self.context, node_id=self.node.id) response = self.delete( '/nodes/%s/allocation' % self.node.uuid, headers={api_base.Version.string: str(api_v1.min_version())}, expect_errors=True) self.assertEqual(http_client.NOT_FOUND, response.status_int) self.assertFalse(mock_destroy.called)
def test_get_by_node_resource_with_fields(self): obj_utils.create_test_allocation(self.context, node_id=self.node.id) data = self.get_json('/nodes/%s/allocation?fields=name,extra' % self.node.uuid, headers=self.headers) self.assertNotIn('uuid', data) self.assertIn('name', data) self.assertEqual({}, data["extra"])
def test_delete_allocation_by_node_invalid_api_version(self, mock_destroy): obj_utils.create_test_allocation(self.context, node_id=self.node.id) response = self.delete( '/nodes/%s/allocation' % self.node.uuid, headers={api_base.Version.string: str(api_v1.min_version())}, expect_errors=True) self.assertEqual(http_client.NOT_FOUND, response.status_int) self.assertFalse(mock_destroy.called)
def test_allocation_get_all_invalid_api_version(self): obj_utils.create_test_allocation(self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(), name='allocation_1') response = self.get_json('/allocations', headers={api_base.Version.string: '1.14'}, expect_errors=True) self.assertEqual(http_client.NOT_FOUND, response.status_int)
def test_get_all_by_state(self): for i in range(5): if i < 3: state = 'allocating' else: state = 'active' obj_utils.create_test_allocation(self.context, state=state, uuid=uuidutils.generate_uuid(), name='allocation%s' % i) data = self.get_json("/allocations?state=allocating", headers=self.headers) self.assertEqual(3, len(data['allocations']))
def test_get_all_by_node_name(self): for i in range(5): if i < 3: node_id = self.node.id else: node_id = 100000 + i obj_utils.create_test_allocation(self.context, node_id=node_id, uuid=uuidutils.generate_uuid(), name='allocation%s' % i) data = self.get_json("/allocations?node=%s" % self.node.name, headers=self.headers) self.assertEqual(3, len(data['allocations']))
def test_links(self): uuid = uuidutils.generate_uuid() obj_utils.create_test_allocation(self.context, uuid=uuid, node_id=self.node.id) data = self.get_json('/allocations/%s' % uuid, headers=self.headers) self.assertIn('links', data) self.assertEqual(2, len(data['links'])) self.assertIn(uuid, data['links'][0]['href']) for l in data['links']: bookmark = l['rel'] == 'bookmark' self.assertTrue(self.validate_link(l['href'], bookmark=bookmark, headers=self.headers))
def test_get_all_by_node_name(self): for i in range(5): if i < 3: node_id = self.node.id else: node_id = 100000 + i obj_utils.create_test_allocation( self.context, node_id=node_id, uuid=uuidutils.generate_uuid(), name='allocation%s' % i) data = self.get_json("/allocations?node=%s" % self.node.name, headers=self.headers) self.assertEqual(3, len(data['allocations']))
def test_get_all_by_state(self): for i in range(5): if i < 3: state = 'allocating' else: state = 'active' obj_utils.create_test_allocation( self.context, state=state, uuid=uuidutils.generate_uuid(), name='allocation%s' % i) data = self.get_json("/allocations?state=allocating", headers=self.headers) self.assertEqual(3, len(data['allocations']))
def test_links(self): uuid = uuidutils.generate_uuid() obj_utils.create_test_allocation(self.context, uuid=uuid, node_id=self.node.id) data = self.get_json('/allocations/%s' % uuid, headers=self.headers) self.assertIn('links', data) self.assertEqual(2, len(data['links'])) self.assertIn(uuid, data['links'][0]['href']) for l in data['links']: bookmark = l['rel'] == 'bookmark' self.assertTrue( self.validate_link(l['href'], bookmark=bookmark, headers=self.headers))
def test_get_collection_custom_fields(self): fields = 'uuid,extra' for i in range(3): obj_utils.create_test_allocation(self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(), name='allocation%s' % i) data = self.get_json('/allocations?fields=%s' % fields, headers=self.headers) self.assertEqual(3, len(data['allocations'])) for allocation in data['allocations']: # We always append "links" self.assertItemsEqual(['uuid', 'extra', 'links'], allocation)
def test_nodes_candidates_do_not_match(self, mock_acquire): obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), resource_class='x-large', power_state='power off', provision_state='available') # Resource class does not match node = obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), power_state='power on', resource_class='x-small', provision_state='available') allocation = obj_utils.create_test_allocation( self.context, resource_class='x-large', candidate_nodes=[node['uuid']]) allocations.do_allocate(self.context, allocation) self.assertIn('none of the requested nodes', allocation['last_error']) self.assertIn('x-large', allocation['last_error']) self.assertEqual('error', allocation['state']) # All nodes are filtered out on the database level. self.assertFalse(mock_acquire.called)
def test_get_one_with_suffix(self): allocation = obj_utils.create_test_allocation(self.context, name='pg.1', node_id=self.node.id) data = self.get_json('/allocations/%s' % allocation.uuid, headers=self.headers) self.assertEqual(allocation.uuid, data['uuid'])
def test_uuid_associated_with_another_instance(self): uuid = uuidutils.generate_uuid() obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), instance_uuid=uuid, resource_class='x-large', provision_state='active') node = obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), resource_class='x-large', provision_state='active') allocation = obj_utils.create_test_allocation(self.context, uuid=uuid, resource_class='x-large') self.assertRaises(exception.InstanceAssociated, allocations.backfill_allocation, self.context, allocation, node.id) allocation = objects.Allocation.get_by_uuid(self.context, allocation['uuid']) self.assertEqual('error', allocation['state']) self.assertIn('associated', allocation['last_error']) self.assertIsNone(allocation['node_id']) node = objects.Node.get_by_uuid(self.context, node['uuid']) self.assertIsNone(node['instance_uuid']) self.assertIsNone(node['allocation_id'])
def test_with_candidates(self): obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), power_state='power on', resource_class='x-large', provision_state='available') node = obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), power_state='power on', resource_class='x-large', provision_state='available') allocation = obj_utils.create_test_allocation( self.context, resource_class='x-large', candidate_nodes=[node['uuid']]) allocations.do_allocate(self.context, allocation) allocation = objects.Allocation.get_by_uuid(self.context, allocation['uuid']) self.assertIsNone(allocation['last_error']) self.assertEqual('active', allocation['state']) node = objects.Node.get_by_uuid(self.context, node['uuid']) self.assertEqual(allocation['uuid'], node['instance_uuid']) self.assertEqual(allocation['id'], node['allocation_id']) self.assertEqual([node['uuid']], allocation['candidate_nodes'])
def test_with_candidates(self): obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), power_state='power on', resource_class='x-large', provision_state='available') node = obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), power_state='power on', resource_class='x-large', provision_state='available') allocation = obj_utils.create_test_allocation( self.context, resource_class='x-large', candidate_nodes=[node['uuid']]) allocations.do_allocate(self.context, allocation) allocation = objects.Allocation.get_by_uuid(self.context, allocation['uuid']) self.assertIsNone(allocation['last_error']) self.assertEqual('active', allocation['state']) node = objects.Node.get_by_uuid(self.context, node['uuid']) self.assertEqual(allocation['uuid'], node['instance_uuid']) self.assertEqual(allocation['id'], node['allocation_id']) self.assertEqual([node['uuid']], allocation['candidate_nodes'])
def test_nodes_filtered_out_project(self, mock_acquire): # Owner and lessee do not match obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), owner='54321', resource_class='x-large', power_state='power off', provision_state='available') obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), lessee='54321', resource_class='x-large', power_state='power off', provision_state='available') allocation = obj_utils.create_test_allocation(self.context, resource_class='x-large', owner='12345') allocations.do_allocate(self.context, allocation) self.assertIn('no available nodes', allocation['last_error']) self.assertIn('x-large', allocation['last_error']) self.assertEqual('error', allocation['state']) # All nodes are filtered out on the database level. self.assertFalse(mock_acquire.called)
def test_nodes_locked(self, mock_acquire): self.config(node_locked_retry_attempts=2, group='conductor') node1 = obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), maintenance=False, resource_class='x-large', power_state='power off', provision_state='available', reservation='example.com') node2 = obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), resource_class='x-large', power_state='power off', provision_state='available', reservation='example.com') allocation = obj_utils.create_test_allocation(self.context, resource_class='x-large') allocations.do_allocate(self.context, allocation) self.assertIn('could not reserve any of 2', allocation['last_error']) self.assertEqual('error', allocation['state']) self.assertEqual(6, mock_acquire.call_count) # NOTE(dtantsur): node are tried in random order by design, so we # cannot directly use assert_has_calls. Check that all nodes are tried # before going into retries (rather than each tried 3 times in a row). nodes = [call[0][1] for call in mock_acquire.call_args_list] for offset in (0, 2, 4): self.assertEqual(set(nodes[offset:offset + 2]), {node1.uuid, node2.uuid})
def test_nodes_locked(self, mock_acquire): self.config(node_locked_retry_attempts=2, group='conductor') node1 = obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), maintenance=False, resource_class='x-large', power_state='power off', provision_state='available', reservation='example.com') node2 = obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), resource_class='x-large', power_state='power off', provision_state='available', reservation='example.com') allocation = obj_utils.create_test_allocation(self.context, resource_class='x-large') allocations.do_allocate(self.context, allocation) self.assertIn('could not reserve any of 2', allocation['last_error']) self.assertEqual('error', allocation['state']) self.assertEqual(6, mock_acquire.call_count) # NOTE(dtantsur): node are tried in random order by design, so we # cannot directly use assert_has_calls. Check that all nodes are tried # before going into retries (rather than each tried 3 times in a row). nodes = [call[0][1] for call in mock_acquire.call_args_list] for offset in (0, 2, 4): self.assertEqual(set(nodes[offset:offset + 2]), {node1.uuid, node2.uuid})
def test_get_one_with_suffix(self): allocation = obj_utils.create_test_allocation(self.context, name='pg.1', node_id=self.node.id) data = self.get_json('/allocations/%s' % allocation.uuid, headers=self.headers) self.assertEqual(allocation.uuid, data['uuid'])
def test_get_by_node_resource(self): allocation = obj_utils.create_test_allocation(self.context, node_id=self.node.id) data = self.get_json('/nodes/%s/allocation' % self.node.uuid, headers=self.headers) self.assertEqual(allocation.uuid, data['uuid']) self.assertEqual({}, data["extra"]) self.assertEqual(self.node.uuid, data["node_uuid"])
def test_get_by_node_resource_and_id(self): allocation = obj_utils.create_test_allocation(self.context, node_id=self.node.id) response = self.get_json('/nodes/%s/allocation/%s' % (self.node.uuid, allocation.uuid), headers=self.headers, expect_errors=True) self.assertEqual('application/json', response.content_type) self.assertEqual(http_client.METHOD_NOT_ALLOWED, response.status_int)
def test_get_collection_custom_fields(self): fields = 'uuid,extra' for i in range(3): obj_utils.create_test_allocation( self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(), name='allocation%s' % i) data = self.get_json( '/allocations?fields=%s' % fields, headers=self.headers) self.assertEqual(3, len(data['allocations'])) for allocation in data['allocations']: # We always append "links" self.assertItemsEqual(['uuid', 'extra', 'links'], allocation)
def test_get_by_node_resource(self): allocation = obj_utils.create_test_allocation(self.context, node_id=self.node.id) data = self.get_json('/nodes/%s/allocation' % self.node.uuid, headers=self.headers) self.assertEqual(allocation.uuid, data['uuid']) self.assertEqual({}, data["extra"]) self.assertEqual(self.node.uuid, data["node_uuid"])
def test_get_one_custom_fields(self): allocation = obj_utils.create_test_allocation(self.context, node_id=self.node.id) fields = 'resource_class,extra' data = self.get_json('/allocations/%s?fields=%s' % (allocation.uuid, fields), headers=self.headers) # We always append "links" self.assertItemsEqual(['resource_class', 'extra', 'links'], data)
def setUp(self): super(TestDelete, self).setUp() self.node = obj_utils.create_test_node(self.context) self.allocation = obj_utils.create_test_allocation( self.context, node_id=self.node.id, name='alloc1') self.mock_get_topic = self.useFixture( fixtures.MockPatchObject(rpcapi.ConductorAPI, 'get_random_topic') ).mock
def setUp(self): super(TestDelete, self).setUp() self.node = obj_utils.create_test_node(self.context) self.allocation = obj_utils.create_test_allocation( self.context, node_id=self.node.id, name='alloc1') self.mock_get_topic = self.useFixture( fixtures.MockPatchObject(rpcapi.ConductorAPI, 'get_random_topic')).mock
def test_get_one_custom_fields(self): allocation = obj_utils.create_test_allocation(self.context, node_id=self.node.id) fields = 'resource_class,extra' data = self.get_json( '/allocations/%s?fields=%s' % (allocation.uuid, fields), headers=self.headers) # We always append "links" self.assertItemsEqual(['resource_class', 'extra', 'links'], data)
def test_get_by_node_resource_and_id(self): allocation = obj_utils.create_test_allocation(self.context, node_id=self.node.id) response = self.get_json('/nodes/%s/allocation/%s' % (self.node.uuid, allocation.uuid), headers=self.headers, expect_errors=True) self.assertEqual('application/json', response.content_type) self.assertEqual(http_client.METHOD_NOT_ALLOWED, response.status_int)
def test_get_custom_fields_invalid_fields(self): allocation = obj_utils.create_test_allocation(self.context, node_id=self.node.id) fields = 'uuid,spongebob' response = self.get_json( '/allocations/%s?fields=%s' % (allocation.uuid, fields), headers=self.headers, expect_errors=True) self.assertEqual(http_client.BAD_REQUEST, response.status_int) self.assertEqual('application/json', response.content_type) self.assertIn('spongebob', response.json['error_message'])
def test_get_one(self): allocation = obj_utils.create_test_allocation(self.context, node_id=self.node.id) data = self.get_json('/allocations/%s' % allocation.uuid, headers=self.headers) self.assertEqual(allocation.uuid, data['uuid']) self.assertEqual({}, data["extra"]) self.assertEqual(self.node.uuid, data["node_uuid"]) # never expose the node_id self.assertNotIn('node_id', data)
def test_get_one(self): allocation = obj_utils.create_test_allocation(self.context, node_id=self.node.id) data = self.get_json('/allocations/%s' % allocation.uuid, headers=self.headers) self.assertEqual(allocation.uuid, data['uuid']) self.assertEqual({}, data["extra"]) self.assertEqual(self.node.uuid, data["node_uuid"]) # never expose the node_id self.assertNotIn('node_id', data)
def test_get_custom_fields_invalid_fields(self): allocation = obj_utils.create_test_allocation(self.context, node_id=self.node.id) fields = 'uuid,spongebob' response = self.get_json('/allocations/%s?fields=%s' % (allocation.uuid, fields), headers=self.headers, expect_errors=True) self.assertEqual(http_client.BAD_REQUEST, response.status_int) self.assertEqual('application/json', response.content_type) self.assertIn('spongebob', response.json['error_message'])
def test_many(self): allocations = [] for id_ in range(5): allocation = obj_utils.create_test_allocation( self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(), name='allocation%s' % id_) allocations.append(allocation.uuid) data = self.get_json('/allocations', headers=self.headers) self.assertEqual(len(allocations), len(data['allocations'])) uuids = [n['uuid'] for n in data['allocations']] six.assertCountEqual(self, allocations, uuids)
def test_collection_links(self): allocations = [] for id_ in range(5): allocation = obj_utils.create_test_allocation( self.context, uuid=uuidutils.generate_uuid(), name='allocation%s' % id_) allocations.append(allocation.uuid) data = self.get_json('/allocations/?limit=3', headers=self.headers) self.assertEqual(3, len(data['allocations'])) next_marker = data['allocations'][-1]['uuid'] self.assertIn(next_marker, data['next'])
def test_sort_key(self): allocations = [] for id_ in range(3): allocation = obj_utils.create_test_allocation( self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(), name='allocation%s' % id_) allocations.append(allocation.uuid) data = self.get_json('/allocations?sort_key=uuid', headers=self.headers) uuids = [n['uuid'] for n in data['allocations']] self.assertEqual(sorted(allocations), uuids)
def test_sort_key_allowed(self): allocation_uuids = [] for id_ in range(3, 0, -1): allocation = obj_utils.create_test_allocation( self.context, uuid=uuidutils.generate_uuid(), name='allocation%s' % id_) allocation_uuids.append(allocation.uuid) allocation_uuids.reverse() data = self.get_json('/allocations?sort_key=name', headers=self.headers) data_uuids = [p['uuid'] for p in data['allocations']] self.assertEqual(allocation_uuids, data_uuids)
def test_sort_key(self): allocations = [] for id_ in range(3): allocation = obj_utils.create_test_allocation( self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(), name='allocation%s' % id_) allocations.append(allocation.uuid) data = self.get_json('/allocations?sort_key=uuid', headers=self.headers) uuids = [n['uuid'] for n in data['allocations']] self.assertEqual(sorted(allocations), uuids)
def test_sort_key_allowed(self): allocation_uuids = [] for id_ in range(3, 0, -1): allocation = obj_utils.create_test_allocation( self.context, uuid=uuidutils.generate_uuid(), name='allocation%s' % id_) allocation_uuids.append(allocation.uuid) allocation_uuids.reverse() data = self.get_json('/allocations?sort_key=name', headers=self.headers) data_uuids = [p['uuid'] for p in data['allocations']] self.assertEqual(allocation_uuids, data_uuids)
def test_collection_links(self): allocations = [] for id_ in range(5): allocation = obj_utils.create_test_allocation( self.context, uuid=uuidutils.generate_uuid(), name='allocation%s' % id_) allocations.append(allocation.uuid) data = self.get_json('/allocations/?limit=3', headers=self.headers) self.assertEqual(3, len(data['allocations'])) next_marker = data['allocations'][-1]['uuid'] self.assertIn(next_marker, data['next'])
def test_non_existing_node(self): allocation = obj_utils.create_test_allocation(self.context, resource_class='x-large') self.assertRaises(exception.NodeNotFound, allocations.backfill_allocation, self.context, allocation, 42) allocation = objects.Allocation.get_by_uuid(self.context, allocation['uuid']) self.assertEqual('error', allocation['state']) self.assertIn('Node 42 could not be found', allocation['last_error']) self.assertIsNone(allocation['node_id'])
def test_many(self): allocations = [] for id_ in range(5): allocation = obj_utils.create_test_allocation( self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(), name='allocation%s' % id_) allocations.append(allocation.uuid) data = self.get_json('/allocations', headers=self.headers) self.assertEqual(len(allocations), len(data['allocations'])) uuids = [n['uuid'] for n in data['allocations']] six.assertCountEqual(self, allocations, uuids)
def test_destroy_allocation_with_node(self): node = obj_utils.create_test_node(self.context) allocation = obj_utils.create_test_allocation(self.context, node_id=node['id']) node.instance_uuid = allocation['uuid'] node.allocation_id = allocation['id'] node.save() self.service.destroy_allocation(self.context, allocation) self.assertRaises(exception.AllocationNotFound, objects.Allocation.get_by_uuid, self.context, allocation['uuid']) node = objects.Node.get_by_uuid(self.context, node['uuid']) self.assertIsNone(node['instance_uuid']) self.assertIsNone(node['allocation_id'])
def test_destroy_allocation_with_node(self): node = obj_utils.create_test_node(self.context) allocation = obj_utils.create_test_allocation(self.context, node_id=node['id']) node.instance_uuid = allocation['uuid'] node.allocation_id = allocation['id'] node.save() self.service.destroy_allocation(self.context, allocation) self.assertRaises(exception.AllocationNotFound, objects.Allocation.get_by_uuid, self.context, allocation['uuid']) node = objects.Node.get_by_uuid(self.context, node['uuid']) self.assertIsNone(node['instance_uuid']) self.assertIsNone(node['allocation_id'])
def test_success(self): node = obj_utils.create_test_node(self.context, power_state='power on', resource_class='x-large', provision_state='available') allocation = obj_utils.create_test_allocation(self.context, resource_class='x-large') allocations.do_allocate(self.context, allocation) allocation = objects.Allocation.get_by_uuid(self.context, allocation['uuid']) self.assertIsNone(allocation['last_error']) self.assertEqual('active', allocation['state']) node = objects.Node.get_by_uuid(self.context, node['uuid']) self.assertEqual(allocation['uuid'], node['instance_uuid']) self.assertEqual(allocation['id'], node['allocation_id'])
def test_get_collection_pagination_no_uuid(self): fields = 'node_uuid' limit = 2 allocations = [] for id_ in range(3): allocation = obj_utils.create_test_allocation( self.context, node_id=self.node.id, uuid=uuidutils.generate_uuid(), name='allocation%s' % id_) allocations.append(allocation) data = self.get_json( '/allocations?fields=%s&limit=%s' % (fields, limit), headers=self.headers) self.assertEqual(limit, len(data['allocations'])) self.assertIn('marker=%s' % allocations[limit - 1].uuid, data['next'])
def test_with_unassociated_node(self): node = obj_utils.create_test_node(self.context, instance_uuid=None, resource_class='x-large', provision_state='active') allocation = obj_utils.create_test_allocation(self.context, resource_class='x-large') allocations.backfill_allocation(self.context, allocation, node.id) allocation = objects.Allocation.get_by_uuid(self.context, allocation['uuid']) self.assertIsNone(allocation['last_error']) self.assertEqual('active', allocation['state']) node = objects.Node.get_by_uuid(self.context, node['uuid']) self.assertEqual(allocation['uuid'], node['instance_uuid']) self.assertEqual(allocation['id'], node['allocation_id'])
def test_nodes_filtered_out(self, mock_acquire): # Resource class does not match obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), resource_class='x-small', power_state='power off', provision_state='available') # Provision state is not available obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), resource_class='x-large', power_state='power off', provision_state='manageable') # Power state is undefined obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), resource_class='x-large', power_state=None, provision_state='available') # Maintenance mode is on obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), maintenance=True, resource_class='x-large', power_state='power off', provision_state='available') # Already associated obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), instance_uuid=uuidutils.generate_uuid(), resource_class='x-large', power_state='power off', provision_state='available') allocation = obj_utils.create_test_allocation(self.context, resource_class='x-large') allocations.do_allocate(self.context, allocation) self.assertIn('no available nodes', allocation['last_error']) self.assertIn('x-large', allocation['last_error']) self.assertEqual('error', allocation['state']) # All nodes are filtered out on the database level. self.assertFalse(mock_acquire.called)
def test_destroy_allocation_with_active_node(self): node = obj_utils.create_test_node(self.context, provision_state='active') allocation = obj_utils.create_test_allocation(self.context, node_id=node['id']) node.instance_uuid = allocation['uuid'] node.allocation_id = allocation['id'] node.save() exc = self.assertRaises(messaging.rpc.ExpectedException, self.service.destroy_allocation, self.context, allocation) # Compare true exception hidden by @messaging.expected_exceptions self.assertEqual(exception.InvalidState, exc.exc_info[0]) objects.Allocation.get_by_uuid(self.context, allocation['uuid']) node = objects.Node.get_by_uuid(self.context, node['uuid']) self.assertEqual(allocation['uuid'], node['instance_uuid']) self.assertEqual(allocation['id'], node['allocation_id'])
def test_nodes_changed_after_lock(self, mock_acquire): nodes = [obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), resource_class='x-large', power_state='power off', provision_state='available') for _ in range(5)] for node in nodes: db_utils.create_test_node_trait(trait='tr1', node_id=node.id) # Modify nodes in-memory so that they no longer match the allocation: # Resource class does not match nodes[0].resource_class = 'x-small' # Provision state is not available nodes[1].provision_state = 'deploying' # Maintenance mode is on nodes[2].maintenance = True # Already associated nodes[3].instance_uuid = uuidutils.generate_uuid() # Traits changed nodes[4].traits.objects[:] = [] mock_acquire.side_effect = [ mock.MagicMock(**{'__enter__.return_value.node': node}) for node in nodes ] allocation = obj_utils.create_test_allocation(self.context, resource_class='x-large', traits=['tr1']) allocations.do_allocate(self.context, allocation) self.assertIn('all nodes were filtered out', allocation['last_error']) self.assertEqual('error', allocation['state']) # No retries for these failures. self.assertEqual(5, mock_acquire.call_count)
def test_nodes_candidates_do_not_match(self, mock_acquire): obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), resource_class='x-large', power_state='power off', provision_state='available') # Resource class does not match node = obj_utils.create_test_node(self.context, uuid=uuidutils.generate_uuid(), power_state='power on', resource_class='x-small', provision_state='available') allocation = obj_utils.create_test_allocation( self.context, resource_class='x-large', candidate_nodes=[node['uuid']]) allocations.do_allocate(self.context, allocation) self.assertIn('none of the requested nodes', allocation['last_error']) self.assertIn('x-large', allocation['last_error']) self.assertEqual('error', allocation['state']) # All nodes are filtered out on the database level. self.assertFalse(mock_acquire.called)