test/environment.py: ported to pytest, added a test on separators (#3375)

This commit is contained in:
Massimiliano Culpo 2017-03-07 16:03:12 +01:00 committed by Todd Gamblin
parent 3d9cd72e33
commit c6d9a45f18

View File

@ -22,46 +22,41 @@
# License along with this program; if not, write to the Free Software # License along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA # Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
############################################################################## ##############################################################################
import unittest
import os import os
import pytest
from spack import spack_root from spack import spack_root
from llnl.util.filesystem import join_path
from spack.environment import EnvironmentModifications from spack.environment import EnvironmentModifications
from spack.environment import SetEnv, UnsetEnv
from spack.environment import RemovePath, PrependPath, AppendPath from spack.environment import RemovePath, PrependPath, AppendPath
from spack.environment import SetEnv, UnsetEnv
from spack.util.environment import filter_system_paths, filter_system_bin_paths from spack.util.environment import filter_system_paths, filter_system_bin_paths
class EnvironmentTest(unittest.TestCase): @pytest.fixture()
def prepare_environment_for_tests():
def setUp(self): """Sets a few dummy variables in the current environment, that will be
useful for the tests below.
"""
os.environ['UNSET_ME'] = 'foo' os.environ['UNSET_ME'] = 'foo'
os.environ['EMPTY_PATH_LIST'] = '' os.environ['EMPTY_PATH_LIST'] = ''
os.environ['PATH_LIST'] = '/path/second:/path/third' os.environ['PATH_LIST'] = '/path/second:/path/third'
os.environ['REMOVE_PATH_LIST'] = \ os.environ['REMOVE_PATH_LIST'] = '/a/b:/duplicate:/a/c:/remove/this:/a/d:/duplicate/:/f/g' # NOQA: ignore=E501
'/a/b:/duplicate:/a/c:/remove/this:/a/d:/duplicate/:/f/g' yield
for x in ('UNSET_ME', 'EMPTY_PATH_LIST', 'PATH_LIST', 'REMOVE_PATH_LIST'):
if x in os.environ:
del os.environ[x]
def tearDown(self):
pass
def test_set(self): @pytest.fixture
env = EnvironmentModifications() def env(prepare_environment_for_tests):
env.set('A', 'dummy value') """Returns an empty EnvironmentModifications object."""
env.set('B', 3) return EnvironmentModifications()
env.apply_modifications()
self.assertEqual('dummy value', os.environ['A'])
self.assertEqual(str(3), os.environ['B'])
def test_unset(self):
env = EnvironmentModifications()
self.assertEqual('foo', os.environ['UNSET_ME'])
env.unset('UNSET_ME')
env.apply_modifications()
self.assertRaises(KeyError, os.environ.__getitem__, 'UNSET_ME')
def test_filter_system_paths(self): @pytest.fixture
filtered = filter_system_paths([ def miscellaneous_paths():
"""Returns a list of paths, including system ones."""
return [
'/usr/local/Cellar/gcc/5.3.0/lib', '/usr/local/Cellar/gcc/5.3.0/lib',
'/usr/local/lib', '/usr/local/lib',
'/usr/local', '/usr/local',
@ -75,37 +70,108 @@ def test_filter_system_paths(self):
'/lib64', '/lib64',
'/include', '/include',
'/opt/some-package/include', '/opt/some-package/include',
]) ]
self.assertEqual(filtered,
['/usr/local/Cellar/gcc/5.3.0/lib',
'/usr/local/opt/some-package/lib',
'/usr/opt/lib',
'/opt/some-package/include'])
filtered = filter_system_bin_paths([
@pytest.fixture
def bin_paths():
"""Returns a list of bin paths, including system ones."""
return [
'/usr/local/Cellar/gcc/5.3.0/bin', '/usr/local/Cellar/gcc/5.3.0/bin',
'/usr/local/bin', '/usr/local/bin',
'/usr/local/opt/some-package/bin', '/usr/local/opt/some-package/bin',
'/usr/opt/bin', '/usr/opt/bin',
'/bin', '/bin',
'/opt/some-package/bin', '/opt/some-package/bin',
]) ]
self.assertEqual(filtered,
['/usr/local/bin',
@pytest.fixture
def files_to_be_sourced():
"""Returns a list of files to be sourced"""
datadir = os.path.join(
spack_root, 'lib', 'spack', 'spack', 'test', 'data'
)
files = [
os.path.join(datadir, 'sourceme_first.sh'),
os.path.join(datadir, 'sourceme_second.sh'),
os.path.join(datadir, 'sourceme_parameters.sh intel64')
]
return files
def test_set(env):
"""Tests setting values in the environment."""
# Here we are storing the commands to set a couple of variables
env.set('A', 'dummy value')
env.set('B', 3)
# ...and then we are executing them
env.apply_modifications()
assert 'dummy value' == os.environ['A']
assert str(3) == os.environ['B']
def test_unset(env):
"""Tests unsetting values in the environment."""
# Assert that the target variable is there and unset it
assert 'foo' == os.environ['UNSET_ME']
env.unset('UNSET_ME')
env.apply_modifications()
# Trying to retrieve is after deletion should cause a KeyError
with pytest.raises(KeyError):
os.environ['UNSET_ME']
def test_filter_system_paths(miscellaneous_paths):
"""Tests that the filtering of system paths works as expected."""
filtered = filter_system_paths(miscellaneous_paths)
expected = [
'/usr/local/Cellar/gcc/5.3.0/lib',
'/usr/local/opt/some-package/lib',
'/usr/opt/lib',
'/opt/some-package/include'
]
assert filtered == expected
def test_filter_system_bin_paths(bin_paths):
"""Tests that the filtering of system bin paths works as expected."""
filtered = filter_system_bin_paths(bin_paths)
expected = [
'/usr/local/bin',
'/bin', '/bin',
'/usr/local/Cellar/gcc/5.3.0/bin', '/usr/local/Cellar/gcc/5.3.0/bin',
'/usr/local/opt/some-package/bin', '/usr/local/opt/some-package/bin',
'/usr/opt/bin', '/usr/opt/bin',
'/opt/some-package/bin']) '/opt/some-package/bin'
]
assert filtered == expected
def test_set_path(self):
env = EnvironmentModifications() def test_set_path(env):
"""Tests setting paths in an environment variable."""
# Check setting paths with the default separator
env.set_path('A', ['foo', 'bar', 'baz']) env.set_path('A', ['foo', 'bar', 'baz'])
env.apply_modifications() env.apply_modifications()
self.assertEqual('foo:bar:baz', os.environ['A'])
def test_path_manipulation(self): assert 'foo:bar:baz' == os.environ['A']
env = EnvironmentModifications()
env.set_path('B', ['foo', 'bar', 'baz'], separator=';')
env.apply_modifications()
assert 'foo;bar;baz' == os.environ['B']
def test_path_manipulation(env):
"""Tests manipulating list of paths in the environment."""
env.append_path('PATH_LIST', '/path/last') env.append_path('PATH_LIST', '/path/last')
env.prepend_path('PATH_LIST', '/path/first') env.prepend_path('PATH_LIST', '/path/first')
@ -122,82 +188,80 @@ def test_path_manipulation(self):
env.remove_path('REMOVE_PATH_LIST', '/duplicate/') env.remove_path('REMOVE_PATH_LIST', '/duplicate/')
env.apply_modifications() env.apply_modifications()
self.assertEqual(
'/path/first:/path/second:/path/third:/path/last',
os.environ['PATH_LIST']
)
self.assertEqual(
'/path/first:/path/middle:/path/last',
os.environ['EMPTY_PATH_LIST']
)
self.assertEqual(
'/path/first:/path/middle:/path/last',
os.environ['NEWLY_CREATED_PATH_LIST']
)
self.assertEqual('/a/b:/a/c:/a/d:/f/g', os.environ['REMOVE_PATH_LIST'])
def test_extra_arguments(self): expected = '/path/first:/path/second:/path/third:/path/last'
env = EnvironmentModifications() assert os.environ['PATH_LIST'] == expected
expected = '/path/first:/path/middle:/path/last'
assert os.environ['EMPTY_PATH_LIST'] == expected
expected = '/path/first:/path/middle:/path/last'
assert os.environ['NEWLY_CREATED_PATH_LIST'] == expected
assert os.environ['REMOVE_PATH_LIST'] == '/a/b:/a/c:/a/d:/f/g'
def test_extra_arguments(env):
"""Tests that we can attach extra arguments to any command."""
env.set('A', 'dummy value', who='Pkg1') env.set('A', 'dummy value', who='Pkg1')
for x in env: for x in env:
assert 'who' in x.args assert 'who' in x.args
env.apply_modifications()
self.assertEqual('dummy value', os.environ['A'])
def test_extend(self): env.apply_modifications()
env = EnvironmentModifications() assert 'dummy value' == os.environ['A']
def test_extend(env):
"""Tests that we can construct a list of environment modifications
starting from another list.
"""
env.set('A', 'dummy value') env.set('A', 'dummy value')
env.set('B', 3) env.set('B', 3)
copy_construct = EnvironmentModifications(env) copy_construct = EnvironmentModifications(env)
self.assertEqual(len(copy_construct), 2)
assert len(copy_construct) == 2
for x, y in zip(env, copy_construct): for x, y in zip(env, copy_construct):
assert x is y assert x is y
def test_source_files(self):
datadir = join_path(spack_root, 'lib', 'spack', @pytest.mark.usefixtures('prepare_environment_for_tests')
'spack', 'test', 'data') def test_source_files(files_to_be_sourced):
files = [ """Tests the construction of a list of environment modifications that are
join_path(datadir, 'sourceme_first.sh'), the result of sourcing a file.
join_path(datadir, 'sourceme_second.sh'), """
join_path(datadir, 'sourceme_parameters.sh intel64')
] env = EnvironmentModifications.from_sourcing_files(*files_to_be_sourced)
env = EnvironmentModifications.from_sourcing_files(*files)
modifications = env.group_by_name() modifications = env.group_by_name()
# This is sensitive to the user's environment; can include # This is sensitive to the user's environment; can include
# spurious entries for things like PS1 # spurious entries for things like PS1
# #
# TODO: figure out how to make a bit more robust. # TODO: figure out how to make a bit more robust.
self.assertTrue(len(modifications) >= 4) assert len(modifications) >= 4
# Set new variables # Set new variables
self.assertEqual(len(modifications['NEW_VAR']), 1) assert len(modifications['NEW_VAR']) == 1
self.assertTrue(isinstance(modifications['NEW_VAR'][0], SetEnv)) assert isinstance(modifications['NEW_VAR'][0], SetEnv)
self.assertEqual(modifications['NEW_VAR'][0].value, 'new') assert modifications['NEW_VAR'][0].value == 'new'
self.assertEqual(len(modifications['FOO']), 1) assert len(modifications['FOO']) == 1
self.assertTrue(isinstance(modifications['FOO'][0], SetEnv)) assert isinstance(modifications['FOO'][0], SetEnv)
self.assertEqual(modifications['FOO'][0].value, 'intel64') assert modifications['FOO'][0].value == 'intel64'
# Unset variables # Unset variables
self.assertEqual(len(modifications['EMPTY_PATH_LIST']), 1) assert len(modifications['EMPTY_PATH_LIST']) == 1
self.assertTrue(isinstance( assert isinstance(modifications['EMPTY_PATH_LIST'][0], UnsetEnv)
modifications['EMPTY_PATH_LIST'][0], UnsetEnv))
# Modified variables
self.assertEqual(len(modifications['UNSET_ME']), 1)
self.assertTrue(isinstance(modifications['UNSET_ME'][0], SetEnv))
self.assertEqual(modifications['UNSET_ME'][0].value, 'overridden')
self.assertEqual(len(modifications['PATH_LIST']), 3) # Modified variables
self.assertTrue( assert len(modifications['UNSET_ME']) == 1
isinstance(modifications['PATH_LIST'][0], RemovePath) assert isinstance(modifications['UNSET_ME'][0], SetEnv)
) assert modifications['UNSET_ME'][0].value == 'overridden'
self.assertEqual(modifications['PATH_LIST'][0].value, '/path/third')
self.assertTrue( assert len(modifications['PATH_LIST']) == 3
isinstance(modifications['PATH_LIST'][1], AppendPath) assert isinstance(modifications['PATH_LIST'][0], RemovePath)
) assert modifications['PATH_LIST'][0].value == '/path/third'
self.assertEqual(modifications['PATH_LIST'][1].value, '/path/fourth') assert isinstance(modifications['PATH_LIST'][1], AppendPath)
self.assertTrue( assert modifications['PATH_LIST'][1].value == '/path/fourth'
isinstance(modifications['PATH_LIST'][2], PrependPath) assert isinstance(modifications['PATH_LIST'][2], PrependPath)
) assert modifications['PATH_LIST'][2].value == '/path/first'
self.assertEqual(modifications['PATH_LIST'][2].value, '/path/first')