Add tests for opencas.py
Signed-off-by: Jan Musial <jan.musial@intel.com>
This commit is contained in:
489
test/utils_tests/opencas-py-tests/test_cas_config_01.py
Normal file
489
test/utils_tests/opencas-py-tests/test_cas_config_01.py
Normal file
@@ -0,0 +1,489 @@
|
||||
#
|
||||
# Copyright(c) 2012-2019 Intel Corporation
|
||||
# SPDX-License-Identifier: BSD-3-Clause-Clear
|
||||
#
|
||||
|
||||
import pytest
|
||||
from mock import patch, mock_open
|
||||
from textwrap import dedent
|
||||
import helpers as h
|
||||
|
||||
import opencas
|
||||
|
||||
|
||||
@patch("builtins.open", new_callable=mock_open)
|
||||
def test_cas_config_from_file_exception(mock_file):
|
||||
mock_file.raises = ValueError()
|
||||
|
||||
with pytest.raises(Exception):
|
||||
opencas.cas_config.from_file("/dummy/file.conf")
|
||||
|
||||
mock_file.assert_called_once_with("/dummy/file.conf", "r")
|
||||
|
||||
|
||||
@patch(
|
||||
"builtins.open",
|
||||
new_callable=h.MockConfigFile,
|
||||
buffer="""
|
||||
[caches]
|
||||
1 /dev/nvme0n1 WT
|
||||
[cores]
|
||||
1 1 /dev/sdc
|
||||
""",
|
||||
)
|
||||
def test_cas_config_from_file_no_vertag(mock_file):
|
||||
with pytest.raises(ValueError):
|
||||
opencas.cas_config.from_file("/dummy/file.conf")
|
||||
|
||||
|
||||
@patch(
|
||||
"builtins.open",
|
||||
new_callable=h.MockConfigFile,
|
||||
buffer="""
|
||||
version=03.08.00
|
||||
#[caches]
|
||||
#1 /dev/nvme0n1 WT
|
||||
#[cores]
|
||||
#1 1 /dev/sdc
|
||||
""",
|
||||
)
|
||||
@patch("opencas.cas_config.core_config.from_line")
|
||||
@patch("opencas.cas_config.cache_config.from_line")
|
||||
@patch("opencas.cas_config.insert_core")
|
||||
@patch("opencas.cas_config.insert_cache")
|
||||
def test_cas_config_from_file_comments_only(
|
||||
mock_insert_cache,
|
||||
mock_insert_core,
|
||||
mock_cache_from_line,
|
||||
mock_core_from_line,
|
||||
mock_file,
|
||||
):
|
||||
|
||||
config = opencas.cas_config.from_file("/dummy/file.conf")
|
||||
|
||||
mock_cache_from_line.assert_not_called()
|
||||
mock_core_from_line.assert_not_called()
|
||||
mock_insert_cache.assert_not_called()
|
||||
mock_insert_core.assert_not_called()
|
||||
|
||||
assert config.is_empty()
|
||||
|
||||
|
||||
ConflictingConfigException = opencas.cas_config.ConflictingConfigException
|
||||
AlreadyConfiguredException = opencas.cas_config.AlreadyConfiguredException
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"caches_config,cores_config,exception",
|
||||
[
|
||||
(
|
||||
[
|
||||
"1 /dev/dummy0n1 WT",
|
||||
"2 /dev/dummy0n1 WT",
|
||||
"3 /dev/dummy0n1 WT",
|
||||
],
|
||||
["1 1 /dev/dummyc"],
|
||||
ConflictingConfigException,
|
||||
),
|
||||
(
|
||||
["1 /dev/dummyc WT"],
|
||||
["1 1 /dev/dummyc"],
|
||||
ConflictingConfigException,
|
||||
),
|
||||
(
|
||||
["1 /dev/dummya WT", "1 /dev/dummy0n1 WT"],
|
||||
["1 1 /dev/dummyc"],
|
||||
ConflictingConfigException,
|
||||
),
|
||||
(
|
||||
["1 /dev/dummya WT", "1 /dev/dummya WT"],
|
||||
["1 1 /dev/dummyc"],
|
||||
AlreadyConfiguredException,
|
||||
),
|
||||
(
|
||||
["1 /dev/dummya WT"],
|
||||
["1 1 /dev/dummyc", "1 1 /dev/dummyc"],
|
||||
AlreadyConfiguredException,
|
||||
),
|
||||
(
|
||||
["2 /dev/dummya WT"],
|
||||
["1 1 /dev/dummyc", "2 1 /dev/dummyb"],
|
||||
KeyError,
|
||||
),
|
||||
(
|
||||
["1 /dev/dummya WT", "2 /dev/dummy0n1 WT"],
|
||||
["1 1 /dev/dummyc", "2 1 /dev/dummyc"],
|
||||
ConflictingConfigException,
|
||||
),
|
||||
],
|
||||
)
|
||||
@patch("builtins.open", new_callable=h.MockConfigFile)
|
||||
@patch("opencas.cas_config.cache_config.validate_config")
|
||||
@patch("opencas.cas_config.core_config.validate_config")
|
||||
def test_cas_config_from_file_inconsistent_configs(
|
||||
mock_validate_core,
|
||||
mock_validate_cache,
|
||||
mock_file,
|
||||
caches_config,
|
||||
cores_config,
|
||||
exception,
|
||||
):
|
||||
|
||||
mock_file.set_contents(
|
||||
dedent(
|
||||
"""
|
||||
version=3.8.0
|
||||
[caches]
|
||||
{0}
|
||||
[cores]
|
||||
{1}
|
||||
"""
|
||||
).format("\n".join(caches_config), "\n".join(cores_config))
|
||||
)
|
||||
|
||||
with pytest.raises(exception):
|
||||
opencas.cas_config.from_file("/dummy/file.conf")
|
||||
|
||||
|
||||
@patch(
|
||||
"builtins.open",
|
||||
new_callable=h.MockConfigFile,
|
||||
buffer="""
|
||||
version=3.8.0
|
||||
[caches]
|
||||
1 /dev/dummy0n1 WT
|
||||
[cores]
|
||||
1 1 /dev/dummyc
|
||||
""",
|
||||
)
|
||||
@patch("opencas.cas_config.cache_config.validate_config")
|
||||
@patch("opencas.cas_config.core_config.validate_config")
|
||||
def test_cas_config_is_empty_non_empty(
|
||||
mock_validate_core, mock_validate_cache, mock_file
|
||||
):
|
||||
|
||||
config = opencas.cas_config.from_file("/dummy/file.conf")
|
||||
|
||||
assert not config.is_empty()
|
||||
|
||||
|
||||
def test_cas_config_double_add_cache():
|
||||
config = opencas.cas_config()
|
||||
|
||||
cache = opencas.cas_config.cache_config(1, "/dev/dummy", "WT")
|
||||
config.insert_cache(cache)
|
||||
|
||||
with pytest.raises(AlreadyConfiguredException):
|
||||
config.insert_cache(cache)
|
||||
|
||||
|
||||
def test_cas_config_double_add_core():
|
||||
config = opencas.cas_config()
|
||||
cache = opencas.cas_config.cache_config(1, "/dev/dummy1", "WT")
|
||||
config.insert_cache(cache)
|
||||
|
||||
core = opencas.cas_config.core_config(1, 1, "/dev/dummy")
|
||||
config.insert_core(core)
|
||||
|
||||
with pytest.raises(AlreadyConfiguredException):
|
||||
config.insert_core(core)
|
||||
|
||||
|
||||
def test_cas_config_insert_core_no_cache():
|
||||
config = opencas.cas_config()
|
||||
|
||||
core = opencas.cas_config.core_config(1, 1, "/dev/dummy")
|
||||
|
||||
with pytest.raises(KeyError):
|
||||
config.insert_core(core)
|
||||
|
||||
|
||||
@patch("os.path.realpath")
|
||||
def test_cas_config_add_same_cache_symlinked_01(mock_realpath):
|
||||
mock_realpath.side_effect = (
|
||||
lambda x: "/dev/dummy1" if x == "/dev/dummy_link" else x
|
||||
)
|
||||
|
||||
config = opencas.cas_config()
|
||||
cache = opencas.cas_config.cache_config(1, "/dev/dummy1", "WT")
|
||||
config.insert_cache(cache)
|
||||
|
||||
cache_symlinked = opencas.cas_config.cache_config(
|
||||
2, "/dev/dummy_link", "WB"
|
||||
)
|
||||
|
||||
with pytest.raises(ConflictingConfigException):
|
||||
config.insert_cache(cache_symlinked)
|
||||
|
||||
|
||||
@patch("os.path.realpath")
|
||||
def test_cas_config_add_same_cache_symlinked_02(mock_realpath):
|
||||
mock_realpath.side_effect = (
|
||||
lambda x: "/dev/dummy1" if x == "/dev/dummy_link" else x
|
||||
)
|
||||
|
||||
config = opencas.cas_config()
|
||||
cache = opencas.cas_config.cache_config(1, "/dev/dummy1", "WT")
|
||||
config.insert_cache(cache)
|
||||
|
||||
cache_symlinked = opencas.cas_config.cache_config(
|
||||
1, "/dev/dummy_link", "WB"
|
||||
)
|
||||
|
||||
with pytest.raises(AlreadyConfiguredException):
|
||||
config.insert_cache(cache_symlinked)
|
||||
|
||||
|
||||
@patch("os.path.realpath")
|
||||
def test_cas_config_add_same_core_symlinked_01(mock_realpath):
|
||||
mock_realpath.side_effect = (
|
||||
lambda x: "/dev/dummy1" if x == "/dev/dummy_link" else x
|
||||
)
|
||||
|
||||
config = opencas.cas_config()
|
||||
config.insert_cache(
|
||||
opencas.cas_config.cache_config(1, "/dev/dummy_cache", "WB")
|
||||
)
|
||||
core = opencas.cas_config.core_config(1, 1, "/dev/dummy1")
|
||||
config.insert_core(core)
|
||||
|
||||
core_symlinked = opencas.cas_config.core_config(1, 2, "/dev/dummy_link")
|
||||
|
||||
with pytest.raises(ConflictingConfigException):
|
||||
config.insert_core(core_symlinked)
|
||||
|
||||
|
||||
@patch("os.path.realpath")
|
||||
def test_cas_config_add_same_core_symlinked_02(mock_realpath):
|
||||
mock_realpath.side_effect = (
|
||||
lambda x: "/dev/dummy1" if x == "/dev/dummy_link" else x
|
||||
)
|
||||
|
||||
config = opencas.cas_config()
|
||||
config.insert_cache(
|
||||
opencas.cas_config.cache_config(1, "/dev/dummy_cache", "WB")
|
||||
)
|
||||
core = opencas.cas_config.core_config(1, 1, "/dev/dummy1")
|
||||
config.insert_core(core)
|
||||
|
||||
core_symlinked = opencas.cas_config.core_config(1, 1, "/dev/dummy_link")
|
||||
|
||||
with pytest.raises(AlreadyConfiguredException):
|
||||
config.insert_core(core_symlinked)
|
||||
|
||||
|
||||
@patch("os.path.realpath")
|
||||
@patch("os.listdir")
|
||||
def test_cas_config_get_by_id_path(mock_listdir, mock_realpath):
|
||||
mock_listdir.return_value = [
|
||||
"wwn-1337deadbeef-x0x0",
|
||||
"wwn-1337deadbeef-x0x0-part1",
|
||||
"nvme-INTEL_SSDAAAABBBBBCCC_0984547ASDDJHHHFH",
|
||||
]
|
||||
mock_realpath.side_effect = (
|
||||
lambda x: "/dev/dummy1"
|
||||
if x == "/dev/disk/by-id/wwn-1337deadbeef-x0x0-part1"
|
||||
else x
|
||||
)
|
||||
|
||||
path = opencas.cas_config.get_by_id_path("/dev/dummy1")
|
||||
|
||||
assert path == "/dev/disk/by-id/wwn-1337deadbeef-x0x0-part1"
|
||||
|
||||
|
||||
@patch("os.path.realpath")
|
||||
@patch("os.listdir")
|
||||
def test_cas_config_get_by_id_path_not_found(mock_listdir, mock_realpath):
|
||||
mock_listdir.return_value = [
|
||||
"wwn-1337deadbeef-x0x0",
|
||||
"wwn-1337deadbeef-x0x0-part1",
|
||||
"nvme-INTEL_SSDAAAABBBBBCCC_0984547ASDDJHHHFH",
|
||||
]
|
||||
mock_realpath.side_effect = lambda x: x
|
||||
|
||||
with pytest.raises(ValueError):
|
||||
path = opencas.cas_config.get_by_id_path("/dev/dummy1")
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"caches_config,cores_config",
|
||||
[
|
||||
(
|
||||
[
|
||||
"1 /dev/dummy0n1 WT",
|
||||
"2 /dev/dummy0n2 WT",
|
||||
"3 /dev/dummy0n3 WT",
|
||||
],
|
||||
["1 1 /dev/dummyc"],
|
||||
),
|
||||
([], []),
|
||||
(
|
||||
[
|
||||
"1 /dev/dummy0n1 WT",
|
||||
"2 /dev/dummy0n2 WT",
|
||||
"3 /dev/dummy0n3 WT",
|
||||
],
|
||||
[
|
||||
"1 1 /dev/dummyc1",
|
||||
"2 200 /dev/dummyc2",
|
||||
"3 100 /dev/dummyc3",
|
||||
],
|
||||
),
|
||||
(
|
||||
[
|
||||
"1 /dev/dummy0n1 WT cleaning_policy=acp",
|
||||
"2 /dev/dummy0n2 pt ioclass_file=mango.csv",
|
||||
"3 /dev/dummy0n3 WA cache_line_size=16",
|
||||
("4 /dev/dummyc wb cache_line_size=16,"
|
||||
"ioclass_file=mango.csv,cleaning_policy=nop"),
|
||||
],
|
||||
[],
|
||||
),
|
||||
],
|
||||
)
|
||||
@patch("builtins.open", new_callable=h.MockConfigFile)
|
||||
@patch("opencas.cas_config.cache_config.validate_config")
|
||||
@patch("opencas.cas_config.core_config.validate_config")
|
||||
def test_cas_config_from_file_to_file(
|
||||
mock_validate_core,
|
||||
mock_validate_cache,
|
||||
mock_file,
|
||||
caches_config,
|
||||
cores_config,
|
||||
):
|
||||
"""
|
||||
1. Read config from mocked file with parametrized caches and cores section
|
||||
2. Serialize config back to mocked file
|
||||
3. Check if serialized file is proper config file and the same content-wise
|
||||
as the initial file. Specifically check:
|
||||
* Version tag is present in first line
|
||||
* There is only one of each [caches] and [cores] sections marking
|
||||
* [cores] section comes after [caches]
|
||||
* sets of caches and cores are equal before and after test
|
||||
"""
|
||||
|
||||
mock_file.set_contents(
|
||||
dedent(
|
||||
"""
|
||||
version=3.8.0
|
||||
[caches]
|
||||
{0}
|
||||
[cores]
|
||||
{1}
|
||||
"""
|
||||
).format("\n".join(caches_config), "\n".join(cores_config))
|
||||
)
|
||||
|
||||
config = opencas.cas_config.from_file("/dummy/file.conf")
|
||||
|
||||
config.write("/dummy/file.conf")
|
||||
|
||||
f = mock_file("/dummy/file.conf", "r")
|
||||
contents_hashed = h.get_hashed_config_list(f)
|
||||
|
||||
assert contents_hashed[0] == "version=3.8.0"
|
||||
assert contents_hashed.count("[caches]") == 1
|
||||
assert contents_hashed.count("[cores]") == 1
|
||||
|
||||
caches_index = contents_hashed.index("[caches]")
|
||||
cores_index = contents_hashed.index("[cores]")
|
||||
|
||||
assert cores_index > caches_index
|
||||
|
||||
caches_hashed = h.get_hashed_config_list(caches_config)
|
||||
cores_hashed = h.get_hashed_config_list(cores_config)
|
||||
|
||||
assert set(caches_hashed) == set(
|
||||
contents_hashed[caches_index + 1 : cores_index]
|
||||
)
|
||||
assert set(cores_hashed) == set(contents_hashed[cores_index + 1 :])
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
"caches_config,cores_config",
|
||||
[
|
||||
(
|
||||
[
|
||||
"1 /dev/dummy0n1 WT",
|
||||
"2 /dev/dummy0n2 WT",
|
||||
"3 /dev/dummy0n3 WT",
|
||||
],
|
||||
["1 1 /dev/dummyc"],
|
||||
),
|
||||
([], []),
|
||||
(
|
||||
[
|
||||
"1 /dev/dummy0n1 WT",
|
||||
"2 /dev/dummy0n2 WT",
|
||||
"3 /dev/dummy0n3 WT",
|
||||
],
|
||||
[
|
||||
"1 1 /dev/dummyc1",
|
||||
"2 200 /dev/dummyc2",
|
||||
"3 100 /dev/dummyc3",
|
||||
],
|
||||
),
|
||||
(
|
||||
[
|
||||
"1 /dev/dummy0n1 WT cleaning_policy=acp",
|
||||
"2 /dev/dummy0n2 pt ioclass_file=mango.csv",
|
||||
"3 /dev/dummy0n3 WA cache_line_size=16",
|
||||
("4 /dev/dummyc wb cache_line_size=16,"
|
||||
"ioclass_file=mango.csv,cleaning_policy=nop"),
|
||||
],
|
||||
[],
|
||||
),
|
||||
],
|
||||
)
|
||||
@patch("builtins.open", new_callable=h.MockConfigFile)
|
||||
@patch("opencas.cas_config.cache_config.validate_config")
|
||||
@patch("opencas.cas_config.core_config.validate_config")
|
||||
def test_cas_config_from_file_insert_cache_insert_core_to_file(
|
||||
mock_validate_core,
|
||||
mock_validate_cache,
|
||||
mock_file,
|
||||
caches_config,
|
||||
cores_config,
|
||||
):
|
||||
"""
|
||||
1. Read config from mocked file with parametrized caches and cores section
|
||||
2. Add one core and one cache to config
|
||||
3. Serialize config back to mocked file
|
||||
4. Compare that config file after serialization is same content-wise with
|
||||
initial + added core and cache
|
||||
"""
|
||||
|
||||
mock_file.set_contents(
|
||||
dedent(
|
||||
"""
|
||||
version=3.8.0
|
||||
[caches]
|
||||
{0}
|
||||
[cores]
|
||||
{1}
|
||||
"""
|
||||
).format("\n".join(caches_config), "\n".join(cores_config))
|
||||
)
|
||||
|
||||
config = opencas.cas_config.from_file("/dummy/file.conf")
|
||||
|
||||
config.insert_cache(opencas.cas_config.cache_config(5, "/dev/mango", "WT"))
|
||||
config.insert_core(opencas.cas_config.core_config(5, 1, "/dev/mango_core"))
|
||||
|
||||
config.write("/dummy/file.conf")
|
||||
|
||||
f = mock_file("/dummy/file.conf", "r")
|
||||
contents_hashed = h.get_hashed_config_list(f)
|
||||
|
||||
caches_index = contents_hashed.index("[caches]")
|
||||
cores_index = contents_hashed.index("[cores]")
|
||||
|
||||
caches_hashed = h.get_hashed_config_list(caches_config)
|
||||
cores_hashed = h.get_hashed_config_list(cores_config)
|
||||
|
||||
assert set(contents_hashed[caches_index + 1 : cores_index]) - set(
|
||||
caches_hashed
|
||||
) == set(["5/dev/mangowt"])
|
||||
assert set(contents_hashed[cores_index + 1 :]) - set(cores_hashed) == set(
|
||||
["51/dev/mango_core"]
|
||||
)
|
Reference in New Issue
Block a user