Added pre/post execution methods to strategies

In this changeset, I broke down the execute() method to sequentially
call 3 methods:

- pre_execute()
- do_execute()
- post_execute()

This changeset also removes the cluster model parameter from the
execute() method to now become a `model` property of a strategy which
is lazy loaded whenever needed.

Partially Implements: blueprint efficacy-indicator

Change-Id: I2f697938db693acfa95b2c2fbecfdc1b733c93fd
This commit is contained in:
Vincent Françoise
2016-06-01 16:42:53 +02:00
parent 84b12f8f1e
commit 2b95a4cbc4
18 changed files with 764 additions and 756 deletions

View File

@@ -36,10 +36,11 @@ class SolutionFaker(object):
def build():
metrics = fake.FakerMetricsCollector()
current_state_cluster = faker_cluster_state.FakerModelCollector()
sercon = strategies.BasicConsolidation()
sercon.ceilometer = mock.\
MagicMock(get_statistics=metrics.mock_get_statistics)
return sercon.execute(current_state_cluster.generate_scenario_1())
sercon = strategies.BasicConsolidation(config=mock.Mock())
sercon._model = current_state_cluster.generate_scenario_1()
sercon.ceilometer = mock.MagicMock(
get_statistics=metrics.mock_get_statistics)
return sercon.execute()
class SolutionFakerSingleHyp(object):
@@ -47,12 +48,12 @@ class SolutionFakerSingleHyp(object):
def build():
metrics = fake.FakerMetricsCollector()
current_state_cluster = faker_cluster_state.FakerModelCollector()
sercon = strategies.BasicConsolidation()
sercon.ceilometer = \
mock.MagicMock(get_statistics=metrics.mock_get_statistics)
return sercon.execute(
sercon = strategies.BasicConsolidation(config=mock.Mock())
sercon._model = (
current_state_cluster.generate_scenario_3_with_2_hypervisors())
sercon.ceilometer = mock.MagicMock(
get_statistics=metrics.mock_get_statistics)
return sercon.execute()
class TestActionScheduling(base.DbTestCase):

View File

@@ -13,6 +13,7 @@
# implied.
# See the License for the specific language governing permissions and
# limitations under the License.
import mock
from watcher.decision_engine.solution.default import DefaultSolution
@@ -20,10 +21,7 @@ from watcher.decision_engine.strategy.context.default import \
DefaultStrategyContext
from watcher.decision_engine.strategy.selection.default import \
DefaultStrategySelector
from watcher.decision_engine.strategy.strategies.dummy_strategy import \
DummyStrategy
from watcher.metrics_engine.cluster_model_collector.manager import \
CollectorManager
from watcher.decision_engine.strategy.strategies import dummy_strategy
from watcher.tests.db import base
from watcher.tests.objects import utils as obj_utils
@@ -32,18 +30,19 @@ class TestStrategyContext(base.DbTestCase):
def setUp(self):
super(TestStrategyContext, self).setUp()
obj_utils.create_test_goal(self.context, id=1, name="DUMMY")
audit_template = obj_utils.create_test_audit_template(
self.context)
audit_template = obj_utils.create_test_audit_template(self.context)
self.audit = obj_utils.create_test_audit(
self.context, audit_template_id=audit_template.id)
strategy_context = DefaultStrategyContext()
@mock.patch.object(dummy_strategy.DummyStrategy, 'model',
new_callable=mock.PropertyMock)
@mock.patch.object(DefaultStrategySelector, 'select')
@mock.patch.object(CollectorManager, "get_cluster_model_collector",
mock.Mock())
def test_execute_strategy(self, mock_call):
mock_call.return_value = DummyStrategy()
def test_execute_strategy(self, mock_call, m_model):
m_model.return_value = mock.Mock()
mock_call.return_value = dummy_strategy.DummyStrategy(
config=mock.Mock())
solution = self.strategy_context.execute_strategy(
self.audit.uuid, self.context)
self.assertIsInstance(solution, DefaultSolution)

View File

@@ -31,11 +31,30 @@ from watcher.tests.decision_engine.strategy.strategies \
class TestBasicConsolidation(base.BaseTestCase):
# fake metrics
fake_metrics = faker_metrics_collector.FakerMetricsCollector()
# fake cluster
fake_cluster = faker_cluster_state.FakerModelCollector()
def setUp(self):
super(TestBasicConsolidation, self).setUp()
# fake metrics
self.fake_metrics = faker_metrics_collector.FakerMetricsCollector()
# fake cluster
self.fake_cluster = faker_cluster_state.FakerModelCollector()
p_model = mock.patch.object(
strategies.BasicConsolidation, "model",
new_callable=mock.PropertyMock)
self.m_model = p_model.start()
self.addCleanup(p_model.stop)
p_ceilometer = mock.patch.object(
strategies.BasicConsolidation, "ceilometer",
new_callable=mock.PropertyMock)
self.m_ceilometer = p_ceilometer.start()
self.addCleanup(p_ceilometer.stop)
self.m_model.return_value = model_root.ModelRoot()
self.m_ceilometer.return_value = mock.Mock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
self.strategy = strategies.BasicConsolidation(config=mock.Mock())
def test_cluster_size(self):
size_cluster = len(
@@ -44,134 +63,98 @@ class TestBasicConsolidation(base.BaseTestCase):
self.assertEqual(size_cluster_assert, size_cluster)
def test_basic_consolidation_score_hypervisor(self):
cluster = self.fake_cluster.generate_scenario_1()
sercon = strategies.BasicConsolidation()
sercon.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
model = self.fake_cluster.generate_scenario_1()
self.m_model.return_value = model
node_1_score = 0.023333333333333317
self.assertEqual(node_1_score, sercon.calculate_score_node(
cluster.get_hypervisor_from_id("Node_1"),
cluster))
self.assertEqual(node_1_score, self.strategy.calculate_score_node(
model.get_hypervisor_from_id("Node_1")))
node_2_score = 0.26666666666666666
self.assertEqual(node_2_score, sercon.calculate_score_node(
cluster.get_hypervisor_from_id("Node_2"),
cluster))
self.assertEqual(node_2_score, self.strategy.calculate_score_node(
model.get_hypervisor_from_id("Node_2")))
node_0_score = 0.023333333333333317
self.assertEqual(node_0_score, sercon.calculate_score_node(
cluster.get_hypervisor_from_id("Node_0"),
cluster))
self.assertEqual(node_0_score, self.strategy.calculate_score_node(
model.get_hypervisor_from_id("Node_0")))
def test_basic_consolidation_score_vm(self):
cluster = self.fake_cluster.generate_scenario_1()
sercon = strategies.BasicConsolidation()
sercon.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
vm_0 = cluster.get_vm_from_id("VM_0")
model = self.fake_cluster.generate_scenario_1()
self.m_model.return_value = model
vm_0 = model.get_vm_from_id("VM_0")
vm_0_score = 0.023333333333333317
self.assertEqual(vm_0_score, sercon.calculate_score_vm(vm_0, cluster))
self.assertEqual(vm_0_score, self.strategy.calculate_score_vm(vm_0))
vm_1 = cluster.get_vm_from_id("VM_1")
vm_1 = model.get_vm_from_id("VM_1")
vm_1_score = 0.023333333333333317
self.assertEqual(vm_1_score, sercon.calculate_score_vm(vm_1, cluster))
vm_2 = cluster.get_vm_from_id("VM_2")
self.assertEqual(vm_1_score, self.strategy.calculate_score_vm(vm_1))
vm_2 = model.get_vm_from_id("VM_2")
vm_2_score = 0.033333333333333326
self.assertEqual(vm_2_score, sercon.calculate_score_vm(vm_2, cluster))
vm_6 = cluster.get_vm_from_id("VM_6")
self.assertEqual(vm_2_score, self.strategy.calculate_score_vm(vm_2))
vm_6 = model.get_vm_from_id("VM_6")
vm_6_score = 0.02666666666666669
self.assertEqual(vm_6_score, sercon.calculate_score_vm(vm_6, cluster))
vm_7 = cluster.get_vm_from_id("VM_7")
self.assertEqual(vm_6_score, self.strategy.calculate_score_vm(vm_6))
vm_7 = model.get_vm_from_id("VM_7")
vm_7_score = 0.013333333333333345
self.assertEqual(vm_7_score, sercon.calculate_score_vm(vm_7, cluster))
self.assertEqual(vm_7_score, self.strategy.calculate_score_vm(vm_7))
def test_basic_consolidation_score_vm_disk(self):
cluster = self.fake_cluster.generate_scenario_5_with_vm_disk_0()
sercon = strategies.BasicConsolidation()
sercon.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
vm_0 = cluster.get_vm_from_id("VM_0")
model = self.fake_cluster.generate_scenario_5_with_vm_disk_0()
self.m_model.return_value = model
vm_0 = model.get_vm_from_id("VM_0")
vm_0_score = 0.023333333333333355
self.assertEqual(vm_0_score, sercon.calculate_score_vm(vm_0, cluster))
self.assertEqual(vm_0_score, self.strategy.calculate_score_vm(vm_0, ))
def test_basic_consolidation_weight(self):
cluster = self.fake_cluster.generate_scenario_1()
sercon = strategies.BasicConsolidation()
sercon.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
vm_0 = cluster.get_vm_from_id("VM_0")
model = self.fake_cluster.generate_scenario_1()
self.m_model.return_value = model
vm_0 = model.get_vm_from_id("VM_0")
cores = 16
# 80 Go
disk = 80
# mem 8 Go
mem = 8
vm_0_weight_assert = 3.1999999999999997
self.assertEqual(vm_0_weight_assert,
sercon.calculate_weight(cluster, vm_0, cores, disk,
mem))
self.assertEqual(
vm_0_weight_assert,
self.strategy.calculate_weight(vm_0, cores, disk, mem))
def test_calculate_migration_efficacy(self):
sercon = strategies.BasicConsolidation()
sercon.calculate_migration_efficacy()
self.strategy.calculate_migration_efficacy()
def test_exception_model(self):
sercon = strategies.BasicConsolidation()
self.assertRaises(exception.ClusterStateNotDefined, sercon.execute,
None)
self.m_model.return_value = None
self.assertRaises(
exception.ClusterStateNotDefined, self.strategy.execute)
def test_exception_cluster_empty(self):
sercon = strategies.BasicConsolidation()
model = model_root.ModelRoot()
self.assertRaises(exception.ClusterEmpty, sercon.execute,
model)
def test_calculate_score_vm_raise_cluster_state_not_found(self):
metrics = faker_metrics_collector.FakerMetricsCollector()
metrics.empty_one_metric("CPU_COMPUTE")
sercon = strategies.BasicConsolidation()
sercon.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
self.assertRaises(exception.ClusterStateNotDefined,
sercon.calculate_score_vm, "VM_1", None)
self.m_model.return_value = model
self.assertRaises(exception.ClusterEmpty, self.strategy.execute)
def test_check_migration(self):
sercon = strategies.BasicConsolidation()
fake_cluster = faker_cluster_state.FakerModelCollector()
model = fake_cluster.generate_scenario_3_with_2_hypervisors()
model = self.fake_cluster.generate_scenario_3_with_2_hypervisors()
self.m_model.return_value = model
all_vms = model.get_all_vms()
all_hyps = model.get_all_hypervisors()
vm0 = all_vms[list(all_vms.keys())[0]]
hyp0 = all_hyps[list(all_hyps.keys())[0]]
sercon.check_migration(model, hyp0, hyp0, vm0)
self.strategy.check_migration(hyp0, hyp0, vm0)
def test_threshold(self):
sercon = strategies.BasicConsolidation()
fake_cluster = faker_cluster_state.FakerModelCollector()
model = fake_cluster.generate_scenario_3_with_2_hypervisors()
model = self.fake_cluster.generate_scenario_3_with_2_hypervisors()
self.m_model.return_value = model
all_hyps = model.get_all_hypervisors()
hyp0 = all_hyps[list(all_hyps.keys())[0]]
sercon.check_threshold(model, hyp0, 1000, 1000, 1000)
threshold_cores = sercon.get_threshold_cores()
sercon.set_threshold_cores(threshold_cores + 1)
self.assertEqual(threshold_cores + 1, sercon.get_threshold_cores())
def test_number_of(self):
sercon = strategies.BasicConsolidation()
sercon.get_number_of_released_nodes()
sercon.get_number_of_migrations()
self.assertFalse(self.strategy.check_threshold(
hyp0, 1000, 1000, 1000))
def test_basic_consolidation_migration(self):
sercon = strategies.BasicConsolidation()
sercon.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
model = self.fake_cluster.generate_scenario_3_with_2_hypervisors()
self.m_model.return_value = model
solution = sercon.execute(
self.fake_cluster.generate_scenario_3_with_2_hypervisors())
solution = self.strategy.execute()
actions_counter = collections.Counter(
[action.get('action_type') for action in solution.actions])
@@ -187,27 +170,22 @@ class TestBasicConsolidation(base.BaseTestCase):
# calculate_weight
def test_execute_no_workload(self):
sercon = strategies.BasicConsolidation()
sercon.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
model = (
self.fake_cluster
.generate_scenario_4_with_1_hypervisor_no_vm())
self.m_model.return_value = model
current_state_cluster = faker_cluster_state.FakerModelCollector()
model = current_state_cluster. \
generate_scenario_4_with_1_hypervisor_no_vm()
with mock.patch.object(strategies.BasicConsolidation,
'calculate_weight') \
as mock_score_call:
with mock.patch.object(
strategies.BasicConsolidation, 'calculate_weight'
) as mock_score_call:
mock_score_call.return_value = 0
solution = sercon.execute(model)
self.assertEqual(100, solution.efficacy)
solution = self.strategy.execute()
self.assertEqual(0, solution.efficacy)
def test_check_parameters(self):
sercon = strategies.BasicConsolidation()
sercon.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
solution = sercon.execute(
self.fake_cluster.generate_scenario_3_with_2_hypervisors())
model = self.fake_cluster.generate_scenario_3_with_2_hypervisors()
self.m_model.return_value = model
solution = self.strategy.execute()
loader = default.DefaultActionLoader()
for action in solution.actions:
loaded_action = loader.load(action['action_type'])

View File

@@ -14,7 +14,10 @@
# See the License for the specific language governing permissions and
# limitations under the License.
import mock
from watcher.applier.actions.loading import default
from watcher.decision_engine.model import model_root
from watcher.decision_engine.strategy import strategies
from watcher.tests import base
from watcher.tests.decision_engine.strategy.strategies import \
@@ -22,18 +25,33 @@ from watcher.tests.decision_engine.strategy.strategies import \
class TestDummyStrategy(base.TestCase):
def setUp(self):
super(TestDummyStrategy, self).setUp()
# fake cluster
self.fake_cluster = faker_cluster_state.FakerModelCollector()
p_model = mock.patch.object(
strategies.DummyStrategy, "model",
new_callable=mock.PropertyMock)
self.m_model = p_model.start()
self.addCleanup(p_model.stop)
self.m_model.return_value = model_root.ModelRoot()
self.strategy = strategies.DummyStrategy(config=mock.Mock())
self.m_model.return_value = model_root.ModelRoot()
self.strategy = strategies.DummyStrategy(config=mock.Mock())
def test_dummy_strategy(self):
dummy = strategies.DummyStrategy()
fake_cluster = faker_cluster_state.FakerModelCollector()
model = fake_cluster.generate_scenario_3_with_2_hypervisors()
solution = dummy.execute(model)
dummy = strategies.DummyStrategy(config=mock.Mock())
solution = dummy.execute()
self.assertEqual(3, len(solution.actions))
def test_check_parameters(self):
dummy = strategies.DummyStrategy()
fake_cluster = faker_cluster_state.FakerModelCollector()
model = fake_cluster.generate_scenario_3_with_2_hypervisors()
solution = dummy.execute(model)
model = self.fake_cluster.generate_scenario_3_with_2_hypervisors()
self.m_model.return_value = model
solution = self.strategy.execute()
loader = default.DefaultActionLoader()
for action in solution.actions:
loaded_action = loader.load(action['action_type'])

View File

@@ -32,93 +32,95 @@ from watcher.tests.decision_engine.strategy.strategies \
class TestOutletTempControl(base.BaseTestCase):
# fake metrics
fake_metrics = faker_metrics_collector.FakerMetricsCollector()
# fake cluster
fake_cluster = faker_cluster_state.FakerModelCollector()
def setUp(self):
super(TestOutletTempControl, self).setUp()
# fake metrics
self.fake_metrics = faker_metrics_collector.FakerMetricsCollector()
# fake cluster
self.fake_cluster = faker_cluster_state.FakerModelCollector()
p_model = mock.patch.object(
strategies.OutletTempControl, "model",
new_callable=mock.PropertyMock)
self.m_model = p_model.start()
self.addCleanup(p_model.stop)
p_ceilometer = mock.patch.object(
strategies.OutletTempControl, "ceilometer",
new_callable=mock.PropertyMock)
self.m_ceilometer = p_ceilometer.start()
self.addCleanup(p_ceilometer.stop)
self.m_model.return_value = model_root.ModelRoot()
self.m_ceilometer.return_value = mock.Mock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
self.strategy = strategies.OutletTempControl(config=mock.Mock())
def test_calc_used_res(self):
model = self.fake_cluster.generate_scenario_3_with_2_hypervisors()
strategy = strategies.OutletTempControl()
self.m_model.return_value = model
hypervisor = model.get_hypervisor_from_id('Node_0')
cap_cores = model.get_resource_from_id(resource.ResourceType.cpu_cores)
cap_mem = model.get_resource_from_id(resource.ResourceType.memory)
cap_disk = model.get_resource_from_id(resource.ResourceType.disk)
cores_used, mem_used, disk_used = strategy.calc_used_res(model,
hypervisor,
cap_cores,
cap_mem,
cap_disk)
cores_used, mem_used, disk_used = self.strategy.calc_used_res(
hypervisor, cap_cores, cap_mem, cap_disk)
self.assertEqual((10, 2, 20), (cores_used, mem_used, disk_used))
def test_group_hosts_by_outlet_temp(self):
model = self.fake_cluster.generate_scenario_3_with_2_hypervisors()
strategy = strategies.OutletTempControl()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
h1, h2 = strategy.group_hosts_by_outlet_temp(model)
self.m_model.return_value = model
h1, h2 = self.strategy.group_hosts_by_outlet_temp()
self.assertEqual('Node_1', h1[0]['hv'].uuid)
self.assertEqual('Node_0', h2[0]['hv'].uuid)
def test_choose_vm_to_migrate(self):
model = self.fake_cluster.generate_scenario_3_with_2_hypervisors()
strategy = strategies.OutletTempControl()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
h1, h2 = strategy.group_hosts_by_outlet_temp(model)
vm_to_mig = strategy.choose_vm_to_migrate(model, h1)
self.m_model.return_value = model
h1, h2 = self.strategy.group_hosts_by_outlet_temp()
vm_to_mig = self.strategy.choose_vm_to_migrate(h1)
self.assertEqual('Node_1', vm_to_mig[0].uuid)
self.assertEqual('a4cab39b-9828-413a-bf88-f76921bf1517',
vm_to_mig[1].uuid)
def test_filter_dest_servers(self):
model = self.fake_cluster.generate_scenario_3_with_2_hypervisors()
strategy = strategies.OutletTempControl()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
h1, h2 = strategy.group_hosts_by_outlet_temp(model)
vm_to_mig = strategy.choose_vm_to_migrate(model, h1)
dest_hosts = strategy.filter_dest_servers(model, h2, vm_to_mig[1])
self.m_model.return_value = model
h1, h2 = self.strategy.group_hosts_by_outlet_temp()
vm_to_mig = self.strategy.choose_vm_to_migrate(h1)
dest_hosts = self.strategy.filter_dest_servers(h2, vm_to_mig[1])
self.assertEqual(1, len(dest_hosts))
self.assertEqual('Node_0', dest_hosts[0]['hv'].uuid)
def test_exception_model(self):
strategy = strategies.OutletTempControl()
self.assertRaises(exception.ClusterStateNotDefined, strategy.execute,
None)
self.m_model.return_value = None
self.assertRaises(
exception.ClusterStateNotDefined, self.strategy.execute)
def test_exception_cluster_empty(self):
strategy = strategies.OutletTempControl()
model = model_root.ModelRoot()
self.assertRaises(exception.ClusterEmpty, strategy.execute, model)
self.m_model.return_value = model
self.assertRaises(exception.ClusterEmpty, self.strategy.execute)
def test_execute_cluster_empty(self):
strategy = strategies.OutletTempControl()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
model = model_root.ModelRoot()
self.assertRaises(exception.ClusterEmpty, strategy.execute, model)
self.m_model.return_value = model
self.assertRaises(exception.ClusterEmpty, self.strategy.execute)
def test_execute_no_workload(self):
strategy = strategies.OutletTempControl()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
model = self.fake_cluster.generate_scenario_4_with_1_hypervisor_no_vm()
self.m_model.return_value = model
current_state_cluster = faker_cluster_state.FakerModelCollector()
model = current_state_cluster. \
generate_scenario_4_with_1_hypervisor_no_vm()
solution = strategy.execute(model)
solution = self.strategy.execute()
self.assertEqual([], solution.actions)
def test_execute(self):
strategy = strategies.OutletTempControl()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
model = self.fake_cluster.generate_scenario_3_with_2_hypervisors()
solution = strategy.execute(model)
self.m_model.return_value = model
solution = self.strategy.execute()
actions_counter = collections.Counter(
[action.get('action_type') for action in solution.actions])
@@ -126,11 +128,9 @@ class TestOutletTempControl(base.BaseTestCase):
self.assertEqual(1, num_migrations)
def test_check_parameters(self):
outlet = strategies.OutletTempControl()
outlet.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
model = self.fake_cluster.generate_scenario_3_with_2_hypervisors()
solution = outlet.execute(model)
self.m_model.return_value = model
solution = self.strategy.execute()
loader = default.DefaultActionLoader()
for action in solution.actions:
loaded_action = loader.load(action['action_type'])

View File

@@ -17,213 +17,215 @@
# See the License for the specific language governing permissions and
# limitations under the License.
#
import mock
from watcher.decision_engine.model import model_root
from watcher.decision_engine.strategy import strategies
from watcher.tests import base
from watcher.tests.decision_engine.strategy.strategies \
import faker_cluster_and_metrics
class TestSmartConsolidation(base.BaseTestCase):
fake_cluster = faker_cluster_and_metrics.FakerModelCollector()
class TestVMWorkloadConsolidation(base.BaseTestCase):
def setUp(self):
super(TestVMWorkloadConsolidation, self).setUp()
# fake cluster
self.fake_cluster = faker_cluster_and_metrics.FakerModelCollector()
p_model = mock.patch.object(
strategies.VMWorkloadConsolidation, "model",
new_callable=mock.PropertyMock)
self.m_model = p_model.start()
self.addCleanup(p_model.stop)
p_ceilometer = mock.patch.object(
strategies.VMWorkloadConsolidation, "ceilometer",
new_callable=mock.PropertyMock)
self.m_ceilometer = p_ceilometer.start()
self.addCleanup(p_ceilometer.stop)
# fake metrics
self.fake_metrics = faker_cluster_and_metrics.FakeCeilometerMetrics(
self.m_model.return_value)
self.m_model.return_value = model_root.ModelRoot()
self.m_ceilometer.return_value = mock.Mock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
self.strategy = strategies.VMWorkloadConsolidation(config=mock.Mock())
def test_get_vm_utilization(self):
cluster = self.fake_cluster.generate_scenario_1()
fake_metrics = faker_cluster_and_metrics.FakeCeilometerMetrics(cluster)
strategy = strategies.VMWorkloadConsolidation()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=fake_metrics.mock_get_statistics)
vm_0 = cluster.get_vm_from_id("VM_0")
model = self.fake_cluster.generate_scenario_1()
self.m_model.return_value = model
self.fake_metrics.model = model
vm_0 = model.get_vm_from_id("VM_0")
vm_util = dict(cpu=1.0, ram=1, disk=10)
self.assertEqual(vm_util,
strategy.get_vm_utilization(vm_0.uuid, cluster))
self.strategy.get_vm_utilization(vm_0.uuid, model))
def test_get_hypervisor_utilization(self):
cluster = self.fake_cluster.generate_scenario_1()
fake_metrics = faker_cluster_and_metrics.FakeCeilometerMetrics(cluster)
strategy = strategies.VMWorkloadConsolidation()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=fake_metrics.mock_get_statistics)
node_0 = cluster.get_hypervisor_from_id("Node_0")
model = self.fake_cluster.generate_scenario_1()
self.m_model.return_value = model
self.fake_metrics.model = model
node_0 = model.get_hypervisor_from_id("Node_0")
node_util = dict(cpu=1.0, ram=1, disk=10)
self.assertEqual(node_util,
strategy.get_hypervisor_utilization(node_0, cluster))
self.assertEqual(
node_util,
self.strategy.get_hypervisor_utilization(node_0, model))
def test_get_hypervisor_capacity(self):
cluster = self.fake_cluster.generate_scenario_1()
fake_metrics = faker_cluster_and_metrics.FakeCeilometerMetrics(cluster)
strategy = strategies.VMWorkloadConsolidation()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=fake_metrics.mock_get_statistics)
node_0 = cluster.get_hypervisor_from_id("Node_0")
model = self.fake_cluster.generate_scenario_1()
self.m_model.return_value = model
self.fake_metrics.model = model
node_0 = model.get_hypervisor_from_id("Node_0")
node_util = dict(cpu=40, ram=64, disk=250)
self.assertEqual(node_util,
strategy.get_hypervisor_capacity(node_0, cluster))
self.strategy.get_hypervisor_capacity(node_0, model))
def test_get_relative_hypervisor_utilization(self):
model = self.fake_cluster.generate_scenario_1()
fake_metrics = faker_cluster_and_metrics.FakeCeilometerMetrics(model)
strategy = strategies.VMWorkloadConsolidation()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=fake_metrics.mock_get_statistics)
self.m_model.return_value = model
self.fake_metrics.model = model
hypervisor = model.get_hypervisor_from_id('Node_0')
rhu = strategy.get_relative_hypervisor_utilization(hypervisor, model)
rhu = self.strategy.get_relative_hypervisor_utilization(
hypervisor, model)
expected_rhu = {'disk': 0.04, 'ram': 0.015625, 'cpu': 0.025}
self.assertEqual(expected_rhu, rhu)
def test_get_relative_cluster_utilization(self):
model = self.fake_cluster.generate_scenario_1()
fake_metrics = faker_cluster_and_metrics.FakeCeilometerMetrics(model)
strategy = strategies.VMWorkloadConsolidation()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=fake_metrics.mock_get_statistics)
cru = strategy.get_relative_cluster_utilization(model)
self.m_model.return_value = model
self.fake_metrics.model = model
cru = self.strategy.get_relative_cluster_utilization(model)
expected_cru = {'cpu': 0.05, 'disk': 0.05, 'ram': 0.0234375}
self.assertEqual(expected_cru, cru)
def test_add_migration(self):
model = self.fake_cluster.generate_scenario_1()
fake_metrics = faker_cluster_and_metrics.FakeCeilometerMetrics(model)
strategy = strategies.VMWorkloadConsolidation()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=fake_metrics.mock_get_statistics)
self.m_model.return_value = model
self.fake_metrics.model = model
h1 = model.get_hypervisor_from_id('Node_0')
h2 = model.get_hypervisor_from_id('Node_1')
vm_uuid = 'VM_0'
strategy.add_migration(vm_uuid, h1, h2, model)
self.assertEqual(1, len(strategy.solution.actions))
self.strategy.add_migration(vm_uuid, h1, h2, model)
self.assertEqual(1, len(self.strategy.solution.actions))
expected = {'action_type': 'migrate',
'input_parameters': {'dst_hypervisor': h2.uuid,
'src_hypervisor': h1.uuid,
'migration_type': 'live',
'resource_id': vm_uuid}}
self.assertEqual(expected, strategy.solution.actions[0])
self.assertEqual(expected, self.strategy.solution.actions[0])
def test_is_overloaded(self):
strategy = strategies.VMWorkloadConsolidation()
model = self.fake_cluster.generate_scenario_1()
fake_metrics = faker_cluster_and_metrics.FakeCeilometerMetrics(model)
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=fake_metrics.mock_get_statistics)
self.m_model.return_value = model
self.fake_metrics.model = model
h1 = model.get_hypervisor_from_id('Node_0')
cc = {'cpu': 1.0, 'ram': 1.0, 'disk': 1.0}
res = strategy.is_overloaded(h1, model, cc)
res = self.strategy.is_overloaded(h1, model, cc)
self.assertEqual(False, res)
cc = {'cpu': 0.025, 'ram': 1.0, 'disk': 1.0}
res = strategy.is_overloaded(h1, model, cc)
res = self.strategy.is_overloaded(h1, model, cc)
self.assertEqual(False, res)
cc = {'cpu': 0.024, 'ram': 1.0, 'disk': 1.0}
res = strategy.is_overloaded(h1, model, cc)
res = self.strategy.is_overloaded(h1, model, cc)
self.assertEqual(True, res)
def test_vm_fits(self):
model = self.fake_cluster.generate_scenario_1()
fake_metrics = faker_cluster_and_metrics.FakeCeilometerMetrics(model)
strategy = strategies.VMWorkloadConsolidation()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=fake_metrics.mock_get_statistics)
self.m_model.return_value = model
self.fake_metrics.model = model
h = model.get_hypervisor_from_id('Node_1')
vm_uuid = 'VM_0'
cc = {'cpu': 1.0, 'ram': 1.0, 'disk': 1.0}
res = strategy.vm_fits(vm_uuid, h, model, cc)
res = self.strategy.vm_fits(vm_uuid, h, model, cc)
self.assertEqual(True, res)
cc = {'cpu': 0.025, 'ram': 1.0, 'disk': 1.0}
res = strategy.vm_fits(vm_uuid, h, model, cc)
res = self.strategy.vm_fits(vm_uuid, h, model, cc)
self.assertEqual(False, res)
def test_add_action_activate_hypervisor(self):
model = self.fake_cluster.generate_scenario_1()
fake_metrics = faker_cluster_and_metrics.FakeCeilometerMetrics(model)
strategy = strategies.VMWorkloadConsolidation()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=fake_metrics.mock_get_statistics)
self.m_model.return_value = model
self.fake_metrics.model = model
h = model.get_hypervisor_from_id('Node_0')
strategy.add_action_activate_hypervisor(h)
self.strategy.add_action_activate_hypervisor(h)
expected = [{'action_type': 'change_nova_service_state',
'input_parameters': {'state': 'up',
'resource_id': 'Node_0'}}]
self.assertEqual(expected, strategy.solution.actions)
self.assertEqual(expected, self.strategy.solution.actions)
def test_add_action_deactivate_hypervisor(self):
model = self.fake_cluster.generate_scenario_1()
fake_metrics = faker_cluster_and_metrics.FakeCeilometerMetrics(model)
strategy = strategies.VMWorkloadConsolidation()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=fake_metrics.mock_get_statistics)
self.m_model.return_value = model
self.fake_metrics.model = model
h = model.get_hypervisor_from_id('Node_0')
strategy.add_action_deactivate_hypervisor(h)
self.strategy.add_action_deactivate_hypervisor(h)
expected = [{'action_type': 'change_nova_service_state',
'input_parameters': {'state': 'down',
'resource_id': 'Node_0'}}]
self.assertEqual(expected, strategy.solution.actions)
self.assertEqual(expected, self.strategy.solution.actions)
def test_deactivate_unused_hypervisors(self):
model = self.fake_cluster.generate_scenario_1()
fake_metrics = faker_cluster_and_metrics.FakeCeilometerMetrics(model)
strategy = strategies.VMWorkloadConsolidation()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=fake_metrics.mock_get_statistics)
self.m_model.return_value = model
self.fake_metrics.model = model
h1 = model.get_hypervisor_from_id('Node_0')
h2 = model.get_hypervisor_from_id('Node_1')
vm_uuid = 'VM_0'
strategy.deactivate_unused_hypervisors(model)
self.assertEqual(0, len(strategy.solution.actions))
self.strategy.deactivate_unused_hypervisors(model)
self.assertEqual(0, len(self.strategy.solution.actions))
# Migrate VM to free the hypervisor
strategy.add_migration(vm_uuid, h1, h2, model)
self.strategy.add_migration(vm_uuid, h1, h2, model)
strategy.deactivate_unused_hypervisors(model)
self.strategy.deactivate_unused_hypervisors(model)
expected = {'action_type': 'change_nova_service_state',
'input_parameters': {'state': 'down',
'resource_id': 'Node_0'}}
self.assertEqual(2, len(strategy.solution.actions))
self.assertEqual(expected, strategy.solution.actions[1])
self.assertEqual(2, len(self.strategy.solution.actions))
self.assertEqual(expected, self.strategy.solution.actions[1])
def test_offload_phase(self):
model = self.fake_cluster.generate_scenario_1()
fake_metrics = faker_cluster_and_metrics.FakeCeilometerMetrics(model)
strategy = strategies.VMWorkloadConsolidation()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=fake_metrics.mock_get_statistics)
self.m_model.return_value = model
self.fake_metrics.model = model
cc = {'cpu': 1.0, 'ram': 1.0, 'disk': 1.0}
strategy.offload_phase(model, cc)
self.strategy.offload_phase(model, cc)
expected = []
self.assertEqual(expected, strategy.solution.actions)
self.assertEqual(expected, self.strategy.solution.actions)
def test_consolidation_phase(self):
model = self.fake_cluster.generate_scenario_1()
fake_metrics = faker_cluster_and_metrics.FakeCeilometerMetrics(model)
strategy = strategies.VMWorkloadConsolidation()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=fake_metrics.mock_get_statistics)
self.m_model.return_value = model
self.fake_metrics.model = model
h1 = model.get_hypervisor_from_id('Node_0')
h2 = model.get_hypervisor_from_id('Node_1')
vm_uuid = 'VM_0'
cc = {'cpu': 1.0, 'ram': 1.0, 'disk': 1.0}
strategy.consolidation_phase(model, cc)
self.strategy.consolidation_phase(model, cc)
expected = [{'action_type': 'migrate',
'input_parameters': {'dst_hypervisor': h2.uuid,
'src_hypervisor': h1.uuid,
'migration_type': 'live',
'resource_id': vm_uuid}}]
self.assertEqual(expected, strategy.solution.actions)
self.assertEqual(expected, self.strategy.solution.actions)
def test_strategy(self):
model = self.fake_cluster.generate_scenario_2()
fake_metrics = faker_cluster_and_metrics.FakeCeilometerMetrics(model)
strategy = strategies.VMWorkloadConsolidation()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=fake_metrics.mock_get_statistics)
self.m_model.return_value = model
self.fake_metrics.model = model
h1 = model.get_hypervisor_from_id('Node_0')
cc = {'cpu': 1.0, 'ram': 1.0, 'disk': 1.0}
strategy.offload_phase(model, cc)
strategy.consolidation_phase(model, cc)
strategy.optimize_solution(model)
h2 = strategy.solution.actions[0][
self.strategy.offload_phase(model, cc)
self.strategy.consolidation_phase(model, cc)
self.strategy.optimize_solution(model)
h2 = self.strategy.solution.actions[0][
'input_parameters']['dst_hypervisor']
expected = [{'action_type': 'migrate',
'input_parameters': {'dst_hypervisor': h2,
@@ -236,18 +238,16 @@ class TestSmartConsolidation(base.BaseTestCase):
'migration_type': 'live',
'resource_id': 'VM_1'}}]
self.assertEqual(expected, strategy.solution.actions)
self.assertEqual(expected, self.strategy.solution.actions)
def test_strategy2(self):
model = self.fake_cluster.generate_scenario_3()
fake_metrics = faker_cluster_and_metrics.FakeCeilometerMetrics(model)
strategy = strategies.VMWorkloadConsolidation()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=fake_metrics.mock_get_statistics)
self.m_model.return_value = model
self.fake_metrics.model = model
h1 = model.get_hypervisor_from_id('Node_0')
h2 = model.get_hypervisor_from_id('Node_1')
cc = {'cpu': 1.0, 'ram': 1.0, 'disk': 1.0}
strategy.offload_phase(model, cc)
self.strategy.offload_phase(model, cc)
expected = [{'action_type': 'migrate',
'input_parameters': {'dst_hypervisor': h2.uuid,
'migration_type': 'live',
@@ -263,15 +263,15 @@ class TestSmartConsolidation(base.BaseTestCase):
'migration_type': 'live',
'resource_id': 'VM_8',
'src_hypervisor': h1.uuid}}]
self.assertEqual(expected, strategy.solution.actions)
strategy.consolidation_phase(model, cc)
self.assertEqual(expected, self.strategy.solution.actions)
self.strategy.consolidation_phase(model, cc)
expected.append({'action_type': 'migrate',
'input_parameters': {'dst_hypervisor': h1.uuid,
'migration_type': 'live',
'resource_id': 'VM_7',
'src_hypervisor': h2.uuid}})
self.assertEqual(expected, strategy.solution.actions)
strategy.optimize_solution(model)
self.assertEqual(expected, self.strategy.solution.actions)
self.strategy.optimize_solution(model)
del expected[3]
del expected[1]
self.assertEqual(expected, strategy.solution.actions)
self.assertEqual(expected, self.strategy.solution.actions)

