~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

TOMOYO Linux Cross Reference
Linux/scripts/kconfig/tests/conftest.py

Version: ~ [ linux-6.12-rc7 ] ~ [ linux-6.11.7 ] ~ [ linux-6.10.14 ] ~ [ linux-6.9.12 ] ~ [ linux-6.8.12 ] ~ [ linux-6.7.12 ] ~ [ linux-6.6.60 ] ~ [ linux-6.5.13 ] ~ [ linux-6.4.16 ] ~ [ linux-6.3.13 ] ~ [ linux-6.2.16 ] ~ [ linux-6.1.116 ] ~ [ linux-6.0.19 ] ~ [ linux-5.19.17 ] ~ [ linux-5.18.19 ] ~ [ linux-5.17.15 ] ~ [ linux-5.16.20 ] ~ [ linux-5.15.171 ] ~ [ linux-5.14.21 ] ~ [ linux-5.13.19 ] ~ [ linux-5.12.19 ] ~ [ linux-5.11.22 ] ~ [ linux-5.10.229 ] ~ [ linux-5.9.16 ] ~ [ linux-5.8.18 ] ~ [ linux-5.7.19 ] ~ [ linux-5.6.19 ] ~ [ linux-5.5.19 ] ~ [ linux-5.4.285 ] ~ [ linux-5.3.18 ] ~ [ linux-5.2.21 ] ~ [ linux-5.1.21 ] ~ [ linux-5.0.21 ] ~ [ linux-4.20.17 ] ~ [ linux-4.19.323 ] ~ [ linux-4.18.20 ] ~ [ linux-4.17.19 ] ~ [ linux-4.16.18 ] ~ [ linux-4.15.18 ] ~ [ linux-4.14.336 ] ~ [ linux-4.13.16 ] ~ [ linux-4.12.14 ] ~ [ linux-4.11.12 ] ~ [ linux-4.10.17 ] ~ [ linux-4.9.337 ] ~ [ linux-4.4.302 ] ~ [ linux-3.10.108 ] ~ [ linux-2.6.32.71 ] ~ [ linux-2.6.0 ] ~ [ linux-2.4.37.11 ] ~ [ unix-v6-master ] ~ [ ccs-tools-1.8.12 ] ~ [ policy-sample ] ~
Architecture: ~ [ i386 ] ~ [ alpha ] ~ [ m68k ] ~ [ mips ] ~ [ ppc ] ~ [ sparc ] ~ [ sparc64 ] ~

Diff markup

Differences between /scripts/kconfig/tests/conftest.py (Architecture i386) and /scripts/kconfig/tests/conftest.py (Architecture mips)


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

~ [ source navigation ] ~ [ diff markup ] ~ [ identifier search ] ~

kernel.org | git.kernel.org | LWN.net | Project Home | SVN repository | Mail admin

Linux® is a registered trademark of Linus Torvalds in the United States and other countries.
TOMOYO® is a registered trademark of NTT DATA CORPORATION.

sflogo.php