Add unit testing to kb_config

Change-Id: I64b4a6baaa481eeccb34b228c520eb81a1ae0d46
This commit is contained in:
ahothan 2020-07-28 18:30:19 -07:00
parent 1316bd443d
commit ee744e7ca7
3 changed files with 137 additions and 6 deletions

View File

@ -902,8 +902,7 @@ def generate_charts(json_results, html_file_name, is_config):
is_config) is_config)
return 0 return 0
def process_cli_args(args):
def main():
cli_opts = [ cli_opts = [
cfg.StrOpt("config", cfg.StrOpt("config",
short="c", short="c",
@ -987,7 +986,10 @@ def main():
metavar="<source json file>"), metavar="<source json file>"),
] ]
CONF.register_cli_opts(cli_opts) CONF.register_cli_opts(cli_opts)
CONF(sys.argv[1:], project="kloudbuster", version=__version__) CONF(args, project="kloudbuster", version=__version__)
def main():
process_cli_args(sys.argv[1:])
logging.setup("kloudbuster") logging.setup("kloudbuster")
if CONF.rc and not CONF.tested_rc: if CONF.rc and not CONF.tested_rc:

93
tests/conftest.py Normal file
View File

@ -0,0 +1,93 @@
"""
This module is used to define shared pytest fixtures.
Because this module is placed under tests, all fixtures defined here can be used
by all test cases below tests
"""
import os
import shutil
import pytest
def stage_file(dirname, filename, content=None):
# we cannot use a os.path.join because we want to support
# multi-parts in the filename
if dirname.endswith('/') and filename.startswith('/'):
pathname = dirname + filename[1:]
elif filename.startswith('/') or dirname.endswith('/'):
pathname = dirname + filename
else:
pathname = dirname + '/' + filename
print('Staging file: ', pathname)
os.makedirs(os.path.dirname(pathname), exist_ok=True)
if content is None:
content = pathname
with open(pathname, 'w') as ff:
ff.write(content)
@pytest.fixture
def stage_fs():
"""
This fixture can be used to stage a complete file system below a given root.
This is a fixture factory and each test function can call stage_fs with the root of the
file system to stage and with a configuration.
The entire root_fs will be deleted when the fixture terminates unless skip_clean=True
Example of files_config:
{
'file1.yaml': 'any content',
'folder1': {
'file_with_arbitrary_content.yaml': None,
'empty_file.txt': '',
'nested_empty_folder: {}
}
'folder1/file2.txt': None
}
if '/tmp/pico' is passed as fs_root, this fixture will stage the following files:
/tmp/pico/file1.yaml (containing 'any content')
/tmp/pico/folder1/file_with_arbitrary_content.yaml (containing arbitary text)
/tmp/pico/folder1/empty_file.txt (empty)
/tmp/pico/folder1/nested_empty_folder/ (empty directory)
/tmp/pico/folder1/file2.txt (any content)
To use this fixture, simply add "stage_fs" as argument to your test function, then
call stage_fs() with arguments described in below _stage_fs function.
Also see the unit test code (test_fixtures.py)
"""
saved_fs_root = []
def _stage_fs(fs_root, files_config, skip_clean=False):
"""
fs_root: pathname of the root under which all all the files defined in files_config must be staged
files_config: a dict of file content reflecting the desired staged file system
skip_clean: set to True if you do not want the staged directory to be cleaned on exit (for troubleshooting only)
"""
if not saved_fs_root:
if skip_clean:
# for troubleshooting, it is possible to preserve
# the stage_fs directory after the test finishes
saved_fs_root.append(None)
else:
saved_fs_root.append(fs_root)
# remove the stage_fs root directory at start
# so we're sure we start with a clean directory
shutil.rmtree(fs_root, ignore_errors=True)
os.makedirs(fs_root, exist_ok=True)
for file, content in files_config.items():
if isinstance(content, dict):
# remove any "/" at start
if file[0] == '/':
file = file[1:]
new_fs_root = os.path.join(fs_root, file)
os.makedirs(new_fs_root, exist_ok=True)
_stage_fs(new_fs_root, content)
else:
stage_file(fs_root, file, content)
yield _stage_fs
if saved_fs_root:
if saved_fs_root[0]:
# remove the stage_fs directory when the fixture terminates
shutil.rmtree(saved_fs_root[0], ignore_errors=True)

View File

@ -19,7 +19,43 @@ test_kloudbuster
Tests for `kloudbuster` module. Tests for `kloudbuster` module.
""" """
from kloudbuster.kb_config import KBConfig from kloudbuster.kb_config import KBConfig
from kloudbuster.kloudbuster import process_cli_args
def test_config(): def test_kbconfig_default():
cfg = KBConfig() # verify that we load the defaulgt config properly
cfg.update_configs() kbcfg = KBConfig()
kbcfg.update_configs()
cfg = kbcfg.config_scale
assert cfg.openrc_file is None
assert cfg.vm_creation_concurrency == 5
assert cfg.client.flavor.vcpus == 1
config_yaml = """
client:
flavor:
vcpus: 100
ram: 2048
disk: 0
extra_specs:
"hw:cpu_policy": dedicated
storage_stage_configs:
vm_count: 1
target: 'volume'
disk_size: 10
io_file_size: 55
"""
def test_kbconfig_overide(stage_fs):
config_fs = {
'config.yaml': config_yaml
}
stage_fs('/tmp/kbtest', config_fs)
# verify that config override is working
args = ['-c', '/tmp/kbtest/config.yaml']
process_cli_args(args)
kbcfg = KBConfig()
kbcfg.init_with_cli()
kbcfg.update_configs()
cfg = kbcfg.config_scale
print(cfg.client.storage_stage_configs)
assert cfg.client.flavor.vcpus == 100
assert cfg.client.storage_stage_configs.io_file_size == 55