View File

@@ -23,7 +23,7 @@ from watcher.applier.actions.loading import default
from watcher.common import exception
from watcher.decision_engine.model import model_root
from watcher.decision_engine.model import resource
from watcher.decision_engine.strategy.strategies import workload_balance
from watcher.decision_engine.strategy import strategies
from watcher.tests import base
from watcher.tests.decision_engine.strategy.strategies \
import faker_cluster_state
@@ -32,31 +32,51 @@ from watcher.tests.decision_engine.strategy.strategies \
class TestWorkloadBalance(base.BaseTestCase):
# fake metrics
fake_metrics = faker_metrics_collector.FakerMetricsCollector()
# fake cluster
fake_cluster = faker_cluster_state.FakerModelCollector()
def setUp(self):
super(TestWorkloadBalance, self).setUp()
# fake metrics
self.fake_metrics = faker_metrics_collector.FakerMetricsCollector()
# fake cluster
self.fake_cluster = faker_cluster_state.FakerModelCollector()
p_model = mock.patch.object(
strategies.WorkloadBalance, "model",
new_callable=mock.PropertyMock)
self.m_model = p_model.start()
self.addCleanup(p_model.stop)
p_ceilometer = mock.patch.object(
strategies.BasicConsolidation, "ceilometer",
new_callable=mock.PropertyMock)
self.m_ceilometer = p_ceilometer.start()
self.addCleanup(p_ceilometer.stop)
self.m_model.return_value = model_root.ModelRoot()
self.m_ceilometer.return_value = mock.Mock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
self.strategy = strategies.WorkloadBalance(config=mock.Mock())
def test_calc_used_res(self):
model = self.fake_cluster.generate_scenario_6_with_2_hypervisors()
strategy = workload_balance.WorkloadBalance()
self.m_model.return_value = model
hypervisor = model.get_hypervisor_from_id('Node_0')
cap_cores = model.get_resource_from_id(resource.ResourceType.cpu_cores)
cap_mem = model.get_resource_from_id(resource.ResourceType.memory)
cap_disk = model.get_resource_from_id(resource.ResourceType.disk)
cores_used, mem_used, disk_used = strategy.calculate_used_resource(
model, hypervisor, cap_cores, cap_mem, cap_disk)
cores_used, mem_used, disk_used = (
self.strategy.calculate_used_resource(
hypervisor, cap_cores, cap_mem, cap_disk))
self.assertEqual((cores_used, mem_used, disk_used), (20, 4, 40))
def test_group_hosts_by_cpu_util(self):
model = self.fake_cluster.generate_scenario_6_with_2_hypervisors()
strategy = workload_balance.WorkloadBalance()
strategy.threshold = 30
strategy.ceilometer = mock.MagicMock(
self.m_model.return_value = model
self.strategy.threshold = 30
self.strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics_wb)
h1, h2, avg, w_map = strategy.group_hosts_by_cpu_util(model)
h1, h2, avg, w_map = self.strategy.group_hosts_by_cpu_util()
# print h1, h2, avg, w_map
self.assertEqual(h1[0]['hv'].uuid, 'Node_0')
self.assertEqual(h2[0]['hv'].uuid, 'Node_1')
@@ -64,73 +84,69 @@ class TestWorkloadBalance(base.BaseTestCase):
def test_choose_vm_to_migrate(self):
model = self.fake_cluster.generate_scenario_6_with_2_hypervisors()
strategy = workload_balance.WorkloadBalance()
strategy.ceilometer = mock.MagicMock(
self.m_model.return_value = model
self.strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics_wb)
h1, h2, avg, w_map = strategy.group_hosts_by_cpu_util(model)
vm_to_mig = strategy.choose_vm_to_migrate(model, h1, avg, w_map)
h1, h2, avg, w_map = self.strategy.group_hosts_by_cpu_util()
vm_to_mig = self.strategy.choose_vm_to_migrate(h1, avg, w_map)
self.assertEqual(vm_to_mig[0].uuid, 'Node_0')
self.assertEqual(vm_to_mig[1].uuid,
"73b09e16-35b7-4922-804e-e8f5d9b740fc")
def test_choose_vm_notfound(self):
model = self.fake_cluster.generate_scenario_6_with_2_hypervisors()
strategy = workload_balance.WorkloadBalance()
strategy.ceilometer = mock.MagicMock(
self.m_model.return_value = model
self.strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics_wb)
h1, h2, avg, w_map = strategy.group_hosts_by_cpu_util(model)
h1, h2, avg, w_map = self.strategy.group_hosts_by_cpu_util()
vms = model.get_all_vms()
vms.clear()
vm_to_mig = strategy.choose_vm_to_migrate(model, h1, avg, w_map)
vm_to_mig = self.strategy.choose_vm_to_migrate(h1, avg, w_map)
self.assertEqual(vm_to_mig, None)
def test_filter_destination_hosts(self):
model = self.fake_cluster.generate_scenario_6_with_2_hypervisors()
strategy = workload_balance.WorkloadBalance()
strategy.ceilometer = mock.MagicMock(
self.m_model.return_value = model
self.strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics_wb)
h1, h2, avg, w_map = strategy.group_hosts_by_cpu_util(model)
vm_to_mig = strategy.choose_vm_to_migrate(model, h1, avg, w_map)
dest_hosts = strategy.filter_destination_hosts(model, h2, vm_to_mig[1],
avg, w_map)
h1, h2, avg, w_map = self.strategy.group_hosts_by_cpu_util()
vm_to_mig = self.strategy.choose_vm_to_migrate(h1, avg, w_map)
dest_hosts = self.strategy.filter_destination_hosts(
h2, vm_to_mig[1], avg, w_map)
self.assertEqual(len(dest_hosts), 1)
self.assertEqual(dest_hosts[0]['hv'].uuid, 'Node_1')
def test_exception_model(self):
strategy = workload_balance.WorkloadBalance()
self.assertRaises(exception.ClusterStateNotDefined, strategy.execute,
None)
self.m_model.return_value = None
self.assertRaises(
exception.ClusterStateNotDefined, self.strategy.execute)
def test_exception_cluster_empty(self):
strategy = workload_balance.WorkloadBalance()
model = model_root.ModelRoot()
self.assertRaises(exception.ClusterEmpty, strategy.execute, model)
self.m_model.return_value = model
self.assertRaises(exception.ClusterEmpty, self.strategy.execute)
def test_execute_cluster_empty(self):
strategy = workload_balance.WorkloadBalance()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics_wb)
model = model_root.ModelRoot()
self.assertRaises(exception.ClusterEmpty, strategy.execute, model)
self.m_model.return_value = model
self.strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics_wb)
self.assertRaises(exception.ClusterEmpty, self.strategy.execute)
def test_execute_no_workload(self):
strategy = workload_balance.WorkloadBalance()
strategy.ceilometer = mock.MagicMock(
model = self.fake_cluster.generate_scenario_4_with_1_hypervisor_no_vm()
self.m_model.return_value = model
self.strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics_wb)
current_state_cluster = faker_cluster_state.FakerModelCollector()
model = current_state_cluster. \
generate_scenario_4_with_1_hypervisor_no_vm()
solution = strategy.execute(model)
solution = self.strategy.execute()
self.assertEqual(solution.actions, [])
def test_execute(self):
strategy = workload_balance.WorkloadBalance()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics_wb)
model = self.fake_cluster.generate_scenario_6_with_2_hypervisors()
solution = strategy.execute(model)
self.m_model.return_value = model
self.strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics_wb)
solution = self.strategy.execute()
actions_counter = collections.Counter(
[action.get('action_type') for action in solution.actions])
@@ -138,11 +154,11 @@ class TestWorkloadBalance(base.BaseTestCase):
self.assertEqual(num_migrations, 1)
def test_check_parameters(self):
strategy = workload_balance.WorkloadBalance()
strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics_wb)
model = self.fake_cluster.generate_scenario_6_with_2_hypervisors()
solution = strategy.execute(model)
self.m_model.return_value = model
self.strategy.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics_wb)
solution = self.strategy.execute()
loader = default.DefaultActionLoader()
for action in solution.actions:
loaded_action = loader.load(action['action_type'])

