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_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_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_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 _resume_allocations(self, context): """Resume unfinished allocations on restart.""" filters = {'state': states.ALLOCATING, 'conductor_affinity': self.conductor.id} for allocation in objects.Allocation.list(context, filters=filters): LOG.debug('Resuming unfinished allocation %s', allocation.uuid) allocations.do_allocate(context, allocation)
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_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_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_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)