diff options
author | Jakub Ružička <jakub.ruzicka@nic.cz> | 2022-08-26 16:58:54 +0200 |
---|---|---|
committer | Jakub Ružička <jakub.ruzicka@nic.cz> | 2022-09-27 15:13:48 +0200 |
commit | ec1265fd6066f6aa132260d7a130c3b43afe3d73 (patch) | |
tree | bbed53313085cd4a81a2cc647fcddae363f549bf /tests | |
parent | Merge branch 'master' into manager (diff) | |
download | knot-resolver-ec1265fd6066f6aa132260d7a130c3b43afe3d73.tar.xz knot-resolver-ec1265fd6066f6aa132260d7a130c3b43afe3d73.zip |
tests: remove tests/packaging
Cleanup before introduction of new packaging tests.
See: https://gitlab.nic.cz/knot/knot-resolver/-/issues/612
Diffstat (limited to 'tests')
-rw-r--r-- | tests/packaging/README.rst | 87 | ||||
-rw-r--r-- | tests/packaging/conftest.py | 10 | ||||
-rw-r--r-- | tests/packaging/test_packaging.py | 494 |
3 files changed, 0 insertions, 591 deletions
diff --git a/tests/packaging/README.rst b/tests/packaging/README.rst deleted file mode 100644 index 997f6667..00000000 --- a/tests/packaging/README.rst +++ /dev/null @@ -1,87 +0,0 @@ -.. SPDX-License-Identifier: GPL-3.0-or-later - -Packaging tests -=============== - -Packaging tests used pytest, docker and each directory with subdirectory *.packaging* -is called as *component*. - -Run tests for all components: - -.. code-block:: - - pytest -r fEsxX tests/packaging - -List all components: - -.. code-block:: - - pytest tests/packaging --collect-only - -Run test for specific component (*doc/.packaging*): - -.. code-block:: - - pytest -r fEsxX tests/packaging -k test_collect[debian_10-doc/.packaging] - -.. note:: - - For debug add argument :code:`-s`. - -daemon/.packaging component ---------------------------- - -This is special component that is used by all others components. -For each distribution and version are created two docker images with this component. -One with building dependencies and one for running dependencies. -*Build docker image* is tagged as :code:`kr-packaging-tests-<distro><version>-build` -and *Run docker image* is tagged as :code:`kr-packaging-tests-<distro><version>-run`. - -Others components ------------------ - -All others components are based on *daemon/.packaging* component (docker image). -When component needs new building dependencies, new running dependencies -or some scripts that change build or run phase (see `File structure of each component`_), -new docker image is created. -*Build docker image* is tagged as :code:`kr-packaging-tests-<distro><version>-<component>-build` -and *Run docker image* is tagged as :code:`kr-packaging-tests-<distro><version>-<component>-run`. - -File structure of each component ------------------------------------- - -* <distro> - * <version> - * builddeps - list of build dependencies - * rundeps - list of runtime dependencies - * pre-build.sh - script called before build phase - * post-build.sh - script called after build phase - * pre-run.sh - script called before run phase - * post-run.sh - script called after run phase - * install.sh and build.sh - scripts to rewrite standard commands for building and installing knot-resolvers - * pre-test.sh - script called immediately before testing -* test.config or test.sh - kresd config test or shell script (one of them must exists) - -Commands order to create docker image -------------------------------------- - -For *build docker image*: - -#. run pre-build.sh -#. install packages specified in the file *builddeps* -#. run build.sh -#. run install.sh -#. run post-build.sh - -For *run docker image*: - -#. run pre-run.sh -#. install packages specified in the file *rundeps* -#. run pre-test.sh -#. run test (:code:`kresd -c test.config` or :code:`test.sh`) -#. run post-build.sh - - -.. note:: - - knot-resolver builded in *build docker image* is automatically moved to *run docker image*. diff --git a/tests/packaging/conftest.py b/tests/packaging/conftest.py deleted file mode 100644 index 7279c15c..00000000 --- a/tests/packaging/conftest.py +++ /dev/null @@ -1,10 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -import pytest -import os - - -def pytest_configure(): - pytest.KR_PYTESTS_DIR = os.path.dirname(os.path.realpath(__file__)) - pytest.KR_ROOT_DIR = os.path.join(pytest.KR_PYTESTS_DIR, "..", "..") - pytest.KR_PREFIX = "kr-packaging-tests-" diff --git a/tests/packaging/test_packaging.py b/tests/packaging/test_packaging.py deleted file mode 100644 index 1a9bc413..00000000 --- a/tests/packaging/test_packaging.py +++ /dev/null @@ -1,494 +0,0 @@ -# SPDX-License-Identifier: GPL-3.0-or-later - -import os -import pytest -import docker -import logging -from pathlib import Path -from abc import ABC, abstractmethod - - -logging.basicConfig(level=logging.INFO) -logger = logging.getLogger(__name__) -logger.setLevel(logging.DEBUG) -client = docker.from_env() - - -class DockerCmdError(Exception): - """ Raised when shell command in Docker container failed """ - pass - - -class ContainerHandler(): - def __init__(self, image): - self.img_id = image - self.container = None - - def run(self): - self.container = client.containers.run(self.img_id, network_mode='host', - tty=True, detach=True) - logger.info('Run container ID={}'.format(self.container)) - - def stop(self): - self.container.kill() - - def exec_cmd(self, cmd, workdir): - # workaround: When exec_run is called in GitLab CI/CD workdir argument doesn't work. - inter_cmd = '' - if workdir is not None: - inter_cmd = 'cd {}; '.format(workdir) - - rcode, out = self.container.exec_run('/bin/sh -c \'' + inter_cmd + cmd + '\'') - if rcode != 0: - raise DockerCmdError(rcode, out) - - def getFiles(self, output, path): - strm, stat = self.container.get_archive(path) - with open(output, 'wb') as ofile: - for data in strm: - ofile.write(data) - - -class DockerImages(ABC): - def __init__(self, version): - self.version = version - self.module = None - self.distro = None - self.build_id = None - self.run_id = None - - @abstractmethod - def cmd_pkgs_install(self): - raise NotImplementedError - - @abstractmethod - def cmd_kresd_install(self): - raise NotImplementedError - - @abstractmethod - def cmd_kresd_build(self): - raise NotImplementedError - - def readDependencies(self, deps_file): - """Read dependencies from file""" - listf = None - try: - with open(deps_file, 'r') as f: - listf = f.read().splitlines() - except FileNotFoundError: - pass - - return listf - - def __genDockerFile(self, path, from_image=None): - """Generate Dockerfile for build image""" - if self.module is None: - raise AttributeError - - if from_image is None: - if os.path.isfile(os.path.join(self.module, self.distro, 'docker-image-name')): - with open(os.path.join(self.module, self.distro, 'docker-image-name')) as f: - from_image = f.read() - else: - from_image = '{0}:{1}'.format(self.distro, self.version) - - distro_dir = os.path.join(self.module, self.distro, self.version) - - dockerf = open(os.path.join(path, 'Dockerfile-build'), 'w') - - dockerf.write('FROM {}\n'.format(from_image)) - dockerf.write('WORKDIR /root/kresd\n') - if self.module == 'daemon/.packaging': - dockerf.write('COPY . /root/kresd\n') - # when this file doesn't exists, tzdata needs user interaction - dockerf.write('RUN if [ ! -f /etc/localtime ];' + - 'then ln -fs /usr/share/zoneinfo/Europe/Prague /etc/localtime; fi\n') - if os.path.isfile(os.path.join(distro_dir, 'pre-build.sh')): - dockerf.write('RUN {}\n'.format(os.path.join(distro_dir, 'pre-build.sh'))) - if os.path.isfile(os.path.join(distro_dir, 'builddeps')): - dockerf.write('RUN {0} {1}\n'.format(self.cmd_pkgs_install(), - ' '.join(self.readDependencies(os.path.join(distro_dir, 'builddeps'))))) - if os.path.isfile(os.path.join(distro_dir, 'build.sh')): - dockerf.write('RUN {}\n'.format(os.path.join(distro_dir, 'build.sh'))) - else: - dockerf.write('RUN {}\n'.format(self.cmd_kresd_build())) - if os.path.isfile(os.path.join(distro_dir, 'install.sh')): - dockerf.write('RUN {}\n'.format(os.path.join(distro_dir, 'install.sh'))) - else: - dockerf.write('RUN {}\n'.format(self.cmd_kresd_install())) - if os.path.isfile(os.path.join(distro_dir, 'post-build.sh')): - dockerf.write('RUN {}\n'.format(os.path.join(distro_dir, 'post-build.sh'))) - - dockerf.close() - - def __genDockerFile_run(self, path, build_id, from_image=None): - """Generate Dockerfile for run image""" - if self.module is None: - raise AttributeError - - if from_image is None: - if os.path.isfile(os.path.join(self.module, self.distro, 'docker-image-name')): - with open(os.path.join(self.module, self.distro, 'docker-image-name')) as f: - from_image = f.read() - else: - from_image = '{0}:{1}'.format(self.distro, self.version) - - distro_dir = os.path.join(self.module, self.distro, self.version) - - dockerf = open(os.path.join(path, 'Dockerfile-run'), 'w') - - dockerf.write('FROM {}\n'.format(from_image)) - dockerf.write('COPY --from={} /root/kresd /root/kresd\n'.format(build_id)) - dockerf.write('WORKDIR /root/kresd\n') - if os.path.isfile(os.path.join(distro_dir, 'pre-run.sh')): - dockerf.write('RUN {}\n'.format(os.path.join(distro_dir, 'pre-run.sh'))) - if os.path.isfile(os.path.join(distro_dir, 'rundeps')): - dockerf.write('RUN {0} {1}\n'.format(self.cmd_pkgs_install(), - ' '.join(self.readDependencies(os.path.join(distro_dir, 'rundeps'))))) - if os.path.isfile(os.path.join(distro_dir, 'pre-test.sh')): - dockerf.write('RUN {}\n'.format(os.path.join(distro_dir, 'pre-test.sh'))) - - dockerf.close() - - def build_printing_errors(self, path, dockerfile, network_mode, tag, rm): - try: - return client.images.build(path=path, dockerfile=dockerfile, - network_mode=network_mode, tag=tag, rm=rm) - except docker.errors.BuildError as e: - iterable = iter(e.build_log) - while True: - try: - item = next(iterable) - if item['stream']: - for l in item['stream'].splitlines(): - stripped = l.strip() - if stripped: - logging.error(stripped) - except StopIteration: - break - raise e - - def build(self, tmpdir, tag="", from_image=None): - self.__genDockerFile(tmpdir, from_image=from_image) - - logger.debug('tmpdir={}'.format(tmpdir)) - logger.debug('datadir={}'.format(pytest.KR_ROOT_DIR)) - logger.debug('tag={}'.format(tag)) - image = self.build_printing_errors(path=str(pytest.KR_ROOT_DIR), - dockerfile=os.path.join(tmpdir, 'Dockerfile-build'), - network_mode='host', tag=tag, rm=True) - logger.info('"Build image" ID={} created'.format(image[0].short_id)) - self.build_id = image[0].short_id - return self.build_id - - def build_run(self, tmpdir, build_id, from_image=None, tag=""): - self.__genDockerFile_run(tmpdir, build_id, from_image=from_image) - - logger.debug('tmpdir={}'.format(tmpdir)) - logger.debug('datadir={}'.format(tmpdir)) - logger.debug('tag={}'.format(tag)) - image = self.build_printing_errors(path=str(tmpdir), - dockerfile=os.path.join(tmpdir, 'Dockerfile-run'), - network_mode='host', tag=tag, rm=True) - logger.info('"Run image" ID={} created'.format(image[0].short_id)) - self.run_id = image[0].short_id - return self.run_id - - -class DebianImage(DockerImages): - def __init__(self, version): - super().__init__(version) - self.distro = 'debian' - - def cmd_pkgs_install(self): - return 'apt-get install -y ' - - def cmd_kresd_install(self): - return 'ninja -C build_packaging install >/dev/null' - - def cmd_kresd_build(self): - return """\\ - [ -d /root/kresd/build_packaging ] && rm -rf /root/kresd/build_packaging/; \\ - CFLAGS=\"$CFLAGS -Wall -pedantic -fno-omit-frame-pointer\"; \\ - LDFLAGS=\"$LDFLAGS -Wl,--as-needed\"; \\ - meson build_packaging \\ - --buildtype=plain \\ - --prefix=/root/kresd/install_packaging \\ - --libdir=lib \\ - --default-library=static \\ - -Dsystemd_files=enabled \\ - -Dclient=enabled \\ - -Dkeyfile_default=/usr/share/dns/root.key \\ - -Droot_hints=/usr/share/dns/root.hints \\ - -Dinstall_kresd_conf=enabled \\ - -Dunit_tests=enabled \\ - -Dc_args=\"${CFLAGS}\" \\ - -Dc_link_args=\"${LDFLAGS}\"; \\ - ninja -C build_packaging - """ - - -class UbuntuImage(DebianImage): - def __init__(self, version): - super().__init__(version) - self.distro = 'ubuntu' - - -class CentosImage(DockerImages): - def __init__(self, version): - super().__init__(version) - self.distro = 'centos' - - def cmd_pkgs_install(self): - return "yum install -y " - - def cmd_kresd_install(self): - return 'ninja-build -C build_packaging install' - - def cmd_kresd_build(self): - return """\\ - [ -d /root/kresd/build_packaging ] && rm -rf /root/kresd/build_packaging/; \\ - CFLAGS=\"$CFLAGS -Wall -pedantic -fno-omit-frame-pointer\"; \\ - LDFLAGS=\"$LDFLAGS -Wl,--as-needed\"; \\ - meson build_packaging \\ - --buildtype=plain \\ - --prefix=/root/kresd/install_packaging \\ - --sbindir=sbin \\ - --libdir=lib \\ - --includedir=include \\ - --sysconfdir=etc \\ - --default-library=static \\ - -Dsystemd_files=enabled \\ - -Dclient=enabled \\ - -Dunit_tests=enabled \\ - -Dmanaged_ta=enabled \\ - -Dkeyfile_default=/root/kresd/install_packaging/var/lib/knot-resolver/root.keys \\ - -Dinstall_root_keys=enabled \\ - -Dinstall_kresd_conf=enabled; \\ - ninja-build -C build_packaging - """ - - -class FedoraImage(DockerImages): - def __init__(self, version): - super().__init__(version) - self.distro = 'fedora' - - def cmd_pkgs_install(self): - return "dnf install -y " - - def cmd_kresd_install(self): - return 'ninja -C build_packaging install >/dev/null' - - def cmd_kresd_build(self): - return """\\ - [ -d /root/kresd/build_packaging ] && rm -rf /root/kresd/build_packaging/; \\ - CFLAGS=\"$CFLAGS -Wall -pedantic -fno-omit-frame-pointer\"; \\ - LDFLAGS=\"$LDFLAGS -Wl,--as-needed\"; \\ - meson build_packaging \\ - --buildtype=plain \\ - --prefix=/root/kresd/install_packaging \\ - --sbindir=sbin \\ - --libdir=lib \\ - --includedir=include \\ - --sysconfdir=etc \\ - --default-library=static \\ - -Dsystemd_files=enabled \\ - -Dclient=enabled \\ - -Dunit_tests=enabled \\ - -Dmanaged_ta=enabled \\ - -Dkeyfile_default=/root/kresd/install_packaging/var/lib/knot-resolver/root.keys \\ - -Dinstall_root_keys=enabled \\ - -Dinstall_kresd_conf=enabled; \\ - ninja -C build_packaging - """ - - -class LeapImage(FedoraImage): - def __init__(self, version): - super().__init__(version) - self.distro = 'leap' - - def cmd_pkgs_install(self): - return "zypper install -y " - - -def create_distro_image(name, version): - img = None - - if (name == 'debian'): - img = DebianImage(version) - elif (name == 'ubuntu'): - img = UbuntuImage(version) - elif (name == 'centos'): - img = CentosImage(version) - elif (name == 'fedora'): - img = FedoraImage(version) - elif (name == 'leap'): - img = LeapImage(version) - else: - img = None - - return img - - -def list_dirs(path, exclude=None): - """return all 'packaging' directories with full path""" - filtered_dirs = [] - - for rootpath, dirs, _ in os.walk(path): - - if (os.path.basename(rootpath) == '.packaging'): - fdir = os.path.relpath(rootpath, path) - if exclude is not None: - if fdir not in exclude: - filtered_dirs.append(fdir) - else: - filtered_dirs.append(fdir) - - return filtered_dirs - - -def list_tests_dirs(): - """return all 'packaging' directories""" - return list_dirs(pytest.KR_ROOT_DIR) - - -def list_distro_vers(distro_root): - """ - return list of { 'name': distro_name, 'version': distro_version) - pairs found in distro_root - """ - # transform list of paths like TOP/debian/10 into (debian, 10) - dist_ver = [{'name': p.parts[-2], 'version': p.parts[-1]} for p - in Path(distro_root).glob('*/*') if p.is_dir()] - - return list(dist_ver) - - -MODULES = list_tests_dirs() -DISTROS = list_distro_vers(os.path.join(pytest.KR_ROOT_DIR, 'daemon/.packaging')) -DISTROS_NAMES = ['{0}_{1}'.format(distro['name'], distro['version']) for distro in DISTROS] - - -@pytest.fixture(scope='session', params=DISTROS, ids=DISTROS_NAMES) -def buildenv(request, tmpdir_factory): - distro = request.param - - logger.debug('Creating main images for "{0} {1}"'.format(distro['name'], distro['version'])) - img = create_distro_image(distro['name'], distro['version']) - if img is None: - logger.warning('Unknown distro {}'.format(distro['name'])) - else: - img.module = 'daemon/.packaging' - tmpdir = tmpdir_factory.mktemp(distro['name']+distro['version']) - img.build(tmpdir, tag=pytest.KR_PREFIX+distro['name']+distro['version']+'-build') - img.build_run(tmpdir, img.build_id, - tag=pytest.KR_PREFIX+distro['name']+distro['version']+'-run') - - yield img -# client.images.remove(img.run_id) -# client.images.remove(img.build_id) - - -@pytest.mark.parametrize('module', MODULES) -def test_collect(module, buildenv, tmp_path): - logger.info(' ### Run test {} ###'.format(module)) - - if buildenv is None: - logger.error('Distro "{0} {1}" isn\'t implemented'.format(buildenv.distro, - buildenv.version)) - assert False - - rcode = None - buildmod = None - module_dir = os.path.join(pytest.KR_ROOT_DIR, module) - distro_dir = os.path.join(module_dir, buildenv.distro, buildenv.version) - - if os.path.isfile(os.path.join(distro_dir, 'NOTSUPPORTED')): - pytest.skip('Unsupported linux distribution ({0} {1}:{2})'.format(buildenv.distro, buildenv.version, module)) - - try: - if module == 'daemon/.packaging': - # use main "run image" without changes - logging.info('Use main "run image"') - ch = ContainerHandler(buildenv.run_id) - ch.run() - elif buildenv is not None: - if os.path.isfile(os.path.join(distro_dir, 'pre-build.sh')) \ - or os.path.isfile(os.path.join(distro_dir, 'builddeps')): - # create module specific "build image" - logger.info('Create new "build image"') - buildmod = create_distro_image(buildenv.distro, buildenv.version) - buildmod.module = module - buildmod.build(tmp_path, from_image=buildenv.build_id, - tag=pytest.KR_PREFIX+buildmod.distro+buildmod.version+'-' + - module.replace('/.packaging', '')+'-build') - - if buildmod is not None: - # new build image was made, create new module specific "run image" - logger.info('Create module specific "run image" from Dockerfile') - buildmod.build_run(tmp_path, buildmod.build_id, - tag=pytest.KR_PREFIX+buildmod.distro+buildmod.version+'-' + - module.replace('/.packaging', '')+'-run', from_image=buildenv.run_id) - ch = ContainerHandler(buildmod.run_id) - ch.run() - elif os.path.isfile(os.path.join(distro_dir, 'pre-run.sh')) \ - or os.path.isfile(os.path.join(distro_dir, 'rundeps')): - # use main "run image" and apply module specific changes - logger.info('Apply module specific changes to "run image"') - buildmod = buildenv - ch = ContainerHandler(buildmod.run_id) - ch.run() - - if os.path.isfile(os.path.join(distro_dir, 'pre-run.sh')): - ch.exec_cmd(os.path.join(module, buildenv.distro, buildenv.version, - 'pre-run.sh'), '/root/kresd/') - - if os.path.isfile(os.path.join(distro_dir, 'rundeps')): - logger.debug(buildmod.cmd_pkgs_install() + ' '.join( - buildmod.readDependencies(os.path.join(distro_dir, 'rundeps')))) - ch.exec_cmd(buildmod.cmd_pkgs_install() + ' '.join( - buildmod.readDependencies(os.path.join(distro_dir, 'rundeps'))), - '/root/kresd/') - - if os.path.isfile(os.path.join(distro_dir, 'pre-test.sh')): - ch.exec_cmd(os.path.join(module, buildenv.distro, buildenv.version, - 'pre-test.sh'), '/root/kresd/') - else: - # use main "run image" without changes - logging.info('Use main "run image"') - ch = ContainerHandler(buildenv.run_id) - ch.run() - - # run test - if os.path.isfile(os.path.join(module_dir, 'test.config')): - ch.exec_cmd('/root/kresd/install_packaging/sbin/kresd -n -c ' + os.path.join('..', - module, 'test.config'), '/root/kresd/install_packaging/') - elif os.path.isfile(os.path.join(module_dir, 'test.sh')): - ch.exec_cmd(os.path.join('..', module, 'test.sh'), - '/root/kresd/install_packaging/') - else: - ch.stop() - ch.container.remove() - logger.error('Test file (test.config or test.sh) not found') - assert False - - rcode = 0 - - if os.path.isfile(os.path.join(distro_dir, 'post-run.sh')): - ch.exec_cmd(os.path.join(module, buildenv.distro, buildenv.version, 'post-run.sh'), - '/root/kresd/') - - except DockerCmdError as err: - rcode, out = err.args - logger.debug('rcode: {}'.format(rcode)) - logger.error(out.decode('utf-8')) - finally: - ch.stop() - ch.container.remove() - if buildmod is not None and buildmod is not buildenv: - client.images.remove(buildmod.run_id) - client.images.remove(buildmod.build_id) - - assert(rcode == 0) |