ee744e7ca7
Change-Id: I64b4a6baaa481eeccb34b228c520eb81a1ae0d46
94 lines
3.5 KiB
Python
94 lines
3.5 KiB
Python
"""
|
|
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)
|