def test_dispatch_to_all_managers_mainline_fails(self):
        # Ensure that if the mainline manager is unable to run the method
        # that we properly fall back to generic.
        hardware.dispatch_to_all_managers('mainline_fail')

        self.assertEqual(1,
                         self.mainline_hwm.obj._call_counts['mainline_fail'])
        self.assertEqual(1, self.generic_hwm.obj._call_counts['mainline_fail'])
    def test_dispatch_to_all_managers_mainline_fails(self):
        # Ensure that if the mainline manager is unable to run the method
        # that we properly fall back to generic.
        hardware.dispatch_to_all_managers('mainline_fail')

        self.assertEqual(
            1, self.mainline_hwm.obj._call_counts['mainline_fail'])
        self.assertEqual(1, self.generic_hwm.obj._call_counts['mainline_fail'])
    def test_dispatch_to_all_managers_mainline_only(self):
        results = hardware.dispatch_to_all_managers('generic_none')

        self.assertEqual(1, self.generic_hwm.obj._call_counts['generic_none'])
        self.assertEqual({'FakeGenericHardwareManager': None,
                          'FakeMainlineHardwareManager': 'specific'},
                         results)
Example #4
0
    def get_clean_steps(self, node, ports):
        """Get the list of clean steps supported for the node and ports

        :param node: A dict representation of a node
        :param ports: A dict representation of ports attached to node

        :returns: A list of clean steps with keys step, priority, and
            reboot_requested
        """
        LOG.debug(
            'Getting clean steps, called with node: %(node)s, '
            'ports: %(ports)s', {
                'node': node,
                'ports': ports
            })
        hardware.cache_node(node)
        # Results should be a dict, not a list
        candidate_steps = hardware.dispatch_to_all_managers(
            'get_clean_steps', node, ports)

        LOG.debug('Clean steps before deduplication: %s', candidate_steps)
        clean_steps = hardware.deduplicate_steps(candidate_steps)
        LOG.debug('Returning clean steps: %s', clean_steps)

        return {
            'clean_steps': clean_steps,
            'hardware_manager_version': hardware.get_current_versions(),
        }
Example #5
0
def _get_current_clean_version():
    """Fetches versions from all hardware managers.

    :returns: Dict in the format {name: version} containing one entry for
              every hardware manager.
    """
    return {version.get('name'): version.get('version')
            for version in hardware.dispatch_to_all_managers(
                'get_version').values()}
    def test_dispatch_to_all_managers_generic_method_only(self):
        results = hardware.dispatch_to_all_managers('specific_none')

        self.assertEqual(1, self.generic_hwm.obj._call_counts['specific_none'])
        self.assertEqual(
            {
                'FakeGenericHardwareManager': 'generic',
                'FakeMainlineHardwareManager': None
            }, results)
    def test_dispatch_to_all_managers_both_succeed(self):
        # In the case where both managers will work; only the most specific
        # manager should have it's function called.
        results = hardware.dispatch_to_all_managers('both_succeed')

        self.assertEqual({'FakeGenericHardwareManager': 'generic_both',
                          'FakeMainlineHardwareManager': 'specific_both'},
                         results)
        self.assertEqual(1, self.mainline_hwm.obj._call_counts['both_succeed'])
        self.assertEqual(1, self.generic_hwm.obj._call_counts['both_succeed'])
    def test_dispatch_to_all_managers_both_succeed(self):
        # In the case where both managers will work; only the most specific
        # manager should have it's function called.
        results = hardware.dispatch_to_all_managers('both_succeed')

        self.assertEqual(
            {
                'FakeGenericHardwareManager': 'generic_both',
                'FakeMainlineHardwareManager': 'specific_both'
            }, results)
        self.assertEqual(1, self.mainline_hwm.obj._call_counts['both_succeed'])
        self.assertEqual(1, self.generic_hwm.obj._call_counts['both_succeed'])
    def get_clean_steps(self, node, ports):
        """Get the list of clean steps supported for the node and ports

        :param node: A dict representation of a node
        :param ports: A dict representation of ports attached to node

        :returns: A list of clean steps with keys step, priority, and
            reboot_requested
        """
        # Results should be a dict, not a list
        steps = hardware.dispatch_to_all_managers('get_clean_steps',
                                                  node, ports)

        return {
            'clean_steps': steps,
            'hardware_manager_version': _get_current_clean_version()
        }
Example #10
0
    def get_clean_steps(self, node, ports):
        """Get the list of clean steps supported for the node and ports

        :param node: A dict representation of a node
        :param ports: A dict representation of ports attached to node

        :returns: A list of clean steps with keys step, priority, and
            reboot_requested
        """
        LOG.debug('Getting clean steps, called with node: %(node)s, '
                  'ports: %(ports)s', {'node': node, 'ports': ports})
        # Results should be a dict, not a list
        steps = hardware.dispatch_to_all_managers('get_clean_steps',
                                                  node, ports)

        LOG.debug('Returning clean steps: %s', steps)
        return {
            'clean_steps': steps,
            'hardware_manager_version': _get_current_clean_version()
        }
Example #11
0
def _get_current_clean_version():
    return {version.get('name'): version.get('version')
            for version in hardware.dispatch_to_all_managers(
                'get_version').values()}
