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:
Jean-Emile DARTOIS 2015-12-10 09:34:38 +01:00
parent 92940ba9e2
commit 62570525ad
30 changed files with 153 additions and 160 deletions

View File

@ -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

View File

@ -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

View File

@ -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)

View File

@ -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__)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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__)

View File

@ -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))

View File

@ -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__)

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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]]

View File

@ -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):

View File

@ -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)

View File

@ -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'

View File

@ -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

View File

@ -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:

View File

@ -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)

View File

@ -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')

View File

@ -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):