Update tests

Signed-off-by: Jan Musial <jan.musial@intel.com>
This commit is contained in:
Jan Musial 2019-10-24 14:13:24 +02:00
parent aaedfb35dd
commit df1ba933de
4 changed files with 641 additions and 27 deletions

View File

@ -52,7 +52,7 @@ def get_hashed_config_list(conf):
def get_conf_line_hash(line):
"""
Removes whitespace, lowercases, comments and sorts cache params if present.
Removes whitespace, lowercases, comments and sorts params if present.
Returns empty line for comment-only lines
We don't care about order of params and kinds of whitespace in config lines
@ -60,15 +60,15 @@ def get_conf_line_hash(line):
testing we pretend we don't.
"""
def sort_cache_params(params):
def sort_params(params):
return ",".join(sorted(params.split(",")))
line = line.split("#")[0]
cache_params_pattern = re.compile(r"(.*?\s)(\S+=\S+)")
match = cache_params_pattern.search(line)
params_pattern = re.compile(r"(.*?\s)(\S+=\S+)")
match = params_pattern.search(line)
if match:
sorted_params = sort_cache_params(match.group(2))
sorted_params = sort_params(match.group(2))
line = match.group(1) + sorted_params
return "".join(line.lower().split())

View File

@ -339,6 +339,14 @@ def test_cas_config_get_by_id_path_not_found(mock_listdir, mock_realpath):
],
[],
),
(
[
"1 /dev/dummy0n1 WT cleaning_policy=acp",
],
[
"1 1 /dev/dummy1 lazy_startup=true"
],
),
],
)
@patch("builtins.open", new_callable=h.MockConfigFile)

View File