View File

@@ -19,6 +19,7 @@
import mock
from watcher.decision_engine.model import model_root
from watcher.decision_engine.strategy import strategies
from watcher.tests import base
from watcher.tests.decision_engine.strategy.strategies \
@@ -28,40 +29,48 @@ from watcher.tests.decision_engine.strategy.strategies \
class TestWorkloadStabilization(base.BaseTestCase):
# fake metrics
fake_metrics = faker_metrics_collector.FakerMetricsCollector()
# fake cluster
fake_cluster = faker_cluster_state.FakerModelCollector()
def setUp(self):
super(TestWorkloadStabilization, self).setUp()
hosts_load_assert = {'Node_0':
{'cpu_util': 0.07, 'memory.resident': 7.0,
'vcpus': 40},
'Node_1':
{'cpu_util': 0.05, 'memory.resident': 5,
'vcpus': 40},
'Node_2':
{'cpu_util': 0.1, 'memory.resident': 29,
'vcpus': 40},
'Node_3':
{'cpu_util': 0.04, 'memory.resident': 8,
'vcpus': 40},
'Node_4':
{'cpu_util': 0.02, 'memory.resident': 4,
'vcpus': 40}}
# fake metrics
self.fake_metrics = faker_metrics_collector.FakerMetricsCollector()
# fake cluster
self.fake_cluster = faker_cluster_state.FakerModelCollector()
self.hosts_load_assert = {
'Node_0': {'cpu_util': 0.07, 'memory.resident': 7.0, 'vcpus': 40},
'Node_1': {'cpu_util': 0.05, 'memory.resident': 5, 'vcpus': 40},
'Node_2': {'cpu_util': 0.1, 'memory.resident': 29, 'vcpus': 40},
'Node_3': {'cpu_util': 0.04, 'memory.resident': 8, 'vcpus': 40},
'Node_4': {'cpu_util': 0.02, 'memory.resident': 4, 'vcpus': 40}}
p_model = mock.patch.object(
strategies.WorkloadStabilization, "model",
new_callable=mock.PropertyMock)
self.m_model = p_model.start()
self.addCleanup(p_model.stop)
p_ceilometer = mock.patch.object(
strategies.WorkloadStabilization, "ceilometer",
new_callable=mock.PropertyMock)
self.m_ceilometer = p_ceilometer.start()
self.addCleanup(p_ceilometer.stop)
self.m_model.return_value = model_root.ModelRoot()
self.m_ceilometer.return_value = mock.Mock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
self.strategy = strategies.WorkloadStabilization(config=mock.Mock())
def test_get_vm_load(self):
model = self.fake_cluster.generate_scenario_1()
sd = strategies.WorkloadStabilization()
sd.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
self.m_model.return_value = self.fake_cluster.generate_scenario_1()
vm_0_dict = {'uuid': 'VM_0', 'vcpus': 10,
'cpu_util': 7, 'memory.resident': 2}
self.assertEqual(sd.get_vm_load("VM_0", model), vm_0_dict)
self.assertEqual(vm_0_dict, self.strategy.get_vm_load("VM_0"))
def test_normalize_hosts_load(self):
model = self.fake_cluster.generate_scenario_1()
sd = strategies.WorkloadStabilization()
self.m_model.return_value = self.fake_cluster.generate_scenario_1()
fake_hosts = {'Node_0': {'cpu_util': 0.07, 'memory.resident': 7},
'Node_1': {'cpu_util': 0.05, 'memory.resident': 5}}
normalized_hosts = {'Node_0':
@@ -70,99 +79,82 @@ class TestWorkloadStabilization(base.BaseTestCase):
'Node_1':
{'cpu_util': 0.05,
'memory.resident': 0.03787878787878788}}
self.assertEqual(sd.normalize_hosts_load(fake_hosts, model),
normalized_hosts)
self.assertEqual(
normalized_hosts,
self.strategy.normalize_hosts_load(fake_hosts))
def test_get_hosts_load(self):
sd = strategies.WorkloadStabilization()
sd.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
self.m_model.return_value = self.fake_cluster.generate_scenario_1()
self.assertEqual(
sd.get_hosts_load(self.fake_cluster.generate_scenario_1()),
self.strategy.get_hosts_load(),
self.hosts_load_assert)
def test_get_sd(self):
sd = strategies.WorkloadStabilization()
test_cpu_sd = 0.027
test_ram_sd = 9.3
self.assertEqual(
round(sd.get_sd(self.hosts_load_assert, 'cpu_util'), 3),
round(self.strategy.get_sd(
self.hosts_load_assert, 'cpu_util'), 3),
test_cpu_sd)
self.assertEqual(
round(sd.get_sd(self.hosts_load_assert, 'memory.resident'), 1),
round(self.strategy.get_sd(
self.hosts_load_assert, 'memory.resident'), 1),
test_ram_sd)
def test_calculate_weighted_sd(self):
sd = strategies.WorkloadStabilization()
sd_case = [0.5, 0.75]
self.assertEqual(sd.calculate_weighted_sd(sd_case), 1.25)
self.assertEqual(self.strategy.calculate_weighted_sd(sd_case), 1.25)
def test_calculate_migration_case(self):
model = self.fake_cluster.generate_scenario_1()
sd = strategies.WorkloadStabilization()
sd.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
self.assertEqual(sd.calculate_migration_case(
self.hosts_load_assert, "VM_5", "Node_2", "Node_1",
model)[-1]["Node_1"],
self.m_model.return_value = self.fake_cluster.generate_scenario_1()
self.assertEqual(
self.strategy.calculate_migration_case(
self.hosts_load_assert, "VM_5",
"Node_2", "Node_1")[-1]["Node_1"],
{'cpu_util': 2.55, 'memory.resident': 21, 'vcpus': 40})
def test_simulate_migrations(self):
sd = strategies.WorkloadStabilization()
sd.host_choice = 'retry'
sd.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
model = self.fake_cluster.generate_scenario_1()
self.m_model.return_value = model
self.strategy.host_choice = 'retry'
self.assertEqual(
len(sd.simulate_migrations(self.fake_cluster.generate_scenario_1(),
self.hosts_load_assert)),
8)
8,
len(self.strategy.simulate_migrations(self.hosts_load_assert)))
def test_check_threshold(self):
sd = strategies.WorkloadStabilization()
sd.thresholds = {'cpu_util': 0.001, 'memory.resident': 0.2}
sd.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
sd.simulate_migrations = mock.Mock(return_value=True)
self.assertTrue(
sd.check_threshold(self.fake_cluster.generate_scenario_1()))
self.m_model.return_value = self.fake_cluster.generate_scenario_1()
self.strategy.thresholds = {'cpu_util': 0.001, 'memory.resident': 0.2}
self.strategy.simulate_migrations = mock.Mock(return_value=True)
self.assertTrue(self.strategy.check_threshold())
def test_execute_one_migration(self):
sd = strategies.WorkloadStabilization()
model = self.fake_cluster.generate_scenario_1()
sd.thresholds = {'cpu_util': 0.001, 'memory.resident': 0.2}
sd.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
sd.simulate_migrations = mock.Mock(return_value=[{'vm': 'VM_4',
's_host': 'Node_2',
'host': 'Node_1'}])
with mock.patch.object(sd, 'migrate') as mock_migration:
sd.execute(model)
mock_migration.assert_called_once_with(model, 'VM_4', 'Node_2',
'Node_1')
self.m_model.return_value = self.fake_cluster.generate_scenario_1()
self.strategy.thresholds = {'cpu_util': 0.001, 'memory.resident': 0.2}
self.strategy.simulate_migrations = mock.Mock(
return_value=[{'vm': 'VM_4', 's_host': 'Node_2', 'host': 'Node_1'}]
)
with mock.patch.object(self.strategy, 'migrate') as mock_migration:
self.strategy.execute()
mock_migration.assert_called_once_with(
'VM_4', 'Node_2', 'Node_1')
def test_execute_multiply_migrations(self):
sd = strategies.WorkloadStabilization()
model = self.fake_cluster.generate_scenario_1()
sd.thresholds = {'cpu_util': 0.00001, 'memory.resident': 0.0001}
sd.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
sd.simulate_migrations = mock.Mock(return_value=[{'vm': 'VM_4',
's_host': 'Node_2',
'host': 'Node_1'},
{'vm': 'VM_3',
's_host': 'Node_2',
'host': 'Node_4'}])
with mock.patch.object(sd, 'migrate') as mock_migrate:
sd.execute(model)
self.m_model.return_value = self.fake_cluster.generate_scenario_1()
self.strategy.thresholds = {'cpu_util': 0.00001,
'memory.resident': 0.0001}
self.strategy.simulate_migrations = mock.Mock(
return_value=[{'vm': 'VM_4', 's_host': 'Node_2', 'host': 'Node_1'},
{'vm': 'VM_3', 's_host': 'Node_2', 'host': 'Node_3'}]
)
with mock.patch.object(self.strategy, 'migrate') as mock_migrate:
self.strategy.execute()
self.assertEqual(mock_migrate.call_count, 1)
def test_execute_nothing_to_migrate(self):
sd = strategies.WorkloadStabilization()
model = self.fake_cluster.generate_scenario_1()
sd.thresholds = {'cpu_util': 0.042, 'memory.resident': 0.0001}
sd.ceilometer = mock.MagicMock(
statistic_aggregation=self.fake_metrics.mock_get_statistics)
sd.simulate_migrations = mock.Mock(return_value=False)
with mock.patch.object(sd, 'migrate') as mock_migrate:
sd.execute(model)
self.m_model.return_value = self.fake_cluster.generate_scenario_1()
self.strategy.thresholds = {'cpu_util': 0.042,
'memory.resident': 0.0001}
self.strategy.simulate_migrations = mock.Mock(return_value=False)
with mock.patch.object(self.strategy, 'migrate') as mock_migrate:
self.strategy.execute()
mock_migrate.assert_not_called()