##############################################################################
#   Modules Revision 3.0
#   Providing a flexible user environment
#
#   File:		modules.50-cmds/%M%
#   Revision:		%I%
#   First Edition:	2019/02/24
#   Last Mod.:		%U%, %G%
#
#   Authors:		Xavier Delaruelle, xavier.delaruelle@cea.fr
#
#   Description:	Testuite testsequence
#   Command:        load, unload, switch
#   Modulefiles:
#   Sub-Command:    module switch, prereq, conflict
#
#   Comment:	%C{
#           Test automatic resolution of modulefile dependencies defined
#           through 'module switch' command in modulefiles
#		}C%
#
##############################################################################

# CAUTION: it is not recommended to use the `switch` sub-command in
# modulefiles as this command is intended for the command-line for a 2in1
# operation. Could be removed from the modulefile scope in a future
# release. Use `module unload` and `module load` commands in modulefiles
# instead.

# skip tests if implicit_default option could not be overridden
if {[is_config_locked implicit_default]} {
    send_user "\tskipping tests as implicit_default could not be overridden\n"
} else {

set mp $modpath.deps
set mpre $modpathre.deps

# setup specific environment
setenv_path_var MODULEPATH $mp

# ensure load tests have implicit default enabled
setenv_var MODULES_IMPLICIT_DEFAULT 1

# ensure auto symbolic versions are not set for these tests
setenv_var MODULES_ADVANCED_VERSION_SPEC 0


#
# load tests
#

set ans [list]
lappend ans [list setpath LOADEDMODULES swb:swc]
lappend ans [list setpath _LMFILES_ $mp/swb:$mp/swc]
lappend ans [list setpath MODULES_LMPREREQ swc&swb]
lappend ans [list setpath MODULES_LMNOTUASKED swb]
lappend ans [list setpath MODULES_LMCONFLICT swc&swa]
set tserr [list {load swc} {load swb} \n[msg_top_load swc {} swb {}]]
testouterr_cmd_re sh {load --auto swc} $ans [join $tserr \n]
testouterr_cmd_re sh {load --no-auto swc} $ans [join $tserr \n]

setenv_loaded_module [list swa] [list $mp/swa]
set tserr [list {load swc} {unload swa} {load swb} \n[msg_top_load swc swa swb {}]]
testouterr_cmd_re sh {load --auto swc} $ans [join $tserr \n]
testouterr_cmd_re sh {load --no-auto swc} $ans [join $tserr \n]

setenv_loaded_module [list swb] [list $mp/swb]
set ans [list]
lappend ans [list setpath LOADEDMODULES swb:swc]
lappend ans [list setpath _LMFILES_ $mp/swb:$mp/swc]
lappend ans [list setpath MODULES_LMPREREQ swc&swb]
lappend ans [list setpath MODULES_LMCONFLICT swc&swa]
set tserr [list {load swc}]
testouterr_cmd_re sh {load --auto swc} $ans [join $tserr \n]
testouterr_cmd_re sh {load --no-auto swc} $ans [join $tserr \n]

setenv_loaded_module [list swa swb] [list $mp/swa $mp/swb]
set ans [list]
lappend ans [list setpath LOADEDMODULES swb:swc]
lappend ans [list setpath _LMFILES_ $mp/swb:$mp/swc]
lappend ans [list setpath MODULES_LMPREREQ swc&swb]
lappend ans [list setpath MODULES_LMCONFLICT swc&swa]
set tserr [list {load swc} {unload swa} \n[msg_top_load swc swa {} {}]]
testouterr_cmd_re sh {load --auto swc} $ans [join $tserr \n]
testouterr_cmd_re sh {load --no-auto swc} $ans [join $tserr \n]


# conflict against switched-on module set
setenv_loaded_module [list swd] [list $mp/swd]
setenv_path_var MODULES_LMCONFLICT swd&swb
set tserr [list {load swc} {load swb} \n[msg_load swb [err_conflict swd]] \n[msg_load swc [err_swon swb] [err_reqlo swb]]]
testouterr_cmd_re sh {load --auto swc} ERR [join $tserr \n]
testouterr_cmd_re sh {load --no-auto swc} ERR [join $tserr \n]

# force load
set ans [list]
lappend ans [list setpath LOADEDMODULES swd:swb:swc]
lappend ans [list setpath _LMFILES_ $mp/swd:$mp/swb:$mp/swc]
lappend ans [list setpath MODULES_LMPREREQ swc&swb]
lappend ans [list setpath MODULES_LMNOTUASKED swb]
lappend ans [list setpath MODULES_LMCONFLICT swd&swb:swc&swa]
set tserr [list {load swc} {load swb} \n[msg_load swb [err_conlof swd]] \n[msg_top_load swc {} swb {}]]
testouterr_cmd_re sh {load --force --auto swc} $ans [join $tserr \n]
testouterr_cmd_re sh {load --force --no-auto swc} $ans [join $tserr \n]


# prereq on switched-off module set
setenv_loaded_module [list swa swe] [list $mp/swa $mp/swe]
unsetenv_path_var MODULES_LMCONFLICT
setenv_path_var MODULES_LMPREREQ swe&swa
set ans [list]
lappend ans [list setpath MODULES_LMPREREQ swc&swb]
lappend ans [list setpath _LMFILES_ $mp/swb:$mp/swc]
lappend ans [list setpath LOADEDMODULES swb:swc]
lappend ans [list setpath MODULES_LMNOTUASKED swb]
lappend ans [list setpath MODULES_LMCONFLICT swc&swa]
lappend ans [list ERR]
set tserr [list {load swc} {unload swe} {unload swa} {load swb} {load swe} \n[msg_load swe [err_reqmis swa]] \n[msg_top_load swc [list swa] swb [list [list swe] {}] [err_depref swe]]]
testouterr_cmd_re sh {load --auto swc} $ans [join $tserr \n]
set tserr [list {load swc} \n[msg_unload swa [err_prerequn swe]] \n[msg_load swc [err_swoff swa] [err_conun swa]]]
testouterr_cmd_re sh {load --no-auto swc} ERR [join $tserr \n]

# force load
set ans [list]
lappend ans [list setpath LOADEDMODULES swb:swe:swc]
lappend ans [list setpath _LMFILES_ $mp/swb:$mp/swe:$mp/swc]
lappend ans [list setpath MODULES_LMPREREQ swe&swa:swc&swb]
lappend ans [list setpath MODULES_LMNOTUASKED swb]
lappend ans [list setpath MODULES_LMCONFLICT swc&swa]
set tserr [list {load swc} {unload swe} {unload swa} {load swb} {load swe} \n[msg_load swe [err_reqmisf swa]] \n[msg_top_load swc swa swb swe]]
testouterr_cmd_re sh {load --force --auto swc} $ans [join $tserr \n]
set ans [list]
lappend ans [list setpath LOADEDMODULES swe:swb:swc]
lappend ans [list setpath _LMFILES_ $mp/swe:$mp/swb:$mp/swc]
lappend ans [list setpath MODULES_LMPREREQ swe&swa:swc&swb]
lappend ans [list setpath MODULES_LMNOTUASKED swb]
lappend ans [list setpath MODULES_LMCONFLICT swc&swa]
set tserr [list {load swc} {unload swa} \n[msg_unload swa [err_deplof swe]]\n {load swb} \n[msg_top_load swc swa swb {}]]
testouterr_cmd_re sh {load --force --no-auto swc} $ans [join $tserr \n]


# conflict against switched-on module set and prereq on switched-off module set
setenv_loaded_module [list swd swa swe] [list $mp/swd $mp/swa $mp/swe]
setenv_path_var MODULES_LMCONFLICT swd&swb
setenv_path_var MODULES_LMPREREQ swe&swa

set tserr [list {load swc} {unload swe} {unload swa} {load swb} \n[msg_load swb [err_conflict swd]]\n {load swe} \n[msg_load swe [err_reqmis swa]] \n[msg_load swc [err_swon swb] [err_depref swe] [err_reqlo swb]]]
testouterr_cmd_re sh {load --auto swc} ERR [join $tserr \n]
set tserr [list {load swc} \n[msg_unload swa [err_prerequn swe]] \n[msg_load swc [err_swoff swa] [err_conun swa]]]
testouterr_cmd_re sh {load --no-auto swc} ERR [join $tserr \n]

# force load
set ans [list]
lappend ans [list setpath LOADEDMODULES swd:swb:swe:swc]
lappend ans [list setpath _LMFILES_ $mp/swd:$mp/swb:$mp/swe:$mp/swc]
lappend ans [list setpath MODULES_LMPREREQ swe&swa:swc&swb]
lappend ans [list setpath MODULES_LMNOTUASKED swb]
lappend ans [list setpath MODULES_LMCONFLICT swd&swb:swc&swa]
set tserr [list {load swc} {unload swe} {unload swa} {load swb} \n[msg_load swb [err_conlof swd]]\n {load swe} \n[msg_load swe [err_reqmisf swa]] \n[msg_top_load swc swa swb swe]]
testouterr_cmd_re sh {load --force --auto swc} $ans [join $tserr \n]
set ans [list]
lappend ans [list setpath LOADEDMODULES swd:swe:swb:swc]
lappend ans [list setpath _LMFILES_ $mp/swd:$mp/swe:$mp/swb:$mp/swc]
lappend ans [list setpath MODULES_LMPREREQ swe&swa:swc&swb]
lappend ans [list setpath MODULES_LMNOTUASKED swb]
lappend ans [list setpath MODULES_LMCONFLICT swd&swb:swc&swa]
set tserr [list {load swc} {unload swa} \n[msg_unload swa [err_deplof swe]]\n {load swb} \n[msg_load swb [err_conlof swd]] \n[msg_top_load swc swa swb {}]]
testouterr_cmd_re sh {load --force --no-auto swc} $ans [join $tserr \n]


# switched-off module reloaded after switch
setenv_loaded_module [list swb swc] [list $mp/swb $mp/swc] [list swb]
setenv_path_var MODULES_LMPREREQ swc&swb
setenv_path_var MODULES_LMCONFLICT swc&swa

set tserr [list {load swa} \n[msg_load swa [err_conflict swc]]]
testouterr_cmd_re sh {load --auto swa} ERR [join $tserr \n]
testouterr_cmd_re sh {load --no-auto swa} ERR [join $tserr \n]

# force load
set ans [list]
lappend ans [list setpath LOADEDMODULES swb:swc:swa]
lappend ans [list setpath _LMFILES_ $mp/swb:$mp/swc:$mp/swa]
set tserr [list {load swa} \n[msg_load swa [err_conlof swc]]]
testouterr_cmd_re sh {load --force --auto swa} $ans [join $tserr \n]
testouterr_cmd_re sh {load --force --no-auto swa} $ans [join $tserr \n]


#
# unload tests
#

# regular situation loaded
setenv_loaded_module [list swb swc] [list $mp/swb $mp/swc] [list swb]
setenv_path_var MODULES_LMPREREQ swc&swb
setenv_path_var MODULES_LMCONFLICT swc&swa

set ans [list]
lappend ans [list unsetpath LOADEDMODULES]
lappend ans [list unsetpath _LMFILES_]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMCONFLICT]
lappend ans [list unsetpath MODULES_LMNOTUASKED]
set tserr [list {unload swc} {unload swb} \n[msg_top_unload swc {} swb {}]]
testouterr_cmd_re sh {unload --auto swc} $ans [join $tserr \n]
set ans [list]
lappend ans [list unsetpath LOADEDMODULES]
lappend ans [list unsetpath _LMFILES_]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMNOTUASKED]
lappend ans [list unsetpath MODULES_LMCONFLICT]
testouterr_cmd_re sh {unload --no-auto swc} $ans [join $tserr \n]

