Add engine scheduler unit test
Change-Id: Ib210fff443b34e223141bc7490ddcd4e2e49f48f
This commit is contained in:
parent
99424b71db
commit
c7b473e81f
@ -13,6 +13,7 @@
|
||||
# License for the specific language governing permissions and limitations
|
||||
# under the License.
|
||||
|
||||
import mock
|
||||
import os
|
||||
|
||||
from oslo_config import cfg
|
||||
@ -95,3 +96,25 @@ class TestCase(base.BaseTestCase):
|
||||
return os.path.join(root, project_file)
|
||||
else:
|
||||
return root
|
||||
|
||||
def mock_object(self, obj, attr_name, *args, **kwargs):
|
||||
"""Use python mock to mock an object attribute
|
||||
|
||||
Mocks the specified objects attribute with the given value.
|
||||
Automatically performs 'addCleanup' for the mock.
|
||||
|
||||
"""
|
||||
patcher = mock.patch.object(obj, attr_name, *args, **kwargs)
|
||||
result = patcher.start()
|
||||
self.addCleanup(patcher.stop)
|
||||
return result
|
||||
|
||||
def override_config(self, name, override, group=None):
|
||||
"""Cleanly override CONF variables."""
|
||||
CONF.set_override(name, override, group)
|
||||
self.addCleanup(CONF.clear_override, name, group)
|
||||
|
||||
def flags(self, **kw):
|
||||
"""Override CONF variables for a test."""
|
||||
for k, v in kw.items():
|
||||
self.override_config(k, v)
|
||||
|
0
nimble/tests/unit/engine/scheduler/__init__.py
Normal file
0
nimble/tests/unit/engine/scheduler/__init__.py
Normal file
62
nimble/tests/unit/engine/scheduler/fakes.py
Normal file
62
nimble/tests/unit/engine/scheduler/fakes.py
Normal file
@ -0,0 +1,62 @@
|
||||
# Copyright (c) 2016 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
#
|
||||
"""
|
||||
Fakes For Scheduler tests.
|
||||
"""
|
||||
|
||||
from oslo_versionedobjects import base as object_base
|
||||
|
||||
|
||||
from nimble.engine.scheduler import filter_scheduler
|
||||
from nimble.engine.scheduler import node_manager
|
||||
from nimble.objects import base
|
||||
from nimble.objects import fields as object_fields
|
||||
|
||||
|
||||
class FakeFilterScheduler(filter_scheduler.FilterScheduler):
|
||||
def __init__(self, *args, **kwargs):
|
||||
super(FakeFilterScheduler, self).__init__(*args, **kwargs)
|
||||
self.node_manager = node_manager.NodeManager()
|
||||
|
||||
|
||||
@base.NimbleObjectRegistry.register
|
||||
class FakeNode(base.NimbleObject, object_base.VersionedObjectDictCompat):
|
||||
fields = {
|
||||
'id': object_fields.IntegerField(),
|
||||
'uuid': object_fields.UUIDField(nullable=True),
|
||||
'properties': object_fields.FlexibleDictField(nullable=True),
|
||||
}
|
||||
|
||||
|
||||
fakenode1 = FakeNode(id=1, uuid='1a617131-cdbc-45dc-afff-f21f17ae054e',
|
||||
properties={'capabilities': '',
|
||||
'availability_zone': 'az1',
|
||||
'instance_type': 'type1'})
|
||||
fakenode2 = FakeNode(id=2, uuid='2a617131-cdbc-45dc-afff-f21f17ae054e',
|
||||
properties={'capabilities': '',
|
||||
'availability_zone': 'az2',
|
||||
'instance_type': 'type2'})
|
||||
fakenode3 = FakeNode(id=3, uuid='3a617131-cdbc-45dc-afff-f21f17ae054e',
|
||||
properties={'capabilities': '',
|
||||
'availability_zone': 'az3',
|
||||
'instance_type': 'type3'})
|
||||
|
||||
|
||||
class FakeNodeState(node_manager.NodeState):
|
||||
def __init__(self, node, attribute_dict):
|
||||
super(FakeNodeState, self).__init__(node)
|
||||
for (key, val) in attribute_dict.items():
|
||||
setattr(self, key, val)
|
174
nimble/tests/unit/engine/scheduler/test_base_filter.py
Normal file
174
nimble/tests/unit/engine/scheduler/test_base_filter.py
Normal file
@ -0,0 +1,174 @@
|
||||
# Copyright (c) 2016 OpenStack Foundation.
|
||||
#
|
||||
# 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 nimble.engine.scheduler import base_filter
|
||||
from nimble.tests import base as test
|
||||
|
||||
|
||||
class TestBaseFilter(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestBaseFilter, self).setUp()
|
||||
self.filter = base_filter.BaseFilter()
|
||||
|
||||
def test_filter_one_is_called(self):
|
||||
filters = [1, 2, 3, 4]
|
||||
filter_properties = {'x': 'y'}
|
||||
|
||||
self.filter._filter_one = mock.Mock()
|
||||
self.filter._filter_one.side_effect = [False, True, True, False]
|
||||
calls = [mock.call(i, filter_properties) for i in filters]
|
||||
|
||||
result = list(self.filter.filter_all(filters, filter_properties))
|
||||
self.assertEqual([2, 3], result)
|
||||
self.filter._filter_one.assert_has_calls(calls)
|
||||
|
||||
|
||||
class FakeExtension(object):
|
||||
|
||||
def __init__(self, plugin):
|
||||
self.plugin = plugin
|
||||
|
||||
|
||||
class BaseFakeFilter(base_filter.BaseFilter):
|
||||
pass
|
||||
|
||||
|
||||
class FakeFilter1(BaseFakeFilter):
|
||||
"""Derives from BaseFakeFilter and has a fake entry point defined.
|
||||
|
||||
Entry point is returned by fake ExtensionManager.
|
||||
Should be included in the output of all_classes.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class FakeFilter2(BaseFakeFilter):
|
||||
"""Derives from BaseFakeFilter but has no entry point.
|
||||
|
||||
Should be not included in all_classes.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class FakeFilter3(base_filter.BaseFilter):
|
||||
"""Does not derive from BaseFakeFilter.
|
||||
|
||||
Should not be included.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class FakeFilter4(BaseFakeFilter):
|
||||
"""Derives from BaseFakeFilter and has an entry point.
|
||||
|
||||
Should be included.
|
||||
"""
|
||||
pass
|
||||
|
||||
|
||||
class FakeFilter5(BaseFakeFilter):
|
||||
"""Derives from BaseFakeFilter but has no entry point.
|
||||
|
||||
Should not be included.
|
||||
"""
|
||||
run_filter_once_per_request = True
|
||||
pass
|
||||
|
||||
|
||||
class FilterA(base_filter.BaseFilter):
|
||||
def filter_all(self, list_objs, filter_properties):
|
||||
# return all but the first object
|
||||
return list_objs[1:]
|
||||
|
||||
|
||||
class FilterB(base_filter.BaseFilter):
|
||||
def filter_all(self, list_objs, filter_properties):
|
||||
# return an empty list
|
||||
return None
|
||||
|
||||
|
||||
class FakeExtensionManager(list):
|
||||
|
||||
def __init__(self, namespace):
|
||||
classes = [FakeFilter1, FakeFilter3, FakeFilter4]
|
||||
exts = map(FakeExtension, classes)
|
||||
super(FakeExtensionManager, self).__init__(exts)
|
||||
self.namespace = namespace
|
||||
|
||||
|
||||
class TestBaseFilterHandler(test.TestCase):
|
||||
|
||||
def setUp(self):
|
||||
super(TestBaseFilterHandler, self).setUp()
|
||||
self.mock_object(base_filter.base_handler.extension,
|
||||
'ExtensionManager', FakeExtensionManager)
|
||||
self.handler = base_filter.BaseFilterHandler(BaseFakeFilter,
|
||||
'fake_filters')
|
||||
|
||||
def test_get_all_classes(self):
|
||||
# In order for a FakeFilter to be returned by get_all_classes, it has
|
||||
# to comply with these rules:
|
||||
# * It must be derived from BaseFakeFilter
|
||||
# AND
|
||||
# * It must have a python entrypoint assigned (returned by
|
||||
# FakeExtensionManager)
|
||||
expected = [FakeFilter1, FakeFilter4]
|
||||
result = self.handler.get_all_classes()
|
||||
self.assertEqual(expected, result)
|
||||
|
||||
def _get_filtered_objects(self, filter_classes, index=0):
|
||||
filter_objs_initial = [1, 2, 3, 4]
|
||||
filter_properties = {'x': 'y'}
|
||||
return self.handler.get_filtered_objects(filter_classes,
|
||||
filter_objs_initial,
|
||||
filter_properties,
|
||||
index)
|
||||
|
||||
@mock.patch.object(FakeFilter4, 'filter_all')
|
||||
@mock.patch.object(FakeFilter3, 'filter_all', return_value=None)
|
||||
def test_get_filtered_objects_return_none(self, fake3_filter_all,
|
||||
fake4_filter_all):
|
||||
filter_classes = [FakeFilter1, FakeFilter2, FakeFilter3, FakeFilter4]
|
||||
result = self._get_filtered_objects(filter_classes)
|
||||
self.assertIsNone(result)
|
||||
self.assertFalse(fake4_filter_all.called)
|
||||
|
||||
def test_get_filtered_objects(self):
|
||||
filter_objs_expected = [1, 2, 3, 4]
|
||||
filter_classes = [FakeFilter1, FakeFilter2, FakeFilter3, FakeFilter4]
|
||||
result = self._get_filtered_objects(filter_classes)
|
||||
self.assertEqual(filter_objs_expected, result)
|
||||
|
||||
def test_get_filtered_objects_with_filter_run_once(self):
|
||||
filter_objs_expected = [1, 2, 3, 4]
|
||||
filter_classes = [FakeFilter5]
|
||||
|
||||
with mock.patch.object(FakeFilter5, 'filter_all',
|
||||
return_value=filter_objs_expected
|
||||
) as fake5_filter_all:
|
||||
result = self._get_filtered_objects(filter_classes)
|
||||
self.assertEqual(filter_objs_expected, result)
|
||||
self.assertEqual(1, fake5_filter_all.call_count)
|
||||
|
||||
result = self._get_filtered_objects(filter_classes, index=1)
|
||||
self.assertEqual(filter_objs_expected, result)
|
||||
self.assertEqual(1, fake5_filter_all.call_count)
|
||||
|
||||
result = self._get_filtered_objects(filter_classes, index=2)
|
||||
self.assertEqual(filter_objs_expected, result)
|
||||
self.assertEqual(1, fake5_filter_all.call_count)
|
86
nimble/tests/unit/engine/scheduler/test_node_manager.py
Normal file
86
nimble/tests/unit/engine/scheduler/test_node_manager.py
Normal file
@ -0,0 +1,86 @@
|
||||
# Copyright (c) 2016 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
"""
|
||||
Tests For NodeManager
|
||||
"""
|
||||
|
||||
import mock
|
||||
|
||||
from nimble.common import exception
|
||||
from nimble.engine.scheduler import filters
|
||||
from nimble.engine.scheduler import node_manager
|
||||
from nimble.engine.scheduler.node_manager import NodeState
|
||||
from nimble.tests import base as test
|
||||
from nimble.tests.unit.engine.scheduler import fakes
|
||||
|
||||
|
||||
class FakeFilterClass1(filters.BaseNodeFilter):
|
||||
def node_passes(self, node_state, filter_properties):
|
||||
pass
|
||||
|
||||
|
||||
class FakeFilterClass2(filters.BaseNodeFilter):
|
||||
def node_passes(self, node_state, filter_properties):
|
||||
pass
|
||||
|
||||
|
||||
class NodeManagerTestCase(test.TestCase):
|
||||
"""Test case for NodeManager class."""
|
||||
|
||||
def setUp(self):
|
||||
super(NodeManagerTestCase, self).setUp()
|
||||
self.node_manager = node_manager.NodeManager()
|
||||
|
||||
self.fake_nodes = [NodeState(fakes.fakenode1),
|
||||
NodeState(fakes.fakenode2),
|
||||
NodeState(fakes.fakenode3)]
|
||||
|
||||
def test_choose_node_filters_not_found(self):
|
||||
self.override_config('scheduler_default_filters', 'FakeFilterClass3',
|
||||
'scheduler')
|
||||
self.node_manager.filter_classes = [FakeFilterClass1,
|
||||
FakeFilterClass2]
|
||||
self.assertRaises(exception.SchedulerNodeFilterNotFound,
|
||||
self.node_manager._choose_node_filters, None)
|
||||
|
||||
def test_choose_node_filters(self):
|
||||
self.override_config('scheduler_default_filters', 'FakeFilterClass2',
|
||||
group='scheduler')
|
||||
self.node_manager.filter_classes = [FakeFilterClass1,
|
||||
FakeFilterClass2]
|
||||
|
||||
# Test returns 1 correct filter class
|
||||
filter_classes = self.node_manager._choose_node_filters(None)
|
||||
self.assertEqual(1, len(filter_classes))
|
||||
self.assertEqual('FakeFilterClass2', filter_classes[0].__name__)
|
||||
|
||||
@mock.patch('nimble.engine.scheduler.node_manager.NodeManager.'
|
||||
'_choose_node_filters')
|
||||
def test_get_filtered_nodes(self, _mock_choose_node_filters):
|
||||
filter_class = FakeFilterClass1
|
||||
mock_func = mock.Mock()
|
||||
mock_func.return_value = True
|
||||
filter_class._filter_one = mock_func
|
||||
_mock_choose_node_filters.return_value = [filter_class]
|
||||
|
||||
fake_properties = {'moo': 1, 'cow': 2}
|
||||
expected = []
|
||||
for fake_node in self.fake_nodes:
|
||||
expected.append(mock.call(fake_node, fake_properties))
|
||||
|
||||
result = self.node_manager.get_filtered_nodes(self.fake_nodes,
|
||||
fake_properties)
|
||||
self.assertEqual(expected, mock_func.call_args_list)
|
||||
self.assertEqual(set(self.fake_nodes), set(result))
|
138
nimble/tests/unit/engine/scheduler/test_scheduler_options.py
Normal file
138
nimble/tests/unit/engine/scheduler/test_scheduler_options.py
Normal file
@ -0,0 +1,138 @@
|
||||
# Copyright 2016 OpenStack Foundation
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
"""
|
||||
Tests For PickledScheduler.
|
||||
"""
|
||||
|
||||
import datetime
|
||||
|
||||
from oslo_serialization import jsonutils
|
||||
import six
|
||||
|
||||
from nimble.engine.scheduler import scheduler_options
|
||||
from nimble.tests import base as test
|
||||
|
||||
|
||||
class FakeSchedulerOptions(scheduler_options.SchedulerOptions):
|
||||
def __init__(self, last_checked, now, file_old, file_now, data, filedata):
|
||||
super(FakeSchedulerOptions, self).__init__()
|
||||
# Change internals ...
|
||||
self.last_modified = file_old
|
||||
self.last_checked = last_checked
|
||||
self.data = data
|
||||
|
||||
# For overrides ...
|
||||
self._time_now = now
|
||||
self._file_now = file_now
|
||||
self._file_data = filedata
|
||||
|
||||
self.file_was_loaded = False
|
||||
|
||||
def _get_file_timestamp(self, filename):
|
||||
return self._file_now
|
||||
|
||||
def _get_file_handle(self, filename):
|
||||
self.file_was_loaded = True
|
||||
return six.StringIO(self._file_data)
|
||||
|
||||
def _get_time_now(self):
|
||||
return self._time_now
|
||||
|
||||
|
||||
class SchedulerOptionsTestCase(test.TestCase):
|
||||
def test_get_configuration_first_time_no_flag(self):
|
||||
last_checked = None
|
||||
now = datetime.datetime(2012, 1, 1, 1, 1, 1)
|
||||
file_old = None
|
||||
file_now = datetime.datetime(2012, 1, 1, 1, 1, 1)
|
||||
|
||||
data = dict(a=1, b=2, c=3)
|
||||
jdata = jsonutils.dumps(data)
|
||||
|
||||
fake = FakeSchedulerOptions(last_checked, now, file_old, file_now,
|
||||
{}, jdata)
|
||||
self.assertEqual({}, fake.get_configuration())
|
||||
self.assertFalse(fake.file_was_loaded)
|
||||
|
||||
def test_get_configuration_first_time_empty_file(self):
|
||||
last_checked = None
|
||||
now = datetime.datetime(2012, 1, 1, 1, 1, 1)
|
||||
file_old = None
|
||||
file_now = datetime.datetime(2012, 1, 1, 1, 1, 1)
|
||||
|
||||
jdata = ""
|
||||
|
||||
fake = FakeSchedulerOptions(last_checked, now, file_old, file_now,
|
||||
{}, jdata)
|
||||
self.assertEqual({}, fake.get_configuration('foo.json'))
|
||||
self.assertTrue(fake.file_was_loaded)
|
||||
|
||||
def test_get_configuration_first_time_happy_day(self):
|
||||
last_checked = None
|
||||
now = datetime.datetime(2012, 1, 1, 1, 1, 1)
|
||||
file_old = None
|
||||
file_now = datetime.datetime(2012, 1, 1, 1, 1, 1)
|
||||
|
||||
data = dict(a=1, b=2, c=3)
|
||||
jdata = jsonutils.dumps(data)
|
||||
|
||||
fake = FakeSchedulerOptions(last_checked, now, file_old, file_now,
|
||||
{}, jdata)
|
||||
self.assertEqual(data, fake.get_configuration('foo.json'))
|
||||
self.assertTrue(fake.file_was_loaded)
|
||||
|
||||
def test_get_configuration_second_time_no_change(self):
|
||||
last_checked = datetime.datetime(2011, 1, 1, 1, 1, 1)
|
||||
now = datetime.datetime(2012, 1, 1, 1, 1, 1)
|
||||
file_old = datetime.datetime(2012, 1, 1, 1, 1, 1)
|
||||
file_now = datetime.datetime(2012, 1, 1, 1, 1, 1)
|
||||
|
||||
data = dict(a=1, b=2, c=3)
|
||||
jdata = jsonutils.dumps(data)
|
||||
|
||||
fake = FakeSchedulerOptions(last_checked, now, file_old, file_now,
|
||||
data, jdata)
|
||||
self.assertEqual(data, fake.get_configuration('foo.json'))
|
||||
self.assertFalse(fake.file_was_loaded)
|
||||
|
||||
def test_get_configuration_second_time_too_fast(self):
|
||||
last_checked = datetime.datetime(2011, 1, 1, 1, 1, 1)
|
||||
now = datetime.datetime(2011, 1, 1, 1, 1, 2)
|
||||
file_old = datetime.datetime(2012, 1, 1, 1, 1, 1)
|
||||
file_now = datetime.datetime(2013, 1, 1, 1, 1, 1)
|
||||
|
||||
old_data = dict(a=1, b=2, c=3)
|
||||
data = dict(a=11, b=12, c=13)
|
||||
jdata = jsonutils.dumps(data)
|
||||
|
||||
fake = FakeSchedulerOptions(last_checked, now, file_old, file_now,
|
||||
old_data, jdata)
|
||||
self.assertEqual(old_data, fake.get_configuration('foo.json'))
|
||||
self.assertFalse(fake.file_was_loaded)
|
||||
|
||||
def test_get_configuration_second_time_change(self):
|
||||
last_checked = datetime.datetime(2011, 1, 1, 1, 1, 1)
|
||||
now = datetime.datetime(2012, 1, 1, 1, 1, 1)
|
||||
file_old = datetime.datetime(2012, 1, 1, 1, 1, 1)
|
||||
file_now = datetime.datetime(2013, 1, 1, 1, 1, 1)
|
||||
|
||||
old_data = dict(a=1, b=2, c=3)
|
||||
data = dict(a=11, b=12, c=13)
|
||||
jdata = jsonutils.dumps(data)
|
||||
|
||||
fake = FakeSchedulerOptions(last_checked, now, file_old, file_now,
|
||||
old_data, jdata)
|
||||
self.assertEqual(data, fake.get_configuration('foo.json'))
|
||||
self.assertTrue(fake.file_was_loaded)
|
54
nimble/tests/unit/engine/scheduler/test_weights.py
Normal file
54
nimble/tests/unit/engine/scheduler/test_weights.py
Normal file
@ -0,0 +1,54 @@
|
||||
# Copyright 2016 OpenStack Foundation.
|
||||
# All Rights Reserved.
|
||||
#
|
||||
# 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.
|
||||
|
||||
"""
|
||||
Tests For Scheduler weights.
|
||||
"""
|
||||
|
||||
from nimble.engine.scheduler import base_weight
|
||||
from nimble.tests import base as test
|
||||
|
||||
|
||||
class TestWeightHandler(test.TestCase):
|
||||
def test_no_multiplier(self):
|
||||
class FakeWeigher(base_weight.BaseWeigher):
|
||||
def _weigh_object(self, *args, **kwargs):
|
||||
pass
|
||||
|
||||
self.assertEqual(1.0,
|
||||
FakeWeigher().weight_multiplier())
|
||||
|
||||
def test_no_weight_object(self):
|
||||
class FakeWeigher(base_weight.BaseWeigher):
|
||||
def weight_multiplier(self, *args, **kwargs):
|
||||
pass
|
||||
self.assertRaises(TypeError,
|
||||
FakeWeigher)
|
||||
|
||||
def test_normalization(self):
|
||||
# weight_list, expected_result, minval, maxval
|
||||
map_ = (
|
||||
((), (), None, None),
|
||||
((0.0, 0.0), (0.0, 0.0), None, None),
|
||||
((1.0, 1.0), (0.0, 0.0), None, None),
|
||||
|
||||
((20.0, 50.0), (0.0, 1.0), None, None),
|
||||
((20.0, 50.0), (0.0, 0.375), None, 100.0),
|
||||
((20.0, 50.0), (0.4, 1.0), 0.0, None),
|
||||
((20.0, 50.0), (0.2, 0.5), 0.0, 100.0),
|
||||
)
|
||||
for seq, result, minval, maxval in map_:
|
||||
ret = base_weight.normalize(seq, minval=minval, maxval=maxval)
|
||||
self.assertEqual(result, tuple(ret))
|
22
nimble/tests/unit/fake_constants.py
Normal file
22
nimble/tests/unit/fake_constants.py
Normal file
@ -0,0 +1,22 @@
|
||||
# Copyright 2016 Intel, Inc.
|
||||
#
|
||||
# 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.
|
||||
|
||||
|
||||
IMAGE_ID = 'e79161cd-5f9d-4007-8823-81a807a64332'
|
||||
INSTANCE_ID = 'fa617131-cdbc-45dc-afff-f21f17ae054e'
|
||||
PROJECT_ID = '89afd400-b646-4bbc-b12b-c0a4d63e5bd3'
|
||||
PROJECT2_ID = '452ebfbc-55d9-402a-87af-65061916c24b'
|
||||
PROJECT3_ID = 'f6c912d7-bf30-4b12-af81-a9e0b2f85f85'
|
||||
USER_ID = 'c853ca26-e8ea-4797-8a52-ee124a013d0e'
|
||||
USER2_ID = '95f7b7ed-bd7f-426e-b05f-f1ffeb4f09df'
|
@ -7,6 +7,7 @@ hacking<0.12,>=0.11.0 # Apache-2.0
|
||||
coverage>=3.6 # Apache-2.0
|
||||
python-subunit>=0.0.18 # Apache-2.0/BSD
|
||||
sphinx!=1.3b1,<1.4,>=1.2.1 # BSD
|
||||
ddt>=1.0.1 # MIT
|
||||
oslosphinx>=4.7.0 # Apache-2.0
|
||||
oslotest>=1.10.0 # Apache-2.0
|
||||
testrepository>=0.0.18 # Apache-2.0/BSD
|
||||
|
Loading…
x
Reference in New Issue
Block a user