@ -18,12 +18,15 @@ import opencas
" ",
"#",
" # ",
("TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Npbmcg"
(
"TG9yZW0gaXBzdW0gZG9sb3Igc2l0IGFtZXQsIGNvbnNlY3RldHVyIGFkaXBpc2Npbmcg"
"ZWxpdCwgc2VkIGRvIGVpdXNtb2QgdGVtcG9yIGluY2lkaWR1bnQgdXQgbGFib3JlI"
"GV0IGRvbG9yZSBtYWduYSBhbGlxdWEu"),
"GV0IGRvbG9yZSBtYWduYSBhbGlxdWEu"
),
" # ? } { ! ",
"1 1 /dev/sda /dev/sdb",
"1 2 1 /dev/sda ",
"1 1 /dev/not_a_real_device /dev/sdb",
"1 2 1 /dev/not_a_real_device ",
"1 2 1 /dev/not_a_real_device dinosaur=velociraptor",
],
)
@mock.patch("opencas.cas_config.core_config.validate_config")
@ -32,17 +35,39 @@ def test_core_config_from_line_parsing_checks_01(mock_validate, line):
opencas.cas_config.core_config.from_line(line)
@pytest.mark.parametrize("line", ["1 1 /dev/sda", "1 1 /dev/sda "])
@mock.patch("opencas.cas_config.core_config.validate_config")
def test_core_config_from_line_parsing_checks_02(mock_validate, line):
opencas.cas_config.core_config.from_line(line)
@pytest.mark.parametrize(
"line",
[
"1 1 /dev/not_a_real_device",
"1 1 /dev/not_a_real_device ",
"1 1 /dev/not_a_real_device lazy_startup=true",
"1 1 /dev/not_a_real_device lazy_startup=false",
"1 1 /dev/not_a_real_device lazy_startup=False",
"1 1 /dev/not_a_real_device lazy_startup=True",
],
)
def test_core_config_from_line_parsing_checks_02(line):
opencas.cas_config.core_config.from_line(line, allow_incomplete=True)
@pytest.mark.parametrize(
"line",
[
"1 1 /dev/not_a_real_device dinosaur=velociraptor",
"1 1 /dev/not_a_real_device lazy_startup=maybe",
"1 1 /dev/not_a_real_device lazy_saturday=definitely",
"1 1 /dev/not_a_real_device 00000=345",
"1 1 /dev/not_a_real_device eval(38+4)",
],
)
def test_core_config_from_line_parsing_checks_params_01(line):
with pytest.raises(ValueError):
opencas.cas_config.core_config.from_line(line, allow_incomplete=True)
@mock.patch("os.path.exists")
@mock.patch("os.stat")
def test_core_config_from_line_device_is_directory(
mock_stat, mock_path_exists
):
def test_core_config_from_line_device_is_directory(mock_stat, mock_path_exists):
mock_path_exists.side_effect = h.get_mock_os_exists(["/home/user/stuff"])
mock_stat.return_value = mock.Mock(st_mode=stat.S_IFDIR)
@ -57,7 +82,7 @@ def test_core_config_from_line_device_not_present(mock_stat, mock_path_exists):
mock_stat.side_effect = ValueError()
with pytest.raises(ValueError):
opencas.cas_config.core_config.from_line("1 1 /dev/sda")
opencas.cas_config.core_config.from_line("1 1 /dev/not_a_real_device")
def test_core_config_from_line_recursive_multilevel():
@ -72,7 +97,7 @@ def test_core_config_from_line_multilevel():
@mock.patch("opencas.cas_config.check_block_device")
def test_core_config_from_line_allow_incomplete(mock_check_block,):
opencas.cas_config.core_config.from_line(
"1 1 /dev/sda", allow_incomplete=True
"1 1 /dev/not_a_real_device", allow_incomplete=True
)
assert not mock_check_block.called
@ -100,10 +125,10 @@ def test_core_config_from_line_allow_incomplete(mock_check_block,):
def test_core_config_from_line_cache_id_validation_01(
mock_stat, mock_path_exists, cache_id, core_id
):
mock_path_exists.side_effect = h.get_mock_os_exists(["/dev/sda"])
mock_path_exists.side_effect = h.get_mock_os_exists(["/dev/not_a_real_device"])
mock_stat.return_value = mock.Mock(st_mode=stat.S_IFBLK)
line = "{0} {1} /dev/sda".format(cache_id, core_id)
line = "{0} {1} /dev/not_a_real_device".format(cache_id, core_id)
with pytest.raises(ValueError):
opencas.cas_config.core_config.from_line(line)
@ -117,10 +142,10 @@ def test_core_config_from_line_cache_id_validation_01(
def test_core_config_from_line_cache_id_validation_02(
mock_stat, mock_path_exists, cache_id, core_id
):
mock_path_exists.side_effect = h.get_mock_os_exists(["/dev/sda"])
mock_path_exists.side_effect = h.get_mock_os_exists(["/dev/not_a_real_device"])
mock_stat.return_value = mock.Mock(st_mode=stat.S_IFBLK)
line = "{0} {1} /dev/sda".format(cache_id, core_id)
line = "{0} {1} /dev/not_a_real_device".format(cache_id, core_id)
opencas.cas_config.core_config.from_line(line)
@ -128,8 +153,8 @@ def test_core_config_from_line_cache_id_validation_02(
@pytest.mark.parametrize(
"cache_id,core_id,device",
[
("1", "1", "/dev/sda"),
("16384", "4095", "/dev/sda1"),
("1", "1", "/dev/not_a_real_device"),
("16384", "4095", "/dev/not_a_real_device"),
("16384", "0", "/dev/nvme0n1p"),
("100", "5", "/dev/dm-10"),
],
@ -148,9 +173,7 @@ def test_core_config_from_line_cache_id_validation(
core_reference.validate_config()
core_after = opencas.cas_config.core_config.from_line(
core_reference.to_line()
)
core_after = opencas.cas_config.core_config.from_line(core_reference.to_line())
assert core_after.cache_id == core_reference.cache_id
assert core_after.core_id == core_reference.core_id
assert core_after.device == core_reference.device

View File

@ -0,0 +1,583 @@
#
# Copyright(c) 2019 Intel Corporation
# SPDX-License-Identifier: BSD-3-Clause-Clear
#
import pytest
from mock import patch
import time
import opencas
@patch("opencas.cas_config.from_file")
def test_cas_settle_no_config(mock_config):
"""
Check if raises exception when no config is found
"""
mock_config.side_effect = ValueError
with pytest.raises(Exception):
opencas.wait_for_startup()
@patch("opencas.cas_config.from_file")
@patch("opencas.get_caches_list")
def test_cas_settle_cores_didnt_start_01(mock_list, mock_config):
"""
Check if properly returns uninitialized cores and waits for given time
Single core in config, no devices in runtime config.
"""
mock_config.return_value.get_startup_cores.return_value = [
opencas.cas_config.core_config(42, 13, "/dev/dummy")
]
time_start = time.time()
result = opencas.wait_for_startup(timeout=5, interval=1)
time_stop = time.time()
assert len(result) == 1, "didn't return single uninitialized core"
assert (
result[0].cache_id == 42
and result[0].core_id == 13
and result[0].device == "/dev/dummy"
)
assert 4.5 < time_stop - time_start < 5.5, "didn't wait the right amount of time"
assert mock_list.call_count == 5
@patch("opencas.cas_config.from_file")
@patch("opencas.get_caches_list")
def test_cas_settle_cores_didnt_start_02(mock_list, mock_config):
"""
Check if properly returns uninitialized cores and waits for given time
Single device in config, one device in runtime config, but not the configured core
"""
mock_config.return_value.get_startup_cores.return_value = [
opencas.cas_config.core_config(1, 1, "/dev/dummy")
]
mock_list.return_value = [
{
"type": "cache",
"id": "1",
"disk": "/dev/dummy_cache",
"status": "Active",
"write policy": "wt",
"device": "-",
}
]
time_start = time.time()
result = opencas.wait_for_startup(timeout=1, interval=0.1)
time_stop = time.time()
assert len(result) == 1, "didn't return uninitialized core"
assert 0.5 < time_stop - time_start < 1.5, "didn't wait the right amount of time"
@patch("opencas.cas_config.from_file")
@patch("opencas.get_caches_list")
def test_cas_settle_cores_didnt_start_02(mock_list, mock_config):
"""
Check if properly returns uninitialized cores and waits for given time
The device waited for is in core pool.
"""
mock_config.return_value.get_startup_cores.return_value = [
opencas.cas_config.core_config(1, 1, "/dev/dummy")
]
mock_list.return_value = [
{
"type": "core pool",
"id": "-",
"disk": "-",
"status": "-",
"write policy": "-",
"device": "-",
},
{
"type": "core",
"id": "-",
"disk": "/dev/dummy",
"status": "Detached",
"write policy": "-",
"device": "-",
},
{
"type": "cache",
"id": "2",
"disk": "/dev/dummy_cache",
"status": "Running",
"write policy": "wt",
"device": "-",
},
{
"type": "core",
"id": "42",
"disk": "/dev/other_core",
"status": "Active",
"write policy": "-",
"device": "/dev/cas2-42",
},
]
time_start = time.time()
result = opencas.wait_for_startup(timeout=1, interval=0.1)
time_stop = time.time()
assert len(result) == 1, "didn't return uninitialized core"
assert 0.5 < time_stop - time_start < 1.5, "didn't wait the right amount of time"
# Assert the call count is within some small range in case something freezes up for a second
assert 9 <= mock_list.call_count <= 11
@patch("opencas.cas_config.from_file")
@patch("opencas.get_caches_list")
def test_cas_settle_cores_didnt_start_03(mock_list, mock_config):
"""
Check if properly returns uninitialized cores and waits for given time
The device waited for is not present, but its cache device is already started.
"""
mock_config.return_value.get_startup_cores.return_value = [
opencas.cas_config.core_config(1, 1, "/dev/dummy")
]
mock_list.return_value = [
{
"type": "core pool",
"id": "-",
"disk": "-",
"status": "-",
"write policy": "-",
"device": "-",
},
{
"type": "core",
"id": "-",
"disk": "/dev/other_core",
"status": "Detached",
"write policy": "-",
"device": "-",
},
{
"type": "cache",
"id": "1",
"disk": "/dev/dummy_cache",
"status": "Incomplete",
"write policy": "wt",
"device": "-",
},
{
"type": "core",
"id": "42",
"disk": "/dev/dummy",
"status": "Inactive",
"write policy": "-",
"device": "/dev/cas1-42",
},
{
"type": "cache",
"id": "2",
"disk": "/dev/dummy_cache2",
"status": "Running",
"write policy": "wb",
"device": "-",
},
{
"type": "core",
"id": "3",
"disk": "/dev/dummy2",
"status": "Active",
"write policy": "-",
"device": "/dev/cas1-42",
},
]
time_start = time.time()
result = opencas.wait_for_startup(timeout=1, interval=0.1)
time_stop = time.time()
assert len(result) == 1, "didn't return uninitialized core"
assert 0.5 < time_stop - time_start < 1.5, "didn't wait the right amount of time"
# Assert the call count is within some small range in case something freezes up for a second
assert 9 <= mock_list.call_count <= 11
@patch("opencas.cas_config.from_file")
@patch("opencas.get_caches_list")
def test_cas_settle_cores_didnt_start_04(mock_list, mock_config):
"""
Check if properly returns uninitialized cores
Two devices configured, both not present.
"""
mock_config.return_value.get_startup_cores.return_value = [
opencas.cas_config.core_config(1, 1, "/dev/dummy"),
opencas.cas_config.core_config(4, 44, "/dev/dosko"),
]
mock_list.return_value = [
{
"type": "cache",
"id": "1",
"disk": "/dev/dummy_cache",
"status": "Incomplete",
"write policy": "wt",
"device": "-",
},
{
"type": "core",
"id": "1",
"disk": "/dev/dummy",
"status": "Inactive",
"write policy": "-",
"device": "/dev/cas1-1",
},
{
"type": "core",
"id": "2",
"disk": "/dev/dummy3",
"status": "Active",
"write policy": "-",
"device": "/dev/cas1-2",
},
{
"type": "cache",
"id": "2",
"disk": "/dev/dummy_cache2",
"status": "Running",
"write policy": "wb",
"device": "-",
},
{
"type": "core",
"id": "3",
"disk": "/dev/dummy2",
"status": "Active",
"write policy": "-",
"device": "/dev/cas2-3",
},
]
result = opencas.wait_for_startup(timeout=1, interval=0.1)
assert len(result) == 2, "didn't return uninitialized cores"
@patch("opencas.cas_config.from_file")
@patch("opencas.get_caches_list")
def test_cas_settle_core_started_01(mock_list, mock_config):
"""
Check if properly returns uninitialized cores and doesn't return initialized ones
Two devices configured, one present, one not present.
"""
mock_config.return_value.get_startup_cores.return_value = [
opencas.cas_config.core_config(1, 1, "/dev/dummy"),
opencas.cas_config.core_config(4, 44, "/dev/dosko"),
]
mock_list.return_value = [
{
"type": "core pool",
"id": "-",
"disk": "-",
"status": "-",
"write policy": "-",
"device": "-",
},
{
"type": "core",
"id": "-",
"disk": "/dev/other_core",
"status": "Detached",
"write policy": "-",
"device": "-",
},
{
"type": "cache",
"id": "1",
"disk": "/dev/dummy_cache",
"status": "Incomplete",
"write policy": "wt",
"device": "-",
},
{
"type": "core",
"id": "1",
"disk": "/dev/dummy",
"status": "Active",
"write policy": "-",
"device": "/dev/cas1-1",
},
{
"type": "cache",
"id": "2",
"disk": "/dev/dummy_cache2",
"status": "Running",
"write policy": "wb",
"device": "-",
},
{
"type": "core",
"id": "3",
"disk": "/dev/dummy2",
"status": "Active",
"write policy": "-",
"device": "/dev/cas1-42",
},
]
result = opencas.wait_for_startup(timeout=1, interval=0.1)
assert len(result) == 1, "didn't return uninitialized core"
@patch("opencas.cas_config.from_file")
@patch("opencas.get_caches_list")
def test_cas_settle_core_started_02(mock_list, mock_config):
"""
Check if properly returns uninitialized cores and doesn't return initialized ones
Two devices configured, both present and added.
"""
mock_config.return_value.get_startup_cores.return_value = [
opencas.cas_config.core_config(1, 1, "/dev/dummy"),
opencas.cas_config.core_config(4, 44, "/dev/dosko"),
]
mock_list.return_value = [
{
"type": "core pool",
"id": "-",
"disk": "-",
"status": "-",
"write policy": "-",
"device": "-",
},
{
"type": "core",
"id": "-",
"disk": "/dev/other_core",
"status": "Detached",
"write policy": "-",
"device": "-",
},
{
"type": "cache",
"id": "1",
"disk": "/dev/dummy_cache",
"status": "Running",
"write policy": "wt",
"device": "-",
},
{
"type": "core",
"id": "1",
"disk": "/dev/dummy",
"status": "Active",
"write policy": "-",
"device": "/dev/cas1-42",
},
{
"type": "cache",
"id": "2",
"disk": "/dev/dummy_cache2",
"status": "Running",
"write policy": "wb",
"device": "-",
},
{
"type": "core",
"id": "3",
"disk": "/dev/dummy2",
"status": "Active",
"write policy": "-",
"device": "/dev/cas1-42",
},
{
"type": "cache",
"id": "4",
"disk": "/dev/dummy_cache4",
"status": "Running",
"write policy": "wb",
"device": "-",
},
{
"type": "core",
"id": "44",
"disk": "/dev/dosko",
"status": "Active",
"write policy": "-",
"device": "/dev/cas4-44",
},
]
result = opencas.wait_for_startup(timeout=1, interval=0.1)
assert len(result) == 0, "no cores should remain uninitialized"
@patch("opencas.cas_config.from_file")
@patch("opencas.get_caches_list")
def test_cas_settle_core_started_03(mock_list, mock_config):
"""
Check if properly returns uninitialized cores and doesn't return initialized ones
Two devices configured, simulate them gradually showing up with each call to
get_caches_list()
"""
mock_config.return_value.get_startup_cores.return_value = [
opencas.cas_config.core_config(1, 1, "/dev/dummy"),
opencas.cas_config.core_config(2, 1, "/dev/dosko"),
]
mock_list.side_effect = [
[],
[
{
"type": "cache",
"id": "2",
"disk": "/dev/dummy_cache4",
"status": "Incomplete",
"write policy": "wb",
"device": "-",
},
{
"type": "core",
"id": "1",
"disk": "/dev/dosko",
"status": "Inactive",
"write policy": "-",
"device": "/dev/cas2-1",
},
],
[
{
"type": "cache",
"id": "2",
"disk": "/dev/dummy_cache4",
"status": "Incomplete",
"write policy": "wb",
"device": "-",
},
{
"type": "core",
"id": "1",
"disk": "/dev/dosko",
"status": "Inactive",
"write policy": "-",
"device": "/dev/cas2-1",
},
{
"type": "cache",
"id": "1",
"disk": "/dev/dummy_cache",
"status": "Incomplete",
"write policy": "wt",
"device": "-",
},
{
"type": "core",
"id": "1",
"disk": "/dev/dummy",
"status": "Active",
"write policy": "-",
"device": "/dev/cas1-1",
},
],
[
{
"type": "cache",
"id": "2",
"disk": "/dev/dummy_cache4",
"status": "Running",
"write policy": "wb",
"device": "-",
},
{
"type": "core",
"id": "1",
"disk": "/dev/dosko",
"status": "Active",
"write policy": "-",
"device": "/dev/cas2-1",
},
{
"type": "cache",
"id": "1",
"disk": "/dev/dummy_cache",
"status": "Incomplete",
"write policy": "wt",
"device": "-",
},
{
"type": "core",
"id": "1",
"disk": "/dev/dummy",
"status": "Inactive",
"write policy": "-",
"device": "/dev/cas1-1",
},
],
[
{
"type": "cache",
"id": "2",
"disk": "/dev/dummy_cache4",
"status": "Running",
"write policy": "wb",
"device": "-",
},
{
"type": "core",
"id": "1",
"disk": "/dev/dosko",
"status": "Active",
"write policy": "-",
"device": "/dev/cas2-1",
},
{
"type": "cache",
"id": "1",
"disk": "/dev/dummy_cache",
"status": "Running",
"write policy": "wt",
"device": "-",
},
{
"type": "core",
"id": "1",
"disk": "/dev/dummy",
"status": "Active",
"write policy": "-",
"device": "/dev/cas1-1",
},
],
]
result = opencas.wait_for_startup(timeout=1, interval=0.1)
assert len(result) == 0, "no cores should remain uninitialized"