blob: c252757c1a75b968b0e3c454d6ece3c95e6473db [file] [log] [blame]
#!/usr/bin/env python3
import glob
import json
import re
import os
import pathlib
import pytest
import shutil
import subprocess
import sys
SCRIPT_ROOT = pathlib.Path(__file__).resolve().parent
BR2_EXT_ROOT = (SCRIPT_ROOT / '../../').resolve()
CFG_FS_SCRIPTS_PATH = BR2_EXT_ROOT / 'package' / 'czechlight-cfg-fs'
def run_and_wait(ctx, command_args):
print(f'RUN {command_args}')
with subprocess.Popen(command_args, stdout=sys.stdout, stderr=sys.stderr, env=ctx.get_env()) as proc:
proc.wait()
assert proc.returncode == 0
class SysrepoFixture:
def __init__(self, test_directory, tmp_path):
self.test_directory = SCRIPT_ROOT / test_directory
test_name = self.test_directory.name
self.running_directory = tmp_path / test_name
self.running_directory.mkdir()
self.tmp_path = tmp_path
for fn in ('startup.json', 'version'):
try:
shutil.copy(self.test_directory / fn, self.running_directory)
except FileNotFoundError:
pass
query_file = self.test_directory / 'query'
self.query = query_file.read_text() if query_file.is_file() \
else 'del(."ietf-keystore:keystore"."asymmetric-keys"."asymmetric-key"[0]."cleartext-private-key")'
# all tests must run with clean sysrepo state
self._shm_prefix = 'br2-migr-' + test_name
self._repo_path = self.running_directory / 'sysrepo_repository'
def get_env(self):
res = os.environ.copy()
res['SYSREPO_SHM_PREFIX'] = self._shm_prefix
res['SYSREPO_REPOSITORY_PATH'] = self._repo_path
res['LN2_MODULE_DIR'] = pathlib.Path(os.environ['LIBNETCONF2_SRCDIR']) / 'modules'
res['NP2_MODULE_DIR'] = pathlib.Path(os.environ['NETOPEER2_SRCDIR']) / 'modules'
res['NETOPEER2_SETUP_DIR'] = BR2_EXT_ROOT / 'submodules' / 'buildroot' / 'package' / 'netopeer2'
res['CLA_YANG'] = pathlib.Path(os.environ['CLA_SYSREPO_SRCDIR']) / 'yang'
res['VELIA_YANG'] = pathlib.Path(os.environ['VELIA_SRCDIR']) / 'yang'
res['ALARMS_YANG'] = pathlib.Path(os.environ['SYSREPO_IETF_ALARMS_SRCDIR']) / 'yang'
res['ROUSETTE_YANG'] = pathlib.Path(os.environ['ROUSETTE_SRCDIR']) / 'yang'
res['CFG_FS_YANG'] = CFG_FS_SCRIPTS_PATH / 'yang'
res['CFG_STATIC_DATA'] = CFG_FS_SCRIPTS_PATH / 'static-data'
res['VELIA_STATIC_DATA'] = pathlib.Path(os.environ['VELIA_SRCDIR']) / 'yang'
res['CLA_STATIC_DATA'] = pathlib.Path(os.environ['CLA_SYSREPO_SRCDIR']) / 'yang'
res['PROC_CMDLINE'] = self.test_directory / 'cmdline'
res['CFG_SYSREPO_DIR'] = self.running_directory
res['CURRENT_VERSION_FILE'] = CFG_FS_SCRIPTS_PATH / 'CURRENT_CONFIG_VERSION'
res['TMPDIR'] = self.tmp_path
return res
def nuke_shm(self):
for f in glob.glob(f'/dev/shm/{self._shm_prefix}*'):
os.remove(f)
@pytest.fixture(scope='session')
def max_version():
return (CFG_FS_SCRIPTS_PATH / 'CURRENT_CONFIG_VERSION').read_text()
@pytest.fixture
def sysrepo_fixture(request, tmp_path):
return SysrepoFixture(pathlib.Path(SCRIPT_ROOT / 'data' / request.param), tmp_path)
def find_test_directories():
return [pytest.param(dirname) for dirname in os.listdir(path=SCRIPT_ROOT / 'data')]
@pytest.mark.parametrize("sysrepo_fixture", find_test_directories(), indirect=True)
def test(sysrepo_fixture, max_version):
# prevent running with a stale SHM state
sysrepo_fixture.nuke_shm()
run_and_wait(sysrepo_fixture, [CFG_FS_SCRIPTS_PATH / "cfg-migrate.sh"])
run_and_wait(sysrepo_fixture, [CFG_FS_SCRIPTS_PATH / "cfg-yang.sh"])
assert (sysrepo_fixture.running_directory / 'version').read_text() == max_version
dump = subprocess.run(['sysrepocfg', '-f', 'json', '-d', 'startup', '-X'], check=True, capture_output=True, env=sysrepo_fixture.get_env())
jq = subprocess.run(['jq', sysrepo_fixture.query], input=dump.stdout, check=True, capture_output=True)
actual = json.loads(jq.stdout.decode('utf-8'))
with open(sysrepo_fixture.test_directory / 'expected.json', 'r') as fp_expected:
expected = json.load(fp_expected)
assert actual == expected
sysrepo_fixture.nuke_shm()