Merge pull request #312 from robertbaldyga/rand-generator-improvements
Rand generator improvements
This commit is contained in:
commit
17ec78d88f
@ -18,7 +18,7 @@ SRC=$(shell find $(SRCDIR) $(WRAPDIR) -name \*.c)
|
|||||||
OBJS=$(patsubst %.c, %.o, $(SRC))
|
OBJS=$(patsubst %.c, %.o, $(SRC))
|
||||||
OCFLIB=$(ADAPTERDIR)/libocf.so
|
OCFLIB=$(ADAPTERDIR)/libocf.so
|
||||||
|
|
||||||
all: | sync
|
all: | sync config_random
|
||||||
$(MAKE) $(OCFLIB)
|
$(MAKE) $(OCFLIB)
|
||||||
|
|
||||||
$(OCFLIB): $(OBJS)
|
$(OCFLIB): $(OBJS)
|
||||||
@ -36,6 +36,9 @@ sync:
|
|||||||
@$(MAKE) -C $(OCFDIR) src O=$(ADAPTERDIR)/ocf
|
@$(MAKE) -C $(OCFDIR) src O=$(ADAPTERDIR)/ocf
|
||||||
@$(MAKE) -C $(OCFDIR) env O=$(ADAPTERDIR)/ocf OCF_ENV=posix
|
@$(MAKE) -C $(OCFDIR) env O=$(ADAPTERDIR)/ocf OCF_ENV=posix
|
||||||
|
|
||||||
|
config_random:
|
||||||
|
@python3 utils/configure_random.py
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@rm -rf $(OCFLIB) $(OBJS)
|
@rm -rf $(OCFLIB) $(OBJS)
|
||||||
@echo " CLEAN "
|
@echo " CLEAN "
|
||||||
@ -46,4 +49,4 @@ distclean: clean
|
|||||||
@rm -rf $(INCDIR)/ocf
|
@rm -rf $(INCDIR)/ocf
|
||||||
@echo " DISTCLEAN "
|
@echo " DISTCLEAN "
|
||||||
|
|
||||||
.PHONY: all clean sync distclean
|
.PHONY: all clean sync config_random distclean
|
||||||
|
2
tests/functional/config/random.cfg
Normal file
2
tests/functional/config/random.cfg
Normal file
@ -0,0 +1,2 @@
|
|||||||
|
# This file content will be generated by utils/configure_random.py
|
||||||
|
# triggered from the Makefile
|
@ -11,13 +11,28 @@ from ctypes import (
|
|||||||
c_uint16,
|
c_uint16,
|
||||||
c_int
|
c_int
|
||||||
)
|
)
|
||||||
from tests.utils.random import RandomStringGenerator, RandomGenerator, DefaultRanges
|
from tests.utils.random import RandomStringGenerator, RandomGenerator, DefaultRanges, Range
|
||||||
|
|
||||||
|
from pyocf.types.cache import CacheMode, EvictionPolicy, MetadataLayout, PromotionPolicy
|
||||||
|
from pyocf.types.shared import CacheLineSize
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
sys.path.append(os.path.join(os.path.dirname(__file__), os.path.pardir))
|
sys.path.append(os.path.join(os.path.dirname(__file__), os.path.pardir))
|
||||||
|
|
||||||
|
|
||||||
|
def enum_min(enum):
|
||||||
|
return list(enum)[0].value
|
||||||
|
|
||||||
|
|
||||||
|
def enum_max(enum):
|
||||||
|
return list(enum)[-1].value
|
||||||
|
|
||||||
|
|
||||||
|
def enum_range(enum):
|
||||||
|
return Range(enum_min(enum), enum_max(enum))
|
||||||
|
|
||||||
|
|
||||||
@pytest.fixture(params=RandomGenerator(DefaultRanges.UINT16))
|
@pytest.fixture(params=RandomGenerator(DefaultRanges.UINT16))
|
||||||
def c_uint16_randomize(request):
|
def c_uint16_randomize(request):
|
||||||
return request.param
|
return request.param
|
||||||
@ -46,3 +61,38 @@ def c_int_sector_randomize(request):
|
|||||||
@pytest.fixture(params=RandomStringGenerator())
|
@pytest.fixture(params=RandomStringGenerator())
|
||||||
def string_randomize(request):
|
def string_randomize(request):
|
||||||
return request.param
|
return request.param
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(
|
||||||
|
params=RandomGenerator(DefaultRanges.UINT32).exclude_range(enum_range(CacheMode))
|
||||||
|
)
|
||||||
|
def not_cache_mode_randomize(request):
|
||||||
|
return request.param
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(
|
||||||
|
params=RandomGenerator(DefaultRanges.UINT32).exclude_range(enum_range(CacheLineSize))
|
||||||
|
)
|
||||||
|
def not_cache_line_size_randomize(request):
|
||||||
|
return request.param
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(
|
||||||
|
params=RandomGenerator(DefaultRanges.UINT32).exclude_range(enum_range(EvictionPolicy))
|
||||||
|
)
|
||||||
|
def not_eviction_policy_randomize(request):
|
||||||
|
return request.param
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(
|
||||||
|
params=RandomGenerator(DefaultRanges.UINT32).exclude_range(enum_range(PromotionPolicy))
|
||||||
|
)
|
||||||
|
def not_promotion_policy_randomize(request):
|
||||||
|
return request.param
|
||||||
|
|
||||||
|
|
||||||
|
@pytest.fixture(
|
||||||
|
params=RandomGenerator(DefaultRanges.UINT32).exclude_range(enum_range(MetadataLayout))
|
||||||
|
)
|
||||||
|
def not_metadata_layout_randomize(request):
|
||||||
|
return request.param
|
||||||
|
@ -11,7 +11,7 @@ from pyocf.types.cache import Cache, CacheMode, EvictionPolicy, MetadataLayout,
|
|||||||
from pyocf.types.shared import OcfError, CacheLineSize
|
from pyocf.types.shared import OcfError, CacheLineSize
|
||||||
from pyocf.types.volume import Volume
|
from pyocf.types.volume import Volume
|
||||||
from pyocf.utils import Size
|
from pyocf.utils import Size
|
||||||
from tests.utils.random import RandomGenerator, DefaultRanges
|
from tests.utils.random import RandomGenerator, DefaultRanges, Range
|
||||||
|
|
||||||
logger = logging.getLogger(__name__)
|
logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
@ -21,38 +21,30 @@ def try_start_cache(**config):
|
|||||||
cache = Cache.start_on_device(cache_device, **config)
|
cache = Cache.start_on_device(cache_device, **config)
|
||||||
cache.stop()
|
cache.stop()
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.security
|
@pytest.mark.security
|
||||||
@pytest.mark.parametrize("cls", CacheLineSize)
|
@pytest.mark.parametrize("cls", CacheLineSize)
|
||||||
def test_fuzzy_start_cache_mode(pyocf_ctx, cls, c_uint32_randomize):
|
def test_fuzzy_start_cache_mode(pyocf_ctx, cls, not_cache_mode_randomize):
|
||||||
"""
|
"""
|
||||||
Test whether it is impossible to start cache with invalid cache mode value.
|
Test whether it is impossible to start cache with invalid cache mode value.
|
||||||
:param pyocf_ctx: basic pyocf context fixture
|
:param pyocf_ctx: basic pyocf context fixture
|
||||||
:param cls: cache line size value to start cache with
|
:param cls: cache line size value to start cache with
|
||||||
:param c_uint32_randomize: cache mode enum value to start cache with
|
:param c_uint32_randomize: cache mode enum value to start cache with
|
||||||
"""
|
"""
|
||||||
if c_uint32_randomize not in [item.value for item in CacheMode]:
|
|
||||||
with pytest.raises(OcfError, match="OCF_ERR_INVALID_CACHE_MODE"):
|
with pytest.raises(OcfError, match="OCF_ERR_INVALID_CACHE_MODE"):
|
||||||
try_start_cache(cache_mode=c_uint32_randomize, cache_line_size=cls)
|
try_start_cache(cache_mode=not_cache_mode_randomize, cache_line_size=cls)
|
||||||
else:
|
|
||||||
logger.warning(f"Test skipped for valid cache mode enum value: '{c_uint32_randomize}'. ")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.security
|
@pytest.mark.security
|
||||||
@pytest.mark.parametrize("cm", CacheMode)
|
@pytest.mark.parametrize("cm", CacheMode)
|
||||||
def test_fuzzy_start_cache_line_size(pyocf_ctx, c_uint64_randomize, cm):
|
def test_fuzzy_start_cache_line_size(pyocf_ctx, not_cache_line_size_randomize, cm):
|
||||||
"""
|
"""
|
||||||
Test whether it is impossible to start cache with invalid cache line size value.
|
Test whether it is impossible to start cache with invalid cache line size value.
|
||||||
:param pyocf_ctx: basic pyocf context fixture
|
:param pyocf_ctx: basic pyocf context fixture
|
||||||
:param c_uint64_randomize: cache line size enum value to start cache with
|
:param c_uint64_randomize: cache line size enum value to start cache with
|
||||||
:param cm: cache mode value to start cache with
|
:param cm: cache mode value to start cache with
|
||||||
"""
|
"""
|
||||||
if c_uint64_randomize not in [item.value for item in CacheLineSize]:
|
|
||||||
with pytest.raises(OcfError, match="OCF_ERR_INVALID_CACHE_LINE_SIZE"):
|
with pytest.raises(OcfError, match="OCF_ERR_INVALID_CACHE_LINE_SIZE"):
|
||||||
try_start_cache(cache_mode=cm, cache_line_size=c_uint64_randomize)
|
try_start_cache(cache_mode=cm, cache_line_size=not_cache_line_size_randomize)
|
||||||
else:
|
|
||||||
logger.warning(
|
|
||||||
f"Test skipped for valid cache line size enum value: '{c_uint64_randomize}'. ")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.security
|
@pytest.mark.security
|
||||||
@ -84,7 +76,7 @@ def test_fuzzy_start_name(pyocf_ctx, string_randomize, cm, cls):
|
|||||||
@pytest.mark.security
|
@pytest.mark.security
|
||||||
@pytest.mark.parametrize("cm", CacheMode)
|
@pytest.mark.parametrize("cm", CacheMode)
|
||||||
@pytest.mark.parametrize("cls", CacheLineSize)
|
@pytest.mark.parametrize("cls", CacheLineSize)
|
||||||
def test_fuzzy_start_eviction_policy(pyocf_ctx, c_uint32_randomize, cm, cls):
|
def test_fuzzy_start_eviction_policy(pyocf_ctx, not_eviction_policy_randomize, cm, cls):
|
||||||
"""
|
"""
|
||||||
Test whether it is impossible to start cache with invalid eviction policy value.
|
Test whether it is impossible to start cache with invalid eviction policy value.
|
||||||
:param pyocf_ctx: basic pyocf context fixture
|
:param pyocf_ctx: basic pyocf context fixture
|
||||||
@ -92,18 +84,18 @@ def test_fuzzy_start_eviction_policy(pyocf_ctx, c_uint32_randomize, cm, cls):
|
|||||||
:param cm: cache mode value to start cache with
|
:param cm: cache mode value to start cache with
|
||||||
:param cls: cache line size value to start cache with
|
:param cls: cache line size value to start cache with
|
||||||
"""
|
"""
|
||||||
if c_uint32_randomize not in [item.value for item in EvictionPolicy]:
|
|
||||||
with pytest.raises(OcfError, match="OCF_ERR_INVAL"):
|
with pytest.raises(OcfError, match="OCF_ERR_INVAL"):
|
||||||
try_start_cache(eviction_policy=c_uint32_randomize, cache_mode=cm, cache_line_size=cls)
|
try_start_cache(
|
||||||
else:
|
eviction_policy=not_eviction_policy_randomize,
|
||||||
logger.warning(
|
cache_mode=cm,
|
||||||
f"Test skipped for valid eviction policy enum value: '{c_uint32_randomize}'. ")
|
cache_line_size=cls
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.security
|
@pytest.mark.security
|
||||||
@pytest.mark.parametrize("cm", CacheMode)
|
@pytest.mark.parametrize("cm", CacheMode)
|
||||||
@pytest.mark.parametrize("cls", CacheLineSize)
|
@pytest.mark.parametrize("cls", CacheLineSize)
|
||||||
def test_fuzzy_start_metadata_layout(pyocf_ctx, c_uint32_randomize, cm, cls):
|
def test_fuzzy_start_metadata_layout(pyocf_ctx, not_metadata_layout_randomize, cm, cls):
|
||||||
"""
|
"""
|
||||||
Test whether it is impossible to start cache with invalid metadata layout value.
|
Test whether it is impossible to start cache with invalid metadata layout value.
|
||||||
:param pyocf_ctx: basic pyocf context fixture
|
:param pyocf_ctx: basic pyocf context fixture
|
||||||
@ -111,12 +103,12 @@ def test_fuzzy_start_metadata_layout(pyocf_ctx, c_uint32_randomize, cm, cls):
|
|||||||
:param cm: cache mode value to start cache with
|
:param cm: cache mode value to start cache with
|
||||||
:param cls: cache line size value to start cache with
|
:param cls: cache line size value to start cache with
|
||||||
"""
|
"""
|
||||||
if c_uint32_randomize not in [item.value for item in MetadataLayout]:
|
|
||||||
with pytest.raises(OcfError, match="OCF_ERR_INVAL"):
|
with pytest.raises(OcfError, match="OCF_ERR_INVAL"):
|
||||||
try_start_cache(metadata_layout=c_uint32_randomize, cache_mode=cm, cache_line_size=cls)
|
try_start_cache(
|
||||||
else:
|
metadata_layout=not_metadata_layout_randomize,
|
||||||
logger.warning(
|
cache_mode=cm,
|
||||||
f"Test skipped for valid metadata layout enum value: '{c_uint32_randomize}'. ")
|
cache_line_size=cls
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.security
|
@pytest.mark.security
|
||||||
@ -131,23 +123,18 @@ def test_fuzzy_start_max_queue_size(pyocf_ctx, max_wb_queue_size, c_uint32_rando
|
|||||||
:param c_uint32_randomize: queue unblock size value to start cache with
|
:param c_uint32_randomize: queue unblock size value to start cache with
|
||||||
:param cls: cache line size value to start cache with
|
:param cls: cache line size value to start cache with
|
||||||
"""
|
"""
|
||||||
if c_uint32_randomize >= max_wb_queue_size:
|
|
||||||
with pytest.raises(OcfError, match="OCF_ERR_INVAL"):
|
with pytest.raises(OcfError, match="OCF_ERR_INVAL"):
|
||||||
try_start_cache(
|
try_start_cache(
|
||||||
max_queue_size=max_wb_queue_size,
|
max_queue_size=max_wb_queue_size,
|
||||||
queue_unblock_size=c_uint32_randomize,
|
queue_unblock_size=max_wb_queue_size + c_uint32_randomize,
|
||||||
cache_mode=CacheMode.WB,
|
cache_mode=CacheMode.WB,
|
||||||
cache_line_size=cls)
|
cache_line_size=cls)
|
||||||
else:
|
|
||||||
logger.warning(f"Test skipped for valid values: "
|
|
||||||
f"'max_queue_size={max_wb_queue_size}, "
|
|
||||||
f"queue_unblock_size={c_uint32_randomize}'.")
|
|
||||||
|
|
||||||
|
|
||||||
@pytest.mark.security
|
@pytest.mark.security
|
||||||
@pytest.mark.parametrize("cm", CacheMode)
|
@pytest.mark.parametrize("cm", CacheMode)
|
||||||
@pytest.mark.parametrize("cls", CacheLineSize)
|
@pytest.mark.parametrize("cls", CacheLineSize)
|
||||||
def test_fuzzy_start_promotion_policy(pyocf_ctx, c_uint32_randomize, cm, cls):
|
def test_fuzzy_start_promotion_policy(pyocf_ctx, not_promotion_policy_randomize, cm, cls):
|
||||||
"""
|
"""
|
||||||
Test whether it is impossible to start cache with invalid promotion policy
|
Test whether it is impossible to start cache with invalid promotion policy
|
||||||
:param pyocf_ctx: basic pyocf context fixture
|
:param pyocf_ctx: basic pyocf context fixture
|
||||||
@ -155,9 +142,9 @@ def test_fuzzy_start_promotion_policy(pyocf_ctx, c_uint32_randomize, cm, cls):
|
|||||||
:param cm: cache mode value to start cache with
|
:param cm: cache mode value to start cache with
|
||||||
:param cls: cache line size to start cache with
|
:param cls: cache line size to start cache with
|
||||||
"""
|
"""
|
||||||
if c_uint32_randomize not in [item.value for item in PromotionPolicy]:
|
|
||||||
with pytest.raises(OcfError, match="OCF_ERR_INVAL"):
|
with pytest.raises(OcfError, match="OCF_ERR_INVAL"):
|
||||||
try_start_cache(cache_mode=cm, cache_line_size=cls, promotion_policy=c_uint32_randomize)
|
try_start_cache(
|
||||||
else:
|
cache_mode=cm,
|
||||||
logger.warning(
|
cache_line_size=cls,
|
||||||
f"Test skipped for valid promotion policy: '{c_uint32_randomize}'. ")
|
promotion_policy=not_promotion_policy_randomize
|
||||||
|
)
|
||||||
|
@ -36,6 +36,8 @@ class DefaultRanges(Range, enum.Enum):
|
|||||||
|
|
||||||
class RandomGenerator:
|
class RandomGenerator:
|
||||||
def __init__(self, base_range=DefaultRanges.INT, count=1000):
|
def __init__(self, base_range=DefaultRanges.INT, count=1000):
|
||||||
|
with open("config/random.cfg") as f:
|
||||||
|
self.random = random.Random(int(f.read()))
|
||||||
self.exclude = []
|
self.exclude = []
|
||||||
self.range = base_range
|
self.range = base_range
|
||||||
self.count = count
|
self.count = count
|
||||||
@ -43,6 +45,7 @@ class RandomGenerator:
|
|||||||
|
|
||||||
def exclude_range(self, excl_range):
|
def exclude_range(self, excl_range):
|
||||||
self.exclude.append(excl_range)
|
self.exclude.append(excl_range)
|
||||||
|
return self
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
return self
|
return self
|
||||||
@ -52,7 +55,7 @@ class RandomGenerator:
|
|||||||
raise StopIteration()
|
raise StopIteration()
|
||||||
self.n += 1
|
self.n += 1
|
||||||
while True:
|
while True:
|
||||||
val = random.randint(self.range.min, self.range.max)
|
val = self.random.randint(self.range.min, self.range.max)
|
||||||
if self.exclude:
|
if self.exclude:
|
||||||
excl_map = map(lambda e: e.is_within(val), self.exclude)
|
excl_map = map(lambda e: e.is_within(val), self.exclude)
|
||||||
is_excluded = reduce(lambda a, b: a or b, excl_map)
|
is_excluded = reduce(lambda a, b: a or b, excl_map)
|
||||||
@ -63,6 +66,8 @@ class RandomGenerator:
|
|||||||
|
|
||||||
class RandomStringGenerator:
|
class RandomStringGenerator:
|
||||||
def __init__(self, len_range=Range(0, 20), count=700):
|
def __init__(self, len_range=Range(0, 20), count=700):
|
||||||
|
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)
|
||||||
self.count = count
|
self.count = count
|
||||||
self.n = 0
|
self.n = 0
|
||||||
@ -77,7 +82,7 @@ class RandomStringGenerator:
|
|||||||
string.punctuation,
|
string.punctuation,
|
||||||
string.hexdigits]:
|
string.hexdigits]:
|
||||||
yield ''.join(random.choice(t) for _ in range(
|
yield ''.join(random.choice(t) for _ in range(
|
||||||
random.randint(len_range.min, len_range.max)
|
self.random.randint(len_range.min, len_range.max)
|
||||||
))
|
))
|
||||||
|
|
||||||
def __iter__(self):
|
def __iter__(self):
|
||||||
|
13
tests/functional/utils/configure_random.py
Executable file
13
tests/functional/utils/configure_random.py
Executable file
@ -0,0 +1,13 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
|
||||||
|
#
|
||||||
|
# Copyright(c) 2012-2018 Intel Corporation
|
||||||
|
# SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||||
|
#
|
||||||
|
|
||||||
|
import sys
|
||||||
|
import random
|
||||||
|
|
||||||
|
|
||||||
|
with open("config/random.cfg", "w") as f:
|
||||||
|
f.write(str(random.randint(0, sys.maxsize)))
|
Loading…
Reference in New Issue
Block a user