def _ejection_test(self, env):
        """Are we ejecting nodes whose images are no longer in the current
        image list?
        """
        strategy = sps.SimpleProportionalStrategy()
        strategy.update_current_state(**env)
        directives = strategy.directives()
        if len(directives) == 0:
            directives = [sb.CacheNode('a', 'b', 'c')]
        ejection_directives = filter(
            lambda direct: isinstance(direct, sb.EjectNode), directives)
        ejected_node_uuids = sb.build_attribute_set(ejection_directives,
                                                    'node_uuid')
        for node in env['nodes']:
            # Make sure that cached nodes with invalid images are ejected.
            if node.cached_image_uuid == INVALID_IMAGE.uuid and node.cached:
                self.assertIn(node.node_uuid,
                              ejected_node_uuids,
                              ("A node with an invalid image UUID was not "
                               "ejected from the cache. Node UUID: %s" % (
                                   node.node_uuid)))

        # Ensure ejected nodes are marked as 'provisioned'.
        nodes_by_uuid = {node.node_uuid: node for node in env['nodes']}
        for node_uuid in ejected_node_uuids:
            self.assertTrue(nodes_by_uuid[node_uuid].provisioned)

        # Make sure the strategy is not trying to cache to ejected nodes.
        cache_directives = filter(
            lambda direct: isinstance(direct, sb.CacheNode), directives)
        cached_node_uuids = sb.build_attribute_set(cache_directives,
                                                   'node_uuid')
        self.assertEqual(
            0, len(cached_node_uuids.intersection(ejected_node_uuids)),
            "One or more ejected nodes scheduled to cache immediately!")
 def test_dont_eject_provisioned_nodes(self):
     """Don't try to eject nodes which are considered provisioned."""
     strategy = sps.SimpleProportionalStrategy()
     invalid_cached_and_provisioned_node = {
         'nodes': [sb.NodeInput("caaa", "Compute", True, True,
                                INVALID_IMAGE)],
         'flavors': sb_test.TEST_FLAVORS,
         'images': sb_test.TEST_IMAGES
     }
     strategy.update_current_state(**invalid_cached_and_provisioned_node)
     directives = strategy.directives()
     self.assertTrue(len(directives) == 0,
                     "Trying to eject a provisioned node!")
 def _test_proportion_goal_versus_environment(self, test_percentage=0.50):
     """Test that strategy goals are always being met by directives output.
     Are we always caching at least enough to hit our proportion goal.
     """
     CONF.set_override('percentage_to_cache',
                       test_percentage,
                       group='simple_proportional_strategy')
     strategy = sps.SimpleProportionalStrategy()
     for env_name, env in self.environments.iteritems():
         print("Testing %s environment." % env_name)
         strategy.update_current_state(**env)
         directives = strategy.directives()
         print("Directives:")
         if directives:
             for directive in directives:
                 print(str(directive))
         for flavor in env['flavors']:
             self._test_proportion_goal_versus_flavor(
                 strategy, directives, env['nodes'], flavor)
    def test_percentage_clamp(self):
        """Make sure valid percentages are valid, and invalid percentages
        raise exceptions.
        """
        valid_percentages = [0, 0.01, 0.025, 0.05011, 0.1, 0.15, 0.9999, 1]
        invalid_percentages = [-1, -5, -0.1, 1.001, 1.00001]
        for percentage in valid_percentages:
            CONF.set_override('percentage_to_cache',
                              percentage,
                              group='simple_proportional_strategy')
            try:
                sps.SimpleProportionalStrategy()
            except sps.InvalidPercentageError:
                self.assertTrue(False, (
                    "SimpleProportionalStrategy raised InvalidPercentageError "
                    "for %f inappropriately." % (percentage)))

        for percentage in invalid_percentages:
            CONF.set_override('percentage_to_cache',
                              percentage,
                              group='simple_proportional_strategy')
            self.assertRaises(sps.InvalidPercentageError,
                              sps.SimpleProportionalStrategy)