From 92f67c65f065c29e2ab90f55cadac5a95162feb6 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Thu, 25 Feb 2021 05:37:24 -0500 Subject: [PATCH 01/17] pyocf: valid ranges for cleaning policy params Signed-off-by: Michal Mielewczyk --- tests/functional/pyocf/types/cache.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/tests/functional/pyocf/types/cache.py b/tests/functional/pyocf/types/cache.py index c519be6..d263b91 100644 --- a/tests/functional/pyocf/types/cache.py +++ b/tests/functional/pyocf/types/cache.py @@ -76,6 +76,14 @@ class ConfValidValues: promotion_nhit_insertion_threshold_range = range(2, 1000) promotion_nhit_trigger_threshold_range = range(0, 100) + cleaning_alru_wake_up_time_range = range(0, 3600) + cleaning_alru_staleness_time_range = range(1, 3600) + cleaning_alru_flush_max_buffers_range = range(1, 10000) + cleaning_alru_activity_threshold_range = range(0, 1000000) + + cleaning_acp_wake_up_time_range = range(0, 10000) + cleaning_acp_flush_max_buffers_range = range(1, 10000) + CACHE_MODE_NONE = -1 From 43ff4aae5f427ed81c3e1901909d781b258986ed Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Thu, 25 Feb 2021 17:15:34 -0500 Subject: [PATCH 02/17] pyocf: security test for alru params Signed-off-by: Michal Mielewczyk --- .../tests/security/test_management_fuzzy.py | 40 +++++++++++++++++++ 1 file changed, 40 insertions(+) diff --git a/tests/functional/tests/security/test_management_fuzzy.py b/tests/functional/tests/security/test_management_fuzzy.py index f2dcd4a..57cda02 100644 --- a/tests/functional/tests/security/test_management_fuzzy.py +++ b/tests/functional/tests/security/test_management_fuzzy.py @@ -179,6 +179,46 @@ def test_neg_set_alru_param(pyocf_ctx, cm, cls): cache.set_cleaning_policy_param(CleaningPolicy.ALRU, i, 1) +def get_alru_param_valid_rage(param_id): + if param_id == AlruParams.WAKE_UP_TIME: + return ConfValidValues.cleaning_alru_wake_up_time_range + elif param_id == AlruParams.STALE_BUFFER_TIME: + return ConfValidValues.cleaning_alru_staleness_time_range + elif param_id == AlruParams.FLUSH_MAX_BUFFERS: + return ConfValidValues.cleaning_alru_flush_max_buffers_range + elif param_id == AlruParams.ACTIVITY_THRESHOLD: + return ConfValidValues.cleaning_alru_activity_threshold_range + + +@pytest.mark.parametrize("cm", CacheMode) +@pytest.mark.parametrize("cls", CacheLineSize) +@pytest.mark.parametrize("param", AlruParams) +@pytest.mark.security +def test_neg_set_alru_param_value(pyocf_ctx, cm, cls, param): + """ + Test whether it is possible to set invalid value to any of alru cleaning policy params + :param pyocf_ctx: basic pyocf context fixture + :param cm: cache mode we start with + :param cls: cache line size we start with + :param param: alru parameter to fuzz + :return: + """ + # Start cache device + cache_device = Volume(S.from_MiB(30)) + cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) + + cache.set_cleaning_policy(CleaningPolicy.ALRU) + + # Set to invalid alru param value and check if failed + valid_range = get_alru_param_valid_rage(param) + for i in RandomGenerator(DefaultRanges.UINT32): + if i in valid_range: + continue + with pytest.raises(OcfError, match="Error setting cleaning policy param"): + cache.set_cleaning_policy_param(CleaningPolicy.ALRU, param, i) + print("\n" + i) + + @pytest.mark.parametrize("cm", CacheMode) @pytest.mark.parametrize("cls", CacheLineSize) @pytest.mark.security From 482861423bf68c419b2595e7dd2ec4d353d2cdd2 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Thu, 25 Feb 2021 17:15:57 -0500 Subject: [PATCH 03/17] pyocf: security test for acp params Signed-off-by: Michal Mielewczyk --- .../tests/security/test_management_fuzzy.py | 36 +++++++++++++++++++ 1 file changed, 36 insertions(+) diff --git a/tests/functional/tests/security/test_management_fuzzy.py b/tests/functional/tests/security/test_management_fuzzy.py index 57cda02..9347797 100644 --- a/tests/functional/tests/security/test_management_fuzzy.py +++ b/tests/functional/tests/security/test_management_fuzzy.py @@ -242,6 +242,42 @@ def test_neg_set_acp_param(pyocf_ctx, cm, cls): cache.set_cleaning_policy_param(CleaningPolicy.ALRU, i, 1) +def get_acp_param_valid_rage(param_id): + if param_id == AcpParams.WAKE_UP_TIME: + return ConfValidValues.cleaning_acp_wake_up_time_range + elif param_id == AcpParams.FLUSH_MAX_BUFFERS: + return ConfValidValues.cleaning_acp_flush_max_buffers_range + + +@pytest.mark.parametrize("cm", CacheMode) +@pytest.mark.parametrize("cls", CacheLineSize) +@pytest.mark.parametrize("param", AcpParams) +@pytest.mark.security +def test_neg_set_acp_param_value(pyocf_ctx, cm, cls, param): + """ + Test whether it is possible to set invalid value to any of acp cleaning policy params + :param pyocf_ctx: basic pyocf context fixture + :param cm: cache mode we start with + :param cls: cache line size we start with + :param param: acp parameter to fuzz + :return: + """ + # Start cache device + cache_device = Volume(S.from_MiB(30)) + cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) + + cache.set_cleaning_policy(CleaningPolicy.ACP) + + # Set to invalid acp param value and check if failed + valid_range = get_acp_param_valid_rage(param) + for i in RandomGenerator(DefaultRanges.UINT32): + if i in valid_range: + continue + with pytest.raises(OcfError, match="Error setting cleaning policy param"): + cache.set_cleaning_policy_param(CleaningPolicy.ACP, param, i) + print("\n" + i) + + @pytest.mark.parametrize("cm", CacheMode) @pytest.mark.parametrize("cls", CacheLineSize) @pytest.mark.security From d909698790092a4078094ac071816a70c05da542 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Thu, 25 Feb 2021 17:16:31 -0500 Subject: [PATCH 04/17] pyocf: fix acp security test Signed-off-by: Michal Mielewczyk --- tests/functional/tests/security/test_management_fuzzy.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/tests/security/test_management_fuzzy.py b/tests/functional/tests/security/test_management_fuzzy.py index 9347797..d8c5ad5 100644 --- a/tests/functional/tests/security/test_management_fuzzy.py +++ b/tests/functional/tests/security/test_management_fuzzy.py @@ -239,7 +239,7 @@ def test_neg_set_acp_param(pyocf_ctx, cm, cls): if i in [item.value for item in AcpParams]: continue with pytest.raises(OcfError, match="Error setting cleaning policy param"): - cache.set_cleaning_policy_param(CleaningPolicy.ALRU, i, 1) + cache.set_cleaning_policy_param(CleaningPolicy.ACP, i, 1) def get_acp_param_valid_rage(param_id): From f61472c3f4a7c3d4832f4fc735575bf4634935c7 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Fri, 26 Feb 2021 03:19:17 -0500 Subject: [PATCH 05/17] Validate seq cutoff threshold value Signed-off-by: Michal Mielewczyk --- inc/ocf_def.h | 2 ++ src/mngt/ocf_mngt_core.c | 7 +++++++ 2 files changed, 9 insertions(+) diff --git a/inc/ocf_def.h b/inc/ocf_def.h index 26934d4..5d9c95a 100644 --- a/inc/ocf_def.h +++ b/inc/ocf_def.h @@ -176,6 +176,8 @@ typedef enum { } ocf_cache_mode_t; #define OCF_SEQ_CUTOFF_MAX_STREAMS 256 +#define OCF_SEQ_CUTOFF_MIN_THRESHOLD 1 +#define OCF_SEQ_CUTOFF_MAX_THRESHOLD 4194181 typedef enum { ocf_seq_cutoff_policy_always = 0, diff --git a/src/mngt/ocf_mngt_core.c b/src/mngt/ocf_mngt_core.c index c76d54c..19300b6 100644 --- a/src/mngt/ocf_mngt_core.c +++ b/src/mngt/ocf_mngt_core.c @@ -898,6 +898,13 @@ static int _cache_mngt_set_core_seq_cutoff_threshold(ocf_core_t core, void *cntx uint32_t threshold = *(uint32_t*) cntx; uint32_t threshold_old = ocf_core_get_seq_cutoff_threshold(core); + if (threshold < OCF_SEQ_CUTOFF_MIN_THRESHOLD || + threshold > OCF_SEQ_CUTOFF_MAX_THRESHOLD) { + ocf_core_log(core, log_info, + "Invalid sequential cutoff threshold!\n"); + return -OCF_ERR_INVAL; + } + if (threshold_old == threshold) { ocf_core_log(core, log_info, "Sequential cutoff threshold %u bytes is " From 9aebf57efa31afed6d1b099e481f39a315da394b Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Fri, 26 Feb 2021 03:20:37 -0500 Subject: [PATCH 06/17] pyocf: valid ranges for seq cutoff threshold Signed-off-by: Michal Mielewczyk --- tests/functional/pyocf/types/cache.py | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/tests/functional/pyocf/types/cache.py b/tests/functional/pyocf/types/cache.py index d263b91..85118e2 100644 --- a/tests/functional/pyocf/types/cache.py +++ b/tests/functional/pyocf/types/cache.py @@ -84,6 +84,8 @@ class ConfValidValues: cleaning_acp_wake_up_time_range = range(0, 10000) cleaning_acp_flush_max_buffers_range = range(1, 10000) + seq_cutoff_threshold_rage = range(1, 4194181) + CACHE_MODE_NONE = -1 @@ -310,7 +312,7 @@ class Cache: self.write_unlock() if status: - raise OcfError("Error setting cache seq cut off policy", status) + raise OcfError("Error setting cache seq cut off policy threshold", status) def get_partition_info(self, part_id: int): ioclass_info = IoClassInfo() From 73d6fb33de40a0821186b1efb6880f764ec52eae Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Fri, 26 Feb 2021 03:33:10 -0500 Subject: [PATCH 07/17] pyocf: api for setting core seq cutoff threshold Signed-off-by: Michal Mielewczyk --- tests/functional/pyocf/types/core.py | 14 ++++++++++++++ 1 file changed, 14 insertions(+) diff --git a/tests/functional/pyocf/types/core.py b/tests/functional/pyocf/types/core.py index 7d8a9ac..3981bf1 100644 --- a/tests/functional/pyocf/types/core.py +++ b/tests/functional/pyocf/types/core.py @@ -162,6 +162,18 @@ class Core: self.cache.write_unlock() + def set_seq_cut_off_threshold(self, threshold): + self.cache.write_lock() + + status = self.cache.owner.lib.ocf_mngt_core_set_seq_cutoff_threshold( + self.handle, threshold + ) + if status: + self.cache.write_unlock() + raise OcfError("Error setting core seq cut off policy threshold", status) + + self.cache.write_unlock() + def reset_stats(self): self.cache.owner.lib.ocf_core_stats_initialize(self.handle) @@ -211,6 +223,8 @@ lib.ocf_core_get_volume.argtypes = [c_void_p] lib.ocf_core_get_volume.restype = c_void_p lib.ocf_mngt_core_set_seq_cutoff_policy.argtypes = [c_void_p, c_uint32] lib.ocf_mngt_core_set_seq_cutoff_policy.restype = c_int +lib.ocf_mngt_core_set_seq_cutoff_threshold.argtypes = [c_void_p, c_uint32] +lib.ocf_mngt_core_set_seq_cutoff_threshold.restype = c_int lib.ocf_stats_collect_core.argtypes = [c_void_p, c_void_p, c_void_p, c_void_p, c_void_p] lib.ocf_stats_collect_core.restype = c_int lib.ocf_core_get_info.argtypes = [c_void_p, c_void_p] From 5c053ad9649b3bcbd915942e3d884dad501731df Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Fri, 26 Feb 2021 03:36:56 -0500 Subject: [PATCH 08/17] pyocf: security test for seq cutoff threshold Signed-off-by: Michal Mielewczyk --- .../tests/security/test_management_fuzzy.py | 65 +++++++++++++++++++ 1 file changed, 65 insertions(+) diff --git a/tests/functional/tests/security/test_management_fuzzy.py b/tests/functional/tests/security/test_management_fuzzy.py index d8c5ad5..b605695 100644 --- a/tests/functional/tests/security/test_management_fuzzy.py +++ b/tests/functional/tests/security/test_management_fuzzy.py @@ -126,6 +126,71 @@ def test_neg_cache_set_seq_cut_off_policy(pyocf_ctx, cm, cls): cache.set_seq_cut_off_policy(i) +@pytest.mark.parametrize("cm", CacheMode) +@pytest.mark.parametrize("cls", CacheLineSize) +@pytest.mark.security +def test_neg_cache_set_seq_cut_off_threshold(pyocf_ctx, cm, cls): + """ + Test whether it is possible to change cache seq cut-off threshold to invalid value + :param pyocf_ctx: basic pyocf context fixture + :param cm: cache mode we start with + :param cls: cache line size we start with + :return: + """ + # Start cache device + cache_device = Volume(S.from_MiB(30)) + cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) + + # Create 2 core devices + core_device1 = Volume(S.from_MiB(10)) + core1 = Core.using_device(core_device1, name="core1") + core_device2 = Volume(S.from_MiB(10)) + core2 = Core.using_device(core_device2, name="core2") + + # Add cores + cache.add_core(core1) + cache.add_core(core2) + + # Change cache seq cut off policy to invalid one and check if failed + for i in RandomGenerator(DefaultRanges.UINT32): + if i in ConfValidValues.seq_cutoff_threshold_rage: + continue + with pytest.raises(OcfError, match="Error setting cache seq cut off policy threshold"): + cache.set_seq_cut_off_threshold(i) + print("\n" + i) + + +@pytest.mark.parametrize("cm", CacheMode) +@pytest.mark.parametrize("cls", CacheLineSize) +@pytest.mark.security +def test_neg_core_set_seq_cut_off_threshold(pyocf_ctx, cm, cls): + """ + Test whether it is possible to change core seq cut-off threshold to invalid value + :param pyocf_ctx: basic pyocf context fixture + :param cm: cache mode we start with + :param cls: cache line size we start with + :return: + """ + # Start cache device + cache_device = Volume(S.from_MiB(30)) + cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) + + # Create core device + core_device = Volume(S.from_MiB(10)) + core = Core.using_device(core_device, name="core") + + # Add core + cache.add_core(core) + + # Change core seq cut off policy to invalid one and check if failed + for i in RandomGenerator(DefaultRanges.UINT32): + if i in ConfValidValues.seq_cutoff_threshold_rage: + continue + with pytest.raises(OcfError, match="Error setting core seq cut off policy threshold"): + core.set_seq_cut_off_threshold(i) + print("\n" + i) + + @pytest.mark.parametrize("cm", CacheMode) @pytest.mark.parametrize("cls", CacheLineSize) @pytest.mark.security From 95d756de9106ac065ce30f511b7dba6567184e35 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Tue, 2 Mar 2021 09:45:04 +0100 Subject: [PATCH 09/17] Remove ioclass min_size from public API Signed-off-by: Michal Mielewczyk --- inc/ocf_mngt.h | 5 ----- src/mngt/ocf_mngt_io_class.c | 2 +- .../unit/tests/mngt/ocf_mngt_io_class.c/ocf_mngt_io_class.c | 1 - 3 files changed, 1 insertion(+), 7 deletions(-) diff --git a/inc/ocf_mngt.h b/inc/ocf_mngt.h index 49ea778..1e61690 100644 --- a/inc/ocf_mngt.h +++ b/inc/ocf_mngt.h @@ -862,11 +862,6 @@ struct ocf_mngt_io_class_config { */ ocf_cache_mode_t cache_mode; - /** - * @brief IO class minimum size - */ - uint32_t min_size; - /** * @brief IO class maximum size */ diff --git a/src/mngt/ocf_mngt_io_class.c b/src/mngt/ocf_mngt_io_class.c index c7c7b2f..e0b6d7d 100644 --- a/src/mngt/ocf_mngt_io_class.c +++ b/src/mngt/ocf_mngt_io_class.c @@ -116,7 +116,7 @@ static int _ocf_mngt_io_class_configure(ocf_cache_t cache, const char *name = cfg->name; int16_t prio = cfg->prio; ocf_cache_mode_t cache_mode = cfg->cache_mode; - uint32_t min = cfg->min_size; + uint32_t min = 0; uint32_t max = cfg->max_size; OCF_CHECK_NULL(cache->device); diff --git a/tests/unit/tests/mngt/ocf_mngt_io_class.c/ocf_mngt_io_class.c b/tests/unit/tests/mngt/ocf_mngt_io_class.c/ocf_mngt_io_class.c index db6db4c..04c0741 100644 --- a/tests/unit/tests/mngt/ocf_mngt_io_class.c/ocf_mngt_io_class.c +++ b/tests/unit/tests/mngt/ocf_mngt_io_class.c/ocf_mngt_io_class.c @@ -98,7 +98,6 @@ static inline void setup_valid_config(struct ocf_mngt_io_class_config *cfg, cfg[i].name = remove ? NULL : "test_io_class_name" ; cfg[i].prio = i; cfg[i].cache_mode = ocf_cache_mode_pt; - cfg[i].min_size = 2*i; cfg[i].max_size = 20*i; } } From 06edc48717a8e5dd3ff0503c7207a0a87daa5d9c Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Tue, 2 Mar 2021 13:12:22 +0100 Subject: [PATCH 10/17] pyocf: remove min_size from ioclass config Signed-off-by: Michal Mielewczyk --- tests/functional/pyocf/types/cache.py | 3 --- tests/functional/pyocf/types/ioclass.py | 1 - tests/functional/tests/eviction/test_eviction.py | 2 -- tests/functional/tests/management/test_attach_cache.py | 2 +- 4 files changed, 1 insertion(+), 7 deletions(-) diff --git a/tests/functional/pyocf/types/cache.py b/tests/functional/pyocf/types/cache.py index 85118e2..b17361f 100644 --- a/tests/functional/pyocf/types/cache.py +++ b/tests/functional/pyocf/types/cache.py @@ -357,7 +357,6 @@ class Cache: self, part_id: int, name: str, - min_size: int, max_size: int, priority: int, cache_mode=CACHE_MODE_NONE, @@ -379,7 +378,6 @@ class Cache: ) ioclasses_info._config[i]._prio = ioclass_info._priority ioclasses_info._config[i]._cache_mode = ioclass_info._cache_mode - ioclasses_info._config[i]._min_size = ioclass_info._min_size ioclasses_info._config[i]._max_size = ioclass_info._max_size self.read_unlock() @@ -387,7 +385,6 @@ class Cache: ioclasses_info._config[part_id]._name = name.encode("ascii") ioclasses_info._config[part_id]._cache_mode = int(cache_mode) ioclasses_info._config[part_id]._prio = priority - ioclasses_info._config[part_id]._min_size = min_size ioclasses_info._config[part_id]._max_size = max_size self.write_lock() diff --git a/tests/functional/pyocf/types/ioclass.py b/tests/functional/pyocf/types/ioclass.py index a4fd3fb..e5bafdb 100644 --- a/tests/functional/pyocf/types/ioclass.py +++ b/tests/functional/pyocf/types/ioclass.py @@ -26,7 +26,6 @@ class IoClassConfig(Structure): ("_name", c_char_p), ("_prio", c_uint16), ("_cache_mode", c_int), - ("_min_size", c_uint32), ("_max_size", c_uint32), ] diff --git a/tests/functional/tests/eviction/test_eviction.py b/tests/functional/tests/eviction/test_eviction.py index 7a004c9..6cb7232 100644 --- a/tests/functional/tests/eviction/test_eviction.py +++ b/tests/functional/tests/eviction/test_eviction.py @@ -93,14 +93,12 @@ def test_evict_overflown_pinned(pyocf_ctx, cls: CacheLineSize): cache.configure_partition( part_id=test_ioclass_id, name="default_ioclass", - min_size=0, max_size=100, priority=1, ) cache.configure_partition( part_id=pinned_ioclass_id, name="pinned_ioclass", - min_size=0, max_size=pinned_ioclass_max_occupancy, priority=-1, ) diff --git a/tests/functional/tests/management/test_attach_cache.py b/tests/functional/tests/management/test_attach_cache.py index b901179..56557a3 100644 --- a/tests/functional/tests/management/test_attach_cache.py +++ b/tests/functional/tests/management/test_attach_cache.py @@ -51,7 +51,7 @@ def test_attach_different_size( cache.add_core(core) cache.configure_partition( - part_id=1, name="test_part", min_size=0, max_size=50, priority=1 + part_id=1, name="test_part", max_size=50, priority=1 ) cache.set_seq_cut_off_policy(SeqCutOffPolicy.NEVER) From f1012b020bcb122c02e7cd758a747aa7b2260a64 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Fri, 26 Feb 2021 07:30:17 -0500 Subject: [PATCH 11/17] Validate ioclass config Signed-off-by: Michal Mielewczyk --- src/metadata/metadata_partition.h | 1 + src/mngt/ocf_mngt_io_class.c | 7 +++++++ 2 files changed, 8 insertions(+) diff --git a/src/metadata/metadata_partition.h b/src/metadata/metadata_partition.h index d38acd0..f9ae453 100644 --- a/src/metadata/metadata_partition.h +++ b/src/metadata/metadata_partition.h @@ -11,6 +11,7 @@ #define PARTITION_DEFAULT 0 #define PARTITION_INVALID ((ocf_part_id_t)-1) +#define PARTITION_SIZE_MIN 0 #define PARTITION_SIZE_MAX 100 void ocf_metadata_get_partition_info( diff --git a/src/mngt/ocf_mngt_io_class.c b/src/mngt/ocf_mngt_io_class.c index e0b6d7d..e348551 100644 --- a/src/mngt/ocf_mngt_io_class.c +++ b/src/mngt/ocf_mngt_io_class.c @@ -256,6 +256,13 @@ static int _ocf_mngt_io_class_validate_cfg(ocf_cache_t cache, return -OCF_ERR_INVAL; } + if (cfg->max_size < PARTITION_SIZE_MIN || + cfg->max_size > PARTITION_SIZE_MAX) { + ocf_cache_log(cache, log_info, + "Invalid value of the partition max size\n"); + return -OCF_ERR_INVAL; + } + return 0; } From 080e13a071157c043068fec4b343c36041cf9cc8 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Fri, 26 Feb 2021 07:31:43 -0500 Subject: [PATCH 12/17] pyocf: valid ranges for ioclass config values Signed-off-by: Michal Mielewczyk --- tests/functional/pyocf/types/cache.py | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/tests/functional/pyocf/types/cache.py b/tests/functional/pyocf/types/cache.py index b17361f..c065e48 100644 --- a/tests/functional/pyocf/types/cache.py +++ b/tests/functional/pyocf/types/cache.py @@ -86,6 +86,11 @@ class ConfValidValues: seq_cutoff_threshold_rage = range(1, 4194181) + ioclass_id_range = range(0, 32) + ioclass_priority_range = range(-1, 255) + ioclass_min_size_range = range(0, 100) + ioclass_max_size_range = range(0, 100) + CACHE_MODE_NONE = -1 From fa556247d795b960f15a27fd4cdfe37f0098af04 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Fri, 26 Feb 2021 07:32:47 -0500 Subject: [PATCH 13/17] pyocf: change encoding of ioclass name Signed-off-by: Michal Mielewczyk --- tests/functional/pyocf/types/cache.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/functional/pyocf/types/cache.py b/tests/functional/pyocf/types/cache.py index c065e48..b018574 100644 --- a/tests/functional/pyocf/types/cache.py +++ b/tests/functional/pyocf/types/cache.py @@ -387,7 +387,7 @@ class Cache: self.read_unlock() - ioclasses_info._config[part_id]._name = name.encode("ascii") + ioclasses_info._config[part_id]._name = name.encode("utf-8") ioclasses_info._config[part_id]._cache_mode = int(cache_mode) ioclasses_info._config[part_id]._prio = priority ioclasses_info._config[part_id]._max_size = max_size From c4a2dc4cadb7965c6717240fd8e4eb6d8b5e974e Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Fri, 26 Feb 2021 07:36:05 -0500 Subject: [PATCH 14/17] pyocf: security tests for ioclass api Signed-off-by: Michal Mielewczyk --- .../tests/security/test_management_fuzzy.py | 138 +++++++++++++++++- 1 file changed, 137 insertions(+), 1 deletion(-) diff --git a/tests/functional/tests/security/test_management_fuzzy.py b/tests/functional/tests/security/test_management_fuzzy.py index b605695..bfbbdde 100644 --- a/tests/functional/tests/security/test_management_fuzzy.py +++ b/tests/functional/tests/security/test_management_fuzzy.py @@ -4,10 +4,12 @@ # import pytest +import string from pyocf.types.cache import ( Cache, CacheMode, + CACHE_MODE_NONE, CleaningPolicy, AlruParams, AcpParams, @@ -18,7 +20,7 @@ from pyocf.types.cache import ( from pyocf.types.core import Core from pyocf.types.volume import Volume from pyocf.utils import Size as S -from tests.utils.random import RandomGenerator, DefaultRanges +from tests.utils.random import Range, RandomGenerator, DefaultRanges, RandomStringGenerator from pyocf.types.shared import OcfError, CacheLineSize, SeqCutOffPolicy from ctypes import c_uint64, c_uint32, c_uint8 @@ -454,3 +456,137 @@ def test_neg_set_nhit_promotion_policy_param_threshold(pyocf_ctx, cm, cls): cache.set_promotion_policy_param( PromotionPolicy.NHIT, NhitParams.INSERTION_THRESHOLD, i ) + + +@pytest.mark.parametrize("cm", CacheMode) +@pytest.mark.parametrize("cls", CacheLineSize) +@pytest.mark.security +def test_neg_set_ioclass_max_size(pyocf_ctx, cm, cls): + """ + Test whether it is possible to add ioclass with invaild max size + :param pyocf_ctx: basic pyocf context fixture + :param cm: cache mode we start with + :param cls: cache line size we start with + :return: + """ + # Start cache device + cache_device = Volume(S.from_MiB(30)) + cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) + + # Set invalid max size and check if failed + for i in RandomGenerator(DefaultRanges.UINT32): + if i in ConfValidValues.ioclass_max_size_range: + continue + with pytest.raises(OcfError, match="Error adding partition to cache"): + cache.configure_partition( + part_id=1, + name="unclassified", + max_size=i, + priority=0, + cache_mode=CACHE_MODE_NONE, + ) + print("\n" + i) + + +@pytest.mark.parametrize("cm", CacheMode) +@pytest.mark.parametrize("cls", CacheLineSize) +@pytest.mark.security +def test_neg_set_ioclass_priority(pyocf_ctx, cm, cls): + """ + Test whether it is possible to add ioclass with invaild priority + :param pyocf_ctx: basic pyocf context fixture + :param cm: cache mode we start with + :param cls: cache line size we start with + :return: + """ + # Start cache device + cache_device = Volume(S.from_MiB(30)) + cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) + + # Set invalid priority and check if failed + for i in RandomGenerator(DefaultRanges.INT16): + if i in ConfValidValues.ioclass_priority_range: + continue + with pytest.raises(OcfError, match="Error adding partition to cache"): + cache.configure_partition( + part_id=1, + name="unclassified", + max_size=100, + priority=i, + cache_mode=CACHE_MODE_NONE, + ) + print("\n" + i) + + +@pytest.mark.parametrize("cm", CacheMode) +@pytest.mark.parametrize("cls", CacheLineSize) +@pytest.mark.security +def test_neg_set_ioclass_cache_mode(pyocf_ctx, cm, cls): + """ + Test whether it is possible to add ioclass with invaild cache mode + :param pyocf_ctx: basic pyocf context fixture + :param cm: cache mode we start with + :param cls: cache line size we start with + :return: + """ + # Start cache device + cache_device = Volume(S.from_MiB(30)) + cache = Cache.start_on_device(cache_device, cache_mode=cm, cache_line_size=cls) + + # Set invalid cache mode and check if failed + for i in RandomGenerator(DefaultRanges.INT): + if i in list(CacheMode) + [CACHE_MODE_NONE]: + continue + with pytest.raises(OcfError, match="Error adding partition to cache"): + cache.configure_partition( + part_id=1, name="unclassified", max_size=100, priority=1, cache_mode=i + ) + print("\n" + i) + + +@pytest.mark.security +def test_neg_set_ioclass_name(pyocf_ctx): + """ + Test whether it is possible to add ioclass with invaild name + :param pyocf_ctx: basic pyocf context fixture + :return: + """ + invalid_chars = [chr(c) for c in range(256) if chr(c) not in string.printable] + invalid_chars += [",", '"'] + + # Start cache device + cache_device = Volume(S.from_MiB(30)) + cache = Cache.start_on_device( + cache_device, cache_mode=CacheMode.WT, cache_line_size=CacheLineSize.LINE_4KiB + ) + + # Set invalid name and check if failed + for name in RandomStringGenerator( + len_range=Range(0, 1024), count=10000, extra_chars=invalid_chars + ): + if not any(c for c in invalid_chars if c in name): + continue + with pytest.raises(OcfError, match="Error adding partition to cache"): + cache.configure_partition(part_id=1, name=name, max_size=100, priority=1) + print(f"\n{name}") + + +@pytest.mark.security +def test_neg_set_ioclass_name_len(pyocf_ctx): + """ + Test whether it is possible to add ioclass with too long name + :param pyocf_ctx: basic pyocf context fixture + :return: + """ + + # Start cache device + cache_device = Volume(S.from_MiB(30)) + cache = Cache.start_on_device( + cache_device, cache_mode=CacheMode.WT, cache_line_size=CacheLineSize.LINE_4KiB + ) + + # Set invalid name and check if failed + for name in RandomStringGenerator(len_range=Range(1025, 4096), count=10000): + with pytest.raises(OcfError, match="Error adding partition to cache"): + cache.configure_partition(part_id=1, name=name, max_size=100, priority=1) + print(f"\n{name}") From a81be31dd42a3cb9c7393a2cb5288bb2c69d9d3f Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Fri, 26 Feb 2021 07:39:45 -0500 Subject: [PATCH 15/17] pyocf: default range for int16 Signed-off-by: Michal Mielewczyk --- tests/functional/tests/utils/random.py | 1 + 1 file changed, 1 insertion(+) diff --git a/tests/functional/tests/utils/random.py b/tests/functional/tests/utils/random.py index 9d642d2..d16b163 100644 --- a/tests/functional/tests/utils/random.py +++ b/tests/functional/tests/utils/random.py @@ -28,6 +28,7 @@ class Range: class DefaultRanges(Range, enum.Enum): UINT8 = 0, c_uint8(-1).value + INT16 = int(-c_uint16(-1).value / 2) - 1, int(c_uint16(-1).value / 2) UINT16 = 0, c_uint16(-1).value UINT32 = 0, c_uint32(-1).value UINT64 = 0, c_uint64(-1).value From 7f862c30804159838a35b048915f41d50fe7ad28 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Tue, 2 Mar 2021 13:52:40 +0100 Subject: [PATCH 16/17] pyocf: improve random string generator Set of random characters may be exteded with a custom list. Signed-off-by: Michal Mielewczyk --- tests/functional/tests/utils/random.py | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/tests/functional/tests/utils/random.py b/tests/functional/tests/utils/random.py index d16b163..1d4d2f2 100644 --- a/tests/functional/tests/utils/random.py +++ b/tests/functional/tests/utils/random.py @@ -66,14 +66,14 @@ class RandomGenerator: class RandomStringGenerator: - def __init__(self, len_range=Range(0, 20), count=700): + def __init__(self, len_range=Range(0, 20), count=700, extra_chars=[]): with open("config/random.cfg") as f: self.random = random.Random(int(f.read())) - self.generator = self.__string_generator(len_range) + self.generator = self.__string_generator(len_range, extra_chars) self.count = count self.n = 0 - def __string_generator(self, len_range): + def __string_generator(self, len_range, extra_chars): while True: for t in [string.digits, string.ascii_letters + string.digits, @@ -81,7 +81,8 @@ class RandomStringGenerator: string.ascii_uppercase, string.printable, string.punctuation, - string.hexdigits]: + string.hexdigits, + *extra_chars]: yield ''.join(random.choice(t) for _ in range( self.random.randint(len_range.min, len_range.max) )) From 3a26bc56cda3d9ed17bb0a4beefd577760e42431 Mon Sep 17 00:00:00 2001 From: Michal Mielewczyk Date: Tue, 2 Mar 2021 13:54:38 +0100 Subject: [PATCH 17/17] pyocf: improve test logging Signed-off-by: Michal Mielewczyk --- .../tests/security/test_management_fuzzy.py | 25 +++++++++++++------ 1 file changed, 18 insertions(+), 7 deletions(-) diff --git a/tests/functional/tests/security/test_management_fuzzy.py b/tests/functional/tests/security/test_management_fuzzy.py index bfbbdde..b9c884f 100644 --- a/tests/functional/tests/security/test_management_fuzzy.py +++ b/tests/functional/tests/security/test_management_fuzzy.py @@ -45,6 +45,7 @@ def test_neg_change_cache_mode(pyocf_ctx, cm, cls): continue with pytest.raises(OcfError, match="Error changing cache mode"): cache.change_cache_mode(i) + print(f"\n{i}") @pytest.mark.parametrize("cm", CacheMode) @@ -68,6 +69,7 @@ def test_neg_set_cleaning_policy(pyocf_ctx, cm, cls): continue with pytest.raises(OcfError, match="Error changing cleaning policy"): cache.set_cleaning_policy(i) + print(f"\n{i}") @pytest.mark.parametrize("cm", CacheMode) @@ -93,6 +95,7 @@ def test_neg_attach_cls(pyocf_ctx, cm, cls): continue with pytest.raises(OcfError, match="Attaching cache device failed"): cache.attach_device(cache_device, cache_line_size=i) + print(f"\n{i}") @pytest.mark.parametrize("cm", CacheMode) @@ -126,6 +129,7 @@ def test_neg_cache_set_seq_cut_off_policy(pyocf_ctx, cm, cls): continue with pytest.raises(OcfError, match="Error setting cache seq cut off policy"): cache.set_seq_cut_off_policy(i) + print(f"\n{i}") @pytest.mark.parametrize("cm", CacheMode) @@ -159,7 +163,7 @@ def test_neg_cache_set_seq_cut_off_threshold(pyocf_ctx, cm, cls): continue with pytest.raises(OcfError, match="Error setting cache seq cut off policy threshold"): cache.set_seq_cut_off_threshold(i) - print("\n" + i) + print(f"\n{i}") @pytest.mark.parametrize("cm", CacheMode) @@ -190,7 +194,7 @@ def test_neg_core_set_seq_cut_off_threshold(pyocf_ctx, cm, cls): continue with pytest.raises(OcfError, match="Error setting core seq cut off policy threshold"): core.set_seq_cut_off_threshold(i) - print("\n" + i) + print(f"\n{i}") @pytest.mark.parametrize("cm", CacheMode) @@ -221,6 +225,7 @@ def test_neg_core_set_seq_cut_off_policy(pyocf_ctx, cm, cls): continue with pytest.raises(OcfError, match="Error setting core seq cut off policy"): core.set_seq_cut_off_policy(i) + print(f"\n{i}") @pytest.mark.parametrize("cm", CacheMode) @@ -244,6 +249,7 @@ def test_neg_set_alru_param(pyocf_ctx, cm, cls): continue with pytest.raises(OcfError, match="Error setting cleaning policy param"): cache.set_cleaning_policy_param(CleaningPolicy.ALRU, i, 1) + print(f"\n{i}") def get_alru_param_valid_rage(param_id): @@ -283,7 +289,7 @@ def test_neg_set_alru_param_value(pyocf_ctx, cm, cls, param): continue with pytest.raises(OcfError, match="Error setting cleaning policy param"): cache.set_cleaning_policy_param(CleaningPolicy.ALRU, param, i) - print("\n" + i) + print(f"\n{i}") @pytest.mark.parametrize("cm", CacheMode) @@ -307,6 +313,7 @@ def test_neg_set_acp_param(pyocf_ctx, cm, cls): continue with pytest.raises(OcfError, match="Error setting cleaning policy param"): cache.set_cleaning_policy_param(CleaningPolicy.ACP, i, 1) + print(f"\n{i}") def get_acp_param_valid_rage(param_id): @@ -342,7 +349,7 @@ def test_neg_set_acp_param_value(pyocf_ctx, cm, cls, param): continue with pytest.raises(OcfError, match="Error setting cleaning policy param"): cache.set_cleaning_policy_param(CleaningPolicy.ACP, param, i) - print("\n" + i) + print(f"\n{i}") @pytest.mark.parametrize("cm", CacheMode) @@ -366,6 +373,7 @@ def test_neg_set_promotion_policy(pyocf_ctx, cm, cls): continue with pytest.raises(OcfError, match="Error setting promotion policy"): cache.set_promotion_policy(i) + print(f"\n{i}") @pytest.mark.parametrize("cm", CacheMode) @@ -394,6 +402,7 @@ def test_neg_set_nhit_promotion_policy_param(pyocf_ctx, cm, cls): continue with pytest.raises(OcfError, match="Error setting promotion policy parameter"): cache.set_promotion_policy_param(PromotionPolicy.NHIT, i, 1) + print(f"\n{i}") @pytest.mark.parametrize("cm", CacheMode) @@ -425,6 +434,7 @@ def test_neg_set_nhit_promotion_policy_param_trigger(pyocf_ctx, cm, cls): cache.set_promotion_policy_param( PromotionPolicy.NHIT, NhitParams.TRIGGER_THRESHOLD, i ) + print(f"\n{i}") @pytest.mark.parametrize("cm", CacheMode) @@ -456,6 +466,7 @@ def test_neg_set_nhit_promotion_policy_param_threshold(pyocf_ctx, cm, cls): cache.set_promotion_policy_param( PromotionPolicy.NHIT, NhitParams.INSERTION_THRESHOLD, i ) + print(f"\n{i}") @pytest.mark.parametrize("cm", CacheMode) @@ -485,7 +496,7 @@ def test_neg_set_ioclass_max_size(pyocf_ctx, cm, cls): priority=0, cache_mode=CACHE_MODE_NONE, ) - print("\n" + i) + print(f"\n{i}") @pytest.mark.parametrize("cm", CacheMode) @@ -515,7 +526,7 @@ def test_neg_set_ioclass_priority(pyocf_ctx, cm, cls): priority=i, cache_mode=CACHE_MODE_NONE, ) - print("\n" + i) + print(f"\n{i}") @pytest.mark.parametrize("cm", CacheMode) @@ -541,7 +552,7 @@ def test_neg_set_ioclass_cache_mode(pyocf_ctx, cm, cls): cache.configure_partition( part_id=1, name="unclassified", max_size=100, priority=1, cache_mode=i ) - print("\n" + i) + print(f"\n{i}") @pytest.mark.security