# unload requirement
set ans [list]
lappend ans [list unsetpath LOADEDMODULES]
lappend ans [list unsetpath _LMFILES_]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMCONFLICT]
lappend ans [list unsetpath MODULES_LMNOTUASKED]
set tserr [list {unload swc} {unload swb} \n[msg_top_unload swb swc {} {}]]
testouterr_cmd_re sh {unload --auto swb} $ans [join $tserr \n]
set tserr [list [msg_unload swb [err_prerequn swc]]]
testouterr_cmd_re sh {unload --no-auto swb} ERR [join $tserr \n]


# requirement module is loaded after its dependent
setenv_loaded_module [list swc swb] [list $mp/swc $mp/swb] [list swb]
setenv_path_var MODULES_LMPREREQ swc&swb
setenv_path_var MODULES_LMCONFLICT swc&swa

set ans [list]
lappend ans [list setpath LOADEDMODULES swb]
lappend ans [list setpath _LMFILES_ $mp/swb]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMCONFLICT]
set tserr [list {unload swc}]
testouterr_cmd_re sh {unload --auto swc} $ans [join $tserr \n]
testouterr_cmd_re sh {unload --no-auto swc} $ans [join $tserr \n]

# unload requirement (which is not seen as requirement as it is loaded after)
set ans [list]
lappend ans [list setpath LOADEDMODULES swc]
lappend ans [list setpath _LMFILES_ $mp/swc]
lappend ans [list unsetpath MODULES_LMNOTUASKED]
set tserr [list {unload swb}]
testouterr_cmd_re sh {unload --auto swb} $ans [join $tserr \n]
testouterr_cmd_re sh {unload --no-auto swb} $ans [join $tserr \n]


