consolidation of watcher
Change-Id: I9c82ef4d8a81af98afdfc34f5ad496bcade4af6a
This commit is contained in:
@@ -31,7 +31,7 @@ from watcher.tests.objects import utils as obj_utils
|
||||
def post_get_test_action(**kw):
|
||||
action = api_utils.action_post_data(**kw)
|
||||
action_plan = db_utils.get_test_action_plan()
|
||||
action['action_plan_id'] = None
|
||||
del action['action_plan_id']
|
||||
action['action_plan_uuid'] = kw.get('action_plan_uuid',
|
||||
action_plan['uuid'])
|
||||
action['next'] = None
|
||||
|
||||
63
watcher/tests/api/v1/test_goals.py
Normal file
63
watcher/tests/api/v1/test_goals.py
Normal file
@@ -0,0 +1,63 @@
|
||||
# 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 oslo_config import cfg
|
||||
from watcher.tests.api import base as api_base
|
||||
|
||||
CONF = cfg.CONF
|
||||
|
||||
|
||||
class TestListGoal(api_base.FunctionalTest):
|
||||
|
||||
def setUp(self):
|
||||
super(TestListGoal, self).setUp()
|
||||
|
||||
def _assert_goal_fields(self, goal):
|
||||
goal_fields = ['name', 'strategy']
|
||||
for field in goal_fields:
|
||||
self.assertIn(field, goal)
|
||||
|
||||
def test_one(self):
|
||||
response = self.get_json('/goals')
|
||||
self._assert_goal_fields(response['goals'][0])
|
||||
|
||||
def test_get_one(self):
|
||||
goal_name = CONF.watcher_goals.goals.keys()[0]
|
||||
response = self.get_json('/goals/%s' % goal_name)
|
||||
self.assertEqual(goal_name, response['name'])
|
||||
self._assert_goal_fields(response)
|
||||
|
||||
def test_detail(self):
|
||||
goal_name = CONF.watcher_goals.goals.keys()[0]
|
||||
response = self.get_json('/goals/detail')
|
||||
self.assertEqual(goal_name, response['goals'][0]["name"])
|
||||
self._assert_goal_fields(response['goals'][0])
|
||||
|
||||
def test_detail_against_single(self):
|
||||
goal_name = CONF.watcher_goals.goals.keys()[0]
|
||||
response = self.get_json('/goals/%s/detail' % goal_name,
|
||||
expect_errors=True)
|
||||
self.assertEqual(404, response.status_int)
|
||||
|
||||
def test_many(self):
|
||||
response = self.get_json('/goals')
|
||||
self.assertEqual(len(CONF.watcher_goals.goals),
|
||||
len(response['goals']))
|
||||
|
||||
def test_collection_links(self):
|
||||
response = self.get_json('/goals/?limit=2')
|
||||
self.assertEqual(2, len(response['goals']))
|
||||
|
||||
def test_collection_links_default_limit(self):
|
||||
cfg.CONF.set_override('max_limit', 3, 'api')
|
||||
response = self.get_json('/goals')
|
||||
self.assertEqual(3, len(response['goals']))
|
||||
@@ -1,65 +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 oslo_config import cfg
|
||||
|
||||
from watcher.applier.framework.default_applier import DefaultApplier
|
||||
|
||||
from watcher.common import utils
|
||||
from watcher.decision_engine.framework.default_planner import DefaultPlanner
|
||||
from watcher.decision_engine.strategies.basic_consolidation import \
|
||||
BasicConsolidation
|
||||
from watcher.openstack.common import log
|
||||
from watcher.tests.db import base
|
||||
from watcher.tests.db import utils as db_utils
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
FakerStateCollector
|
||||
from watcher.tests.decision_engine.faker_metrics_collector import \
|
||||
FakerMetricsCollector
|
||||
|
||||
from oslo_config import cfg
|
||||
|
||||
CONF = cfg.CONF
|
||||
""
|
||||
class TestApplier(base.DbTestCase):
|
||||
default_planner = DefaultPlanner()
|
||||
|
||||
def create_solution(self):
|
||||
metrics = FakerMetricsCollector()
|
||||
current_state_cluster = FakerStateCollector()
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(metrics)
|
||||
return sercon.execute(current_state_cluster.generate_scenario_1())
|
||||
|
||||
def test_scheduler_w(self):
|
||||
CONF.debug = True
|
||||
log.setup('watcher-sercon-demo')
|
||||
|
||||
CONF.keystone_authtoken.auth_uri = "http://10.50.0.105:5000/v3"
|
||||
CONF.keystone_authtoken.admin_user = "admin"
|
||||
CONF.keystone_authtoken.admin_password = "openstacktest"
|
||||
CONF.keystone_authtoken.admin_tenant_name = "test"
|
||||
|
||||
audit = db_utils.create_test_audit(uuid=utils.generate_uuid())
|
||||
|
||||
action_plan = self.default_planner.schedule(self.context,
|
||||
audit.id,
|
||||
self.create_solution())
|
||||
|
||||
applier = DefaultApplier()
|
||||
applier.execute(self.context, action_plan.uuid)
|
||||
"""""
|
||||
@@ -1,99 +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 keystoneclient import session
|
||||
|
||||
from keystoneclient.auth.identity import v3
|
||||
|
||||
import cinderclient.v2.client as ciclient
|
||||
import glanceclient.v2.client as glclient
|
||||
import keystoneclient.v3.client as ksclient
|
||||
import neutronclient.neutron.client as netclient
|
||||
import novaclient.v2.client as nvclient
|
||||
|
||||
from watcher.common.utils import CONF
|
||||
from oslo_config import cfg
|
||||
from watcher.applier.framework.command.migrate_command import MigrateCommand
|
||||
from watcher.applier.framework.command.wrapper.nova_wrapper import NovaWrapper
|
||||
from watcher.decision_engine.framework.default_planner import Primitives
|
||||
from watcher.openstack.common import log
|
||||
|
||||
cfg.CONF.import_opt('auth_uri', 'keystoneclient.middleware.auth_token',
|
||||
group='keystone_authtoken')
|
||||
cfg.CONF.import_opt('admin_user', 'keystoneclient.middleware.auth_token',
|
||||
group='keystone_authtoken')
|
||||
cfg.CONF.import_opt('admin_password', 'keystoneclient.middleware.auth_token',
|
||||
group='keystone_authtoken')
|
||||
cfg.CONF.import_opt('admin_tenant_name',
|
||||
'keystoneclient.middleware.auth_token',
|
||||
group='keystone_authtoken')
|
||||
|
||||
cfg.CONF.keystone_authtoken.auth_uri = "http://10.50.0.105:5000/v3/"
|
||||
cfg.CONF.keystone_authtoken.admin_user = "admin"
|
||||
cfg.CONF.keystone_authtoken.admin_password = "openstacktest"
|
||||
cfg.CONF.keystone_authtoken.admin_tenant_name = "test"
|
||||
|
||||
try:
|
||||
cfg.CONF.debug = True
|
||||
log.setup('watcher-sercon-demo')
|
||||
creds = \
|
||||
{'auth_url': CONF.keystone_authtoken.auth_uri,
|
||||
'username': CONF.keystone_authtoken.admin_user,
|
||||
'password': CONF.keystone_authtoken.admin_password,
|
||||
'project_name': CONF.keystone_authtoken.admin_tenant_name,
|
||||
'user_domain_name': "default",
|
||||
'project_domain_name': "default"}
|
||||
auth = v3.Password(auth_url=creds['auth_url'],
|
||||
username=creds['username'],
|
||||
password=creds['password'],
|
||||
project_name=creds['project_name'],
|
||||
user_domain_name=creds[
|
||||
'user_domain_name'],
|
||||
project_domain_name=creds[
|
||||
'project_domain_name'])
|
||||
sess = session.Session(auth=auth)
|
||||
nova = nvclient.Client("3", session=sess)
|
||||
neutron = netclient.Client('2.0', session=sess)
|
||||
neutron.format = 'json'
|
||||
keystone = ksclient.Client(**creds)
|
||||
|
||||
glance_endpoint = keystone. \
|
||||
service_catalog.url_for(service_type='image',
|
||||
endpoint_type='publicURL')
|
||||
glance = glclient.Client(glance_endpoint,
|
||||
token=keystone.auth_token)
|
||||
|
||||
cinder = ciclient.Client('2', session=sess)
|
||||
wrapper = NovaWrapper(user=creds['username'], nova=nova,
|
||||
neutron=neutron, glance=glance,
|
||||
cinder=cinder)
|
||||
instance = wrapper. \
|
||||
create_instance(hypervisor_id='ldev-indeedsrv006',
|
||||
inst_name="demo_instance_1",
|
||||
keypair_name='admin',
|
||||
image_id=
|
||||
"2b958331-379b-4618-b2ba-fbe8a608b2bb")
|
||||
|
||||
cmd = MigrateCommand(instance.id, Primitives.COLD_MIGRATE,
|
||||
'ldev-indeedsrv006',
|
||||
'ldev-indeedsrv005')
|
||||
resu = cmd.execute(cmd)
|
||||
resu.result()
|
||||
# wrapper.delete_instance(instance.id)
|
||||
except Exception as e:
|
||||
print("rollback " + unicode(e))
|
||||
"""""
|
||||
@@ -1,6 +1,8 @@
|
||||
# -*- 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
|
||||
@@ -13,6 +15,7 @@
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
from mock import call
|
||||
from mock import MagicMock
|
||||
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# -*- 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
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# -*- 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
|
||||
@@ -13,6 +15,7 @@
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
|
||||
from mock import MagicMock
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# -*- 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
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# -*- 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
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# -*- 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
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# -*- 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
|
||||
@@ -13,6 +15,7 @@
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
|
||||
from watcher.decision_engine.framework.manager_decision_engine import \
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# -*- 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
|
||||
@@ -13,6 +15,7 @@
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import mock
|
||||
import oslo.messaging as om
|
||||
@@ -42,12 +45,6 @@ class TestApplierAPI(base.TestCase):
|
||||
'check_api_version',
|
||||
api_version=ApplierAPI().API_VERSION)
|
||||
|
||||
def test_execute_action_plan_throw_exception(self):
|
||||
action_plan_uuid = "uuid"
|
||||
self.assertRaises(exception.InvalidUuidOrName,
|
||||
self.api.launch_action_plan,
|
||||
action_plan_uuid)
|
||||
|
||||
def test_execute_audit_without_error(self):
|
||||
with mock.patch.object(om.RPCClient, 'call') as mock_call:
|
||||
action_plan_uuid = utils.generate_uuid()
|
||||
@@ -56,3 +53,9 @@ class TestApplierAPI(base.TestCase):
|
||||
self.context.to_dict(),
|
||||
'launch_action_plan',
|
||||
action_plan_uuid=action_plan_uuid)
|
||||
|
||||
def test_execute_action_plan_throw_exception(self):
|
||||
action_plan_uuid = "uuid"
|
||||
self.assertRaises(exception.InvalidUuidOrName,
|
||||
self.api.launch_action_plan,
|
||||
action_plan_uuid)
|
||||
|
||||
85
watcher/tests/collector/test_influxdb.py
Normal file
85
watcher/tests/collector/test_influxdb.py
Normal file
@@ -0,0 +1,85 @@
|
||||
# -*- 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 mock
|
||||
from watcher.metrics_engine.api.metrics_resource_collector import \
|
||||
AggregationFunction
|
||||
from watcher.metrics_engine.framework.datasources.influxdb_collector import \
|
||||
InfluxDBCollector
|
||||
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestInfluxDB(base.TestCase):
|
||||
def get_databases(self):
|
||||
return {'name': 'indeed'}
|
||||
|
||||
def test_get_measurement(self):
|
||||
influx = InfluxDBCollector()
|
||||
influx.get_client = mock.MagicMock()
|
||||
influx.get_client.get_list_database = self.get_databases
|
||||
result = influx.get_measurement("")
|
||||
self.assertEqual(result, [])
|
||||
|
||||
def test_build_query(self):
|
||||
influx = InfluxDBCollector()
|
||||
influx.get_client = mock.MagicMock()
|
||||
query = influx.build_query("cpu_compute")
|
||||
self.assertEqual(str(query), "SELECT * FROM \"cpu_compute\" ;")
|
||||
|
||||
def test_build_query_aggregate(self):
|
||||
influx = InfluxDBCollector()
|
||||
influx.get_client = mock.MagicMock()
|
||||
query = influx.build_query("cpu_compute",
|
||||
aggregation_function=AggregationFunction.
|
||||
COUNT)
|
||||
self.assertEqual(str(query),
|
||||
"SELECT count(value) FROM \"cpu_compute\" ;")
|
||||
|
||||
def test_build_query_aggregate_intervals(self):
|
||||
influx = InfluxDBCollector()
|
||||
influx.get_client = mock.MagicMock()
|
||||
query = influx.build_query("cpu_compute",
|
||||
aggregation_function=AggregationFunction.
|
||||
COUNT,
|
||||
intervals="5m")
|
||||
self.assertEqual(str(query),
|
||||
"SELECT count(value) FROM \"cpu_compute\" "
|
||||
"group by time(5m);")
|
||||
|
||||
def test_build_query_aggregate_filters(self):
|
||||
influx = InfluxDBCollector()
|
||||
influx.get_client = mock.MagicMock()
|
||||
filters = ['host=server1']
|
||||
query = influx.build_query("cpu_compute",
|
||||
aggregation_function=AggregationFunction.
|
||||
COUNT,
|
||||
intervals="5m",
|
||||
filters=filters)
|
||||
self.assertEqual(str(query), 'SELECT count(value) FROM'
|
||||
' \"cpu_compute" WHERE'
|
||||
' host = \'server1\' group by time(5m);')
|
||||
|
||||
def test_get_qusurement_start(self):
|
||||
influx = InfluxDBCollector()
|
||||
influx.get_client = mock.MagicMock()
|
||||
influx.get_client.get_list_database = self.get_databases
|
||||
result = influx.get_measurement("cpu_compute", start_time='now',
|
||||
end_time="now")
|
||||
self.assertEqual(result, [])
|
||||
43
watcher/tests/collector/test_nova_collector.py
Normal file
43
watcher/tests/collector/test_nova_collector.py
Normal 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 mock
|
||||
from watcher.metrics_engine.framework.statedb_collector import NovaCollector
|
||||
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestNovaCollector(base.TestCase):
|
||||
@mock.patch('keystoneclient.v3.client.Client')
|
||||
def setUp(self, mock_ksclient):
|
||||
super(TestNovaCollector, self).setUp()
|
||||
self.wrapper = mock.MagicMock()
|
||||
self.nova_collector = NovaCollector(self.wrapper)
|
||||
|
||||
def test_nova_collector(self):
|
||||
hypervisor = mock.Mock()
|
||||
hypervisor.hypervisor_hostname = "rdev-lannion.eu"
|
||||
hypervisor.service = mock.MagicMock()
|
||||
service = mock.Mock()
|
||||
service.host = ""
|
||||
self.wrapper.get_hypervisors_list.return_value = {hypervisor}
|
||||
self.wrapper.nova.services.find.get.return_value = service
|
||||
model = self.nova_collector.get_latest_state_cluster()
|
||||
self.assertIsNotNone(model)
|
||||
52
watcher/tests/collector/test_query.py
Normal file
52
watcher/tests/collector/test_query.py
Normal file
@@ -0,0 +1,52 @@
|
||||
# -*- 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.
|
||||
#
|
||||
from watcher.metrics_engine.framework.datasources.sql_ast.build_db_query import \
|
||||
DBQuery
|
||||
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestDBQuery(base.TestCase):
|
||||
|
||||
def test_query(self):
|
||||
expected = "SELECT * FROM \"cpu_compute.cpu.user.percent_gauge\" ;"
|
||||
query = DBQuery("cpu_compute.cpu.user.percent_gauge")
|
||||
self.assertEqual(str(query), expected)
|
||||
|
||||
def test_query_where(self):
|
||||
expected = "SELECT * FROM" \
|
||||
" \"cpu_compute.cpu.user.percent_gauge\" WHERE host=jed;"
|
||||
query = DBQuery("cpu_compute.cpu.user.percent_gauge").where(
|
||||
"host=jed")
|
||||
self.assertEqual(str(query), expected)
|
||||
|
||||
def test_query_filter(self):
|
||||
expected = "SELECT mean(value) FROM" \
|
||||
" \"cpu_compute.cpu.user.percent_gauge\" WHERE host=jed;"
|
||||
query = DBQuery("cpu_compute.cpu.user.percent_gauge").where(
|
||||
"host=jed").select("mean(value)")
|
||||
self.assertEqual(str(query), expected)
|
||||
|
||||
def test_query_groupby(self):
|
||||
expected = "SELECT * FROM" \
|
||||
" \"cpu_compute.cpu.user.percent_gauge\" " \
|
||||
"group by time(5m);"
|
||||
query = DBQuery("cpu_compute.cpu.user.percent_gauge").groupby(
|
||||
"time(5m)")
|
||||
self.assertEqual(str(query), expected)
|
||||
@@ -31,7 +31,6 @@ class TestTransportUrlBuilder(base.TestCase):
|
||||
|
||||
def test_transport_url_not_none(self):
|
||||
url = TransportUrlBuilder().url
|
||||
print(url)
|
||||
self.assertIsNotNone(url, "The transport url must not be none")
|
||||
|
||||
def test_transport_url_valid_pattern(self):
|
||||
|
||||
25
watcher/tests/decision_engine/api/messaging/test_decision_engine_command.py
Executable file
25
watcher/tests/decision_engine/api/messaging/test_decision_engine_command.py
Executable file
@@ -0,0 +1,25 @@
|
||||
# -*- 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.api.messaging.decision_engine_command import \
|
||||
DecisionEngineCommand
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestDecisionEngineCommand(base.TestCase):
|
||||
def test_execute(self):
|
||||
DEC = DecisionEngineCommand()
|
||||
self.assertRaises(NotImplementedError, DEC.execute)
|
||||
@@ -0,0 +1,30 @@
|
||||
# -*- 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.api.messaging.event_consumer import EventConsumer
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestEventConsumer(base.TestCase):
|
||||
def test_set_messaging(self):
|
||||
messaging = "test message"
|
||||
EC = EventConsumer()
|
||||
EC.set_messaging(messaging)
|
||||
self.assertEqual(EC.messaging, messaging)
|
||||
|
||||
def test_execute(self):
|
||||
EC = EventConsumer()
|
||||
self.assertRaises(NotImplementedError, EC.execute, None, None, None)
|
||||
0
watcher/tests/decision_engine/api/planner/__init__.py
Executable file
0
watcher/tests/decision_engine/api/planner/__init__.py
Executable file
24
watcher/tests/decision_engine/api/planner/test_planner.py
Executable file
24
watcher/tests/decision_engine/api/planner/test_planner.py
Executable file
@@ -0,0 +1,24 @@
|
||||
# -*- 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.api.planner.planner import Planner
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestPlanner(base.TestCase):
|
||||
def test_schedule(self):
|
||||
pl = Planner()
|
||||
self.assertRaises(NotImplementedError, pl.schedule, None, None, None)
|
||||
26
watcher/tests/decision_engine/api/solution/test_solution.py
Normal file
26
watcher/tests/decision_engine/api/solution/test_solution.py
Normal file
@@ -0,0 +1,26 @@
|
||||
# -*- 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.api.solution.solution import Solution
|
||||
from watcher.decision_engine.framework.model.model_root import ModelRoot
|
||||
from watcher.tests import base
|
||||
|
||||
class TestSolution(base.TestCase):
|
||||
def test_get_model(self):
|
||||
sol = Solution()
|
||||
current_model =
|
||||
sol.set_model(current_model)
|
||||
'''
|
||||
30
watcher/tests/decision_engine/api/solution/test_solution_comparator.py
Executable file
30
watcher/tests/decision_engine/api/solution/test_solution_comparator.py
Executable file
@@ -0,0 +1,30 @@
|
||||
# -*- 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.api.solution.solution import Solution as sol
|
||||
from watcher.decision_engine.api.solution.solution_comparator import Solution
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class test_Solution_Comparator(base.TestCase):
|
||||
def test_compare(self):
|
||||
sol1 = sol()
|
||||
sol2 = sol()
|
||||
solution_comparator = Solution()
|
||||
self.assertRaises(NotImplementedError,
|
||||
solution_comparator.compare,
|
||||
sol1,
|
||||
sol2)
|
||||
25
watcher/tests/decision_engine/api/solution/test_solution_evaluator.py
Executable file
25
watcher/tests/decision_engine/api/solution/test_solution_evaluator.py
Executable file
@@ -0,0 +1,25 @@
|
||||
# -*- 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.api.solution.solution_evaluator import \
|
||||
SolutionEvaluator
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestSolutionEvaluator(base.TestCase):
|
||||
def test_evaluate(self):
|
||||
SE = SolutionEvaluator()
|
||||
self.assertRaises(NotImplementedError, SE.evaluate, None)
|
||||
@@ -0,0 +1,30 @@
|
||||
# -*- 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.api.strategy.meta_action import MetaAction
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestMetaAction(base.TestCase):
|
||||
def test_get_priority(self):
|
||||
MA = MetaAction()
|
||||
MA.set_priority(3)
|
||||
self.assertEqual(MA.get_priority(), 3)
|
||||
|
||||
def test_get_level(self):
|
||||
MA = MetaAction()
|
||||
MA.set_level(5)
|
||||
self.assertEqual(MA.get_level(), 5)
|
||||
24
watcher/tests/decision_engine/api/strategy/test_selector.py
Executable file
24
watcher/tests/decision_engine/api/strategy/test_selector.py
Executable file
@@ -0,0 +1,24 @@
|
||||
# -*- 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.api.strategy.selector import Selector
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestSelector(base.TestCase):
|
||||
def test_define_from_goal(self):
|
||||
Sel = Selector()
|
||||
self.assertRaises(NotImplementedError, Sel.define_from_goal, None)
|
||||
@@ -0,0 +1,25 @@
|
||||
# -*- 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.api.strategy.strategy_context import \
|
||||
StrategyContext
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestStrategyContext(base.TestCase):
|
||||
def test_execute_strategy(self):
|
||||
SC = StrategyContext()
|
||||
self.assertRaises(NotImplementedError, SC.execute_strategy, None)
|
||||
@@ -1,103 +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.
|
||||
#
|
||||
|
||||
# FIXME(jed): remove this class due jenkins build failed
|
||||
# The following librairies are removed from requirement.txt :
|
||||
# - numpy
|
||||
# - matplotlib
|
||||
# These dependencies required a server x, jenkin's server has no
|
||||
# server x
|
||||
|
||||
# import matplotlib.pyplot as plt
|
||||
# import numpy as np
|
||||
|
||||
|
||||
from watcher.decision_engine.strategies.basic_consolidation import \
|
||||
BasicConsolidation
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
FakerStateCollector
|
||||
from watcher.tests.decision_engine.faker_metrics_collector import \
|
||||
FakerMetricsCollector
|
||||
|
||||
|
||||
class PlotConsolidationBasic(object):
|
||||
def plot(self, sercon, orign_model, solution):
|
||||
pass
|
||||
|
||||
# cluster_size = len(orign_model._hypervisors)
|
||||
# labels = []
|
||||
# before_score = []
|
||||
# after_score = []
|
||||
# for hypevisor_id in orign_model.get_all_hypervisors():
|
||||
# labels.append(hypevisor_id)
|
||||
# hypevisor = orign_model.get_hypervisor_from_id(hypevisor_id)
|
||||
# result_before = sercon.calculate_score_node(hypevisor,
|
||||
# orign_model)
|
||||
# result_after = sercon.calculate_score_node(hypevisor,
|
||||
# solution.get_model())
|
||||
# before_score.append(float(result_before * 100))
|
||||
# if result_after == 0:
|
||||
# result_after = 0
|
||||
# after_score.append(float(result_after * 100))
|
||||
#
|
||||
# ind = np.arange(cluster_size) # the x locations for the groups
|
||||
# width = 0.35 # the width of the bars
|
||||
#
|
||||
# fig, ax = plt.subplots()
|
||||
#
|
||||
# rects1 = ax.bar(ind, before_score, width, color='b')
|
||||
#
|
||||
# rects2 = ax.bar(ind + width, after_score, width, color='r')
|
||||
#
|
||||
# # add some text for labels, title and axes ticks
|
||||
# ax.set_ylabel(
|
||||
# 'Score of each hypervisor that represent their \
|
||||
# utilization level')
|
||||
# ax.set_title('Watcher Basic Server consolidation (efficiency ' + str(
|
||||
# sercon.get_solution().get_efficiency()) + " %)")
|
||||
#
|
||||
# ax.set_xticks(ind + width)
|
||||
# ax.set_xticklabels(labels)
|
||||
# ax.set_ylim([0, 140])
|
||||
|
||||
# ax.legend((rects1[0], rects2[0]),
|
||||
# ('Before Consolidation', 'After Consolidation'))
|
||||
|
||||
# def autolabel(rects):
|
||||
# # attach some text labels
|
||||
# for rect in rects:
|
||||
# height = rect.get_height()
|
||||
# ax.text(rect.get_x() + rect.get_width() / 2., 1.05 * height,
|
||||
# '%d' % int(height),
|
||||
# ha='center', va='bottom')
|
||||
#
|
||||
# autolabel(rects1)
|
||||
# autolabel(rects2)
|
||||
|
||||
# plt.show()
|
||||
|
||||
|
||||
cluster = FakerStateCollector()
|
||||
metrics = FakerMetricsCollector()
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(metrics)
|
||||
# try overbooking ? :) 150 % cpu
|
||||
sercon.set_threshold_cores(1)
|
||||
model_cluster = cluster.generate_scenario_1()
|
||||
solution = sercon.execute(model_cluster)
|
||||
plot = PlotConsolidationBasic()
|
||||
plot.plot(sercon, cluster.generate_scenario_1(), solution)
|
||||
@@ -1,45 +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 oslo_config import cfg
|
||||
import time
|
||||
from watcher.decision_engine.strategies.basic_consolidation import \
|
||||
BasicConsolidation
|
||||
|
||||
from watcher.openstack.common import log
|
||||
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
FakerStateCollector
|
||||
from watcher.tests.decision_engine.faker_metrics_collector import \
|
||||
FakerMetricsCollector
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
|
||||
cfg.CONF.debug = True
|
||||
log.setup('metering-controller')
|
||||
|
||||
metrics = FakerMetricsCollector()
|
||||
current_state_cluster = FakerStateCollector()
|
||||
|
||||
sercon = BasicConsolidation("basic", "Basic offline consolidation")
|
||||
sercon.set_metrics_resource_collector(metrics)
|
||||
|
||||
start_time = time.clock()
|
||||
solution = sercon.execute(current_state_cluster.generate_scenario_1())
|
||||
print(time.clock() - start_time, "seconds")
|
||||
print(solution)
|
||||
# planner = DefaultPlanner()
|
||||
# planner.schedule(solution)
|
||||
@@ -1,43 +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 oslo_config import cfg
|
||||
import time
|
||||
from watcher.decision_engine.strategies.basic_consolidation import \
|
||||
BasicConsolidation
|
||||
|
||||
from watcher.openstack.common import log
|
||||
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
FakerStateCollector
|
||||
from watcher.tests.decision_engine.faker_metrics_collector import \
|
||||
FakerMetricsCollector
|
||||
|
||||
|
||||
LOG = log.getLogger(__name__)
|
||||
# debug on
|
||||
cfg.CONF.debug = True
|
||||
log.setup('metering-controller')
|
||||
|
||||
metrics = FakerMetricsCollector()
|
||||
current_state_cluster = FakerStateCollector()
|
||||
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(metrics)
|
||||
|
||||
start_time = time.clock()
|
||||
solution = sercon.execute(current_state_cluster.generate_scenario_1())
|
||||
print("duration =" + str((time.clock() - start_time)), "seconds")
|
||||
LOG.debug(solution)
|
||||
@@ -1,6 +1,8 @@
|
||||
# -*- 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
|
||||
@@ -13,16 +15,17 @@
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import random
|
||||
|
||||
from watcher.decision_engine.api.collector.cluster_state_collector import \
|
||||
ClusterStateCollector
|
||||
from watcher.decision_engine.framework.model.hypervisor import Hypervisor
|
||||
from watcher.decision_engine.framework.model.model_root import ModelRoot
|
||||
from watcher.decision_engine.framework.model.resource import Resource
|
||||
from watcher.decision_engine.framework.model.resource import ResourceType
|
||||
from watcher.decision_engine.framework.model.vm import VM
|
||||
from watcher.metrics_engine.api.cluster_state_collector import \
|
||||
ClusterStateCollector
|
||||
|
||||
|
||||
class FakerStateCollector(ClusterStateCollector):
|
||||
@@ -56,7 +59,7 @@ class FakerStateCollector(ClusterStateCollector):
|
||||
for i in range(0, count_node):
|
||||
node_uuid = "Node_" + str(i)
|
||||
hypervisor = Hypervisor()
|
||||
hypervisor.set_uuid(node_uuid)
|
||||
hypervisor.uuid = node_uuid
|
||||
mem.set_capacity(hypervisor, 132)
|
||||
disk.set_capacity(hypervisor, 250)
|
||||
num_cores.set_capacity(hypervisor, 40)
|
||||
@@ -66,7 +69,7 @@ class FakerStateCollector(ClusterStateCollector):
|
||||
for i in range(0, count_vm):
|
||||
vm_uuid = "VM_" + str(i)
|
||||
vm = VM()
|
||||
vm.set_uuid(vm_uuid)
|
||||
vm.uuid = vm_uuid
|
||||
# print("create "+str(vm))
|
||||
mem.set_capacity(vm, 8)
|
||||
disk.set_capacity(vm, 10)
|
||||
@@ -107,7 +110,7 @@ class FakerStateCollector(ClusterStateCollector):
|
||||
for i in range(0, count_node):
|
||||
node_uuid = "Node_" + str(i)
|
||||
node = Hypervisor()
|
||||
node.set_uuid(node_uuid)
|
||||
node.uuid = node_uuid
|
||||
|
||||
mem.set_capacity(node, 132)
|
||||
disk.set_capacity(node, 250)
|
||||
@@ -118,7 +121,7 @@ class FakerStateCollector(ClusterStateCollector):
|
||||
for i in range(0, count_vm):
|
||||
vm_uuid = "VM_" + str(i)
|
||||
vm = VM()
|
||||
vm.set_uuid(vm_uuid)
|
||||
vm.uuid = vm_uuid
|
||||
# print("create "+str(vm))
|
||||
mem.set_capacity(vm, 2)
|
||||
disk.set_capacity(vm, 20)
|
||||
@@ -178,7 +181,7 @@ class FakerStateCollector(ClusterStateCollector):
|
||||
for i in range(0, count_node):
|
||||
node_uuid = "Node_" + str(i)
|
||||
node = Hypervisor()
|
||||
node.set_uuid(node_uuid)
|
||||
node.uuid = node_uuid
|
||||
mem.set_capacity(node, 132)
|
||||
disk.set_capacity(node, 250)
|
||||
num_cores.set_capacity(node, 40)
|
||||
@@ -215,7 +218,7 @@ class FakerStateCollector(ClusterStateCollector):
|
||||
for i in range(0, count_node):
|
||||
node_uuid = "Node_" + str(i)
|
||||
node = Hypervisor()
|
||||
node.set_uuid(node_uuid)
|
||||
node.uuid = node_uuid
|
||||
mem.set_capacity(node, 132)
|
||||
disk.set_capacity(node, 250)
|
||||
num_cores.set_capacity(node, 40)
|
||||
@@ -225,14 +228,13 @@ class FakerStateCollector(ClusterStateCollector):
|
||||
for i in range(0, count_vm):
|
||||
vm_uuid = "VM_" + str(i)
|
||||
vm = VM()
|
||||
vm.set_uuid(vm_uuid)
|
||||
vm.uuid = vm_uuid
|
||||
# print("create "+str(vm))
|
||||
mem.set_capacity(vm, 10)
|
||||
disk.set_capacity(vm, 25)
|
||||
num_cores.set_capacity(vm, 16)
|
||||
vms.append(vm)
|
||||
current_state_cluster.add_vm(vm)
|
||||
print(count_vm)
|
||||
indice = 0
|
||||
for j in range(0, 2):
|
||||
node_uuid = "Node_" + str(j)
|
||||
@@ -253,3 +255,84 @@ class FakerStateCollector(ClusterStateCollector):
|
||||
self.map(current_state_cluster, node_uuid, vm_uuid)
|
||||
|
||||
return current_state_cluster
|
||||
|
||||
def generate_scenario_4_with_2_hypervisors(self):
|
||||
vms = []
|
||||
|
||||
current_state_cluster = ModelRoot()
|
||||
# number of nodes
|
||||
count_node = 2
|
||||
# number max of vm per node
|
||||
node_count_vm = 1
|
||||
# total number of virtual machine
|
||||
count_vm = (count_node * node_count_vm)
|
||||
|
||||
# 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_" + str(i)
|
||||
node = Hypervisor()
|
||||
node.uuid = node_uuid
|
||||
|
||||
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)
|
||||
|
||||
for i in range(0, count_vm):
|
||||
vm_uuid = "VM_" + str(i)
|
||||
vm = VM()
|
||||
vm.uuid = vm_uuid
|
||||
# print("create "+str(vm))
|
||||
mem.set_capacity(vm, 2)
|
||||
disk.set_capacity(vm, 20)
|
||||
num_cores.set_capacity(vm, 10)
|
||||
vms.append(vm)
|
||||
current_state_cluster.add_vm(vm)
|
||||
|
||||
current_state_cluster.get_mapping().map(
|
||||
current_state_cluster.get_hypervisor_from_id("Node_0"),
|
||||
current_state_cluster.get_vm_from_id("VM_0"))
|
||||
|
||||
current_state_cluster.get_mapping().map(
|
||||
current_state_cluster.get_hypervisor_from_id("Node_1"),
|
||||
current_state_cluster.get_vm_from_id("VM_1"))
|
||||
|
||||
return current_state_cluster
|
||||
|
||||
def generate_scenario_5_with_1_hypervisor_no_vm(self):
|
||||
current_state_cluster = ModelRoot()
|
||||
# number of nodes
|
||||
count_node = 1
|
||||
|
||||
# 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_" + str(i)
|
||||
node = Hypervisor()
|
||||
node.uuid = node_uuid
|
||||
|
||||
mem.set_capacity(node, 1)
|
||||
disk.set_capacity(node, 1)
|
||||
num_cores.set_capacity(node, 1)
|
||||
# print("create "+str(node))
|
||||
current_state_cluster.add_hypervisor(node)
|
||||
|
||||
return current_state_cluster
|
||||
|
||||
@@ -1,6 +1,8 @@
|
||||
# -*- 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
|
||||
@@ -13,15 +15,130 @@
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
|
||||
import random
|
||||
from watcher.decision_engine.api.collector.metrics_resource_collector import \
|
||||
|
||||
from watcher.metrics_engine.api.metrics_resource_collector import Measure
|
||||
from watcher.metrics_engine.api.metrics_resource_collector import \
|
||||
MetricsResourceCollector
|
||||
|
||||
|
||||
class FakerMetricsCollector(MetricsResourceCollector):
|
||||
def __init__(self):
|
||||
pass
|
||||
self.emptytype = ""
|
||||
|
||||
def empty_one_metric(self, emptytype):
|
||||
self.emptytype = emptytype
|
||||
|
||||
def get_measurement(self,
|
||||
metric,
|
||||
callback=None,
|
||||
start_time=None,
|
||||
end_time=None,
|
||||
filters=None,
|
||||
aggregation_function=None,
|
||||
intervals=None):
|
||||
|
||||
results = []
|
||||
if metric == "compute_cpu_user_percent_gauge":
|
||||
if self.emptytype == "CPU_COMPUTE":
|
||||
pass
|
||||
else:
|
||||
results.append(Measure(0, 5))
|
||||
elif metric == "instance_cpu_percent_gauge":
|
||||
results.append(
|
||||
self.get_average_usage_vm_cpu(filters[0].split('=')[1]))
|
||||
elif metric == "instance_memory_resident_used_bytes_gauge":
|
||||
results.append(
|
||||
self.get_average_usage_vm_memory(filters[0].split('=')[1]))
|
||||
elif metric == "instance_disk_used_bytes_gauge":
|
||||
if self.emptytype == "DISK_COMPUTE":
|
||||
pass
|
||||
else:
|
||||
results.append(
|
||||
self.get_average_usage_vm_disk(filters[0].split('=')[1]))
|
||||
elif metric == "compute_memory_used_bytes_gauge":
|
||||
if self.emptytype == "MEM_COMPUTE":
|
||||
pass
|
||||
else:
|
||||
results.append(self.get_usage_node_cpu(
|
||||
filters[0].split('=')[1]))
|
||||
elif metric == "compute_disk_size_used_bytes_gauge":
|
||||
if self.emptytype == "DISK_COMPUTE":
|
||||
pass
|
||||
else:
|
||||
results.append(self.get_usage_node_disk(
|
||||
filters[0].split('=')[1]))
|
||||
else:
|
||||
results.append(Measure(0, 0))
|
||||
return results
|
||||
|
||||
def get_usage_node_disk(self, uuid):
|
||||
"""The last VM CPU usage values to average
|
||||
|
||||
:param uuid:00
|
||||
:return:
|
||||
"""
|
||||
# query influxdb stream
|
||||
|
||||
# compute in stream
|
||||
|
||||
# Normalize
|
||||
mock = {}
|
||||
# node 0
|
||||
mock['Node_0'] = Measure(0, 7)
|
||||
mock['Node_1'] = Measure(0, 100)
|
||||
# node 1
|
||||
mock['Node_2'] = Measure(0, 10)
|
||||
# node 2
|
||||
mock['Node_3'] = Measure(0, 5)
|
||||
mock['Node_4'] = Measure(0, 5)
|
||||
mock['Node_5'] = Measure(0, 10)
|
||||
|
||||
# node 3
|
||||
mock['Node_6'] = Measure(0, 8)
|
||||
|
||||
# node 4
|
||||
mock['VM_7'] = Measure(0, 4)
|
||||
if uuid not in mock.keys():
|
||||
# mock[uuid] = random.randint(1, 4)
|
||||
mock[uuid] = Measure(0, 8)
|
||||
|
||||
return mock[str(uuid)]
|
||||
|
||||
def get_usage_node_cpu(self, uuid):
|
||||
"""The last VM CPU usage values to average
|
||||
|
||||
:param uuid:00
|
||||
:return:
|
||||
"""
|
||||
# query influxdb stream
|
||||
|
||||
# compute in stream
|
||||
|
||||
# Normalize
|
||||
mock = {}
|
||||
# node 0
|
||||
mock['Node_0'] = Measure(0, 7)
|
||||
mock['Node_1'] = Measure(0, 7)
|
||||
# node 1
|
||||
mock['Node_2'] = Measure(0, 80)
|
||||
# node 2
|
||||
mock['Node_3'] = Measure(0, 5)
|
||||
mock['Node_4'] = Measure(0, 5)
|
||||
mock['Node_5'] = Measure(0, 10)
|
||||
|
||||
# node 3
|
||||
mock['Node_6'] = Measure(0, 8)
|
||||
|
||||
# node 4
|
||||
mock['VM_7'] = Measure(0, 4)
|
||||
if uuid not in mock.keys():
|
||||
# mock[uuid] = random.randint(1, 4)
|
||||
mock[uuid] = Measure(0, 8)
|
||||
|
||||
return mock[str(uuid)]
|
||||
|
||||
def get_average_usage_vm_cpu(self, uuid):
|
||||
"""The last VM CPU usage values to average
|
||||
@@ -36,70 +153,70 @@ class FakerMetricsCollector(MetricsResourceCollector):
|
||||
# Normalize
|
||||
mock = {}
|
||||
# node 0
|
||||
mock['VM_0'] = 7
|
||||
mock['VM_1'] = 7
|
||||
mock['VM_0'] = Measure(0, 7)
|
||||
mock['VM_1'] = Measure(0, 7)
|
||||
# node 1
|
||||
mock['VM_2'] = 10
|
||||
mock['VM_2'] = Measure(0, 10)
|
||||
# node 2
|
||||
mock['VM_3'] = 5
|
||||
mock['VM_4'] = 5
|
||||
mock['VM_5'] = 10
|
||||
mock['VM_3'] = Measure(0, 5)
|
||||
mock['VM_4'] = Measure(0, 5)
|
||||
mock['VM_5'] = Measure(0, 10)
|
||||
|
||||
# node 3
|
||||
mock['VM_6'] = 8
|
||||
mock['VM_6'] = Measure(0, 8)
|
||||
|
||||
# node 4
|
||||
mock['VM_7'] = 4
|
||||
mock['VM_7'] = Measure(0, 4)
|
||||
if uuid not in mock.keys():
|
||||
# mock[uuid] = random.randint(1, 4)
|
||||
mock[uuid] = 8
|
||||
mock[uuid] = Measure(0, 8)
|
||||
|
||||
return mock[str(uuid)]
|
||||
|
||||
def get_average_usage_vm_memory(self, uuid):
|
||||
mock = {}
|
||||
# node 0
|
||||
mock['VM_0'] = 2
|
||||
mock['VM_1'] = 5
|
||||
mock['VM_0'] = Measure(0, 2)
|
||||
mock['VM_1'] = Measure(0, 5)
|
||||
# node 1
|
||||
mock['VM_2'] = 5
|
||||
mock['VM_2'] = Measure(0, 5)
|
||||
# node 2
|
||||
mock['VM_3'] = 8
|
||||
mock['VM_4'] = 5
|
||||
mock['VM_5'] = 16
|
||||
mock['VM_3'] = Measure(0, 8)
|
||||
mock['VM_4'] = Measure(0, 5)
|
||||
mock['VM_5'] = Measure(0, 16)
|
||||
|
||||
# node 3
|
||||
mock['VM_6'] = 8
|
||||
mock['VM_6'] = Measure(0, 8)
|
||||
|
||||
# node 4
|
||||
mock['VM_7'] = 4
|
||||
mock['VM_7'] = Measure(0, 4)
|
||||
if uuid not in mock.keys():
|
||||
# mock[uuid] = random.randint(1, 4)
|
||||
mock[uuid] = 10
|
||||
mock[uuid] = Measure(0, 10)
|
||||
|
||||
return mock[str(uuid)]
|
||||
|
||||
def get_average_usage_vm_disk(self, uuid):
|
||||
mock = {}
|
||||
# node 0
|
||||
mock['VM_0'] = 2
|
||||
mock['VM_1'] = 2
|
||||
mock['VM_0'] = Measure(0, 2)
|
||||
mock['VM_1'] = Measure(0, 2)
|
||||
# node 1
|
||||
mock['VM_2'] = 2
|
||||
mock['VM_2'] = Measure(0, 2)
|
||||
# node 2
|
||||
mock['VM_3'] = 10
|
||||
mock['VM_4'] = 15
|
||||
mock['VM_5'] = 20
|
||||
mock['VM_3'] = Measure(0, 10)
|
||||
mock['VM_4'] = Measure(0, 15)
|
||||
mock['VM_5'] = Measure(0, 20)
|
||||
|
||||
# node 3
|
||||
mock['VM_6'] = 8
|
||||
mock['VM_6'] = Measure(0, 8)
|
||||
|
||||
# node 4
|
||||
mock['VM_7'] = 4
|
||||
mock['VM_7'] = Measure(0, 4)
|
||||
|
||||
if uuid not in mock.keys():
|
||||
# mock[uuid] = random.randint(1, 4)
|
||||
mock[uuid] = 4
|
||||
mock[uuid] = Measure(0, 4)
|
||||
|
||||
return mock[str(uuid)]
|
||||
|
||||
|
||||
@@ -39,14 +39,21 @@ class TestTriggerAuditCommand(DbTestCase):
|
||||
self.context,
|
||||
audit_template_id=self.audit_template.id)
|
||||
|
||||
def test_trigger_audit_wihout_errors(self):
|
||||
def test_trigger_audit_without_errors(self):
|
||||
try:
|
||||
statedb = FakerStateCollector()
|
||||
ressourcedb = FakerMetricsCollector()
|
||||
command = TriggerAuditCommand(MagicMock(), statedb, ressourcedb)
|
||||
command.execute(self.audit.uuid, self.context)
|
||||
except Exception:
|
||||
self.fail("The audit should be trigged wihtour error")
|
||||
self.fail("The audit should be trigged without error")
|
||||
|
||||
def test_trigger_audit_with_errors(self):
|
||||
try:
|
||||
command = TriggerAuditCommand(MagicMock(), 0, 0)
|
||||
command.execute(self.audit.uuid, self.context)
|
||||
except Exception:
|
||||
self.fail("The audit should be trigged with error")
|
||||
|
||||
def test_trigger_audit_state_succes(self):
|
||||
statedb = FakerStateCollector()
|
||||
|
||||
@@ -13,7 +13,6 @@
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
"""
|
||||
import mock
|
||||
from mock import MagicMock
|
||||
from watcher.common import utils
|
||||
@@ -21,22 +20,54 @@ from watcher.decision_engine.framework.command.trigger_audit_command import \
|
||||
TriggerAuditCommand
|
||||
from watcher.decision_engine.framework.messaging.audit_endpoint import \
|
||||
AuditEndpoint
|
||||
from watcher.metrics_engine.framework.collector_manager import CollectorManager
|
||||
from watcher.tests import base
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
FakerStateCollector
|
||||
from watcher.tests.decision_engine.faker_metrics_collector import \
|
||||
FakerMetricsCollector
|
||||
|
||||
|
||||
class TriggerAuditCommandWithExecutor(TriggerAuditCommand):
|
||||
def setUp(self):
|
||||
super(TriggerAuditCommand, self).setUp()
|
||||
|
||||
def executor(self):
|
||||
pass
|
||||
|
||||
|
||||
class TestAuditEndpoint(base.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestAuditEndpoint, self).setUp()
|
||||
self.endpoint = AuditEndpoint(MagicMock())
|
||||
|
||||
def test_do_trigger_audit(self):
|
||||
audit_uuid = utils.generate_uuid()
|
||||
statedb = FakerStateCollector()
|
||||
ressourcedb = FakerMetricsCollector()
|
||||
command = TriggerAuditCommand(MagicMock(), statedb, ressourcedb)
|
||||
endpoint = AuditEndpoint(command)
|
||||
|
||||
with mock.patch.object(CollectorManager, 'get_statedb_collector') \
|
||||
as mock_call2:
|
||||
mock_call2.return_value = 0
|
||||
|
||||
with mock.patch.object(TriggerAuditCommand, 'execute') \
|
||||
as mock_call:
|
||||
mock_call.return_value = 0
|
||||
endpoint.do_trigger_audit(command, audit_uuid)
|
||||
# mock_call.assert_called_once_with()
|
||||
mock_call2.assert_called_once_with()
|
||||
|
||||
def test_trigger_audit(self):
|
||||
audit_uuid = utils.generate_uuid()
|
||||
# todo() add
|
||||
statedb = FakerStateCollector()
|
||||
ressourcedb = FakerMetricsCollector()
|
||||
command = TriggerAuditCommandWithExecutor(MagicMock(),
|
||||
statedb, ressourcedb)
|
||||
endpoint = AuditEndpoint(command)
|
||||
|
||||
with mock.patch.object(TriggerAuditCommand, 'execute') as mock_call:
|
||||
expected_uuid = self.endpoint.trigger_audit(
|
||||
self.context, audit_uuid)
|
||||
self.assertEqual(audit_uuid, expected_uuid)
|
||||
mock_call.assert_called_once_with(audit_uuid, self.context)
|
||||
"""
|
||||
with mock.patch.object(TriggerAuditCommandWithExecutor, 'executor') \
|
||||
as mock_call:
|
||||
mock_call.return_value = 0
|
||||
endpoint.trigger_audit(command, audit_uuid)
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# -*- 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.
|
||||
#
|
||||
from watcher.decision_engine.framework.meta_actions.migrate import Migrate
|
||||
from watcher.decision_engine.framework.model.hypervisor import Hypervisor
|
||||
from watcher.decision_engine.framework.model.vm import VM
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestMigtrate(base.BaseTestCase):
|
||||
def test_set_get_bandwidth(self):
|
||||
vm = VM()
|
||||
hyp_src = Hypervisor()
|
||||
hyp_dst = Hypervisor()
|
||||
mig = Migrate(vm, hyp_src, hyp_dst)
|
||||
mig.set_bandwidth(2)
|
||||
self.assertEqual(mig.get_bandwidth(), 2)
|
||||
@@ -0,0 +1,33 @@
|
||||
# -*- 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.
|
||||
#
|
||||
|
||||
from watcher.decision_engine.framework.model.diskInfo import DiskInfo
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestDiskInfo(base.BaseTestCase):
|
||||
def test_all(self):
|
||||
disk_information = DiskInfo()
|
||||
disk_information.set_size(1024)
|
||||
self.assertEqual(disk_information.get_size(), 1024)
|
||||
|
||||
disk_information.set_scheduler = "scheduler_qcq"
|
||||
|
||||
disk_information.set_device_name("nom_qcq")
|
||||
self.assertEqual(disk_information.get_device_name(), "nom_qcq")
|
||||
106
watcher/tests/decision_engine/framework/model/test_mapping.py
Normal file
106
watcher/tests/decision_engine/framework/model/test_mapping.py
Normal file
@@ -0,0 +1,106 @@
|
||||
# -*- 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 uuid
|
||||
from watcher.decision_engine.framework.model.hypervisor import Hypervisor
|
||||
from watcher.decision_engine.framework.model.vm_state import VMState
|
||||
from watcher.tests import base
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
FakerStateCollector
|
||||
|
||||
|
||||
class TestMapping(base.BaseTestCase):
|
||||
def test_get_node_from_vm(self):
|
||||
fake_cluster = FakerStateCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
|
||||
vms = model.get_all_vms()
|
||||
keys = vms.keys()
|
||||
vm = vms[keys[0]]
|
||||
if vm.uuid != 'VM_0':
|
||||
vm = vms[keys[1]]
|
||||
node = model.mapping.get_node_from_vm(vm)
|
||||
self.assertEqual(node.uuid, 'Node_0')
|
||||
|
||||
def test_get_node_from_vm_id(self):
|
||||
fake_cluster = FakerStateCollector()
|
||||
model = fake_cluster.generate_scenario_4_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 = FakerStateCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
|
||||
vms = model.get_all_vms()
|
||||
self.assertEqual(vms.__len__(), 2)
|
||||
self.assertEqual(vms['VM_0'].state, VMState.ACTIVE.value)
|
||||
self.assertEqual(vms['VM_0'].uuid, 'VM_0')
|
||||
self.assertEqual(vms['VM_1'].state, VMState.ACTIVE.value)
|
||||
self.assertEqual(vms['VM_1'].uuid, 'VM_1')
|
||||
|
||||
def test_get_mapping(self):
|
||||
fake_cluster = FakerStateCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
|
||||
mapping_vm = model.mapping.get_mapping_vm()
|
||||
self.assertEqual(mapping_vm.__len__(), 2)
|
||||
self.assertEqual(mapping_vm['VM_0'], 'Node_0')
|
||||
self.assertEqual(mapping_vm['VM_1'], 'Node_1')
|
||||
|
||||
def test_migrate_vm(self):
|
||||
fake_cluster = FakerStateCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
vms = model.get_all_vms()
|
||||
keys = vms.keys()
|
||||
vm0 = vms[keys[0]]
|
||||
hyp0 = model.mapping.get_node_from_vm_id(vm0.uuid)
|
||||
vm1 = vms[keys[1]]
|
||||
hyp1 = model.mapping.get_node_from_vm_id(vm1.uuid)
|
||||
|
||||
self.assertEqual(model.mapping.migrate_vm(vm1, hyp1, hyp1), False)
|
||||
self.assertEqual(model.mapping.migrate_vm(vm1, hyp0, hyp0), False)
|
||||
self.assertEqual(model.mapping.migrate_vm(vm1, hyp1, hyp0), True)
|
||||
self.assertEqual(model.mapping.migrate_vm(vm1, hyp0, hyp1), True)
|
||||
|
||||
def test_unmap_from_id_log_warning(self):
|
||||
fake_cluster = FakerStateCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
vms = model.get_all_vms()
|
||||
keys = vms.keys()
|
||||
vm0 = vms[keys[0]]
|
||||
id = str(uuid.uuid4())
|
||||
hypervisor = Hypervisor()
|
||||
hypervisor.uuid = id
|
||||
|
||||
model.mapping.unmap_from_id(hypervisor.uuid, vm0.uuid)
|
||||
# self.assertEqual(len(model.mapping.get_node_vms_from_id(
|
||||
# hypervisor.uuid)), 1)
|
||||
|
||||
def test_unmap_from_id(self):
|
||||
fake_cluster = FakerStateCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
vms = model.get_all_vms()
|
||||
keys = vms.keys()
|
||||
vm0 = vms[keys[0]]
|
||||
hyp0 = model.mapping.get_node_from_vm_id(vm0.uuid)
|
||||
|
||||
model.mapping.unmap_from_id(hyp0.uuid, vm0.uuid)
|
||||
self.assertEqual(len(model.mapping.get_node_vms_from_id(
|
||||
hyp0.uuid)), 0)
|
||||
139
watcher/tests/decision_engine/framework/model/test_model.py
Normal file
139
watcher/tests/decision_engine/framework/model/test_model.py
Normal file
@@ -0,0 +1,139 @@
|
||||
# -*- 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 uuid
|
||||
from watcher.common import exception
|
||||
from watcher.common.exception import IllegalArgumentException
|
||||
from watcher.decision_engine.framework.model.hypervisor import Hypervisor
|
||||
from watcher.decision_engine.framework.model.hypervisor_state import \
|
||||
HypervisorState
|
||||
from watcher.decision_engine.framework.model.model_root import ModelRoot
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
FakerStateCollector
|
||||
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestModel(base.BaseTestCase):
|
||||
def test_model(self):
|
||||
fake_cluster = FakerStateCollector()
|
||||
model = fake_cluster.generate_scenario_1()
|
||||
|
||||
self.assertEqual(len(model._hypervisors), 5)
|
||||
self.assertEqual(len(model._vms), 35)
|
||||
self.assertEqual(len(model.get_mapping().get_mapping()), 5)
|
||||
|
||||
def test_add_hypervisor(self):
|
||||
model = ModelRoot()
|
||||
id = str(uuid.uuid4())
|
||||
hypervisor = Hypervisor()
|
||||
hypervisor.uuid = id
|
||||
model.add_hypervisor(hypervisor)
|
||||
self.assertEqual(model.get_hypervisor_from_id(id), hypervisor)
|
||||
|
||||
def test_delete_hypervisor(self):
|
||||
model = ModelRoot()
|
||||
id = str(uuid.uuid4())
|
||||
hypervisor = Hypervisor()
|
||||
hypervisor.uuid = id
|
||||
model.add_hypervisor(hypervisor)
|
||||
self.assertEqual(model.get_hypervisor_from_id(id), hypervisor)
|
||||
model.remove_hypervisor(hypervisor)
|
||||
self.assertRaises(exception.HypervisorNotFound,
|
||||
model.get_hypervisor_from_id, id)
|
||||
|
||||
def test_get_all_hypervisors(self):
|
||||
model = ModelRoot()
|
||||
for i in range(10):
|
||||
id = str(uuid.uuid4())
|
||||
hypervisor = Hypervisor()
|
||||
hypervisor.uuid = id
|
||||
model.add_hypervisor(hypervisor)
|
||||
all_hypervisors = model.get_all_hypervisors()
|
||||
for id in all_hypervisors:
|
||||
hyp = model.get_hypervisor_from_id(id)
|
||||
model.assert_hypervisor(hyp)
|
||||
|
||||
def test_set_get_state_hypervisors(self):
|
||||
model = ModelRoot()
|
||||
id = str(uuid.uuid4())
|
||||
hypervisor = Hypervisor()
|
||||
hypervisor.uuid = id
|
||||
model.add_hypervisor(hypervisor)
|
||||
|
||||
self.assertIsInstance(hypervisor.state, HypervisorState)
|
||||
|
||||
hyp = model.get_hypervisor_from_id(id)
|
||||
hyp.state = HypervisorState.OFFLINE
|
||||
self.assertIsInstance(hyp.state, HypervisorState)
|
||||
|
||||
# /watcher/decision_engine/framework/model/hypervisor.py
|
||||
# set_state accept any char chain.
|
||||
# verification (IsInstance) should be used in the function
|
||||
# hyp.set_state('blablabla')
|
||||
# self.assertEqual(hyp.get_state(), 'blablabla')
|
||||
# self.assertIsInstance(hyp.get_state(), HypervisorState)
|
||||
|
||||
# def test_get_all_vms(self):
|
||||
# model = ModelRoot()
|
||||
# vms = model.get_all_vms()
|
||||
# self.assert(len(model._vms))
|
||||
def test_hypervisor_from_id_raise(self):
|
||||
model = ModelRoot()
|
||||
id = str(uuid.uuid4())
|
||||
hypervisor = Hypervisor()
|
||||
hypervisor.uuid = id
|
||||
model.add_hypervisor(hypervisor)
|
||||
|
||||
id2 = str(uuid.uuid4())
|
||||
self.assertRaises(exception.HypervisorNotFound,
|
||||
model.get_hypervisor_from_id, id2)
|
||||
|
||||
def test_remove_hypervisor_raise(self):
|
||||
model = ModelRoot()
|
||||
id = str(uuid.uuid4())
|
||||
hypervisor = Hypervisor()
|
||||
hypervisor.uuid = id
|
||||
model.add_hypervisor(hypervisor)
|
||||
|
||||
id2 = str(uuid.uuid4())
|
||||
hypervisor2 = Hypervisor()
|
||||
hypervisor2.uuid = id2
|
||||
|
||||
self.assertRaises(exception.HypervisorNotFound,
|
||||
model.remove_hypervisor, hypervisor2)
|
||||
|
||||
def test_assert_hypervisor_raise(self):
|
||||
model = ModelRoot()
|
||||
id = str(uuid.uuid4())
|
||||
hypervisor = Hypervisor()
|
||||
hypervisor.uuid = id
|
||||
model.add_hypervisor(hypervisor)
|
||||
self.assertRaises(IllegalArgumentException,
|
||||
model.assert_hypervisor, "objet_qcq")
|
||||
|
||||
def test_vm_from_id_raise(self):
|
||||
fake_cluster = FakerStateCollector()
|
||||
model = fake_cluster.generate_scenario_1()
|
||||
self.assertRaises(exception.VMNotFound,
|
||||
model.get_vm_from_id, "valeur_qcq")
|
||||
|
||||
def test_assert_vm_raise(self):
|
||||
model = ModelRoot()
|
||||
self.assertRaises(IllegalArgumentException,
|
||||
model.assert_vm, "valeur_qcq")
|
||||
@@ -0,0 +1,32 @@
|
||||
# -*- 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.
|
||||
#
|
||||
from watcher.decision_engine.framework.model.named_element import NamedElement
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestNamedElement(base.BaseTestCase):
|
||||
def test_namedelement(self):
|
||||
id = NamedElement()
|
||||
id.uuid = "BLABLABLA"
|
||||
self.assertEqual(id.uuid, "BLABLABLA")
|
||||
|
||||
def test_set_get_human_id(self):
|
||||
id = NamedElement()
|
||||
id.human_id = "BLABLABLA"
|
||||
self.assertEqual(id.human_id, "BLABLABLA")
|
||||
30
watcher/tests/decision_engine/framework/model/test_vm.py
Normal file
30
watcher/tests/decision_engine/framework/model/test_vm.py
Normal file
@@ -0,0 +1,30 @@
|
||||
# -*- 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.
|
||||
#
|
||||
from watcher.decision_engine.framework.model.vm import VM
|
||||
from watcher.decision_engine.framework.model.vm_state import VMState
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestVm(base.BaseTestCase):
|
||||
def test_namedelement(self):
|
||||
vm = VM()
|
||||
vm.state = VMState.ACTIVE
|
||||
self.assertEqual(vm.state, VMState.ACTIVE)
|
||||
vm.human_id = "human_05"
|
||||
self.assertEqual(vm.human_id, "human_05")
|
||||
@@ -34,3 +34,7 @@ class TestStrategySelector(base.BaseTestCase):
|
||||
selected_strategy.get_name(),
|
||||
exptected_strategy,
|
||||
'The default strategy should be basic')
|
||||
|
||||
def test_load_driver(self):
|
||||
algo = self.strategy_loader.load_driver("basic")
|
||||
self.assertEqual(algo._names[0], "basic")
|
||||
|
||||
@@ -0,0 +1,32 @@
|
||||
# -*- 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.framework.strategy.StrategyManagerImpl import \
|
||||
StrategyContextImpl
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class FakeStrategy(object):
|
||||
def __init__(self):
|
||||
self.name = "BALANCE_LOAD"
|
||||
|
||||
|
||||
class TestStrategyContextImpl(base.BaseTestCase):
|
||||
def test_add_remove_strategy(self):
|
||||
strategy = FakeStrategy()
|
||||
strategy_context = StrategyContextImpl()
|
||||
strategy_context.add_strategy(strategy)
|
||||
strategy_context.remove_strategy(strategy)
|
||||
@@ -15,6 +15,7 @@
|
||||
# limitations under the License.
|
||||
|
||||
import mock
|
||||
from watcher.common.exception import MetaActionNotFound
|
||||
from watcher.common import utils
|
||||
from watcher.db import api as db_api
|
||||
from watcher.decision_engine.framework.default_planner import DefaultPlanner
|
||||
@@ -39,6 +40,17 @@ class SolutionFaker(object):
|
||||
return sercon.execute(current_state_cluster.generate_scenario_1())
|
||||
|
||||
|
||||
class SolutionFakerSingleHyp(object):
|
||||
@staticmethod
|
||||
def build():
|
||||
metrics = FakerMetricsCollector()
|
||||
current_state_cluster = FakerStateCollector()
|
||||
sercon = BasicConsolidation("basic", "Basic offline consolidation")
|
||||
sercon.set_metrics_resource_collector(metrics)
|
||||
return sercon.execute(
|
||||
current_state_cluster.generate_scenario_4_with_2_hypervisors())
|
||||
|
||||
|
||||
class TestDefaultPlanner(base.DbTestCase):
|
||||
default_planner = DefaultPlanner()
|
||||
|
||||
@@ -71,5 +83,25 @@ class TestDefaultPlanner(base.DbTestCase):
|
||||
fake_solution = SolutionFaker.build()
|
||||
action_plan = self.default_planner.schedule(self.context,
|
||||
audit.id, fake_solution)
|
||||
|
||||
self.assertIsNotNone(action_plan.uuid)
|
||||
|
||||
def test_schedule_raise(self):
|
||||
audit = db_utils.create_test_audit(uuid=utils.generate_uuid())
|
||||
fake_solution = SolutionFaker.build()
|
||||
fake_solution._meta_actions[0] = "valeur_qcq"
|
||||
self.assertRaises(MetaActionNotFound, self.default_planner.schedule,
|
||||
self.context, audit.id, fake_solution)
|
||||
|
||||
def test_schedule_scheduled_empty(self):
|
||||
audit = db_utils.create_test_audit(uuid=utils.generate_uuid())
|
||||
fake_solution = SolutionFakerSingleHyp.build()
|
||||
action_plan = self.default_planner.schedule(self.context,
|
||||
audit.id, fake_solution)
|
||||
self.assertIsNotNone(action_plan.uuid)
|
||||
|
||||
def test_scheduler_warning_empty_action_plan(self):
|
||||
audit = db_utils.create_test_audit(uuid=utils.generate_uuid())
|
||||
fake_solution = SolutionFaker.build()
|
||||
action_plan = self.default_planner.schedule(self.context,
|
||||
audit.id, fake_solution)
|
||||
self.assertIsNotNone(action_plan.uuid)
|
||||
|
||||
@@ -0,0 +1,24 @@
|
||||
# -*- 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.framework.default_solution import DefaultSolution
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestDefaultSolution(base.BaseTestCase):
|
||||
def test_default_solution(self):
|
||||
solution = DefaultSolution()
|
||||
solution.add_change_request("BLA")
|
||||
self.assertEqual(solution.meta_actions[0], "BLA")
|
||||
1
watcher/tests/decision_engine/strategies/__init__.py
Normal file
1
watcher/tests/decision_engine/strategies/__init__.py
Normal file
@@ -0,0 +1 @@
|
||||
__author__ = 'Jean-Emile DARTOIS <jean-emile.dartois@b-com.com>'
|
||||
@@ -0,0 +1,314 @@
|
||||
# -*- 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 mock
|
||||
from watcher.common import exception
|
||||
|
||||
from watcher.decision_engine.framework.meta_actions.hypervisor_state import \
|
||||
ChangeHypervisorState
|
||||
from watcher.decision_engine.framework.meta_actions.power_state import \
|
||||
ChangePowerState
|
||||
|
||||
from watcher.decision_engine.framework.meta_actions.migrate import Migrate
|
||||
from watcher.decision_engine.framework.model.model_root import ModelRoot
|
||||
from watcher.decision_engine.strategies.basic_consolidation import \
|
||||
BasicConsolidation
|
||||
from watcher.tests import base
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
FakerStateCollector
|
||||
from watcher.tests.decision_engine.faker_metrics_collector import \
|
||||
FakerMetricsCollector
|
||||
# from watcher.tests.decision_engine.faker_metrics_collector import \
|
||||
# FakerMetricsCollectorEmptyType
|
||||
|
||||
|
||||
class TestBasicConsolidation(base.BaseTestCase):
|
||||
# fake metrics
|
||||
fake_metrics = FakerMetricsCollector()
|
||||
|
||||
# fake cluster
|
||||
fake_cluster = FakerStateCollector()
|
||||
|
||||
def test_cluster_size(self):
|
||||
size_cluster = len(
|
||||
self.fake_cluster.generate_scenario_1().get_all_hypervisors())
|
||||
size_cluster_assert = 5
|
||||
self.assertEqual(size_cluster, size_cluster_assert)
|
||||
|
||||
def test_basic_consolidation_score_hypervisor(self):
|
||||
cluster = self.fake_cluster.generate_scenario_1()
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(self.fake_metrics)
|
||||
node_1_score = 0.01666666666666668
|
||||
self.assertEqual(
|
||||
sercon.calculate_score_node(
|
||||
cluster.get_hypervisor_from_id("Node_1"),
|
||||
cluster), node_1_score)
|
||||
node_2_score = 0.01666666666666668
|
||||
self.assertEqual(
|
||||
sercon.calculate_score_node(
|
||||
cluster.get_hypervisor_from_id("Node_2"),
|
||||
cluster), node_2_score)
|
||||
node_0_score = 0.01666666666666668
|
||||
self.assertEqual(
|
||||
sercon.calculate_score_node(
|
||||
cluster.get_hypervisor_from_id("Node_0"),
|
||||
cluster), node_0_score)
|
||||
|
||||
def test_basic_consolidation_score_vm(self):
|
||||
cluster = self.fake_cluster.generate_scenario_1()
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(self.fake_metrics)
|
||||
vm_0 = cluster.get_vm_from_id("VM_0")
|
||||
vm_0_score = 0.0
|
||||
self.assertEqual(sercon.calculate_score_vm(vm_0, cluster), vm_0_score)
|
||||
|
||||
vm_1 = cluster.get_vm_from_id("VM_1")
|
||||
vm_1_score = 0.0
|
||||
self.assertEqual(sercon.calculate_score_vm(vm_1, cluster),
|
||||
vm_1_score)
|
||||
vm_2 = cluster.get_vm_from_id("VM_2")
|
||||
vm_2_score = 0.0
|
||||
self.assertEqual(sercon.calculate_score_vm(vm_2, cluster), vm_2_score)
|
||||
vm_6 = cluster.get_vm_from_id("VM_6")
|
||||
vm_6_score = 0.0
|
||||
self.assertEqual(sercon.calculate_score_vm(vm_6, cluster), vm_6_score)
|
||||
vm_7 = cluster.get_vm_from_id("VM_7")
|
||||
vm_7_score = 0.0
|
||||
self.assertEqual(sercon.calculate_score_vm(vm_7, cluster), vm_7_score)
|
||||
|
||||
def test_basic_consolidation_weight(self):
|
||||
cluster = self.fake_cluster.generate_scenario_1()
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(self.fake_metrics)
|
||||
vm_0 = cluster.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(sercon.calculate_weight(cluster, vm_0, cores, disk,
|
||||
mem),
|
||||
vm_0_weight_assert)
|
||||
|
||||
def test_calculate_migration_efficiency(self):
|
||||
sercon = BasicConsolidation()
|
||||
sercon.calculate_migration_efficiency()
|
||||
|
||||
def test_exception_model(self):
|
||||
sercon = BasicConsolidation()
|
||||
self.assertRaises(exception.ClusteStateNotDefined, sercon.execute,
|
||||
None)
|
||||
|
||||
def test_exception_cluster_empty(self):
|
||||
sercon = BasicConsolidation()
|
||||
model = ModelRoot()
|
||||
self.assertRaises(exception.ClusterEmpty, sercon.execute,
|
||||
model)
|
||||
|
||||
def test_calculate_score_vm_raise_metric_collector(self):
|
||||
sercon = BasicConsolidation()
|
||||
self.assertRaises(exception.MetricCollectorNotDefined,
|
||||
sercon.calculate_score_vm, "VM_1", None)
|
||||
|
||||
def test_calculate_score_vm_raise_cluster_state_not_found(self):
|
||||
metrics = FakerMetricsCollector()
|
||||
metrics.empty_one_metric("CPU_COMPUTE")
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(metrics)
|
||||
self.assertRaises(exception.ClusteStateNotDefined,
|
||||
sercon.calculate_score_vm, "VM_1", None)
|
||||
|
||||
def test_print_utilization_raise_cluster_state_not_found(self):
|
||||
sercon = BasicConsolidation()
|
||||
self.assertRaises(exception.ClusteStateNotDefined,
|
||||
sercon.print_utilization, None)
|
||||
|
||||
def check_migration(self, array, indice, vm, src, dest):
|
||||
"""Helper to check migration
|
||||
|
||||
:param array:
|
||||
:param indice:
|
||||
:param vm:
|
||||
:param src:
|
||||
:param dest:
|
||||
:return:
|
||||
"""
|
||||
self.assertEqual(array[indice].get_vm().uuid, vm)
|
||||
self.assertEqual(array[indice].get_source_hypervisor().uuid, src)
|
||||
self.assertEqual(array[indice].get_dest_hypervisor().uuid, dest)
|
||||
|
||||
self.assertEqual(array[indice].get_bandwidth(), 0)
|
||||
array[indice].set_bandwidth(5)
|
||||
self.assertEqual(array[indice].get_bandwidth(), 5)
|
||||
|
||||
def test_check_migration(self):
|
||||
sercon = BasicConsolidation()
|
||||
fake_cluster = FakerStateCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
|
||||
all_vms = model.get_all_vms()
|
||||
all_hyps = model.get_all_hypervisors()
|
||||
vm0 = all_vms[all_vms.keys()[0]]
|
||||
hyp0 = all_hyps[all_hyps.keys()[0]]
|
||||
|
||||
sercon.check_migration(model, hyp0, hyp0, vm0)
|
||||
|
||||
def test_threshold(self):
|
||||
sercon = BasicConsolidation()
|
||||
fake_cluster = FakerStateCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
|
||||
all_hyps = model.get_all_hypervisors()
|
||||
hyp0 = all_hyps[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(sercon.get_threshold_cores(), threshold_cores + 1)
|
||||
|
||||
def test_number_of(self):
|
||||
sercon = BasicConsolidation()
|
||||
sercon.get_number_of_released_nodes()
|
||||
sercon.get_number_of_migrations()
|
||||
|
||||
def test_calculate_score_node_raise_1(self):
|
||||
sercon = BasicConsolidation()
|
||||
metrics = FakerStateCollector()
|
||||
|
||||
model = metrics.generate_scenario_4_with_2_hypervisors()
|
||||
all_hyps = model.get_all_hypervisors()
|
||||
hyp0 = all_hyps[all_hyps.keys()[0]]
|
||||
|
||||
self.assertRaises(exception.MetricCollectorNotDefined,
|
||||
sercon.calculate_score_node, hyp0, model)
|
||||
|
||||
def test_calculate_score_node_raise_cpu_compute(self):
|
||||
metrics = FakerMetricsCollector()
|
||||
metrics.empty_one_metric("CPU_COMPUTE")
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(metrics)
|
||||
current_state_cluster = FakerStateCollector()
|
||||
model = current_state_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
|
||||
all_hyps = model.get_all_hypervisors()
|
||||
hyp0 = all_hyps[all_hyps.keys()[0]]
|
||||
|
||||
self.assertRaises(exception.NoDataFound,
|
||||
sercon.calculate_score_node, hyp0, model)
|
||||
|
||||
"""
|
||||
def test_calculate_score_node_raise_memory_compute(self):
|
||||
metrics = FakerMetricsCollector()
|
||||
metrics.empty_one_metric("MEM_COMPUTE")
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(metrics)
|
||||
current_state_cluster = FakerStateCollector()
|
||||
model = current_state_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
|
||||
all_hyps = model.get_all_hypervisors()
|
||||
hyp0 = all_hyps[all_hyps.keys()[0]]
|
||||
self.assertRaises(exception.NoDataFound,
|
||||
sercon.calculate_score_node, hyp0, model)
|
||||
|
||||
def test_calculate_score_node_raise_disk_compute(self):
|
||||
metrics = FakerMetricsCollector()
|
||||
metrics.empty_one_metric("DISK_COMPUTE")
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(metrics)
|
||||
current_state_cluster = FakerStateCollector()
|
||||
model = current_state_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
|
||||
all_hyps = model.get_all_hypervisors()
|
||||
hyp0 = all_hyps[all_hyps.keys()[0]]
|
||||
|
||||
self.assertRaises(exception.NoDataFound,
|
||||
sercon.calculate_score_node, hyp0, model)
|
||||
"""
|
||||
|
||||
def test_basic_consolidation_migration(self):
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(FakerMetricsCollector())
|
||||
solution = None
|
||||
solution = sercon.execute(FakerStateCollector().generate_scenario_1())
|
||||
|
||||
count_migration = 0
|
||||
change_hypervisor_state = 0
|
||||
change_power_state = 0
|
||||
migrate = []
|
||||
for action in solution.meta_actions:
|
||||
if isinstance(action, Migrate):
|
||||
count_migration += 1
|
||||
migrate.append(action)
|
||||
if isinstance(action, ChangeHypervisorState):
|
||||
change_hypervisor_state += 1
|
||||
if isinstance(action, ChangePowerState):
|
||||
change_power_state += 1
|
||||
|
||||
# self.assertEqual(change_hypervisor_state, 1)
|
||||
# self.assertEqual(count_migration, 2)
|
||||
|
||||
def test_execute_cluster_empty(self):
|
||||
metrics = FakerMetricsCollector()
|
||||
current_state_cluster = FakerStateCollector()
|
||||
|
||||
sercon = BasicConsolidation("sercon", "Basic offline consolidation")
|
||||
sercon.set_metrics_resource_collector(metrics)
|
||||
model = current_state_cluster.generate_random(0, 0)
|
||||
self.assertRaises(exception.ClusterEmpty, sercon.execute, model)
|
||||
|
||||
def test_basic_consolidation_random(self):
|
||||
metrics = FakerMetricsCollector()
|
||||
current_state_cluster = FakerStateCollector()
|
||||
|
||||
sercon = BasicConsolidation("sercon", "Basic offline consolidation")
|
||||
sercon.set_metrics_resource_collector(metrics)
|
||||
|
||||
solution = sercon.execute(
|
||||
current_state_cluster.generate_random(25, 2))
|
||||
solution.__str__()
|
||||
|
||||
count_migration = 0
|
||||
change_hypervisor_state = 0
|
||||
change_power_state = 0
|
||||
migrate = []
|
||||
for action in solution.meta_actions:
|
||||
if isinstance(action, Migrate):
|
||||
count_migration += 1
|
||||
migrate.append(action)
|
||||
if isinstance(action, ChangeHypervisorState):
|
||||
change_hypervisor_state += 1
|
||||
if isinstance(action, ChangePowerState):
|
||||
change_power_state += 1
|
||||
|
||||
# calculate_weight
|
||||
def test_execute_no_workload(self):
|
||||
metrics = FakerMetricsCollector()
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(metrics)
|
||||
current_state_cluster = FakerStateCollector()
|
||||
model = current_state_cluster.\
|
||||
generate_scenario_5_with_1_hypervisor_no_vm()
|
||||
|
||||
with mock.patch.object(BasicConsolidation, 'calculate_weight') \
|
||||
as mock_score_call:
|
||||
mock_score_call.return_value = 0
|
||||
solution = sercon.execute(model)
|
||||
self.assertEqual(solution.efficiency, 100)
|
||||
@@ -0,0 +1,27 @@
|
||||
# -*- 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.strategies.dummy_strategy import DummyStrategy
|
||||
from watcher.tests import base
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
FakerStateCollector
|
||||
|
||||
|
||||
class TestDummyStrategy(base.TestCase):
|
||||
def test_dummy_strategy(self):
|
||||
tactique = DummyStrategy("basic", "Basic offline consolidation")
|
||||
fake_cluster = FakerStateCollector()
|
||||
model = fake_cluster.generate_scenario_4_with_2_hypervisors()
|
||||
tactique.execute(model)
|
||||
@@ -1,184 +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.common import exception
|
||||
|
||||
from watcher.decision_engine.framework.meta_actions.hypervisor_state import \
|
||||
ChangeHypervisorState
|
||||
from watcher.decision_engine.framework.meta_actions.power_state import \
|
||||
ChangePowerState
|
||||
|
||||
from watcher.decision_engine.framework.meta_actions.migrate import Migrate
|
||||
from watcher.decision_engine.framework.model.model_root import ModelRoot
|
||||
from watcher.decision_engine.strategies.basic_consolidation import \
|
||||
BasicConsolidation
|
||||
|
||||
from watcher.tests import base
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
FakerStateCollector
|
||||
from watcher.tests.decision_engine.faker_metrics_collector import \
|
||||
FakerMetricsCollector
|
||||
|
||||
|
||||
class TestBasicConsolidation(base.BaseTestCase):
|
||||
# fake metrics
|
||||
fake_metrics = FakerMetricsCollector()
|
||||
|
||||
# fake cluster
|
||||
fake_cluster = FakerStateCollector()
|
||||
|
||||
def test_cluster_size(self):
|
||||
size_cluster = len(
|
||||
self.fake_cluster.generate_scenario_1().get_all_hypervisors())
|
||||
size_cluster_assert = 5
|
||||
self.assertEqual(size_cluster, size_cluster_assert)
|
||||
|
||||
def test_basic_consolidation_score_hypervisor(self):
|
||||
cluster = self.fake_cluster.generate_scenario_1()
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(self.fake_metrics)
|
||||
node_1_score = 0.09862626262626262
|
||||
self.assertEqual(
|
||||
sercon.calculate_score_node(
|
||||
cluster.get_hypervisor_from_id("Node_1"),
|
||||
cluster), node_1_score)
|
||||
node_2_score = 0.29989898989898994
|
||||
self.assertEqual(
|
||||
sercon.calculate_score_node(
|
||||
cluster.get_hypervisor_from_id("Node_2"),
|
||||
cluster), node_2_score)
|
||||
node_0_score = 0.13967676767676765
|
||||
self.assertEqual(
|
||||
sercon.calculate_score_node(
|
||||
cluster.get_hypervisor_from_id("Node_0"),
|
||||
cluster), node_0_score)
|
||||
|
||||
def test_basic_consolidation_score_vm(self):
|
||||
cluster = self.fake_cluster.generate_scenario_1()
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(self.fake_metrics)
|
||||
vm_0 = cluster.get_vm_from_id("VM_0")
|
||||
vm_0_score = 0.6
|
||||
self.assertEqual(sercon.calculate_score_vm(vm_0, cluster), vm_0_score)
|
||||
|
||||
vm_1 = cluster.get_vm_from_id("VM_1")
|
||||
vm_1_score = 1.0999999999999999
|
||||
self.assertEqual(sercon.calculate_score_vm(vm_1, cluster),
|
||||
vm_1_score)
|
||||
vm_2 = cluster.get_vm_from_id("VM_2")
|
||||
vm_2_score = 1.2
|
||||
self.assertEqual(sercon.calculate_score_vm(vm_2, cluster), vm_2_score)
|
||||
|
||||
def test_basic_consolidation_weight(self):
|
||||
cluster = self.fake_cluster.generate_scenario_1()
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(self.fake_metrics)
|
||||
vm_0 = cluster.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(sercon.calculate_weight(cluster, vm_0, cores, disk,
|
||||
mem),
|
||||
vm_0_weight_assert)
|
||||
|
||||
def test_basic_consolidation_efficiency(self):
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(self.fake_metrics)
|
||||
efficient_assert = 100
|
||||
solution = sercon.execute(self.fake_cluster.generate_scenario_1())
|
||||
self.assertEqual(solution.get_efficiency(), efficient_assert)
|
||||
|
||||
def test_exception_model(self):
|
||||
sercon = BasicConsolidation()
|
||||
self.assertRaises(exception.ClusteStateNotDefined, sercon.execute,
|
||||
None)
|
||||
|
||||
def test_exception_cluster_empty(self):
|
||||
sercon = BasicConsolidation()
|
||||
model = ModelRoot()
|
||||
self.assertRaises(exception.ClusterEmpty, sercon.execute,
|
||||
model)
|
||||
|
||||
def test_exception_metric_collector(self):
|
||||
sercon = BasicConsolidation()
|
||||
self.assertRaises(exception.MetricCollectorNotDefined,
|
||||
sercon.calculate_score_vm, "VM_1", None)
|
||||
|
||||
def check_migration(self, array, indice, vm, src, dest):
|
||||
"""Helper to check migration
|
||||
|
||||
:param array:
|
||||
:param indice:
|
||||
:param vm:
|
||||
:param src:
|
||||
:param dest:
|
||||
:return:
|
||||
"""
|
||||
self.assertEqual(array[indice].get_vm().get_uuid(), vm)
|
||||
self.assertEqual(array[indice].get_source_hypervisor().get_uuid(), src)
|
||||
self.assertEqual(array[indice].get_dest_hypervisor().get_uuid(), dest)
|
||||
|
||||
def test_basic_consolidation_migration(self):
|
||||
sercon = BasicConsolidation()
|
||||
sercon.set_metrics_resource_collector(self.fake_metrics)
|
||||
|
||||
solution = sercon.execute(self.fake_cluster.generate_scenario_1())
|
||||
|
||||
count_migration = 0
|
||||
change_hypervisor_state = 0
|
||||
change_power_state = 0
|
||||
migrate = []
|
||||
for action in solution.meta_actions:
|
||||
if isinstance(action, Migrate):
|
||||
count_migration += 1
|
||||
migrate.append(action)
|
||||
if isinstance(action, ChangeHypervisorState):
|
||||
change_hypervisor_state += 1
|
||||
if isinstance(action, ChangePowerState):
|
||||
change_power_state += 1
|
||||
|
||||
self.assertEqual(change_hypervisor_state, 3)
|
||||
self.assertEqual(count_migration, 3)
|
||||
# check migration
|
||||
self.check_migration(migrate, 0, "VM_7", "Node_4", "Node_2")
|
||||
self.check_migration(migrate, 1, "VM_6", "Node_3", "Node_0")
|
||||
self.check_migration(migrate, 2, "VM_2", "Node_1", "Node_0")
|
||||
|
||||
def test_basic_consolidation_random(self):
|
||||
metrics = FakerMetricsCollector()
|
||||
current_state_cluster = FakerStateCollector()
|
||||
|
||||
sercon = BasicConsolidation("sercon", "Basic offline consolidation")
|
||||
sercon.set_metrics_resource_collector(metrics)
|
||||
|
||||
solution = sercon.execute(
|
||||
current_state_cluster.generate_random(25, 2))
|
||||
|
||||
count_migration = 0
|
||||
change_hypervisor_state = 0
|
||||
change_power_state = 0
|
||||
migrate = []
|
||||
for action in solution.meta_actions:
|
||||
if isinstance(action, Migrate):
|
||||
count_migration += 1
|
||||
migrate.append(action)
|
||||
if isinstance(action, ChangeHypervisorState):
|
||||
change_hypervisor_state += 1
|
||||
if isinstance(action, ChangePowerState):
|
||||
change_power_state += 1
|
||||
@@ -1,11 +1,13 @@
|
||||
# -*- 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
|
||||
# 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,
|
||||
@@ -13,6 +15,7 @@
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
|
||||
@@ -1,54 +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.
|
||||
import uuid
|
||||
from watcher.common import exception
|
||||
|
||||
from watcher.decision_engine.framework.model.hypervisor import Hypervisor
|
||||
from watcher.decision_engine.framework.model.model_root import ModelRoot
|
||||
|
||||
from watcher.tests.decision_engine.faker_cluster_state import \
|
||||
FakerStateCollector
|
||||
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
class TestModel(base.BaseTestCase):
|
||||
def test_model(self):
|
||||
fake_cluster = FakerStateCollector()
|
||||
model = fake_cluster.generate_scenario_1()
|
||||
|
||||
self.assertEqual(len(model._hypervisors), 5)
|
||||
self.assertEqual(len(model._vms), 35)
|
||||
self.assertEqual(len(model.get_mapping().get_mapping()), 5)
|
||||
|
||||
def test_add_hypervisor(self):
|
||||
model = ModelRoot()
|
||||
id = str(uuid.uuid4())
|
||||
hypervisor = Hypervisor()
|
||||
hypervisor.set_uuid(id)
|
||||
model.add_hypervisor(hypervisor)
|
||||
self.assertEqual(model.get_hypervisor_from_id(id), hypervisor)
|
||||
|
||||
def test_delete_hypervisor(self):
|
||||
model = ModelRoot()
|
||||
id = str(uuid.uuid4())
|
||||
hypervisor = Hypervisor()
|
||||
hypervisor.set_uuid(id)
|
||||
model.add_hypervisor(hypervisor)
|
||||
self.assertEqual(model.get_hypervisor_from_id(id), hypervisor)
|
||||
model.remove_hypervisor(hypervisor)
|
||||
self.assertRaises(exception.HypervisorNotFound,
|
||||
model.get_hypervisor_from_id, id)
|
||||
@@ -1,11 +1,13 @@
|
||||
# -*- 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
|
||||
# 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,
|
||||
@@ -13,6 +15,7 @@
|
||||
# implied.
|
||||
# See the License for the specific language governing permissions and
|
||||
# limitations under the License.
|
||||
#
|
||||
from watcher.tests import base
|
||||
|
||||
|
||||
|
||||
@@ -1,151 +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 concurrent.futures import ThreadPoolExecutor
|
||||
|
||||
from keystoneclient import session
|
||||
|
||||
from keystoneclient.auth.identity import v3
|
||||
|
||||
import cinderclient.v2.client as ciclient
|
||||
import glanceclient.v2.client as glclient
|
||||
import keystoneclient.v3.client as ksclient
|
||||
import neutronclient.neutron.client as netclient
|
||||
import novaclient.v2.client as nvclient
|
||||
|
||||
from watcher.common.utils import CONF
|
||||
from oslo_config import cfg
|
||||
from watcher.applier.framework.command.migrate_command import MigrateCommand
|
||||
from watcher.applier.framework.command.wrapper.nova_wrapper import NovaWrapper
|
||||
from watcher.decision_engine.framework.default_planner import Primitives
|
||||
from watcher.openstack.common import log
|
||||
import ceilometerclient.v2 as c_client
|
||||
|
||||
cfg.CONF.debug = True
|
||||
log.setup('metering-controller')
|
||||
|
||||
cfg.CONF.import_opt('auth_uri', 'keystoneclient.middleware.auth_token',
|
||||
group='keystone_authtoken')
|
||||
cfg.CONF.import_opt('admin_user', 'keystoneclient.middleware.auth_token',
|
||||
group='keystone_authtoken')
|
||||
cfg.CONF.import_opt('admin_password', 'keystoneclient.middleware.auth_token',
|
||||
group='keystone_authtoken')
|
||||
cfg.CONF.import_opt('admin_tenant_name',
|
||||
'keystoneclient.middleware.auth_token',
|
||||
group='keystone_authtoken')
|
||||
|
||||
cfg.CONF.keystone_authtoken.auth_uri = "http://10.50.0.105:5000/v3/"
|
||||
cfg.CONF.keystone_authtoken.admin_user = "watcher"
|
||||
cfg.CONF.keystone_authtoken.admin_password = "watcher"
|
||||
cfg.CONF.keystone_authtoken.admin_tenant_name = "services"
|
||||
|
||||
|
||||
def make_query(user_id=None, tenant_id=None, resource_id=None,
|
||||
user_ids=None, tenant_ids=None, resource_ids=None):
|
||||
user_ids = user_ids or []
|
||||
tenant_ids = tenant_ids or []
|
||||
resource_ids = resource_ids or []
|
||||
query = []
|
||||
if user_id:
|
||||
user_ids = [user_id]
|
||||
for u_id in user_ids:
|
||||
query.append({"field": "user_id", "op": "eq", "value": u_id})
|
||||
if tenant_id:
|
||||
tenant_ids = [tenant_id]
|
||||
for t_id in tenant_ids:
|
||||
query.append({"field": "project_id", "op": "eq", "value": t_id})
|
||||
if resource_id:
|
||||
resource_ids = [resource_id]
|
||||
for r_id in resource_ids:
|
||||
query.append({"field": "resource_id", "op": "eq", "value": r_id})
|
||||
return query
|
||||
|
||||
|
||||
# nova-manage service enable
|
||||
--host='ldev-indeedsrv005' --service='nova-compute'
|
||||
|
||||
|
||||
def create(wrapper, id, hypervisorid):
|
||||
print("create instance VM_{0} on {1}".format(str(id), str(hypervisorid)))
|
||||
try:
|
||||
|
||||
for image in glance.images.list(name='Cirros'):
|
||||
id_image = image.id
|
||||
|
||||
vm = wrapper.create_instance(hypervisor_id=hypervisorid,
|
||||
inst_name="VM_" + str(id),
|
||||
keypair_name='admin',
|
||||
image_id=id_image,
|
||||
create_new_floating_ip=True,
|
||||
flavor_name='m1.medium')
|
||||
print(vm)
|
||||
except Exception as e:
|
||||
print(unicode(e))
|
||||
|
||||
|
||||
def purge(nova, wrapper):
|
||||
print("Purging the cluster")
|
||||
instances = nova.servers.list()
|
||||
for instance in instances:
|
||||
wrapper.delete_instance(instance.id)
|
||||
|
||||
|
||||
try:
|
||||
executor = ThreadPoolExecutor(max_workers=3)
|
||||
creds = \
|
||||
{'auth_url': CONF.keystone_authtoken.auth_uri,
|
||||
'username': CONF.keystone_authtoken.admin_user,
|
||||
'password': CONF.keystone_authtoken.admin_password,
|
||||
'project_name': CONF.keystone_authtoken.admin_tenant_name,
|
||||
'user_domain_name': "default",
|
||||
'project_domain_name': "default"}
|
||||
auth = v3.Password(auth_url=creds['auth_url'],
|
||||
username=creds['username'],
|
||||
password=creds['password'],
|
||||
project_name=creds['project_name'],
|
||||
user_domain_name=creds[
|
||||
'user_domain_name'],
|
||||
project_domain_name=creds[
|
||||
'project_domain_name'])
|
||||
sess = session.Session(auth=auth)
|
||||
nova = nvclient.Client("3", session=sess)
|
||||
neutron = netclient.Client('2.0', session=sess)
|
||||
neutron.format = 'json'
|
||||
keystone = ksclient.Client(**creds)
|
||||
|
||||
glance_endpoint = keystone. \
|
||||
service_catalog.url_for(service_type='image',
|
||||
endpoint_type='publicURL')
|
||||
glance = glclient.Client(glance_endpoint,
|
||||
token=keystone.auth_token)
|
||||
|
||||
wrapper = NovaWrapper(creds, session=sess)
|
||||
|
||||
wrapper.live_migrate_instance(
|
||||
instance_id="b2aca823-a621-4235-9d56-9f0f75955dc1",
|
||||
dest_hostname="ldev-indeedsrv006", block_migration=True)
|
||||
|
||||
nova-manage service enable --host='ldev-indeedsrv005' \
|
||||
--service='nova-compute'
|
||||
nova-manage service enable --host='ldev-indeedsrv006' \
|
||||
--service='nova-compute'
|
||||
|
||||
|
||||
except Exception as e:
|
||||
print("rollback " + str(e))
|
||||
|
||||
"""
|
||||
Reference in New Issue
Block a user