Tidy up - Watcher Decision Engine package
Some Python class and packages need to be renamed for a better compliance with the shared terminology which provides a better understanding of Watcher objects and components by every contributor. This patchset is there to change the code structure by adding the folder "strategies" and "loading". Partially implements: blueprint glossary-related-refactoring Change-Id: I56fb24ee6762b3186eccde5983233e17bb227cc1
This commit is contained in:
parent
92940ba9e2
commit
62570525ad
|
@ -42,8 +42,8 @@ watcher.database.migration_backend =
|
|||
sqlalchemy = watcher.db.sqlalchemy.migration
|
||||
|
||||
watcher_strategies =
|
||||
dummy = watcher.decision_engine.strategy.dummy_strategy:DummyStrategy
|
||||
basic = watcher.decision_engine.strategy.basic_consolidation:BasicConsolidation
|
||||
dummy = watcher.decision_engine.strategy.strategies.dummy_strategy:DummyStrategy
|
||||
basic = watcher.decision_engine.strategy.strategies.basic_consolidation:BasicConsolidation
|
||||
|
||||
[build_sphinx]
|
||||
source-dir = doc/source
|
||||
|
|
|
@ -22,7 +22,7 @@ import pecan
|
|||
from watcher.api import acl
|
||||
from watcher.api import config as api_config
|
||||
from watcher.api import middleware
|
||||
from watcher.decision_engine.strategy.selector import default \
|
||||
from watcher.decision_engine.strategy.selection import default \
|
||||
as strategy_selector
|
||||
|
||||
# Register options for the service
|
||||
|
|
|
@ -17,9 +17,9 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
import abc
|
||||
import six
|
||||
|
||||
from watcher.decision_engine.strategy.level import StrategyLevel
|
||||
import six
|
||||
from watcher.decision_engine.strategy.common.level import StrategyLevel
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
|
|
|
@ -17,7 +17,7 @@ from oslo_log import log
|
|||
|
||||
from watcher.decision_engine.planner.default import DefaultPlanner
|
||||
from watcher.decision_engine.strategy.context.base import BaseStrategyContext
|
||||
from watcher.decision_engine.strategy.selector.default import StrategySelector
|
||||
from watcher.decision_engine.strategy.selection.default import StrategySelector
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
|
|
@ -0,0 +1,43 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
# Copyright (c) 2015 b<>com
|
||||
#
|
||||
# Authors: Jean-Emile DARTOIS <jean-emile.dartois@b-com.com>
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
import abc
|
||||
from oslo_log import log
|
||||
import six
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
@six.add_metaclass(abc.ABCMeta)
|
||||
class BaseStrategyLoader(object):
|
||||
@abc.abstractmethod
|
||||
def load_available_strategies(self):
|
||||
raise NotImplementedError() # pragma:no cover
|
||||
|
||||
def load(self, strategy_to_load=None):
|
||||
strategy_selected = None
|
||||
try:
|
||||
available_strategies = self.load_available_strategies()
|
||||
strategy_cls = available_strategies.get(
|
||||
strategy_to_load, self.default_strategy_cls
|
||||
)
|
||||
strategy_selected = strategy_cls()
|
||||
except Exception as exc:
|
||||
LOG.exception(exc)
|
||||
|
||||
return strategy_selected
|
|
@ -21,32 +21,21 @@ from __future__ import unicode_literals
|
|||
|
||||
from oslo_log import log
|
||||
from stevedore import ExtensionManager
|
||||
from watcher.decision_engine.strategy.basic_consolidation import \
|
||||
|
||||
from watcher.decision_engine.strategy.loading.base import BaseStrategyLoader
|
||||
from watcher.decision_engine.strategy.strategies.basic_consolidation import \
|
||||
BasicConsolidation
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
||||
class StrategyLoader(object):
|
||||
class DefaultStrategyLoader(BaseStrategyLoader):
|
||||
|
||||
default_strategy_cls = BasicConsolidation
|
||||
|
||||
def load_strategies(self):
|
||||
def load_available_strategies(self):
|
||||
extension_manager = ExtensionManager(
|
||||
namespace='watcher_strategies',
|
||||
invoke_on_load=True,
|
||||
)
|
||||
return {ext.name: ext.plugin for ext in extension_manager.extensions}
|
||||
|
||||
def load(self, model):
|
||||
strategy = None
|
||||
try:
|
||||
available_strategies = self.load_strategies()
|
||||
strategy_cls = available_strategies.get(
|
||||
model, self.default_strategy_cls
|
||||
)
|
||||
strategy = strategy_cls()
|
||||
except Exception as exc:
|
||||
LOG.exception(exc)
|
||||
|
||||
return strategy
|
|
@ -16,9 +16,12 @@
|
|||
|
||||
from oslo_config import cfg
|
||||
from oslo_log import log
|
||||
|
||||
from watcher.common.exception import WatcherException
|
||||
from watcher.decision_engine.strategy.loader import StrategyLoader
|
||||
from watcher.decision_engine.strategy.selector.base import BaseSelector
|
||||
from watcher.decision_engine.strategy.loading.default import \
|
||||
DefaultStrategyLoader
|
||||
from watcher.decision_engine.strategy.selection.base import BaseSelector
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
@ -41,7 +44,7 @@ CONF.register_opts(WATCHER_GOALS_OPTS, goals_opt_group)
|
|||
class StrategySelector(BaseSelector):
|
||||
|
||||
def __init__(self):
|
||||
self.strategy_loader = StrategyLoader()
|
||||
self.strategy_loader = DefaultStrategyLoader()
|
||||
|
||||
def define_from_goal(self, goal_name):
|
||||
strategy_to_load = None
|
|
@ -16,12 +16,12 @@
|
|||
|
||||
import abc
|
||||
from oslo_log import log
|
||||
|
||||
import six
|
||||
from watcher.decision_engine.solution.default import DefaultSolution
|
||||
from watcher.decision_engine.strategy.level import StrategyLevel
|
||||
|
||||
|
||||
from watcher.decision_engine.solution.default import DefaultSolution
|
||||
from watcher.decision_engine.strategy.common.level import StrategyLevel
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
|
|
@ -28,8 +28,8 @@ from watcher.decision_engine.model.hypervisor_state import HypervisorState
|
|||
from watcher.decision_engine.model.power_state import PowerState
|
||||
from watcher.decision_engine.model.resource import ResourceType
|
||||
from watcher.decision_engine.model.vm_state import VMState
|
||||
from watcher.decision_engine.strategy.base import BaseStrategy
|
||||
from watcher.decision_engine.strategy.level import StrategyLevel
|
||||
from watcher.decision_engine.strategy.common.level import StrategyLevel
|
||||
from watcher.decision_engine.strategy.strategies.base import BaseStrategy
|
||||
from watcher.metrics_engine.cluster_history.ceilometer import \
|
||||
CeilometerClusterHistory
|
||||
|
||||
|
@ -53,12 +53,12 @@ class BasicConsolidation(BaseStrategy):
|
|||
and often tend to migrate from one physical machine to another.
|
||||
Hence, the traditional and offline heuristics such as bin packing
|
||||
are not applicable for the placement VM in cloud computing.
|
||||
So, the decision Engine optimizer provide placement strategy considering
|
||||
So, the decision Engine optimizer provides placement strategy considering
|
||||
not only the performance effects but also the workload characteristics of
|
||||
VMs and others metrics like the power consumption and
|
||||
the tenants constraints (SLAs).
|
||||
|
||||
The watcher optimizer use an online VM placement technique
|
||||
The watcher optimizer uses an online VM placement technique
|
||||
based on machine learning and meta-heuristics that must handle :
|
||||
- multi-objectives
|
||||
- Contradictory objectives
|
||||
|
@ -121,9 +121,9 @@ class BasicConsolidation(BaseStrategy):
|
|||
vm_to_mig):
|
||||
'''check if the migration is possible
|
||||
|
||||
:param model: current state of the cluster
|
||||
:param src_hypervisor: the current of the virtual machine
|
||||
:param dest_hypervisor:the destination of the virtual machine
|
||||
:param model: the current state of the cluster
|
||||
:param src_hypervisor: the current node of the virtual machine
|
||||
:param dest_hypervisor: the destination of the virtual machine
|
||||
:param vm_to_mig: the virtual machine
|
||||
:return: True if the there is enough place otherwise false
|
||||
'''
|
||||
|
@ -167,7 +167,7 @@ class BasicConsolidation(BaseStrategy):
|
|||
"""Check threshold
|
||||
|
||||
check the threshold value defined by the ratio of
|
||||
aggregated CPU capacity of VMS on one node to CPU capacity
|
||||
aggregated CPU capacity of VMs on one node to CPU capacity
|
||||
of this node must not exceed the threshold value.
|
||||
:param dest_hypervisor:
|
||||
:param total_cores
|
||||
|
@ -213,7 +213,7 @@ class BasicConsolidation(BaseStrategy):
|
|||
|
||||
def calculate_weight(self, model, element, total_cores_used,
|
||||
total_disk_used, total_memory_used):
|
||||
"""Calculate weight of every
|
||||
"""Calculate weight of every resource
|
||||
|
||||
:param model:
|
||||
:param element:
|
||||
|
@ -248,7 +248,7 @@ class BasicConsolidation(BaseStrategy):
|
|||
return (score_cores + score_disk + score_memory) / 3
|
||||
|
||||
def calculate_score_node(self, hypervisor, model):
|
||||
"""calculate the score that reprensent the utilization level
|
||||
"""calculate the score that represent the utilization level
|
||||
|
||||
:param hypervisor:
|
||||
:param model:
|
||||
|
@ -331,7 +331,7 @@ class BasicConsolidation(BaseStrategy):
|
|||
model)))
|
||||
|
||||
def execute(self, orign_model):
|
||||
LOG.debug("initialize Sercon Consolidation")
|
||||
LOG.debug("Initialize Sercon Consolidation")
|
||||
|
||||
if orign_model is None:
|
||||
raise ClusterStateNotDefined()
|
||||
|
@ -411,7 +411,7 @@ class BasicConsolidation(BaseStrategy):
|
|||
vm_score.append(
|
||||
(vm_id, self.calculate_score_vm(vm, current_model)))
|
||||
|
||||
''' sort VM's by Score '''
|
||||
''' sort VMs by Score '''
|
||||
v = sorted(vm_score, reverse=True, key=lambda x: (x[1]))
|
||||
LOG.debug("VM(s) BFD {0}".format(v))
|
||||
|
|
@ -17,9 +17,9 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
from oslo_log import log
|
||||
from watcher.decision_engine.strategy.strategies.base import BaseStrategy
|
||||
|
||||
from watcher.decision_engine.actions.nop import Nop
|
||||
from watcher.decision_engine.strategy.base import BaseStrategy
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
|
@ -18,7 +18,7 @@
|
|||
import watcher.api.app
|
||||
from watcher.applier import manager_applier
|
||||
from watcher.decision_engine import manager
|
||||
from watcher.decision_engine.strategy.selector import default \
|
||||
from watcher.decision_engine.strategy.selection import default \
|
||||
as strategy_selector
|
||||
|
||||
|
||||
|
|
|
@ -13,7 +13,6 @@
|
|||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from mock import call
|
||||
from mock import MagicMock
|
||||
from watcher.decision_engine.command.audit import TriggerAuditCommand
|
||||
|
@ -21,8 +20,8 @@ from watcher.decision_engine.messaging.events import Events
|
|||
from watcher.objects.audit import Audit
|
||||
from watcher.objects.audit import AuditStatus
|
||||
from watcher.tests.db.base import DbTestCase
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
FakerModelCollector
|
||||
from watcher.tests.decision_engine.strategy.strategies.faker_cluster_state \
|
||||
import FakerModelCollector
|
||||
from watcher.tests.objects import utils as obj_utils
|
||||
|
||||
|
||||
|
|
|
@ -22,7 +22,7 @@ from watcher.decision_engine.messaging.audit_endpoint import AuditEndpoint
|
|||
from watcher.metrics_engine.cluster_model_collector.manager import \
|
||||
CollectorManager
|
||||
from watcher.tests import base
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
from watcher.tests.decision_engine.strategy.strategies.faker_cluster_state import \
|
||||
FakerModelCollector
|
||||
|
||||
|
||||
|
|
|
@ -17,17 +17,18 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
import uuid
|
||||
|
||||
from watcher.decision_engine.model.hypervisor import Hypervisor
|
||||
from watcher.decision_engine.model.vm_state import VMState
|
||||
from watcher.tests import base
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
from watcher.tests.decision_engine.strategy.strategies.faker_cluster_state import \
|
||||
FakerModelCollector
|
||||
|
||||
|
||||
class TestMapping(base.BaseTestCase):
|
||||
def test_get_node_from_vm(self):
|
||||
fake_cluster = FakerModelCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
model = fake_cluster.generate_scenario_3_with_2_hypervisors()
|
||||
|
||||
vms = model.get_all_vms()
|
||||
keys = list(vms.keys())
|
||||
|
@ -39,14 +40,14 @@ class TestMapping(base.BaseTestCase):
|
|||
|
||||
def test_get_node_from_vm_id(self):
|
||||
fake_cluster = FakerModelCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
model = fake_cluster.generate_scenario_3_with_2_hypervisors()
|
||||
|
||||
hyps = model.mapping.get_node_vms_from_id("BLABLABLA")
|
||||
self.assertEqual(hyps.__len__(), 0)
|
||||
|
||||
def test_get_all_vms(self):
|
||||
fake_cluster = FakerModelCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
model = fake_cluster.generate_scenario_3_with_2_hypervisors()
|
||||
|
||||
vms = model.get_all_vms()
|
||||
self.assertEqual(vms.__len__(), 2)
|
||||
|
@ -57,7 +58,7 @@ class TestMapping(base.BaseTestCase):
|
|||
|
||||
def test_get_mapping(self):
|
||||
fake_cluster = FakerModelCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
model = fake_cluster.generate_scenario_3_with_2_hypervisors()
|
||||
|
||||
mapping_vm = model.mapping.get_mapping_vm()
|
||||
self.assertEqual(mapping_vm.__len__(), 2)
|
||||
|
@ -66,7 +67,7 @@ class TestMapping(base.BaseTestCase):
|
|||
|
||||
def test_migrate_vm(self):
|
||||
fake_cluster = FakerModelCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
model = fake_cluster.generate_scenario_3_with_2_hypervisors()
|
||||
vms = model.get_all_vms()
|
||||
keys = list(vms.keys())
|
||||
vm0 = vms[keys[0]]
|
||||
|
@ -81,7 +82,7 @@ class TestMapping(base.BaseTestCase):
|
|||
|
||||
def test_unmap_from_id_log_warning(self):
|
||||
fake_cluster = FakerModelCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
model = fake_cluster.generate_scenario_3_with_2_hypervisors()
|
||||
vms = model.get_all_vms()
|
||||
keys = list(vms.keys())
|
||||
vm0 = vms[keys[0]]
|
||||
|
@ -95,7 +96,7 @@ class TestMapping(base.BaseTestCase):
|
|||
|
||||
def test_unmap_from_id(self):
|
||||
fake_cluster = FakerModelCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
model = fake_cluster.generate_scenario_3_with_2_hypervisors()
|
||||
vms = model.get_all_vms()
|
||||
keys = list(vms.keys())
|
||||
vm0 = vms[keys[0]]
|
||||
|
|
|
@ -17,15 +17,15 @@
|
|||
# limitations under the License.
|
||||
#
|
||||
import uuid
|
||||
|
||||
from watcher.common import exception
|
||||
from watcher.common.exception import IllegalArgumentException
|
||||
from watcher.decision_engine.model.hypervisor import Hypervisor
|
||||
from watcher.decision_engine.model.hypervisor_state import HypervisorState
|
||||
from watcher.decision_engine.model.model_root import ModelRoot
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
FakerModelCollector
|
||||
|
||||
from watcher.tests import base
|
||||
from watcher.tests.decision_engine.strategy.strategies.faker_cluster_state import \
|
||||
FakerModelCollector
|
||||
|
||||
|
||||
class TestModel(base.BaseTestCase):
|
||||
|
|
|
@ -13,20 +13,40 @@
|
|||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
|
||||
from __future__ import unicode_literals
|
||||
|
||||
from mock import patch
|
||||
from stevedore.extension import Extension
|
||||
from stevedore.extension import ExtensionManager
|
||||
from watcher.decision_engine.strategy.dummy_strategy import DummyStrategy
|
||||
from watcher.decision_engine.strategy.loader import StrategyLoader
|
||||
|
||||
from watcher.decision_engine.strategy.loading.default import \
|
||||
DefaultStrategyLoader
|
||||
from watcher.decision_engine.strategy.strategies.base import BaseStrategy
|
||||
from watcher.decision_engine.strategy.strategies.dummy_strategy import \
|
||||
DummyStrategy
|
||||
from watcher.tests.base import TestCase
|
||||
|
||||
|
||||
class TestStrategyLoader(TestCase):
|
||||
class TestDefaultStrategyLoader(TestCase):
|
||||
|
||||
@patch("watcher.decision_engine.strategy.loader.ExtensionManager")
|
||||
strategy_loader = DefaultStrategyLoader()
|
||||
|
||||
def test_load_strategy_with_empty_model(self):
|
||||
selected_strategy = self.strategy_loader.load(None)
|
||||
self.assertIsNotNone(selected_strategy,
|
||||
'The default strategy not be must none')
|
||||
self.assertIsInstance(selected_strategy, BaseStrategy)
|
||||
|
||||
def test_load_strategy_is_basic(self):
|
||||
exptected_strategy = 'basic'
|
||||
selected_strategy = self.strategy_loader.load(exptected_strategy)
|
||||
self.assertEqual(
|
||||
selected_strategy.name,
|
||||
exptected_strategy,
|
||||
'The default strategy should be basic')
|
||||
|
||||
@patch(
|
||||
"watcher.decision_engine.strategy.loading.default.ExtensionManager")
|
||||
def test_strategy_loader(self, m_extension_manager):
|
||||
dummy_strategy_name = "dummy"
|
||||
# Set up the fake Stevedore extensions
|
||||
|
@ -40,15 +60,13 @@ class TestStrategyLoader(TestCase):
|
|||
)],
|
||||
namespace="watcher_strategies",
|
||||
)
|
||||
strategy_loader = StrategyLoader()
|
||||
strategy_loader = DefaultStrategyLoader()
|
||||
loaded_strategy = strategy_loader.load("dummy")
|
||||
|
||||
self.assertEqual("dummy", loaded_strategy.name)
|
||||
self.assertEqual("Dummy Strategy", loaded_strategy.description)
|
||||
|
||||
def test_load_dummy_strategy(self):
|
||||
strategy_loader = StrategyLoader()
|
||||
strategy_loader = DefaultStrategyLoader()
|
||||
loaded_strategy = strategy_loader.load("dummy")
|
||||
|
||||
self.assertEqual("dummy", loaded_strategy.name)
|
||||
self.assertEqual("Dummy Strategy", loaded_strategy.description)
|
||||
self.assertIsInstance(loaded_strategy, DummyStrategy)
|
|
@ -15,10 +15,13 @@
|
|||
# limitations under the License.
|
||||
from mock import patch
|
||||
from oslo_config import cfg
|
||||
|
||||
from watcher.common.exception import WatcherException
|
||||
from watcher.decision_engine.strategy.loader import StrategyLoader
|
||||
from watcher.decision_engine.strategy.selector.default import StrategySelector
|
||||
from watcher.decision_engine.strategy.loading.default import \
|
||||
DefaultStrategyLoader
|
||||
from watcher.decision_engine.strategy.selection.default import StrategySelector
|
||||
from watcher.tests.base import TestCase
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
|
@ -26,7 +29,7 @@ class TestStrategySelector(TestCase):
|
|||
|
||||
strategy_selector = StrategySelector()
|
||||
|
||||
@patch.object(StrategyLoader, 'load')
|
||||
@patch.object(DefaultStrategyLoader, 'load')
|
||||
def test_define_from_goal(self, mock_call):
|
||||
cfg.CONF.set_override(
|
||||
'goals', {"DUMMY": "fake"}, group='watcher_goals'
|
||||
|
@ -36,7 +39,7 @@ class TestStrategySelector(TestCase):
|
|||
self.strategy_selector.define_from_goal(expected_goal)
|
||||
mock_call.assert_called_once_with(expected_strategy)
|
||||
|
||||
@patch.object(StrategyLoader, 'load')
|
||||
@patch.object(DefaultStrategyLoader, 'load')
|
||||
def test_define_from_goal_with_incorrect_mapping(self, mock_call):
|
||||
cfg.CONF.set_override(
|
||||
'goals', {}, group='watcher_goals'
|
||||
|
|
|
@ -167,39 +167,12 @@ class FakerModelCollector(BaseClusterModelCollector):
|
|||
|
||||
return current_state_cluster
|
||||
|
||||
def generate_scenario_2(self):
|
||||
current_state_cluster = ModelRoot()
|
||||
# number of nodes
|
||||
count_node = 5
|
||||
|
||||
# define ressouce ( CPU, MEM disk, ... )
|
||||
mem = Resource(ResourceType.memory)
|
||||
# 2199.954 Mhz
|
||||
num_cores = Resource(ResourceType.cpu_cores)
|
||||
disk = Resource(ResourceType.disk)
|
||||
|
||||
current_state_cluster.create_resource(mem)
|
||||
current_state_cluster.create_resource(num_cores)
|
||||
current_state_cluster.create_resource(disk)
|
||||
|
||||
for i in range(0, count_node):
|
||||
node_uuid = "Node_{0}".format(i)
|
||||
node = Hypervisor()
|
||||
node.uuid = node_uuid
|
||||
node.hostname = "hostname_{0}".format(i)
|
||||
mem.set_capacity(node, 132)
|
||||
disk.set_capacity(node, 250)
|
||||
num_cores.set_capacity(node, 40)
|
||||
# print("create "+str(node))
|
||||
current_state_cluster.add_hypervisor(node)
|
||||
return current_state_cluster
|
||||
|
||||
def map(self, model, h_id, vm_id):
|
||||
model.get_mapping().map(
|
||||
model.get_hypervisor_from_id(h_id),
|
||||
model.get_vm_from_id(vm_id))
|
||||
|
||||
def generate_scenario_3(self):
|
||||
def generate_scenario_2(self):
|
||||
vms = []
|
||||
|
||||
current_state_cluster = ModelRoot()
|
||||
|
@ -263,7 +236,7 @@ class FakerModelCollector(BaseClusterModelCollector):
|
|||
|
||||
return current_state_cluster
|
||||
|
||||
def generate_scenario_4_with_2_hypervisors(self):
|
||||
def generate_scenario_3_with_2_hypervisors(self):
|
||||
vms = []
|
||||
|
||||
current_state_cluster = ModelRoot()
|
||||
|
@ -317,7 +290,7 @@ class FakerModelCollector(BaseClusterModelCollector):
|
|||
|
||||
return current_state_cluster
|
||||
|
||||
def generate_scenario_5_with_1_hypervisor_no_vm(self):
|
||||
def generate_scenario_4_with_1_hypervisor_no_vm(self):
|
||||
current_state_cluster = ModelRoot()
|
||||
# number of nodes
|
||||
count_node = 1
|
|
@ -22,20 +22,18 @@ import mock
|
|||
from mock import MagicMock
|
||||
|
||||
from watcher.common import exception
|
||||
|
||||
from watcher.decision_engine.actions.hypervisor_state import \
|
||||
ChangeHypervisorState
|
||||
from watcher.decision_engine.actions.power_state import ChangePowerState
|
||||
|
||||
from watcher.decision_engine.actions.migration import Migrate
|
||||
from watcher.decision_engine.actions.power_state import ChangePowerState
|
||||
from watcher.decision_engine.model.model_root import ModelRoot
|
||||
from watcher.decision_engine.strategy.basic_consolidation import \
|
||||
from watcher.decision_engine.strategy.strategies.basic_consolidation import \
|
||||
BasicConsolidation
|
||||
from watcher.tests import base
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
FakerModelCollector
|
||||
from watcher.tests.decision_engine.faker_metrics_collector import \
|
||||
FakerMetricsCollector
|
||||
from watcher.tests.decision_engine.strategy.strategies.faker_cluster_state \
|
||||
import FakerModelCollector
|
||||
from watcher.tests.decision_engine.strategy.strategies.faker_metrics_collector\
|
||||
import FakerMetricsCollector
|
||||
|
||||
|
||||
class TestBasicConsolidation(base.BaseTestCase):
|
||||
|
@ -154,7 +152,7 @@ class TestBasicConsolidation(base.BaseTestCase):
|
|||
def test_check_migration(self):
|
||||
sercon = BasicConsolidation()
|
||||
fake_cluster = FakerModelCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
model = fake_cluster.generate_scenario_3_with_2_hypervisors()
|
||||
|
||||
all_vms = model.get_all_vms()
|
||||
all_hyps = model.get_all_hypervisors()
|
||||
|
@ -166,7 +164,7 @@ class TestBasicConsolidation(base.BaseTestCase):
|
|||
def test_threshold(self):
|
||||
sercon = BasicConsolidation()
|
||||
fake_cluster = FakerModelCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
model = fake_cluster.generate_scenario_3_with_2_hypervisors()
|
||||
|
||||
all_hyps = model.get_all_hypervisors()
|
||||
hyp0 = all_hyps[list(all_hyps.keys())[0]]
|
||||
|
@ -188,7 +186,7 @@ class TestBasicConsolidation(base.BaseTestCase):
|
|||
statistic_aggregation=self.fake_metrics.mock_get_statistics)
|
||||
|
||||
solution = sercon.execute(
|
||||
self.fake_cluster.generate_scenario_3())
|
||||
self.fake_cluster.generate_scenario_2())
|
||||
|
||||
actions_counter = Counter(
|
||||
[type(action) for action in solution.actions])
|
||||
|
@ -224,7 +222,7 @@ class TestBasicConsolidation(base.BaseTestCase):
|
|||
|
||||
current_state_cluster = FakerModelCollector()
|
||||
model = current_state_cluster. \
|
||||
generate_scenario_5_with_1_hypervisor_no_vm()
|
||||
generate_scenario_4_with_1_hypervisor_no_vm()
|
||||
|
||||
with mock.patch.object(BasicConsolidation, 'calculate_weight') \
|
||||
as mock_score_call:
|
|
@ -13,15 +13,16 @@
|
|||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from watcher.decision_engine.strategy.dummy_strategy import DummyStrategy
|
||||
from watcher.decision_engine.strategy.strategies.dummy_strategy import \
|
||||
DummyStrategy
|
||||
from watcher.tests import base
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
FakerModelCollector
|
||||
from watcher.tests.decision_engine.strategy.strategies.faker_cluster_state\
|
||||
import FakerModelCollector
|
||||
|
||||
|
||||
class TestDummyStrategy(base.TestCase):
|
||||
def test_dummy_strategy(self):
|
||||
tactique = DummyStrategy("basic", "Basic offline consolidation")
|
||||
fake_cluster = FakerModelCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
model = fake_cluster.generate_scenario_3_with_2_hypervisors()
|
||||
tactique.execute(model)
|
|
@ -1,37 +0,0 @@
|
|||
# -*- encoding: utf-8 -*-
|
||||
# Copyright (c) 2015 b<>com
|
||||
#
|
||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
||||
# you may not use this file except in compliance with the License.
|
||||
# You may obtain a copy of the License at
|
||||
#
|
||||
# http://www.apache.org/licenses/LICENSE-2.0
|
||||
#
|
||||
# Unless required by applicable law or agreed to in writing, software
|
||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
from watcher.decision_engine.strategy.base import BaseStrategy
|
||||
from watcher.decision_engine.strategy.loader import StrategyLoader
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestStrategySelector(base.BaseTestCase):
|
||||
|
||||
strategy_loader = StrategyLoader()
|
||||
|
||||
def test_load_strategy_with_empty_model(self):
|
||||
selected_strategy = self.strategy_loader.load(None)
|
||||
self.assertIsNotNone(selected_strategy,
|
||||
'The default strategy be must not none')
|
||||
self.assertIsInstance(selected_strategy, BaseStrategy)
|
||||
|
||||
def test_load_strategy_is_basic(self):
|
||||
exptected_strategy = 'basic'
|
||||
selected_strategy = self.strategy_loader.load(exptected_strategy)
|
||||
self.assertEqual(
|
||||
selected_strategy.name,
|
||||
exptected_strategy,
|
||||
'The default strategy should be basic')
|
|
@ -16,20 +16,22 @@
|
|||
|
||||
import mock
|
||||
from mock import MagicMock
|
||||
|
||||
from watcher.common.exception import MetaActionNotFound
|
||||
from watcher.common import utils
|
||||
|
||||
from watcher.db import api as db_api
|
||||
from watcher.decision_engine.actions.base import BaseAction
|
||||
from watcher.decision_engine.planner.default import DefaultPlanner
|
||||
from watcher.decision_engine.solution.default import DefaultSolution
|
||||
from watcher.decision_engine.strategy.basic_consolidation import \
|
||||
from watcher.decision_engine.strategy.strategies.basic_consolidation import \
|
||||
BasicConsolidation
|
||||
from watcher.tests.db import base
|
||||
from watcher.tests.db import utils as db_utils
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
FakerModelCollector
|
||||
from watcher.tests.decision_engine.faker_metrics_collector import \
|
||||
FakerMetricsCollector
|
||||
from watcher.tests.decision_engine.strategy.strategies.faker_cluster_state\
|
||||
import FakerModelCollector
|
||||
from watcher.tests.decision_engine.strategy.strategies.faker_metrics_collector\
|
||||
import FakerMetricsCollector
|
||||
from watcher.tests.objects import utils as obj_utils
|
||||
|
||||
|
||||
|
@ -54,7 +56,7 @@ class SolutionFakerSingleHyp(object):
|
|||
get_statistics=metrics.mock_get_statistics)
|
||||
|
||||
return sercon.execute(
|
||||
current_state_cluster.generate_scenario_4_with_2_hypervisors())
|
||||
current_state_cluster.generate_scenario_3_with_2_hypervisors())
|
||||
|
||||
|
||||
class TestActionScheduling(base.DbTestCase):
|
||||
|
|
Loading…
Reference in New Issue