# requirement module is loaded after its dependent, one dummy module loaded before
setenv_loaded_module [list aa swc swb] [list $mp/aa $mp/swc $mp/swb] [list swb]
setenv_path_var MODULES_LMPREREQ swc&swb
setenv_path_var MODULES_LMCONFLICT swc&swa

set ans [list]
lappend ans [list setpath LOADEDMODULES aa:swb]
lappend ans [list setpath _LMFILES_ $mp/aa:$mp/swb]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMCONFLICT]
set tserr [list {unload swc}]
testouterr_cmd_re sh {unload --auto swc} $ans [join $tserr \n]
testouterr_cmd_re sh {unload --no-auto swc} $ans [join $tserr \n]


# conflict against switched-on module set still there
setenv_loaded_module [list swd swb swc] [list $mp/swd $mp/swb $mp/swc] [list swb]
setenv_path_var MODULES_LMPREREQ swc&swb
setenv_path_var MODULES_LMCONFLICT swd&swb:swc&swa

set ans [list]
lappend ans [list setpath LOADEDMODULES swd]
lappend ans [list setpath _LMFILES_ $mp/swd]
lappend ans [list setpath MODULES_LMCONFLICT swd&swb]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMNOTUASKED]
set tserr [list {unload swd} {unload swc} {unload swb} {load swd} \n[msg_top_unload swc {} swb swd]]
testouterr_cmd_re sh {unload --auto swc} $ans [join $tserr \n]
set ans [list]
lappend ans [list setpath LOADEDMODULES swd]
lappend ans [list setpath _LMFILES_ $mp/swd]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMNOTUASKED]
lappend ans [list setpath MODULES_LMCONFLICT swd&swb]
set tserr [list {unload swc} {unload swb} \n[msg_top_unload swc {} swb {}]]
testouterr_cmd_re sh {unload --no-auto swc} $ans [join $tserr \n]

