22#
33# SPDX-License-Identifier: Apache-2.0
44
5+ import contextlib
56import os
67import platform
78import shutil
1314
1415import pytest
1516
16- from west import configuration as config
17-
1817GIT = shutil .which ('git' )
1918
2019# Git capabilities are discovered at runtime in
6261WINDOWS = (platform .system () == 'Windows' )
6362
6463#
65- # Test fixtures
64+ # Contextmanager
65+ #
66+
67+ @contextlib .contextmanager
68+ def update_env (env : dict [str , str | None ]):
69+ """
70+ Temporarily update the process environment variables.
71+ This context manager updates `os.environ` with the key-value pairs
72+ provided in the `env` dictionary for the duration of the `with` block.
73+ Any existing environment variables are preserved and restored when
74+ the block exits.
75+ If the value is set to None, the environment variable is unset.
76+ """
77+ env_bak = dict (os .environ )
78+ env_vars = {}
79+ for k , v in env .items ():
80+ # unset if value is None
81+ if v is None and k in os .environ :
82+ del os .environ [k ]
83+ # set env variable to new value only if v is not None
84+ elif v is not None :
85+ env_vars [k ] = v
86+ # apply the new environment
87+ os .environ .update (env_vars )
88+ try :
89+ yield
90+ finally :
91+ # reset to previous environment
92+ os .environ .clear ()
93+ os .environ .update (env_bak )
94+
95+
96+ @contextlib .contextmanager
97+ def chdir (path ):
98+ """
99+ Temporarily change the current working directory.
100+ This context manager changes the current working directory to `path`
101+ for the duration of the `with` block. After the block exits, the
102+ working directory is restored to its original value.
103+ """
104+ oldpwd = os .getcwd ()
105+ os .chdir (path )
106+ try :
107+ yield
108+ finally :
109+ os .chdir (oldpwd )
110+
111+
112+ #
113+ # Test fixtures (autouse=True)
66114#
67115
68116@pytest .fixture (scope = 'session' , autouse = True )
@@ -86,6 +134,36 @@ def _check_git_capabilities(tmpdir_factory):
86134 except subprocess .CalledProcessError :
87135 pass
88136
137+ @pytest .fixture (autouse = True )
138+ def independent_global_and_system_config (tmpdir_factory ):
139+ # Fixture to ensure that the user's actual global and system configuration
140+ # files are neither used nor touched during test.
141+ #
142+ # We also set ZEPHYR_BASE (to avoid complaints in subcommand
143+ # stderr), but to a spurious location (so that attempts to read
144+ # from inside of it are caught here).
145+ #
146+ tmpdir = Path (tmpdir_factory .mktemp ("test-configs" ))
147+
148+ # config paths
149+ system = tmpdir / 'config.system'
150+ glbl = tmpdir / 'config.global'
151+
152+ # run with environment variables set
153+ with update_env (
154+ {
155+ 'WEST_CONFIG_SYSTEM' : str (system ),
156+ 'WEST_CONFIG_GLOBAL' : str (glbl ),
157+ 'ZEPHYR_BASE' : str (tmpdir / 'no-zephyr-here' ),
158+ }
159+ ):
160+ yield
161+
162+
163+ #
164+ # Test fixtures
165+ #
166+
89167@pytest .fixture (scope = 'session' )
90168def _session_repos (tmp_path_factory ):
91169 '''Just a helper, do not use directly.'''
@@ -237,66 +315,20 @@ def west_init_tmpdir(repos_tmpdir):
237315@pytest .fixture
238316def config_tmpdir (tmpdir ):
239317 # Fixture for running from a temporary directory with
240- # environmental overrides in place so all configuration files
241- # live inside of it. This makes sure we don't touch
242- # the user's actual files.
243- #
244- # We also set ZEPHYR_BASE (to avoid complaints in subcommand
245- # stderr), but to a spurious location (so that attempts to read
246- # from inside of it are caught here).
318+ # environmental overrides in place so local configuration file
319+ # live inside of it. This ensures we don't touch the user's local config.
247320 #
248321 # Using this makes the tests run faster than if we used
249322 # west_init_tmpdir from conftest.py, and also ensures that the
250323 # configuration code doesn't depend on features like the existence
251324 # of a manifest file, helping separate concerns.
252- system = tmpdir / 'config.system'
253- glbl = tmpdir / 'config.global'
254- local = tmpdir / 'config.local'
255-
256- os .environ ['ZEPHYR_BASE' ] = str (tmpdir .join ('no-zephyr-here' ))
257- os .environ ['WEST_CONFIG_SYSTEM' ] = str (system )
258- os .environ ['WEST_CONFIG_GLOBAL' ] = str (glbl )
259- os .environ ['WEST_CONFIG_LOCAL' ] = str (local )
260325
261- # Make sure our environment variables (as well as other topdirs)
262- # are respected from tmpdir, and we aren't going to touch the
263- # user's real files.
264- start_dir = os .getcwd ()
265- tmpdir .chdir ()
326+ # determine a local config in tmp dir
327+ local_config = tmpdir / 'config.local'
266328
267- try :
268- assert config ._location (config .ConfigFile .SYSTEM ) == str (system )
269- assert config ._location (config .ConfigFile .GLOBAL ) == str (glbl )
270- td = tmpdir / 'test-topdir'
271- td .ensure (dir = True )
272- (td / '.west' ).ensure (dir = True )
273- (td / '.west' / 'config' ).ensure (file = True )
274- assert config ._location (config .ConfigFile .LOCAL ) == str (local )
275- assert (config ._location (config .ConfigFile .LOCAL ,
276- topdir = str (td )) ==
277- str (local ))
278- td .remove (rec = 1 )
279- assert not td .exists ()
280-
281- assert not local .exists ()
282-
283- # All clear: switch to the temporary directory and run the test.
329+ # run the test within tmpdir and with env variable set
330+ with chdir (tmpdir ), update_env ({'WEST_CONFIG_LOCAL' : str (local_config )}):
284331 yield tmpdir
285- finally :
286- # Go back to where we started, for repeatability of results.
287- os .chdir (start_dir )
288-
289- # Clean up after ourselves so other test cases don't know
290- # about this tmpdir. It's OK if test cases deleted these
291- # settings already.
292- if 'ZEPHYR_BASE' in os .environ :
293- del os .environ ['ZEPHYR_BASE' ]
294- if 'WEST_CONFIG_SYSTEM' in os .environ :
295- del os .environ ['WEST_CONFIG_SYSTEM' ]
296- if 'WEST_CONFIG_GLOBAL' in os .environ :
297- del os .environ ['WEST_CONFIG_GLOBAL' ]
298- if 'WEST_CONFIG_LOCAL' in os .environ :
299- del os .environ ['WEST_CONFIG_LOCAL' ]
300332
301333#
302334# Helper functions
0 commit comments