Beispiel #1
0
    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)
Beispiel #2
0
    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)
Beispiel #3
0
    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})
Beispiel #4
0
    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_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'])
Beispiel #7
0
 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)
Beispiel #8
0
 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)
Beispiel #9
0
    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_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'])
Beispiel #11
0
    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_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)
Beispiel #13
0
    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)
    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)