# unload module conflicting with requirement
set ans [list]
lappend ans [list setpath LOADEDMODULES swb:swc]
lappend ans [list setpath _LMFILES_ $mp/swb:$mp/swc]
lappend ans [list setpath MODULES_LMPREREQ swc&swb]
lappend ans [list setpath MODULES_LMCONFLICT swc&swa]
lappend ans [list setpath MODULES_LMNOTUASKED swb]
set tserr [list {unload swc} {unload swb} {unload swd} {load swb} {load swc} \n[msg_top_unload swd {} {} [list swb swc]]]
testouterr_cmd_re sh {unload --auto swd} $ans [join $tserr \n]
set ans [list]
lappend ans [list setpath LOADEDMODULES swb:swc]
lappend ans [list setpath _LMFILES_ $mp/swb:$mp/swc]
lappend ans [list setpath MODULES_LMCONFLICT swc&swa]
set tserr [list {unload swd}]
testouterr_cmd_re sh {unload --no-auto swd} $ans [join $tserr \n]

# unload requirement
set ans [list]
lappend ans [list setpath LOADEDMODULES swd]
lappend ans [list setpath _LMFILES_ $mp/swd]
lappend ans [list setpath MODULES_LMCONFLICT swd&swb]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMNOTUASKED]
set tserr [list {unload swd} {unload swc} {unload swb} {load swd} \n[msg_top_unload swb swc {} swd]]
testouterr_cmd_re sh {unload --auto swb} $ans [join $tserr \n]


# switched-off module reloaded after switch
setenv_loaded_module [list swb swc swa] [list $mp/swb $mp/swc $mp/swa] [list swb]
setenv_path_var MODULES_LMPREREQ swc&swb
setenv_path_var MODULES_LMCONFLICT swc&swa

set ans [list]
lappend ans [list setpath LOADEDMODULES swa]
lappend ans [list setpath _LMFILES_ $mp/swa]
lappend ans [list unsetpath MODULES_LMCONFLICT]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMNOTUASKED]
set tserr [list {unload swa} {unload swc} {unload swb} {load swa} \n[msg_top_unload swc {} swb swa]]
testouterr_cmd_re sh {unload --auto swc} $ans [join $tserr \n]
set ans [list]
lappend ans [list setpath LOADEDMODULES swa]
lappend ans [list setpath _LMFILES_ $mp/swa]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMNOTUASKED]
lappend ans [list unsetpath MODULES_LMCONFLICT]
set tserr [list {unload swc} {unload swb} \n[msg_top_unload swc {} swb {}]]
testouterr_cmd_re sh {unload --no-auto swc} $ans [join $tserr \n]

# unload conflict
set ans [list]
lappend ans [list setpath LOADEDMODULES swb:swc]
lappend ans [list setpath _LMFILES_ $mp/swb:$mp/swc]
lappend ans [list setpath MODULES_LMPREREQ swc&swb]
lappend ans [list setpath MODULES_LMCONFLICT swc&swa]
set tserr [list {unload swc} {unload swa} {load swc} \n[msg_top_unload swa {} {} swc]]
testouterr_cmd_re sh {unload --auto swa} $ans [join $tserr \n]
set ans [list]
lappend ans [list setpath LOADEDMODULES swb:swc]
lappend ans [list setpath _LMFILES_ $mp/swb:$mp/swc]
set tserr [list {unload swa}]
testouterr_cmd_re sh {unload --no-auto swa} $ans [join $tserr \n]


