@@ -531,14 +531,15 @@ def test_check_module_path(self):
531531 os .environ ['MODULEPATH' ] = test2
532532 modtool .check_module_path ()
533533 self .assertEqual (modtool .mod_paths , [mod_install_dir , test1 , test2 ])
534- self .assertEqual (os .environ ['MODULEPATH' ], mod_install_dir + ':' + test1 + ':' + test2 )
534+ self .assertEqual (os .environ ['MODULEPATH' ], os . pathsep . join ([ mod_install_dir , test1 , test2 ]) )
535535
536536 # check behaviour if non-existing directories are included in $MODULEPATH
537537 os .environ ['MODULEPATH' ] = '%s:/does/not/exist:%s' % (test3 , test2 )
538538 modtool .check_module_path ()
539539 # non-existing dir is filtered from mod_paths, but stays in $MODULEPATH
540540 self .assertEqual (modtool .mod_paths , [mod_install_dir , test1 , test3 , test2 ])
541- self .assertEqual (os .environ ['MODULEPATH' ], ':' .join ([mod_install_dir , test1 , test3 , '/does/not/exist' , test2 ]))
541+ self .assertEqual (os .environ ['MODULEPATH' ],
542+ os .pathsep .join ([mod_install_dir , test1 , test3 , '/does/not/exist' , test2 ]))
542543
543544 def test_check_module_path_hmns (self ):
544545 """Test behaviour of check_module_path with HierarchicalMNS."""
@@ -1090,8 +1091,9 @@ def test_module_caches(self):
10901091 """Test module caches and invalidate_module_caches_for function."""
10911092 self .assertEqual (mod .MODULE_AVAIL_CACHE , {})
10921093
1093- # purposely extending $MODULEPATH with non-existing path, should be handled fine
1094+ # purposely extending $MODULEPATH with an empty path, should be handled fine
10941095 nonpath = os .path .join (self .test_prefix , 'nosuchfileordirectory' )
1096+ mkdir (nonpath )
10951097 self .modtool .use (nonpath )
10961098 modulepaths = [p for p in os .environ .get ('MODULEPATH' , '' ).split (os .pathsep ) if p ]
10971099 self .assertTrue (any ([os .path .samefile (nonpath , mp ) for mp in modulepaths ]))
@@ -1164,6 +1166,11 @@ def test_module_use_unuse(self):
11641166 self .modtool .use (test_dir3 )
11651167 self .assertTrue (os .environ ['MODULEPATH' ].startswith ('%s:' % test_dir3 ))
11661168
1169+ # Adding an empty modulepath is not possible
1170+ modulepath = os .environ .get ('MODULEPATH' , '' )
1171+ self .assertErrorRegex (EasyBuildError , "Cannot add empty path" , self .modtool .use , '' )
1172+ self .assertEqual (os .environ .get ('MODULEPATH' , '' ), modulepath )
1173+
11671174 # make sure the right test module is loaded
11681175 self .modtool .load (['test' ])
11691176 self .assertEqual (os .getenv ('TEST123' ), 'three' )
@@ -1224,17 +1231,67 @@ def test_module_use_unuse(self):
12241231 self .assertFalse ('MODULEPATH' in os .environ )
12251232 os .environ ['MODULEPATH' ] = old_module_path # Restore
12261233
1227- # Using an empty path still works (technically) (Lmod only, ignored by Tcl)
1228- old_module_path = os .environ ['MODULEPATH' ]
1229- self .modtool .use ('' )
1230- self .assertEqual (os .environ ['MODULEPATH' ], ':' + old_module_path )
1231- self .modtool .unuse ('' )
1232- self .assertEqual (os .environ ['MODULEPATH' ], old_module_path )
1233- # Even works when the whole path is empty
1234- os .environ ['MODULEPATH' ] = ''
1235- self .modtool .unuse ('' )
1236- self .assertFalse ('MODULEPATH' in os .environ )
1237- os .environ ['MODULEPATH' ] = old_module_path # Restore
1234+ def test_add_and_remove_module_path (self ):
1235+ """Test add_module_path and whether remove_module_path undoes changes of add_module_path"""
1236+ test_dir1 = tempfile .mkdtemp (suffix = "_dir1" )
1237+ test_dir2 = tempfile .mkdtemp (suffix = "_dir2" )
1238+ old_module_path = os .environ .get ('MODULEPATH' )
1239+ del os .environ ['MODULEPATH' ]
1240+ self .modtool .add_module_path (test_dir1 )
1241+ self .assertEqual (os .environ ['MODULEPATH' ], test_dir1 )
1242+ self .modtool .add_module_path (test_dir2 )
1243+ test_dir_2_and_1 = os .pathsep .join ([test_dir2 , test_dir1 ])
1244+ self .assertEqual (os .environ ['MODULEPATH' ], test_dir_2_and_1 )
1245+ # Adding the same path does not change the path
1246+ self .modtool .add_module_path (test_dir1 )
1247+ self .assertEqual (os .environ ['MODULEPATH' ], test_dir_2_and_1 )
1248+ self .modtool .add_module_path (test_dir2 )
1249+ self .assertEqual (os .environ ['MODULEPATH' ], test_dir_2_and_1 )
1250+ # Even when a (meaningless) slash is added
1251+ # This occurs when using an empty modules directory name
1252+ self .modtool .add_module_path (os .path .join (test_dir1 , '' ))
1253+ self .assertEqual (os .environ ['MODULEPATH' ], test_dir_2_and_1 )
1254+
1255+ # Similar tests for remove_module_path
1256+ self .modtool .remove_module_path (test_dir2 )
1257+ self .assertEqual (os .environ ['MODULEPATH' ], test_dir1 )
1258+ # Same again -> no-op
1259+ self .modtool .remove_module_path (test_dir2 )
1260+ self .assertEqual (os .environ ['MODULEPATH' ], test_dir1 )
1261+ # And with empty last part
1262+ self .modtool .remove_module_path (os .path .join (test_dir1 , '' ))
1263+ self .assertEqual (os .environ .get ('MODULEPATH' , '' ), '' )
1264+
1265+ # And with some more trickery
1266+ # Lmod seems to remove empty paths: /foo//bar/. -> /foo/bar
1267+ # Environment-Modules 4.x seems to resolve relative paths: /foo/../foo -> /foo
1268+ # Hence we can only check the real paths
1269+ def get_resolved_module_path ():
1270+ return os .pathsep .join (os .path .realpath (p ) for p in os .environ ['MODULEPATH' ].split (os .pathsep ))
1271+
1272+ test_dir1_relative = os .path .join (test_dir1 , '..' , os .path .basename (test_dir1 ))
1273+ test_dir2_dot = os .path .join (os .path .dirname (test_dir2 ), '.' , os .path .basename (test_dir2 ))
1274+ self .modtool .add_module_path (test_dir1_relative )
1275+ self .assertEqual (get_resolved_module_path (), test_dir1 )
1276+ # Adding the same path, but in a different form may be possible, but may also be ignored, e.g. in EnvModules
1277+ self .modtool .add_module_path (test_dir1 )
1278+ if get_resolved_module_path () != test_dir1 :
1279+ self .assertEqual (get_resolved_module_path (), os .pathsep .join ([test_dir1 , test_dir1 ]))
1280+ self .modtool .remove_module_path (test_dir1 )
1281+ self .assertEqual (get_resolved_module_path (), test_dir1 )
1282+ self .modtool .add_module_path (test_dir2_dot )
1283+ self .assertEqual (get_resolved_module_path (), test_dir_2_and_1 )
1284+ self .modtool .remove_module_path (test_dir2_dot )
1285+ self .assertEqual (get_resolved_module_path (), test_dir1 )
1286+ # Force adding such a dot path which can be removed with either variant
1287+ os .environ ['MODULEPATH' ] = os .pathsep .join ([test_dir2_dot , test_dir1_relative ])
1288+ self .modtool .remove_module_path (test_dir2_dot )
1289+ self .assertEqual (get_resolved_module_path (), test_dir1 )
1290+ os .environ ['MODULEPATH' ] = os .pathsep .join ([test_dir2_dot , test_dir1_relative ])
1291+ self .modtool .remove_module_path (test_dir2 )
1292+ self .assertEqual (get_resolved_module_path (), test_dir1 )
1293+
1294+ os .environ ['MODULEPATH' ] = old_module_path # Restore
12381295
12391296 def test_module_use_bash (self ):
12401297 """Test whether effect of 'module use' is preserved when a new bash session is started."""
0 commit comments