^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 1) # SPDX-License-Identifier: GPL-2.0
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 2) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 3) # Copyright (C) 2018 Masahiro Yamada <yamada.masahiro@socionext.com>
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 4) #
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 5)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 6) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 7) Kconfig unit testing framework.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 8)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 9) This provides fixture functions commonly used from test files.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 10) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 11)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 12) import os
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 13) import pytest
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 14) import shutil
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 15) import subprocess
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 16) import tempfile
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 17)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 18) CONF_PATH = os.path.abspath(os.path.join('scripts', 'kconfig', 'conf'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 19)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 20)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 21) class Conf:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 22) """Kconfig runner and result checker.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 23)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 24) This class provides methods to run text-based interface of Kconfig
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 25) (scripts/kconfig/conf) and retrieve the resulted configuration,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 26) stdout, and stderr. It also provides methods to compare those
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 27) results with expectations.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 28) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 29)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 30) def __init__(self, request):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 31) """Create a new Conf instance.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 32)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 33) request: object to introspect the requesting test module
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 34) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 35) # the directory of the test being run
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 36) self._test_dir = os.path.dirname(str(request.fspath))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 37)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 38) # runners
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 39) def _run_conf(self, mode, dot_config=None, out_file='.config',
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 40) interactive=False, in_keys=None, extra_env={}):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 41) """Run text-based Kconfig executable and save the result.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 42)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 43) mode: input mode option (--oldaskconfig, --defconfig=<file> etc.)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 44) dot_config: .config file to use for configuration base
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 45) out_file: file name to contain the output config data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 46) interactive: flag to specify the interactive mode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 47) in_keys: key inputs for interactive modes
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 48) extra_env: additional environments
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 49) returncode: exit status of the Kconfig executable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 50) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 51) command = [CONF_PATH, mode, 'Kconfig']
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 52)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 53) # Override 'srctree' environment to make the test as the top directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 54) extra_env['srctree'] = self._test_dir
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 55)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 56) # Run Kconfig in a temporary directory.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 57) # This directory is automatically removed when done.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 58) with tempfile.TemporaryDirectory() as temp_dir:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 59)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 60) # if .config is given, copy it to the working directory
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 61) if dot_config:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 62) shutil.copyfile(os.path.join(self._test_dir, dot_config),
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 63) os.path.join(temp_dir, '.config'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 64)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 65) ps = subprocess.Popen(command,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 66) stdin=subprocess.PIPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 67) stdout=subprocess.PIPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 68) stderr=subprocess.PIPE,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 69) cwd=temp_dir,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 70) env=dict(os.environ, **extra_env))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 71)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 72) # If input key sequence is given, feed it to stdin.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 73) if in_keys:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 74) ps.stdin.write(in_keys.encode('utf-8'))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 75)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 76) while ps.poll() is None:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 77) # For interactive modes such as oldaskconfig, oldconfig,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 78) # send 'Enter' key until the program finishes.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 79) if interactive:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 80) ps.stdin.write(b'\n')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 81)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 82) self.retcode = ps.returncode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 83) self.stdout = ps.stdout.read().decode()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 84) self.stderr = ps.stderr.read().decode()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 85)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 86) # Retrieve the resulted config data only when .config is supposed
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 87) # to exist. If the command fails, the .config does not exist.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 88) # 'listnewconfig' does not produce .config in the first place.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 89) if self.retcode == 0 and out_file:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 90) with open(os.path.join(temp_dir, out_file)) as f:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 91) self.config = f.read()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 92) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 93) self.config = None
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 94)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 95) # Logging:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 96) # Pytest captures the following information by default. In failure
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 97) # of tests, the captured log will be displayed. This will be useful to
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 98) # figure out what has happened.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 99)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 100) print("[command]\n{}\n".format(' '.join(command)))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 101)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 102) print("[retcode]\n{}\n".format(self.retcode))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 103)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 104) print("[stdout]")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 105) print(self.stdout)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 106)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 107) print("[stderr]")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 108) print(self.stderr)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 109)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 110) if self.config is not None:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 111) print("[output for '{}']".format(out_file))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 112) print(self.config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 113)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 114) return self.retcode
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 115)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 116) def oldaskconfig(self, dot_config=None, in_keys=None):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 117) """Run oldaskconfig.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 118)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 119) dot_config: .config file to use for configuration base (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 120) in_key: key inputs (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 121) returncode: exit status of the Kconfig executable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 122) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 123) return self._run_conf('--oldaskconfig', dot_config=dot_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 124) interactive=True, in_keys=in_keys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 125)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 126) def oldconfig(self, dot_config=None, in_keys=None):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 127) """Run oldconfig.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 128)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 129) dot_config: .config file to use for configuration base (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 130) in_key: key inputs (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 131) returncode: exit status of the Kconfig executable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 132) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 133) return self._run_conf('--oldconfig', dot_config=dot_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 134) interactive=True, in_keys=in_keys)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 135)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 136) def olddefconfig(self, dot_config=None):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 137) """Run olddefconfig.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 138)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 139) dot_config: .config file to use for configuration base (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 140) returncode: exit status of the Kconfig executable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 141) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 142) return self._run_conf('--olddefconfig', dot_config=dot_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 143)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 144) def defconfig(self, defconfig):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 145) """Run defconfig.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 146)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 147) defconfig: defconfig file for input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 148) returncode: exit status of the Kconfig executable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 149) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 150) defconfig_path = os.path.join(self._test_dir, defconfig)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 151) return self._run_conf('--defconfig={}'.format(defconfig_path))
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 152)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 153) def _allconfig(self, mode, all_config):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 154) if all_config:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 155) all_config_path = os.path.join(self._test_dir, all_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 156) extra_env = {'KCONFIG_ALLCONFIG': all_config_path}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 157) else:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 158) extra_env = {}
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 159)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 160) return self._run_conf('--{}config'.format(mode), extra_env=extra_env)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 161)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 162) def allyesconfig(self, all_config=None):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 163) """Run allyesconfig.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 164)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 165) all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 166) returncode: exit status of the Kconfig executable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 167) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 168) return self._allconfig('allyes', all_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 169)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 170) def allmodconfig(self, all_config=None):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 171) """Run allmodconfig.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 172)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 173) all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 174) returncode: exit status of the Kconfig executable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 175) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 176) return self._allconfig('allmod', all_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 177)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 178) def allnoconfig(self, all_config=None):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 179) """Run allnoconfig.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 180)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 181) all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 182) returncode: exit status of the Kconfig executable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 183) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 184) return self._allconfig('allno', all_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 185)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 186) def alldefconfig(self, all_config=None):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 187) """Run alldefconfig.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 188)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 189) all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 190) returncode: exit status of the Kconfig executable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 191) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 192) return self._allconfig('alldef', all_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 193)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 194) def randconfig(self, all_config=None):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 195) """Run randconfig.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 196)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 197) all_config: fragment config file for KCONFIG_ALLCONFIG (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 198) returncode: exit status of the Kconfig executable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 199) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 200) return self._allconfig('rand', all_config)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 201)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 202) def savedefconfig(self, dot_config):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 203) """Run savedefconfig.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 204)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 205) dot_config: .config file for input
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 206) returncode: exit status of the Kconfig executable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 207) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 208) return self._run_conf('--savedefconfig', out_file='defconfig')
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 209)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 210) def listnewconfig(self, dot_config=None):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 211) """Run listnewconfig.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 212)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 213) dot_config: .config file to use for configuration base (optional)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 214) returncode: exit status of the Kconfig executable
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 215) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 216) return self._run_conf('--listnewconfig', dot_config=dot_config,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 217) out_file=None)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 218)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 219) # checkers
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 220) def _read_and_compare(self, compare, expected):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 221) """Compare the result with expectation.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 222)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 223) compare: function to compare the result with expectation
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 224) expected: file that contains the expected data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 225) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 226) with open(os.path.join(self._test_dir, expected)) as f:
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 227) expected_data = f.read()
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 228) return compare(self, expected_data)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 229)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 230) def _contains(self, attr, expected):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 231) return self._read_and_compare(
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 232) lambda s, e: getattr(s, attr).find(e) >= 0,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 233) expected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 234)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 235) def _matches(self, attr, expected):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 236) return self._read_and_compare(lambda s, e: getattr(s, attr) == e,
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 237) expected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 238)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 239) def config_contains(self, expected):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 240) """Check if resulted configuration contains expected data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 241)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 242) expected: file that contains the expected data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 243) returncode: True if result contains the expected data, False otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 244) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 245) return self._contains('config', expected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 246)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 247) def config_matches(self, expected):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 248) """Check if resulted configuration exactly matches expected data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 249)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 250) expected: file that contains the expected data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 251) returncode: True if result matches the expected data, False otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 252) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 253) return self._matches('config', expected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 254)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 255) def stdout_contains(self, expected):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 256) """Check if resulted stdout contains expected data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 257)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 258) expected: file that contains the expected data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 259) returncode: True if result contains the expected data, False otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 260) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 261) return self._contains('stdout', expected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 262)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 263) def stdout_matches(self, expected):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 264) """Check if resulted stdout exactly matches expected data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 265)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 266) expected: file that contains the expected data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 267) returncode: True if result matches the expected data, False otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 268) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 269) return self._matches('stdout', expected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 270)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 271) def stderr_contains(self, expected):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 272) """Check if resulted stderr contains expected data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 273)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 274) expected: file that contains the expected data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 275) returncode: True if result contains the expected data, False otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 276) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 277) return self._contains('stderr', expected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 278)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 279) def stderr_matches(self, expected):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 280) """Check if resulted stderr exactly matches expected data.
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 281)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 282) expected: file that contains the expected data
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 283) returncode: True if result matches the expected data, False otherwise
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 284) """
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 285) return self._matches('stderr', expected)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 286)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 287)
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 288) @pytest.fixture(scope="module")
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 289) def conf(request):
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 290) """Create a Conf instance and provide it to test functions."""
^8f3ce5b39 (kx 2023-10-28 12:00:06 +0300 291) return Conf(request)