# switched-on module not loaded anymore
setenv_loaded_module [list swc] [list $mp/swc]
setenv_path_var MODULES_LMPREREQ swc&swb
setenv_path_var MODULES_LMCONFLICT swc&swa

set ans [list]
lappend ans [list unsetpath LOADEDMODULES]
lappend ans [list unsetpath _LMFILES_]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMCONFLICT]
set tserr [list {unload swc}]
testouterr_cmd_re sh {unload --auto swc} $ans [join $tserr \n]
testouterr_cmd_re sh {unload --no-auto swc} $ans [join $tserr \n]


# another loaded module requires switched-on module
setenv_loaded_module [list swb swc swf] [list $mp/swb $mp/swc $mp/swf] [list swb]
setenv_path_var MODULES_LMPREREQ swc&swb:swf&swb
setenv_path_var MODULES_LMCONFLICT swc&swa

set ans [list]
lappend ans [list setpath LOADEDMODULES swb:swf]
lappend ans [list setpath _LMFILES_ $mp/swb:$mp/swf]
lappend ans [list setpath MODULES_LMPREREQ swf&swb]
lappend ans [list unsetpath MODULES_LMCONFLICT]
set tserr [list {unload swc}]
testouterr_cmd_re sh {unload --auto swc} $ans [join $tserr \n]
testouterr_cmd_re sh {unload --no-auto swc} $ans [join $tserr \n]


# switched-on module manually loaded
setenv_loaded_module [list swb swc] [list $mp/swb $mp/swc]
setenv_path_var MODULES_LMPREREQ swc&swb
setenv_path_var MODULES_LMCONFLICT swc&swa

set ans [list]
lappend ans [list setpath LOADEDMODULES swb]
lappend ans [list setpath _LMFILES_ $mp/swb]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMCONFLICT]
set tserr [list {unload swc}]
testouterr_cmd_re sh {unload --auto swc} $ans [join $tserr \n]
testouterr_cmd_re sh {unload --no-auto swc} $ans [join $tserr \n]


#
# 1-arg-form module switch
#

# load test, empty environment
unsetenv_path_var MODULES_LMPREREQ
unsetenv_path_var MODULES_LMCONFLICT
unsetenv_loaded_module

set ans [list]
lappend ans [list setpath LOADEDMODULES swg/2:swh]
lappend ans [list setpath _LMFILES_ $mp/swg/2:$mp/swh]
lappend ans [list setpath MODULES_LMPREREQ swh&swg]
lappend ans [list setpath MODULES_LMCONFLICT swg/2&swg]
lappend ans [list setpath MODULES_LMNOTUASKED swg/2]
set tserr [list {load swh} {load swg/2} \n[msg_top_load swh {} swg/2 {}]]
testouterr_cmd_re sh {load --auto swh} $ans [join $tserr \n]
testouterr_cmd_re sh {load --no-auto swh} $ans [join $tserr \n]

# load test, conflicting module loaded
setenv_loaded_module [list swg/1] [list $mp/swg/1]
setenv_path_var MODULES_LMCONFLICT swg/1&swg
unsetenv_path_var MODULES_LMPREREQ

set ans [list]
lappend ans [list setpath LOADEDMODULES swg/2:swh]
lappend ans [list setpath _LMFILES_ $mp/swg/2:$mp/swh]
lappend ans [list setpath MODULES_LMPREREQ swh&swg]
lappend ans [list setpath MODULES_LMCONFLICT swg/2&swg]
lappend ans [list setpath MODULES_LMNOTUASKED swg/2]
set tserr [list {load swh} {unload swg/1} {load swg/2} \n[msg_top_load swh swg/1 swg/2 {}]]
testouterr_cmd_re sh {load --auto swh} $ans [join $tserr \n]
testouterr_cmd_re sh {load --no-auto swh} $ans [join $tserr \n]

# load test, requiring module already loaded
setenv_loaded_module [list swg/2] [list $mp/swg/2]
setenv_path_var MODULES_LMCONFLICT swg/2&swg
unsetenv_path_var MODULES_LMPREREQ

