From fa687ec0e0cbed03cc3367afea5244efbd7ed29c Mon Sep 17 00:00:00 2001 From: Anton Beloglazov Date: Thu, 26 Mar 2015 12:00:10 +1100 Subject: [PATCH] Extracted contracts_primitive from contracts_extra to avoid problems with imports, added tests for long values returned by libvirt --- neat/common.py | 1 + neat/contracts_extra.py | 3 -- neat/contracts_primitive.py | 19 +++++++++++ neat/db.py | 2 +- neat/db_utils.py | 1 + neat/globals/db_cleaner.py | 1 + neat/globals/manager.py | 1 + neat/globals/vm_placement/bin_packing.py | 1 + neat/locals/collector.py | 1 + neat/locals/manager.py | 1 + neat/locals/overload/mhod/bruteforce.py | 1 + neat/locals/overload/mhod/core.py | 1 + neat/locals/overload/mhod/l_2_states.py | 1 + .../overload/mhod/multisize_estimation.py | 1 + neat/locals/overload/mhod/nlp.py | 1 + neat/locals/overload/otf.py | 11 +++--- neat/locals/overload/statistics.py | 1 + neat/locals/overload/trivial.py | 1 + neat/locals/underload/trivial.py | 1 + neat/locals/vm_selection/algorithms.py | 1 + tests/locals/test_collector.py | 13 +++++++ tests/locals/test_manager.py | 34 +++++++++++++++++-- tests/test_common.py | 15 ++++++++ tests/test_db.py | 4 +-- 24 files changed, 103 insertions(+), 14 deletions(-) create mode 100644 neat/contracts_primitive.py diff --git a/neat/common.py b/neat/common.py index 42d2921..071e01d 100644 --- a/neat/common.py +++ b/neat/common.py @@ -16,6 +16,7 @@ """ from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * import os diff --git a/neat/contracts_extra.py b/neat/contracts_extra.py index 6b850ef..b8903ca 100644 --- a/neat/contracts_extra.py +++ b/neat/contracts_extra.py @@ -15,9 +15,6 @@ from contracts import new_contract -new_contract('long', lambda x: isinstance(x, (int, long))) -new_contract('function', lambda x: hasattr(x, '__call__')) - import collections new_contract('deque', collections.deque) diff --git a/neat/contracts_primitive.py b/neat/contracts_primitive.py new file mode 100644 index 0000000..62da769 --- /dev/null +++ b/neat/contracts_primitive.py @@ -0,0 +1,19 @@ +# Copyright 2012 Anton Beloglazov +# +# 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 contracts import new_contract + + +new_contract('long', lambda x: isinstance(x, (int, long))) +new_contract('function', lambda x: hasattr(x, '__call__')) diff --git a/neat/db.py b/neat/db.py index 7335adc..193ecbc 100644 --- a/neat/db.py +++ b/neat/db.py @@ -13,7 +13,7 @@ # limitations under the License. from contracts import contract -from neat.contracts_extra import * +from neat.contracts_primitive import * import datetime from sqlalchemy import * diff --git a/neat/db_utils.py b/neat/db_utils.py index 6289933..b9761a6 100644 --- a/neat/db_utils.py +++ b/neat/db_utils.py @@ -13,6 +13,7 @@ # limitations under the License. from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * from sqlalchemy import * diff --git a/neat/globals/db_cleaner.py b/neat/globals/db_cleaner.py index 1f27f1b..a43d260 100644 --- a/neat/globals/db_cleaner.py +++ b/neat/globals/db_cleaner.py @@ -20,6 +20,7 @@ of the database size. """ from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * import datetime diff --git a/neat/globals/manager.py b/neat/globals/manager.py index d8fa9c9..efb1482 100644 --- a/neat/globals/manager.py +++ b/neat/globals/manager.py @@ -68,6 +68,7 @@ the beginning of the global manager's execution. """ from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * import bottle diff --git a/neat/globals/vm_placement/bin_packing.py b/neat/globals/vm_placement/bin_packing.py index c2b0dd6..ef8a568 100644 --- a/neat/globals/vm_placement/bin_packing.py +++ b/neat/globals/vm_placement/bin_packing.py @@ -16,6 +16,7 @@ """ from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * import logging diff --git a/neat/locals/collector.py b/neat/locals/collector.py index 8824ef8..5040f93 100644 --- a/neat/locals/collector.py +++ b/neat/locals/collector.py @@ -91,6 +91,7 @@ invoked, the component performs the following steps: """ from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * import os diff --git a/neat/locals/manager.py b/neat/locals/manager.py index 438bea9..1cbb71f 100644 --- a/neat/locals/manager.py +++ b/neat/locals/manager.py @@ -101,6 +101,7 @@ local manager performs the following steps: """ from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * import requests diff --git a/neat/locals/overload/mhod/bruteforce.py b/neat/locals/overload/mhod/bruteforce.py index b126c0e..814573e 100644 --- a/neat/locals/overload/mhod/bruteforce.py +++ b/neat/locals/overload/mhod/bruteforce.py @@ -16,6 +16,7 @@ """ from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * import nlp diff --git a/neat/locals/overload/mhod/core.py b/neat/locals/overload/mhod/core.py index 2927f20..5131176 100644 --- a/neat/locals/overload/mhod/core.py +++ b/neat/locals/overload/mhod/core.py @@ -16,6 +16,7 @@ """ from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * import neat.locals.overload.mhod.multisize_estimation as estimation diff --git a/neat/locals/overload/mhod/l_2_states.py b/neat/locals/overload/mhod/l_2_states.py index d61bf8b..bede123 100644 --- a/neat/locals/overload/mhod/l_2_states.py +++ b/neat/locals/overload/mhod/l_2_states.py @@ -16,6 +16,7 @@ """ from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * import logging diff --git a/neat/locals/overload/mhod/multisize_estimation.py b/neat/locals/overload/mhod/multisize_estimation.py index 3a20138..e132532 100644 --- a/neat/locals/overload/mhod/multisize_estimation.py +++ b/neat/locals/overload/mhod/multisize_estimation.py @@ -16,6 +16,7 @@ """ from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * from itertools import islice diff --git a/neat/locals/overload/mhod/nlp.py b/neat/locals/overload/mhod/nlp.py index aea6ee8..0290ecc 100644 --- a/neat/locals/overload/mhod/nlp.py +++ b/neat/locals/overload/mhod/nlp.py @@ -16,6 +16,7 @@ """ from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * import operator diff --git a/neat/locals/overload/otf.py b/neat/locals/overload/otf.py index e7f18e5..4227a47 100644 --- a/neat/locals/overload/otf.py +++ b/neat/locals/overload/otf.py @@ -16,6 +16,7 @@ """ from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * import logging @@ -41,7 +42,7 @@ def otf_factory(time_step, migration_time, params): migration_time_normalized = float(migration_time) / time_step def otf_wrapper(utilization, state=None): if state is None or state == {}: - state = {'overload': 0, + state = {'overload': 0, 'total': 0} return otf(params['otf'], params['threshold'], @@ -49,9 +50,9 @@ def otf_factory(time_step, migration_time, params): migration_time_normalized, utilization, state) - + return otf_wrapper - + @contract def otf(otf, threshold, limit, migration_time, utilization, state): @@ -89,10 +90,10 @@ def otf(otf, threshold, limit, migration_time, utilization, state): log.debug('OTF total steps:' + str(state['total'])) log.debug('OTF:' + str(float(state['overload']) / state['total'])) log.debug('OTF migration time:' + str(migration_time)) - log.debug('OTF + migration time:' + + log.debug('OTF + migration time:' + str((migration_time + state['overload']) / \ (migration_time + state['total']))) - log.debug('OTF decision:' + + log.debug('OTF decision:' + str(overload and (migration_time + state['overload']) / \ (migration_time + state['total']) >= otf)) diff --git a/neat/locals/overload/statistics.py b/neat/locals/overload/statistics.py index 8acf157..db53e21 100644 --- a/neat/locals/overload/statistics.py +++ b/neat/locals/overload/statistics.py @@ -16,6 +16,7 @@ """ from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * from numpy import median diff --git a/neat/locals/overload/trivial.py b/neat/locals/overload/trivial.py index 0e62812..7825352 100644 --- a/neat/locals/overload/trivial.py +++ b/neat/locals/overload/trivial.py @@ -16,6 +16,7 @@ """ from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * import logging diff --git a/neat/locals/underload/trivial.py b/neat/locals/underload/trivial.py index a1711b0..911529e 100644 --- a/neat/locals/underload/trivial.py +++ b/neat/locals/underload/trivial.py @@ -16,6 +16,7 @@ """ from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * import logging diff --git a/neat/locals/vm_selection/algorithms.py b/neat/locals/vm_selection/algorithms.py index ceb0123..c712762 100644 --- a/neat/locals/vm_selection/algorithms.py +++ b/neat/locals/vm_selection/algorithms.py @@ -16,6 +16,7 @@ """ from contracts import contract +from neat.contracts_primitive import * from neat.contracts_extra import * from random import choice diff --git a/tests/locals/test_collector.py b/tests/locals/test_collector.py index 3460eac..f2ec90b 100644 --- a/tests/locals/test_collector.py +++ b/tests/locals/test_collector.py @@ -560,6 +560,19 @@ class Collector(TestCase): assert collector.get_host_characteristics(connection) == \ (cores * mhz, ram) + @qc(10) + def get_host_characteristics_long( + ram=int_(min=1, max=4000), + cores=int_(min=1, max=8), + mhz=int_(min=1, max=3000) + ): + with MockTransaction: + connection = libvirt.virConnect() + expect(connection).getInfo().and_return( + ['x86_64', long(ram), cores, mhz, 1, 1, 4, 2]).once() + assert collector.get_host_characteristics(connection) == \ + (cores * mhz, long(ram)) + @qc(1) def log_host_overload(): db = db_utils.init_db('sqlite:///:memory:') diff --git a/tests/locals/test_manager.py b/tests/locals/test_manager.py index 2d568ae..c877fbb 100644 --- a/tests/locals/test_manager.py +++ b/tests/locals/test_manager.py @@ -141,11 +141,26 @@ class LocalManager(TestCase): with MockTransaction: def mock_get_max_ram(vir_connection, uuid): return data[uuid] - connection = libvirt.virConnect() when(manager).get_max_ram(connection, any_string). \ then_call(mock_get_max_ram) + assert manager.get_ram(connection, data.keys()) == data + @qc(10) + def get_ram_long( + data=dict_( + keys=str_(of='abc123-', min_length=36, max_length=36), + values=int_(min=1, max=100), + min_length=0, max_length=10 + ) + ): + data = dict([(k, long(v)) for (k, v) in data.iteritems()]) + with MockTransaction: + def mock_get_max_ram(vir_connection, uuid): + return data[uuid] + connection = libvirt.virConnect() + when(manager).get_max_ram(connection, any_string). \ + then_call(mock_get_max_ram) assert manager.get_ram(connection, data.keys()) == data @qc(10) @@ -159,7 +174,20 @@ class LocalManager(TestCase): expect(connection).lookupByUUIDString(uuid). \ and_return(domain).once() expect(domain).maxMemory().and_return(x).once() - assert manager.get_max_ram(connection, uuid) == int(x / 1024) + assert manager.get_max_ram(connection, uuid) == int(x) / 1024 + + @qc(10) + def get_max_ram_long( + uuid=str_(of='abc123-', min_length=36, max_length=36), + x=int_(min=0) + ): + with MockTransaction: + connection = libvirt.virConnect() + domain = mock('domain') + expect(connection).lookupByUUIDString(uuid). \ + and_return(domain).once() + expect(domain).maxMemory().and_return(long(x)).once() + assert manager.get_max_ram(connection, uuid) == long(x) / 1024 @qc(1) def get_max_ram_none( @@ -167,7 +195,7 @@ class LocalManager(TestCase): ): with MockTransaction: def raise_libvirt_error(): - raise libvirt.libvirtError(None) + raise libvirt.libvirtError(None) connection = libvirt.virConnect() expect(connection).lookupByUUIDString(uuid). \ and_call(lambda _: raise_libvirt_error()) diff --git a/tests/test_common.py b/tests/test_common.py index 5a59992..971ec83 100644 --- a/tests/test_common.py +++ b/tests/test_common.py @@ -174,3 +174,18 @@ class Common(TestCase): migration_time = float(sum(ram)) / len(ram) / bandwidth assert common.calculate_migration_time(data, bandwidth) == \ migration_time + + @qc(10) + def calculate_migration_time_long( + data=dict_( + keys=str_(of='abc123-', min_length=36, max_length=36), + values=int_(min=1, max=1000), + min_length=1, max_length=10 + ), + bandwidth=float_(min=1., max=100.) + ): + data = dict([(k, long(v)) for (k, v) in data.iteritems()]) + ram = data.values() + migration_time = float(sum(ram)) / len(ram) / bandwidth + assert common.calculate_migration_time(data, bandwidth) == \ + migration_time diff --git a/tests/test_db.py b/tests/test_db.py index 00884ba..5315716 100644 --- a/tests/test_db.py +++ b/tests/test_db.py @@ -121,14 +121,14 @@ class Db(TestCase): assert host['cpu_cores'] == 4 assert host['ram'] == 4000 - db.update_host('host1', 3500, 8, 8000) + db.update_host('host1', 3500, 8, 8000L) hosts = db.hosts.select().execute().fetchall() assert len(hosts) == 1 host = hosts[0] assert host['hostname'] == 'host1' assert host['cpu_mhz'] == 3500 assert host['cpu_cores'] == 8 - assert host['ram'] == 8000 + assert host['ram'] == 8000L @qc(10) def select_cpu_mhz_for_host(