blob: c252757c1a75b968b0e3c454d6ece3c95e6473db [file] [log] [blame]
Tomáš Pecka04eb7372022-06-07 08:03:04 +02001#!/usr/bin/env python3
2
Jan Kundrát86cc6462024-05-07 19:28:39 +02003import glob
Tomáš Pecka04eb7372022-06-07 08:03:04 +02004import json
5import re
6import os
7import pathlib
Jan Kundráte950cf72024-09-06 17:46:11 +02008import pytest
Tomáš Pecka04eb7372022-06-07 08:03:04 +02009import shutil
10import subprocess
11import sys
12
Tomáš Pecka04eb7372022-06-07 08:03:04 +020013
14SCRIPT_ROOT = pathlib.Path(__file__).resolve().parent
Jan Kundráte950cf72024-09-06 17:46:11 +020015BR2_EXT_ROOT = (SCRIPT_ROOT / '../../').resolve()
16CFG_FS_SCRIPTS_PATH = BR2_EXT_ROOT / 'package' / 'czechlight-cfg-fs'
Tomáš Pecka04eb7372022-06-07 08:03:04 +020017
Jan Kundráte950cf72024-09-06 17:46:11 +020018def run_and_wait(ctx, command_args):
19 print(f'RUN {command_args}')
Tomáš Pecka04eb7372022-06-07 08:03:04 +020020 with subprocess.Popen(command_args, stdout=sys.stdout, stderr=sys.stderr, env=ctx.get_env()) as proc:
21 proc.wait()
22 assert proc.returncode == 0
23
24
25class SysrepoFixture:
26 def __init__(self, test_directory, tmp_path):
Jan Kundráte950cf72024-09-06 17:46:11 +020027 self.test_directory = SCRIPT_ROOT / test_directory
28 test_name = self.test_directory.name
29 self.running_directory = tmp_path / test_name
30 self.running_directory.mkdir()
31 self.tmp_path = tmp_path
Tomáš Pecka04eb7372022-06-07 08:03:04 +020032
Jan Kundráte950cf72024-09-06 17:46:11 +020033 for fn in ('startup.json', 'version'):
34 try:
35 shutil.copy(self.test_directory / fn, self.running_directory)
36 except FileNotFoundError:
37 pass
Tomáš Pecka04eb7372022-06-07 08:03:04 +020038
Jan Kundráte950cf72024-09-06 17:46:11 +020039 query_file = self.test_directory / 'query'
40 self.query = query_file.read_text() if query_file.is_file() \
41 else 'del(."ietf-keystore:keystore"."asymmetric-keys"."asymmetric-key"[0]."cleartext-private-key")'
Tomáš Pecka04eb7372022-06-07 08:03:04 +020042
Jan Kundrát86cc6462024-05-07 19:28:39 +020043 # all tests must run with clean sysrepo state
Jan Kundráte950cf72024-09-06 17:46:11 +020044 self._shm_prefix = 'br2-migr-' + test_name
45 self._repo_path = self.running_directory / 'sysrepo_repository'
Jan Kundrát86cc6462024-05-07 19:28:39 +020046
Tomáš Pecka04eb7372022-06-07 08:03:04 +020047 def get_env(self):
48 res = os.environ.copy()
Jan Kundrát86cc6462024-05-07 19:28:39 +020049 res['SYSREPO_SHM_PREFIX'] = self._shm_prefix
Jan Kundráte950cf72024-09-06 17:46:11 +020050 res['SYSREPO_REPOSITORY_PATH'] = self._repo_path
51 res['LN2_MODULE_DIR'] = pathlib.Path(os.environ['LIBNETCONF2_SRCDIR']) / 'modules'
52 res['NP2_MODULE_DIR'] = pathlib.Path(os.environ['NETOPEER2_SRCDIR']) / 'modules'
53 res['NETOPEER2_SETUP_DIR'] = BR2_EXT_ROOT / 'submodules' / 'buildroot' / 'package' / 'netopeer2'
Jan Kundrát07a87272024-04-22 23:40:17 +020054 res['CLA_YANG'] = pathlib.Path(os.environ['CLA_SYSREPO_SRCDIR']) / 'yang'
55 res['VELIA_YANG'] = pathlib.Path(os.environ['VELIA_SRCDIR']) / 'yang'
Jan Kundrát07a87272024-04-22 23:40:17 +020056 res['ALARMS_YANG'] = pathlib.Path(os.environ['SYSREPO_IETF_ALARMS_SRCDIR']) / 'yang'
Jan Kundráte950cf72024-09-06 17:46:11 +020057 res['ROUSETTE_YANG'] = pathlib.Path(os.environ['ROUSETTE_SRCDIR']) / 'yang'
58 res['CFG_FS_YANG'] = CFG_FS_SCRIPTS_PATH / 'yang'
59 res['CFG_STATIC_DATA'] = CFG_FS_SCRIPTS_PATH / 'static-data'
60 res['VELIA_STATIC_DATA'] = pathlib.Path(os.environ['VELIA_SRCDIR']) / 'yang'
61 res['CLA_STATIC_DATA'] = pathlib.Path(os.environ['CLA_SYSREPO_SRCDIR']) / 'yang'
62 res['PROC_CMDLINE'] = self.test_directory / 'cmdline'
63 res['CFG_SYSREPO_DIR'] = self.running_directory
64 res['CURRENT_VERSION_FILE'] = CFG_FS_SCRIPTS_PATH / 'CURRENT_CONFIG_VERSION'
65 res['TMPDIR'] = self.tmp_path
Tomáš Pecka04eb7372022-06-07 08:03:04 +020066 return res
67
Jan Kundráte950cf72024-09-06 17:46:11 +020068 def nuke_shm(self):
69 for f in glob.glob(f'/dev/shm/{self._shm_prefix}*'):
70 os.remove(f)
71
Tomáš Pecka04eb7372022-06-07 08:03:04 +020072
73@pytest.fixture(scope='session')
74def max_version():
Jan Kundráte950cf72024-09-06 17:46:11 +020075 return (CFG_FS_SCRIPTS_PATH / 'CURRENT_CONFIG_VERSION').read_text()
Tomáš Pecka04eb7372022-06-07 08:03:04 +020076
77
78@pytest.fixture
79def sysrepo_fixture(request, tmp_path):
80 return SysrepoFixture(pathlib.Path(SCRIPT_ROOT / 'data' / request.param), tmp_path)
81
82
83def find_test_directories():
84 return [pytest.param(dirname) for dirname in os.listdir(path=SCRIPT_ROOT / 'data')]
85
86
87@pytest.mark.parametrize("sysrepo_fixture", find_test_directories(), indirect=True)
88def test(sysrepo_fixture, max_version):
Jan Kundráte950cf72024-09-06 17:46:11 +020089 # prevent running with a stale SHM state
90 sysrepo_fixture.nuke_shm()
Tomáš Pecka04eb7372022-06-07 08:03:04 +020091
Jan Kundráte950cf72024-09-06 17:46:11 +020092 run_and_wait(sysrepo_fixture, [CFG_FS_SCRIPTS_PATH / "cfg-migrate.sh"])
93 run_and_wait(sysrepo_fixture, [CFG_FS_SCRIPTS_PATH / "cfg-yang.sh"])
Tomáš Pecka04eb7372022-06-07 08:03:04 +020094
Jan Kundráte950cf72024-09-06 17:46:11 +020095 assert (sysrepo_fixture.running_directory / 'version').read_text() == max_version
Tomáš Pecka04eb7372022-06-07 08:03:04 +020096
Jan Kundráte950cf72024-09-06 17:46:11 +020097 dump = subprocess.run(['sysrepocfg', '-f', 'json', '-d', 'startup', '-X'], check=True, capture_output=True, env=sysrepo_fixture.get_env())
98 jq = subprocess.run(['jq', sysrepo_fixture.query], input=dump.stdout, check=True, capture_output=True)
99 actual = json.loads(jq.stdout.decode('utf-8'))
100 with open(sysrepo_fixture.test_directory / 'expected.json', 'r') as fp_expected:
101 expected = json.load(fp_expected)
102 assert actual == expected
Tomáš Pecka04eb7372022-06-07 08:03:04 +0200103
Jan Kundráte950cf72024-09-06 17:46:11 +0200104 sysrepo_fixture.nuke_shm()