set ans [list]
lappend ans [list setpath LOADEDMODULES swg/2:swh]
lappend ans [list setpath _LMFILES_ $mp/swg/2:$mp/swh]
lappend ans [list setpath MODULES_LMPREREQ swh&swg]
lappend ans [list setpath MODULES_LMCONFLICT swg/2&swg]
lappend ans [list setpath MODULES_LMNOTUASKED swg/2]
set tserr [list {load swh} {unload swg/2} {load swg/2} \n[msg_top_load swh swg/2 swg/2 {}]]
testouterr_cmd_re sh {load --auto swh} $ans [join $tserr \n]
testouterr_cmd_re sh {load --no-auto swh} $ans [join $tserr \n]

# load test, conflicting module and requiring module loaded
setenv_loaded_module [list swg/1 swg/2] [list $mp/swg/1 $mp/swg/2]
setenv_path_var MODULES_LMCONFLICT swg/1&swg:swg/2&swg
unsetenv_path_var MODULES_LMPREREQ

set ans [list]
lappend ans [list setpath _LMFILES_ $mp/swg/2:$mp/swh]
lappend ans [list setpath LOADEDMODULES swg/2:swh]
lappend ans [list setpath MODULES_LMPREREQ swh&swg]
lappend ans [list setpath MODULES_LMNOTUASKED swg/2]
lappend ans [list setpath MODULES_LMCONFLICT swg/2&swg]
lappend ans [list ERR]
# as swg/2 is seen as the module to unload for 'module switch swg', swg/1 goes to DepRe
# but then as swg/2 is also seen as the module to load, swg/1 gets an error on DepRe loading phase
set tserr [list {load swh} {unload swg/1} {unload swg/2} {load swg/2} {load swg/1} \n[msg_load swg/1 [err_conlo swg]] \n[msg_top_load swh swg/2 swg/2 [list [list swg/1] {}] [err_depref swg/1]]]
testouterr_cmd_re sh {load --auto swh} $ans [join $tserr \n]
set ans [list]
lappend ans [list setpath _LMFILES_ $mp/swg/1:$mp/swh]
lappend ans [list setpath LOADEDMODULES swg/1:swh]
lappend ans [list setpath MODULES_LMPREREQ swh&swg]
lappend ans [list setpath MODULES_LMCONFLICT swg/1&swg]
lappend ans [list ERR]
# there is an attempt to reload swg/2 as the load phase of switch targets swg default version only
# not 'any existing mod version'
set tserr [list {load swh} {unload swg/2} {load swg/2} \n[msg_load swg/2 [err_conlo swg]] \n[msg_top_load swh swg/2 {} {} [err_swon swg/2]]]
testouterr_cmd_re sh {load --no-auto swh} $ans [join $tserr \n]


# unload test, regular situation loaded
setenv_loaded_module [list swg/2 swh] [list $mp/swg/2 $mp/swh] [list swg/2]
setenv_path_var MODULES_LMCONFLICT swg/2&swg
setenv_path_var MODULES_LMPREREQ swh&swg

set ans [list]
lappend ans [list unsetpath LOADEDMODULES]
lappend ans [list unsetpath _LMFILES_]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMNOTUASKED]
lappend ans [list unsetpath MODULES_LMCONFLICT]
set tserr [list {unload swh} {unload swg/2} \n[msg_top_unload swh {} swg/2 {}]]
testouterr_cmd_re sh {unload --auto swh} $ans [join $tserr \n]
testouterr_cmd_re sh {unload --no-auto swh} $ans [join $tserr \n]

# unload test, switched-off module reloaded after switch
setenv_loaded_module [list swg/2 swh swg/1] [list $mp/swg/2 $mp/swh $mp/swg/1] [list swg/2]
setenv_path_var MODULES_LMCONFLICT swg/2&swg:swg/1&swg
setenv_path_var MODULES_LMPREREQ swh&swg

set ans [list]
lappend ans [list setpath LOADEDMODULES swg/1]
lappend ans [list setpath _LMFILES_ $mp/swg/1]
lappend ans [list setpath MODULES_LMCONFLICT swg/1&swg]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMNOTUASKED]
set tserr [list {unload swg/1} {unload swh} {unload swg/2} {load swg/1} \n[msg_top_unload swh {} swg/2 swg/1]]
testouterr_cmd_re sh {unload --auto swh} $ans [join $tserr \n]
set ans [list]
lappend ans [list setpath LOADEDMODULES swg/1]
lappend ans [list setpath _LMFILES_ $mp/swg/1]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMNOTUASKED]
lappend ans [list setpath MODULES_LMCONFLICT swg/1&swg]
# swg/2 is unloaded even if not last swg module loaded, as only those modules
# loaded prior swh are taken into account
set tserr [list {unload swh} {unload swg/2} \n[msg_top_unload swh {} swg/2 {}]]
testouterr_cmd_re sh {unload --no-auto swh} $ans [join $tserr \n]