Example #12
0
def _get_current_clean_version():
    return {
        version.get('name'): version.get('version')
        for version in hardware.dispatch_to_all_managers(
            'get_version').values()
    }
Example #13
0
def _deduplicate_steps(candidate_steps):
    """Remove duplicated clean steps

    Deduplicates clean steps returned from HardwareManagers to prevent
    running a given step more than once. Other than individual step
    priority, it doesn't actually impact the cleaning run which specific
    steps are kept and what HardwareManager they are associated with.
    However, in order to make testing easier, this method returns
    deterministic results.

    Uses the following filtering logic to decide which step "wins":
    - Keep the step that belongs to HardwareManager with highest
      HardwareSupport (larger int) value.
    - If equal support level, keep the step with the higher defined priority
      (larger int).
    - If equal support level and priority, keep the step associated with the
      HardwareManager whose name comes earlier in the alphabet.

    :param candidate_steps: A dict containing all possible clean steps from
        all managers, key=manager, value=list of clean steps
    :returns: A deduplicated dictionary of {hardware_manager:
        [clean-steps]}
    """
    support = hardware.dispatch_to_all_managers(
        'evaluate_hardware_support')

    steps = collections.defaultdict(list)
    deduped_steps = collections.defaultdict(list)

    for manager, manager_steps in candidate_steps.items():
        # We cannot deduplicate steps with unknown hardware support
        if manager not in support:
            LOG.warning('Unknown hardware support for %(manager)s, '
                        'dropping clean steps: %(steps)s',
                        {'manager': manager, 'steps': manager_steps})
            continue

        for step in manager_steps:
            # build a new dict of steps that's easier to filter
            step['hwm'] = {'name': manager,
                           'support': support[manager]}
            steps[step['step']].append(step)

    for step_name, step_list in steps.items():
        # determine the max support level among candidate steps
        max_support = max([x['hwm']['support'] for x in step_list])
        # filter out any steps that are not at the max support for this step
        max_support_steps = [x for x in step_list
                             if x['hwm']['support'] == max_support]

        # determine the max priority among remaining steps
        max_priority = max([x['priority'] for x in max_support_steps])
        # filter out any steps that are not at the max priority for this step
        max_priority_steps = [x for x in max_support_steps
                              if x['priority'] == max_priority]

        # if there are still multiple steps, sort by hwm name and take
        # the first result
        winning_step = sorted(max_priority_steps,
                              key=lambda x: x['hwm']['name'])[0]
        # Remove extra metadata we added to the step for filtering
        manager = winning_step.pop('hwm')['name']
        # Add winning step to deduped_steps
        deduped_steps[manager].append(winning_step)

    return deduped_steps
Example #14
0
def _deduplicate_steps(candidate_steps):
    """Remove duplicated clean steps

    Deduplicates clean steps returned from HardwareManagers to prevent
    running a given step more than once. Other than individual step
    priority, it doesn't actually impact the cleaning run which specific
    steps are kept and what HardwareManager they are associated with.
    However, in order to make testing easier, this method returns
    deterministic results.

    Uses the following filtering logic to decide which step "wins":
    - Keep the step that belongs to HardwareManager with highest
      HardwareSupport (larger int) value.
    - If equal support level, keep the step with the higher defined priority
      (larger int).
    - If equal support level and priority, keep the step associated with the
      HardwareManager whose name comes earlier in the alphabet.

    :param candidate_steps: A dict containing all possible clean steps from
        all managers, key=manager, value=list of clean steps
    :returns: A deduplicated dictionary of {hardware_manager:
        [clean-steps]}
    """
    support = hardware.dispatch_to_all_managers(
        'evaluate_hardware_support')

    steps = collections.defaultdict(list)
    deduped_steps = collections.defaultdict(list)

    for manager, manager_steps in candidate_steps.items():
        # We cannot deduplicate steps with unknown hardware support
        if manager not in support:
            LOG.warning('Unknown hardware support for %(manager)s, '
                        'dropping clean steps: %(steps)s',
                        {'manager': manager, 'steps': manager_steps})
            continue

        for step in manager_steps:
            # build a new dict of steps that's easier to filter
            step['hwm'] = {'name': manager,
                           'support': support[manager]}
            steps[step['step']].append(step)

    for step_name, step_list in steps.items():
        # determine the max support level among candidate steps
        max_support = max([x['hwm']['support'] for x in step_list])
        # filter out any steps that are not at the max support for this step
        max_support_steps = [x for x in step_list
                             if x['hwm']['support'] == max_support]

        # determine the max priority among remaining steps
        max_priority = max([x['priority'] for x in max_support_steps])
        # filter out any steps that are not at the max priority for this step
        max_priority_steps = [x for x in max_support_steps
                              if x['priority'] == max_priority]

        # if there are still multiple steps, sort by hwm name and take
        # the first result
        winning_step = sorted(max_priority_steps,
                              key=lambda x: x['hwm']['name'])[0]
        # Remove extra metadata we added to the step for filtering
        manager = winning_step.pop('hwm')['name']
        # Add winning step to deduped_steps
        deduped_steps[manager].append(winning_step)

    return deduped_steps