-
Notifications
You must be signed in to change notification settings - Fork 205
/
Copy pathenvironment.py
172 lines (142 loc) · 6.35 KB
/
environment.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
# #
# Copyright 2015-2025 Ghent University
#
# This file is part of EasyBuild,
# originally created by the HPC team of Ghent University (http://ugent.be/hpc/en),
# with support of Ghent University (http://ugent.be/hpc),
# the Flemish Supercomputer Centre (VSC) (https://www.vscentrum.be),
# Flemish Research Foundation (FWO) (http://www.fwo.be/en)
# and the Department of Economy, Science and Innovation (EWI) (http://www.ewi-vlaanderen.be/en).
#
# https://github.com/easybuilders/easybuild
#
# EasyBuild is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation v2.
#
# EasyBuild is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with EasyBuild. If not, see <http://www.gnu.org/licenses/>.
# #
"""
Unit tests for environment.py
@author: Kenneth Hoste (Ghent University)
"""
import os
import sys
from test.framework.utilities import EnhancedTestCase, TestLoaderFiltered, init_config
from unittest import TextTestRunner
import easybuild.tools.environment as env
class EnvironmentTest(EnhancedTestCase):
""" Testcase for run module """
def test_setvar(self):
"""Test setvar function."""
self.mock_stdout(True)
env.setvar('FOO', 'bar')
txt = self.get_stdout()
self.mock_stdout(False)
self.assertEqual(os.getenv('FOO'), 'bar')
self.assertEqual(os.environ['FOO'], 'bar')
# no printing if dry run is not enabled
self.assertEqual(txt, '')
build_options = {
'extended_dry_run': True,
'silent': False,
}
init_config(build_options=build_options)
self.mock_stdout(True)
env.setvar('FOO', 'foobaz')
txt = self.get_stdout()
self.mock_stdout(False)
self.assertEqual(os.getenv('FOO'), 'foobaz')
self.assertEqual(os.environ['FOO'], 'foobaz')
self.assertEqual(txt, " export FOO='foobaz'\n")
# disabling verbose
self.mock_stdout(True)
env.setvar('FOO', 'barfoo', verbose=False)
txt = self.get_stdout()
self.mock_stdout(False)
self.assertEqual(os.getenv('FOO'), 'barfoo')
self.assertEqual(os.environ['FOO'], 'barfoo')
self.assertEqual(txt, '')
def test_modify_env(self):
"""Test for modify_env function."""
old_env_vars = {
'TEST_ENV_VAR_TO_UNSET1': 'foobar',
'TEST_ENV_VAR_TO_UNSET2': 'value does not matter',
'TEST_COMMON_ENV_VAR_CHANGED': 'old_value',
'TEST_COMMON_ENV_VAR_SAME_VALUE': 'this_value_stays',
}
new_env_vars = {
'TEST_COMMON_ENV_VAR_CHANGED': 'new_value',
'TEST_NEW_ENV_VAR1': '1',
'TEST_NEW_ENV_VAR2': 'two 2 two',
'TEST_COMMON_ENV_VAR_SAME_VALUE': 'this_value_stays',
}
# prepare test environment first:
# keys in new_env should not be set yet, keys in old_env are expected to be set
for key in new_env_vars:
os.environ.pop(key, None)
for key in old_env_vars:
os.environ[key] = old_env_vars[key]
env.modify_env(os.environ, new_env_vars)
self.assertEqual(os.environ.get('TEST_ENV_VAR_TO_UNSET1'), None)
self.assertEqual(os.environ.get('TEST_ENV_VAR_TO_UNSET2'), None)
self.assertEqual(os.environ.get('TEST_COMMON_ENV_VAR_CHANGED'), 'new_value')
self.assertEqual(os.environ.get('TEST_COMMON_ENV_VAR_SAME_VALUE'), 'this_value_stays')
self.assertEqual(os.environ.get('TEST_NEW_ENV_VAR1'), '1')
self.assertEqual(os.environ.get('TEST_NEW_ENV_VAR2'), 'two 2 two')
# extreme test case: empty entire environment (original env is restored for next tests)
env.modify_env(os.environ, {})
def test_unset_env_vars(self):
"""Test unset_env_vars function."""
os.environ['TEST_ENV_VAR'] = 'test123'
# it's fair to assume $HOME will always be set
home = os.getenv('HOME')
self.assertTrue(home)
key_not_set = 'NO_SUCH_ENV_VAR'
if key_not_set in os.environ:
del os.environ[key_not_set]
res = env.unset_env_vars(['HOME', 'NO_SUCH_ENV_VAR', 'TEST_ENV_VAR'])
self.assertNotIn('HOME', os.environ)
self.assertNotIn('NO_SUCH_ENV_VAR', os.environ)
self.assertNotIn('TEST_ENV_VAR', os.environ)
expected = {
'HOME': home,
'TEST_ENV_VAR': 'test123',
}
self.assertEqual(res, expected)
def test_sanitize_env(self):
"""Test sanitize_env function."""
# define $*PATH variable that include empty entries, those should get filtered out
os.environ['PATH'] = '/bar::/foo:' + self.test_prefix # middle empty entry
os.environ['LD_LIBRARY_PATH'] = '/apps/slurm/default/lib:/usr/lib:' # trailing empty entry
os.environ['LIBRARY_PATH'] = self.test_prefix + ':' + os.environ['HOME'] # no empty entries here
os.environ['CPATH'] = ':' + self.test_prefix # leading empty entry
os.environ['LD_PRELOAD'] = ':::' # only empty entries (should get unset!)
# define $PYTHON* environment variables, these should be unset by sanitize_env
os.environ['PYTHONNOUSERSITE'] = '1'
os.environ['PYTHONPATH'] = self.test_prefix
os.environ['PYTHONOPTIMIZE'] = '1'
env.sanitize_env()
self.assertFalse(any(x for x in os.environ.keys() if x.startswith('PYTHON')))
expected = {
'CPATH': self.test_prefix,
'LD_LIBRARY_PATH': '/apps/slurm/default/lib:/usr/lib',
'LIBRARY_PATH': self.test_prefix + ':' + os.environ['HOME'],
'PATH': '/bar:/foo:' + self.test_prefix,
}
for key in sorted(expected):
self.assertEqual(os.getenv(key), expected[key])
self.assertEqual(os.environ[key], expected[key])
self.assertEqual(os.getenv('LD_PRELOAD'), None)
def suite():
""" returns all the testcases in this module """
return TestLoaderFiltered().loadTestsFromTestCase(EnvironmentTest, sys.argv[1:])
if __name__ == '__main__':
res = TextTestRunner(verbosity=1).run(suite())
sys.exit(len(res.failures))