# unload requirement
set ans [list]
lappend ans [list setpath LOADEDMODULES swg/2:swh]
lappend ans [list setpath _LMFILES_ $mp/swg/2:$mp/swh]
lappend ans [list setpath MODULES_LMCONFLICT swg/2&swg]
lappend ans [list setpath MODULES_LMPREREQ swh&swg]
lappend ans [list setpath MODULES_LMNOTUASKED swg/2]
# reload of the modulefile using 'module switch' disturb natural result: swg/1 swh
# as reload of swh during DepRe triggers the unload of swg/1 then the load of swg/2
set tserr [list {unload swh} {unload swg/1} {unload swg/2} {load swg/1} {load swh} {unload swg/1} {load swg/2} \n[msg_unload swg/2 {Unloading dependent: swh swg/1} {Reloading dependent: swg/1 swh} {Unloading conflict: swg/1} {Loading requirement: swg/2}]]
testouterr_cmd_re sh {unload --auto swg/2} $ans [join $tserr \n]
set tserr [list [msg_unload swg/2 [err_prerequn swh]]]
testouterr_cmd_re sh {unload --no-auto swg/2} ERR [join $tserr \n]

# switched-off module loaded instead of switched-on
setenv_loaded_module [list swh swg/1] [list $mp/swh $mp/swg/1]
setenv_path_var MODULES_LMCONFLICT swg/1&swg
setenv_path_var MODULES_LMPREREQ swh&swg

set ans [list]
lappend ans [list setpath LOADEDMODULES swg/1]
lappend ans [list setpath _LMFILES_ $mp/swg/1]
lappend ans [list unsetpath MODULES_LMPREREQ]
set tserr [list {unload swh}]
testouterr_cmd_re sh {unload --auto swh} $ans [join $tserr \n]
testouterr_cmd_re sh {unload --no-auto swh} $ans [join $tserr \n]

# unload test, switched-off module reloaded after switch and a second match for switched-on module loaded prior main module
setenv_loaded_module [list swg/0 swg/2 swh swg/1] [list $mp/swg/0 $mp/swg/2 $mp/swh $mp/swg/1] [list swg/0 swg/2]
setenv_path_var MODULES_LMCONFLICT swg/0&swg:swg/2&swg:swg/1&swg
setenv_path_var MODULES_LMPREREQ swh&swg

if {$install_unloadmatchorder eq {returnlast}} {
    set ans [list]
    lappend ans [list setpath LOADEDMODULES swg/0:swg/1]
    lappend ans [list setpath _LMFILES_ $mp/swg/0:$mp/swg/1]
    lappend ans [list setpath MODULES_LMNOTUASKED swg/0]
    lappend ans [list setpath MODULES_LMCONFLICT swg/0&swg:swg/1&swg]
    lappend ans [list unsetpath MODULES_LMPREREQ]
    set tserr [list {unload swh} {unload swg/2} \n[msg_top_unload swh {} swg/2 {}]]
} else {
    set ans [list]
    lappend ans [list setpath LOADEDMODULES swg/2:swg/1]
    lappend ans [list setpath _LMFILES_ $mp/swg/2:$mp/swg/1]
    lappend ans [list setpath MODULES_LMNOTUASKED swg/2]
    lappend ans [list setpath MODULES_LMCONFLICT swg/2&swg:swg/1&swg]
    lappend ans [list unsetpath MODULES_LMPREREQ]
    set tserr [list {unload swh} {unload swg/0} \n[msg_top_unload swh {} swg/0 {}]]
}
# closest or farest requirement to unloading module is selected for unload (depending on unload_match_order setting)
testouterr_cmd_re sh {unload --auto swh} $ans [join $tserr \n]
testouterr_cmd_re sh {unload --no-auto swh} $ans [join $tserr \n]


#
# switch test
#

setenv_loaded_module [list swg/2 swh] [list $mp/swg/2 $mp/swh] [list swg/2]
setenv_path_var MODULES_LMCONFLICT swg/2&swg
setenv_path_var MODULES_LMPREREQ swh&swg

set ans [list]
lappend ans [list setpath LOADEDMODULES swb:swc]
lappend ans [list setpath _LMFILES_ $mp/swb:$mp/swc]
lappend ans [list setpath MODULES_LMPREREQ swc&swb]
lappend ans [list setpath MODULES_LMNOTUASKED swb]
lappend ans [list setpath MODULES_LMCONFLICT swc&swa]
set tserr [list {unload swh} {unload swg/2} {load swc} {load swb} \n[msg_top_switch swh swc {} swg/2 {} swb {}]]
testouterr_cmd_re sh {switch --auto swh swc} $ans [join $tserr \n]
testouterr_cmd_re sh {switch --no-auto swh swc} $ans [join $tserr \n]


