@@ -282,6 +282,106 @@ def test_load(self):
282282 self .assertEqual (os .environ .get ('EBROOTGCC' ), None )
283283 self .assertFalse (loaded_modules [- 1 ] == 'GCC/6.4.0-2.28' )
284284
285+ def test_curr_module_paths (self ):
286+ """Test for curr_module_paths function."""
287+
288+ # first, create a couple of (empty) directories to use as entries in $MODULEPATH
289+ test1 = os .path .join (self .test_prefix , 'test1' )
290+ mkdir (test1 )
291+ test2 = os .path .join (self .test_prefix , 'test2' )
292+ mkdir (test2 )
293+ test3 = os .path .join (self .test_prefix , 'test3' )
294+ mkdir (test3 )
295+
296+ os .environ ['MODULEPATH' ] = ''
297+ self .assertEqual (curr_module_paths (), [])
298+
299+ os .environ ['MODULEPATH' ] = '%s:%s:%s' % (test1 , test2 , test3 )
300+ self .assertEqual (curr_module_paths (), [test1 , test2 , test3 ])
301+
302+ # empty entries and non-existing directories are filtered out
303+ os .environ ['MODULEPATH' ] = '/doesnotexist:%s::%s:' % (test2 , test1 )
304+ self .assertEqual (curr_module_paths (), [test2 , test1 ])
305+
306+ def test_check_module_path (self ):
307+ """Test ModulesTool.check_module_path() method"""
308+
309+ # first, create a couple of (empty) directories to use as entries in $MODULEPATH
310+ test1 = os .path .join (self .test_prefix , 'test1' )
311+ mkdir (test1 )
312+ test2 = os .path .join (self .test_prefix , 'test2' )
313+ mkdir (test2 )
314+ test3 = os .path .join (self .test_prefix , 'test3' )
315+ mkdir (test3 )
316+
317+ os .environ ['MODULEPATH' ] = test1
318+
319+ modtool = modules_tool ()
320+
321+ # directory where modules are installed based on current configuration is automatically added in front
322+ mod_install_dir = os .path .join (self .test_installpath , 'modules' , 'all' )
323+ self .assertEqual (modtool .mod_paths , [mod_install_dir , test1 ])
324+
325+ # if mod_paths is reset, it can be restored using check_module_path
326+ modtool .mod_paths = None
327+ modtool .check_module_path ()
328+ self .assertEqual (modtool .mod_paths , [mod_install_dir , test1 ])
329+
330+ # no harm done with multiple subsequent calls
331+ modtool .check_module_path ()
332+ self .assertEqual (modtool .mod_paths , [mod_install_dir , test1 ])
333+
334+ # if $MODULEPATH is tweaked, mod_paths and $MODULEPATH can be corrected with check_module_path
335+ os .environ ['MODULEPATH' ] = test2
336+ modtool .check_module_path ()
337+ self .assertEqual (modtool .mod_paths , [mod_install_dir , test1 , test2 ])
338+ self .assertEqual (os .environ ['MODULEPATH' ], mod_install_dir + ':' + test1 + ':' + test2 )
339+
340+ # check behaviour if non-existing directories are included in $MODULEPATH
341+ os .environ ['MODULEPATH' ] = '%s:/does/not/exist:%s' % (test3 , test2 )
342+ modtool .check_module_path ()
343+ # non-existing dir is filtered from mod_paths, but stays in $MODULEPATH
344+ self .assertEqual (modtool .mod_paths , [mod_install_dir , test1 , test3 , test2 ])
345+ self .assertEqual (os .environ ['MODULEPATH' ], ':' .join ([mod_install_dir , test1 , test3 , '/does/not/exist' , test2 ]))
346+
347+ def test_check_module_path_hmns (self ):
348+ """Test behaviour of check_module_path with HierarchicalMNS."""
349+
350+ # to verify that https://github.com/easybuilders/easybuild-framework/issues/3084 is fixed
351+ # (see also https://github.com/easybuilders/easybuild-framework/issues/2226);
352+ # this bug can be triggered by having at least one non-existing directory in $MODULEPATH,
353+ # and using HierarchicalMNS
354+
355+ os .environ ['EASYBUILD_MODULE_NAMING_SCHEME' ] = 'HierarchicalMNS'
356+ init_config ()
357+
358+ top_mod_dir = os .path .join (self .test_installpath , 'modules' , 'all' )
359+ core_mod_dir = os .path .join (top_mod_dir , 'Core' )
360+ mkdir (core_mod_dir , parents = True )
361+
362+ doesnotexist = os .path .join (self .test_prefix , 'doesnotexist' )
363+ self .assertFalse (os .path .exists (doesnotexist ))
364+
365+ os .environ ['MODULEPATH' ] = '%s:%s' % (core_mod_dir , doesnotexist )
366+ modtool = modules_tool ()
367+
368+ self .assertEqual (modtool .mod_paths , [os .path .dirname (core_mod_dir ), core_mod_dir ])
369+ self .assertEqual (os .environ ['MODULEPATH' ], '%s:%s:%s' % (top_mod_dir , core_mod_dir , doesnotexist ))
370+
371+ # hack prepend_module_path to make sure it's not called again if check_module_path is called again;
372+ # prepend_module_path is fairly expensive, so should be avoided,
373+ # see https://github.com/easybuilders/easybuild-framework/issues/3084
374+ def broken_prepend_module_path (* args , ** kwargs ):
375+ raise EasyBuildError ("broken prepend_module_path" )
376+
377+ modtool .prepend_module_path = broken_prepend_module_path
378+
379+ # if this doesn't trigger a raised error from the hacked prepend_module_path, the bug is fixed
380+ modtool .check_module_path ()
381+
382+ self .assertEqual (modtool .mod_paths , [os .path .dirname (core_mod_dir ), core_mod_dir ])
383+ self .assertEqual (os .environ ['MODULEPATH' ], '%s:%s:%s' % (top_mod_dir , core_mod_dir , doesnotexist ))
384+
285385 def test_prepend_module_path (self ):
286386 """Test prepend_module_path method."""
287387 test_path = tempfile .mkdtemp (prefix = self .test_prefix )
0 commit comments