From 195e4bda54d8fd49936213a8f28349b96fb5acd2 Mon Sep 17 00:00:00 2001 From: Dan Klein Date: Fri, 8 Apr 2016 22:34:20 +0300 Subject: added filters.py ToggleFilter functionality, and its test file --- .../regression/functional_tests/filters_test.py | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 scripts/automation/regression/functional_tests/filters_test.py (limited to 'scripts/automation/regression/functional_tests') diff --git a/scripts/automation/regression/functional_tests/filters_test.py b/scripts/automation/regression/functional_tests/filters_test.py new file mode 100644 index 00000000..5479a70c --- /dev/null +++ b/scripts/automation/regression/functional_tests/filters_test.py @@ -0,0 +1,20 @@ +#!/router/bin/python + +import functional_general_test +import misc_methods +from nose.tools import assert_equal +from nose.tools import assert_not_equal +from nose.tools import assert_raises +from nose.tools import raises + + +class ToggleFilter_Test(functional_general_test.CGeneralFunctional_Test): + + def setUp(self): + pass + + def test_ipv4_gen(self): + pass + + def tearDown(self): + pass -- cgit 1.2.3-korg From 6adf866fc403829d5e24603280c6c6917b9fc357 Mon Sep 17 00:00:00 2001 From: Dan Klein Date: Fri, 8 Apr 2016 23:01:33 +0300 Subject: fixed import issue in test (ugly fix for now) --- scripts/automation/regression/functional_tests/filters_test.py | 9 ++++++++- 1 file changed, 8 insertions(+), 1 deletion(-) (limited to 'scripts/automation/regression/functional_tests') diff --git a/scripts/automation/regression/functional_tests/filters_test.py b/scripts/automation/regression/functional_tests/filters_test.py index 5479a70c..cf2c8148 100644 --- a/scripts/automation/regression/functional_tests/filters_test.py +++ b/scripts/automation/regression/functional_tests/filters_test.py @@ -1,7 +1,14 @@ #!/router/bin/python import functional_general_test -import misc_methods +#HACK FIX ME START +import sys +import os + +CURRENT_PATH = os.path.dirname(os.path.realpath(__file__)) +sys.path.append(os.path.abspath(os.path.join(CURRENT_PATH, '../../trex_control_plane/common'))) +#HACK FIX ME END +import filters from nose.tools import assert_equal from nose.tools import assert_not_equal from nose.tools import assert_raises -- cgit 1.2.3-korg From 9e63f57a80722751221e18ae1e42a7f7ac4983ab Mon Sep 17 00:00:00 2001 From: Dan Klein Date: Sat, 9 Apr 2016 01:08:51 +0300 Subject: added multiple toggle option all test passed! --- .../regression/functional_tests/filters_test.py | 86 +++++++++++++++++++++- .../trex_control_plane/common/filters.py | 7 +- 2 files changed, 88 insertions(+), 5 deletions(-) (limited to 'scripts/automation/regression/functional_tests') diff --git a/scripts/automation/regression/functional_tests/filters_test.py b/scripts/automation/regression/functional_tests/filters_test.py index cf2c8148..b45b98bb 100644 --- a/scripts/automation/regression/functional_tests/filters_test.py +++ b/scripts/automation/regression/functional_tests/filters_test.py @@ -12,16 +12,96 @@ import filters from nose.tools import assert_equal from nose.tools import assert_not_equal from nose.tools import assert_raises +from nose.tools import assert_true, assert_false from nose.tools import raises class ToggleFilter_Test(functional_general_test.CGeneralFunctional_Test): def setUp(self): - pass + self.list_db = [1, 2, 3, 4, 5] + self.set_db = {1, 2, 3, 4, 5} + self.tuple_db = (1, 2, 3, 4, 5) + self.dict_db = {str(x): x**2 + for x in range(5)} + + def test_init_with_dict(self): + toggle_filter = filters.ToggleFilter(self.dict_db) + assert_equal(toggle_filter._toggle_db, set(self.dict_db.keys())) + assert_equal(toggle_filter.filter_items(), self.dict_db) + + + def test_init_with_list(self): + toggle_filter = filters.ToggleFilter(self.list_db) + assert_equal(toggle_filter._toggle_db, set(self.list_db)) + assert_equal(toggle_filter.filter_items(), self.list_db) + + def test_init_with_set(self): + toggle_filter = filters.ToggleFilter(self.set_db) + assert_equal(toggle_filter._toggle_db, self.set_db) + assert_equal(toggle_filter.filter_items(), self.set_db) + + def test_init_with_tuple(self): + toggle_filter = filters.ToggleFilter(self.tuple_db) + assert_equal(toggle_filter._toggle_db, set(self.tuple_db)) + assert_equal(toggle_filter.filter_items(), self.tuple_db) + + @raises(TypeError) + def test_init_with_non_iterable(self): + toggle_filter = filters.ToggleFilter(15) + + def test_dict_toggeling(self): + toggle_filter = filters.ToggleFilter(self.dict_db) + assert_false(toggle_filter.toggle_item("3")) + assert_equal(toggle_filter._toggle_db, {'0', '1', '2', '4'}) + assert_true(toggle_filter.toggle_item("3")) + assert_equal(toggle_filter._toggle_db, {'0', '1', '2', '3', '4'}) + assert_false(toggle_filter.toggle_item("2")) + assert_false(toggle_filter.toggle_item("4")) + self.dict_db.update({'5': 25, '6': 36}) + assert_true(toggle_filter.toggle_item("6")) + + assert_equal(toggle_filter.filter_items(), {'0': 0, '1': 1, '3': 9, '6': 36}) + + del self.dict_db['1'] + assert_equal(toggle_filter.filter_items(), {'0': 0, '3': 9, '6': 36}) + + def test_dict_toggeling_negative(self): + toggle_filter = filters.ToggleFilter(self.dict_db) + assert_raises(KeyError, toggle_filter.toggle_item, "100") + + def test_list_toggeling(self): + toggle_filter = filters.ToggleFilter(self.list_db) + assert_false(toggle_filter.toggle_item(3)) + assert_equal(toggle_filter._toggle_db, {1, 2, 4, 5}) + assert_true(toggle_filter.toggle_item(3)) + assert_equal(toggle_filter._toggle_db, {1, 2, 3, 4, 5}) + assert_false(toggle_filter.toggle_item(2)) + assert_false(toggle_filter.toggle_item(4)) + self.list_db.extend([6 ,7]) + assert_true(toggle_filter.toggle_item(6)) + + assert_equal(toggle_filter.filter_items(), [1, 3 , 5, 6]) + + self.list_db.remove(1) + assert_equal(toggle_filter.filter_items(), [3, 5, 6]) + + def test_list_toggeliing_negative(self): + toggle_filter = filters.ToggleFilter(self.list_db) + assert_raises(KeyError, toggle_filter.toggle_item, 10) + + def test_toggle_multiple_items(self): + toggle_filter = filters.ToggleFilter(self.list_db) + assert_false(toggle_filter.toggle_items(1, 3, 5)) + assert_equal(toggle_filter._toggle_db, {2, 4}) + assert_true(toggle_filter.toggle_items(1, 5)) + assert_equal(toggle_filter._toggle_db, {1, 2, 4, 5}) + + def test_dont_show_after_init(self): + toggle_filter = filters.ToggleFilter(self.list_db, show_by_default = False) + assert_equal(toggle_filter._toggle_db, set()) + assert_equal(toggle_filter.filter_items(), []) - def test_ipv4_gen(self): - pass def tearDown(self): pass diff --git a/scripts/automation/trex_control_plane/common/filters.py b/scripts/automation/trex_control_plane/common/filters.py index 3a05f4d1..d2ca7b16 100644 --- a/scripts/automation/trex_control_plane/common/filters.py +++ b/scripts/automation/trex_control_plane/common/filters.py @@ -23,6 +23,9 @@ class ToggleFilter(object): else: raise KeyError("Provided item key isn't a key of the referenced data structure.") + def toggle_items(self, *args): + return all(map(self.toggle_item, args)) + def filter_items(self): """ Filters the pointed database by showing only the items mapped at toggle_db set. @@ -41,7 +44,7 @@ class ToggleFilter(object): if isinstance(self._data, dict): self._filter_method = ToggleFilter.dict_filter if show_by_default: - self._toggle_db = self._data.keys() + self._toggle_db = set(self._data.keys()) return elif isinstance(self._data, list): self._filter_method = ToggleFilter.list_filter @@ -65,7 +68,7 @@ class ToggleFilter(object): assert isinstance(iterable, dict) return {k: v for k,v in iterable.iteritems() - if function(k, v)} + if function(k)} @staticmethod def list_filter(function, iterable): -- cgit 1.2.3-korg From 3bafb0394c07ef2abb4ce34c7fb4ec01eb09f2df Mon Sep 17 00:00:00 2001 From: Dan Klein Date: Tue, 19 Apr 2016 01:44:04 +0300 Subject: All unit tests passes with both python 2 and python 3. Added more documentation to the ToggleFilter class. --- .../regression/functional_tests/filters_test.py | 2 +- .../trex_control_plane/common/filters.py | 54 ++++++++++++++++++++-- 2 files changed, 52 insertions(+), 4 deletions(-) (limited to 'scripts/automation/regression/functional_tests') diff --git a/scripts/automation/regression/functional_tests/filters_test.py b/scripts/automation/regression/functional_tests/filters_test.py index b45b98bb..abb92999 100644 --- a/scripts/automation/regression/functional_tests/filters_test.py +++ b/scripts/automation/regression/functional_tests/filters_test.py @@ -86,7 +86,7 @@ class ToggleFilter_Test(functional_general_test.CGeneralFunctional_Test): self.list_db.remove(1) assert_equal(toggle_filter.filter_items(), [3, 5, 6]) - def test_list_toggeliing_negative(self): + def test_list_toggling_negative(self): toggle_filter = filters.ToggleFilter(self.list_db) assert_raises(KeyError, toggle_filter.toggle_item, 10) diff --git a/scripts/automation/trex_control_plane/common/filters.py b/scripts/automation/trex_control_plane/common/filters.py index d2ca7b16..bf04a775 100644 --- a/scripts/automation/trex_control_plane/common/filters.py +++ b/scripts/automation/trex_control_plane/common/filters.py @@ -8,12 +8,43 @@ class ToggleFilter(object): This class provides a "sticky" filter, that works by "toggling" items of the original database on and off. """ def __init__(self, db_ref, show_by_default=True): + """ + Instantiate a ToggleFilter object + + :parameters: + db_ref : iterable + an iterable object (i.e. list, set etc) that would serve as the reference db of the instance. + Changes in that object will affect the output of ToggleFilter instance. + + show_by_default: bool + decide if by default all the items are "on", i.e. these items will be presented if no other + toggling occurred. + + default value : **True** + + """ self._data = db_ref self._toggle_db = set() self._filter_method = filter self.__set_initial_state(show_by_default) def toggle_item(self, item_key): + """ + Toggle a single item in/out. + + :parameters: + item_key : + an item the by its value the filter can decide to toggle or not. + Example: int, str and so on. + + :return: + + **True** if item toggled **into** the filtered items + + **False** if item toggled **out from** the filtered items + + :raises: + + KeyError, in case if item key is not part of the toggled list and not part of the referenced db. + + """ if item_key in self._toggle_db: self._toggle_db.remove(item_key) return False @@ -24,7 +55,23 @@ class ToggleFilter(object): raise KeyError("Provided item key isn't a key of the referenced data structure.") def toggle_items(self, *args): - return all(map(self.toggle_item, args)) + """ + Toggle multiple items in/out with a single call. Each item will be ha. + + :parameters: + args : iterable + an iterable object containing all item keys to be toggled in/out + + :return: + + **True** if all toggled items were toggled **into** the filtered items + + **False** if at least one of the items was toggled **out from** the filtered items + + :raises: + + KeyError, in case if ont of the item keys was not part of the toggled list and not part of the referenced db. + + """ + # in python 3, 'map' returns an iterator, so wrapping with 'list' call creates same effect for both python 2 and 3 + return all(list(map(self.toggle_item, args))) def filter_items(self): """ @@ -67,12 +114,13 @@ class ToggleFilter(object): def dict_filter(function, iterable): assert isinstance(iterable, dict) return {k: v - for k,v in iterable.iteritems() + for k,v in iterable.items() if function(k)} @staticmethod def list_filter(function, iterable): - return filter(function, iterable) + # in python 3, filter returns an iterator, so wrapping with list creates same effect for both python 2 and 3 + return list(filter(function, iterable)) @staticmethod def set_filter(function, iterable): -- cgit 1.2.3-korg