#
# broken switched-off or switched-on modules
#

# switched-off module breaks when unloaded
setenv_loaded_module [list rq] [list $mp/rq]

set tserr [list {load swi} {unload rq} \n[msg_unload rq $err_evalabort] \n[msg_load swi [err_swoff rq] [err_conun rq]]]
testouterr_cmd_re sh {load --auto swi} ERR [join $tserr \n]
testouterr_cmd_re sh {load --no-auto swi} ERR [join $tserr \n]


# switched-on module breaks when loaded
unsetenv_loaded_module

set tserr [list {load swj} {load ra} \n[msg_load ra $err_evalabort] \n[msg_load swj [err_swon ra] [err_reqlo ra]]]
testouterr_cmd_re sh {load --auto swj} ERR [join $tserr \n]
testouterr_cmd_re sh {load --no-auto swj} ERR [join $tserr \n]


# switched-on module breaks when unloaded
setenv_loaded_module [list ra swj] [list $mp/ra $mp/swj] [list ra]
setenv_path_var MODULES_LMCONFLICT swj&swa
setenv_path_var MODULES_LMPREREQ swj&ra

set ans [list]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMCONFLICT]
lappend ans [list setpath _LMFILES_ $mp/ra]
lappend ans [list setpath LOADEDMODULES ra]
lappend ans [list ERR]
set tserr [list {unload swj} {unload ra} \n[msg_unload ra $err_evalabort] \n[msg_top_unload swj {} {} {} [err_urequn ra]]]
testouterr_cmd_re sh {unload --auto swj} $ans [join $tserr \n]
set ans [list]
lappend ans [list setpath LOADEDMODULES ra]
lappend ans [list setpath _LMFILES_ $mp/ra]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMCONFLICT]
lappend ans [list ERR]
testouterr_cmd_re sh {unload --no-auto swj} $ans [join $tserr \n]


# switched-off module breaks when unloaded and switched-on module breaks when loaded
setenv_loaded_module [list rq] [list $mp/rq]

set tserr [list {load swk} {unload rq} \n[msg_unload rq $err_evalabort] \n[msg_load swk [err_swoff rq] [err_conun rq]]]
testouterr_cmd_re sh {load --auto swk} ERR [join $tserr \n]
testouterr_cmd_re sh {load --no-auto swk} ERR [join $tserr \n]


# switched-off module produces a module error when unloaded
setenv_loaded_module [list swn] [list $mp/swn]

set tserr [escre [list {load swl} {unload swn} \n[msg_unload swn [msg_moderr "$msg_invcmdname \"bad\"" {bad} $mp/swn 3]] \n[msg_load swl [err_swoff swn] [err_conun swn]]]]
testouterr_cmd_re sh {load --auto swl} ERR [join $tserr \n]
testouterr_cmd_re sh {load --no-auto swl} ERR [join $tserr \n]


# switched-on module produces a module error when loaded
unsetenv_loaded_module

set tserr [escre [list {load swm} {load swn} \n[msg_load swn [msg_moderr "$msg_invcmdname \"bad\"" {bad} $mp/swn 3]] \n[msg_load swm [err_swon swn] [err_reqlo swn]]]]
testouterr_cmd_re sh {load --auto swm} ERR [join $tserr \n]
testouterr_cmd_re sh {load --no-auto swm} ERR [join $tserr \n]


# switched-on module produces a module error when unloaded
setenv_loaded_module [list swn swm] [list $mp/swn $mp/swm] [list swn]
setenv_path_var MODULES_LMCONFLICT swm&swa
setenv_path_var MODULES_LMPREREQ swm&swn

set ans [list]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMCONFLICT]
lappend ans [list setpath _LMFILES_ $mp/swn]
lappend ans [list setpath LOADEDMODULES swn]
lappend ans [list ERR]
set tserr [escre [list {unload swm} {unload swn} \n[msg_unload swn [msg_moderr "$msg_invcmdname \"bad\"" {bad} $mp/swn 3]] \n[msg_top_unload swm {} {} {} [err_urequn swn]]]]
testouterr_cmd_re sh {unload --auto swm} $ans [join $tserr \n]
set ans [list]
lappend ans [list setpath LOADEDMODULES swn]
lappend ans [list setpath _LMFILES_ $mp/swn]
lappend ans [list unsetpath MODULES_LMPREREQ]
lappend ans [list unsetpath MODULES_LMCONFLICT]
lappend ans [list ERR]
testouterr_cmd_re sh {unload --no-auto swm} $ans [join $tserr \n]


#
#  Cleanup
#

reset_test_env

}
