##############################################################################
#   Modules Release Tcl
#   Providing a flexible user environment
#
#   File:		modules.61-coll/%M%
#   Revision:		%I%
#   First Edition:	2016/08/02
#   Last Mod.:		%U%, %G%
#
#   Authors:		Xavier Delaruelle, xavier.delaruelle@cea.fr
#
#   Description:	Testuite testsequence
#   Command:
#   Modulefiles:
#   Sub-Command:
#
#   Comment:	%C{
#			Test the module 'restore' command
#		}C%
#
##############################################################################

set cbadnerrmsg "$error_msgs: Collection $collbadn cannot be found"
set cbadfperrmsg "$error_msgs: Collection $collbadfp cannot be found"
set cbadterrmsg "$error_msgs: Collection $colld (for target \"$colltarget\") cannot be found"
set cderrmsg "Loading loc_rc1/1.0\nLoading load/15\nLoading verssort/1.10\nload $cdmod4\nLoading $cdmod4\nLoading loc_dv2/1.0"
set c1errmsg "Unloading loc_dv2/1.0\nload $c1mod5\nLoading $c1mod5\nload $c1mod6\nLoading $c1mod6"
set c2errmsg "unload $c1mod6\nUnloading $c1mod6\nunload $c1mod5\nUnloading $c1mod5\nunload $cdmod4\nUnloading $cdmod4\nload $c2mod4\nLoading $c2mod4\nload $c2mod5\nLoading $c2mod5\nload $c2mod6\nLoading $c2mod6"
set c1errmsgf2 "unload $c2mod6\nUnloading $c2mod6\nunload $c2mod5\nUnloading $c2mod5\nunload $c2mod4\nUnloading $c2mod4\nload $cdmod4\nLoading $cdmod4\nload $c1mod5\nLoading $c1mod5\nload $c1mod6\nLoading $c1mod6"
set c3errmsg ""
set c4errmsg "unload $c2mod6\nUnloading $c2mod6\nunload $c2mod5\nUnloading $c2mod5\nunload $c2mod4\nUnloading $c2mod4\nUnloading verssort/1.10\nUnloading load/15\nUnloading loc_rc1/1.0"
set c5errmsg $c4errmsg
set badcontfp "$homewithcoll/.Xresources"
set badcontfperrmsg "$error_msgs: $badcontfp is not a valid collection"
set c7errmsg "Loading $modpathre.path3/dcross/dir1/3.0\nLoading $modpathre.path2/cross/6.0\nLoading $modpathre.path1/novercross"
set c8errmsg $c7errmsg
set c9errmsg "load $c9mod1\nLoading $c9mod1\nload $c9mod2\nLoading $c9mod2\nload $c9mod3\nLoading $c9mod3"
set c10errmsg $c9errmsg
set c9errmsg2 "unload $c9mod3\nUnloading $c9mod3\nunload $c9mod2\nUnloading $c9mod2\nload $c9mod2\nLoading $c9mod2\nload $c9mod3\nLoading $c9mod3"
set c11errmsg "load $c11mod1\nLoading $c11mod1\nload $c11mod2\nLoading $c11mod2"
set c12errmsg "unload $c9mod3\nUnloading $c9mod3\nunload $c9mod2\nUnloading $c9mod2\nunload $c9mod1\nUnloading $c9mod1\nload f4\nLoading f4\nload f5\nLoading f5\n\n[msg_load f6 [err_conlo f5]]\n\n[msg_load f7 [err_reqmis f6]]"
set c13errmsg $cderrmsg
set c14errmsg "unload m2\nUnloading m2\nload m3\nLoading m3"
set c15errmsg "Loading '$c15mod1'\nLoading $c15mod2\nLoading '$c15mod3'"
set c16errmsg "Loading '$c16mod1'\nLoading '$c16mod2'\nLoading $c16mod3\nLoading $c16mod4\nLoading '$c16mod5'"
set c17errmsg "Loading $c17mod1\nLoading $c17mod2"
set c19errmsg [escre "Loading $c19mod1{[join $c19mod1vr :]}\nLoading $c19mod2\nLoading '$c19mod3'{[join $c19mod3vr :]}"]
set c20errmsg [escre "Loading $c20mod1{[join $c20mod1vr :]}\nLoading $c20mod2\nLoading '$c20mod3'{[join $c20mod3vr :]}"]
set c22errmsg [escre "Loading $c22mod1{bar =:[join $c22mod1vr :]}\nLoading $c22mod2\nLoading '$c22mod3'{b*r= val1}"]
set c26errmsg [escre "Loading $c26mod1{[join $c26mod1vr :]}\nLoading $c26mod2\nLoading '$c26mod3'{[join $c20mod3vr :]}"]

# set HOME to location containing collections
if { $verbose > 0 } {
    send_user "\tSetup HOME = $homewithcoll\n"
}
set env(HOME) "$homewithcoll"


#
# test restoring nonexistent collection
#

testouterr_cmd "ALL" "restore $collbadn" "ERR" "$cbadnerrmsg"


#
# test restoring nonexistent collection specified as a filepath
#

testouterr_cmd "ALL" "restore $collbadfp" "ERR" "$cbadfperrmsg"


#
# test showing existent file which is not a collection
#

testouterr_cmd "ALL" "restore $badcontfp" "ERR" "$badcontfperrmsg"


#
# test restoring default collection
#

# setup an empty environment
unsetenv_path_var MODULEPATH

lappend ans [list set LOADEDMODULES $cdlm]
lappend ans [list set _LMFILES_ $cdlmf]
lappend ans "(.*)"
lappend ans [list set MODULES_LMALTNAME $cdlmalt]
lappend ans "(.*)"
lappend ans [list set MODULES_LMALTNAME_modshare "(.*)"]
lappend ans "(.*)"
lappend ans "(.*)"
lappend ans [list set MODULEPATH $cdmodpath]
lappend ans [list set LOADEDMODULES_modshare "(.*)"]
lappend ans [list set _LMFILES__modshare "(.*)"]
lappend ans [list set MODULEPATH_modshare "(.*)"]

testouterr_cmd_re "ALL" "restore" $ans "$cderrmsg"


#
# test restoring default collection saved with version pinned and with parts
# of this environment already loaded (default version comparison)
#

eval setenv_path_var MODULEPATH [split $cdmodpath ":"]
setenv_loaded_module [split $cdlm_part ":"] [split $cdlmf_part ":"]
eval setenv_path_var MODULES_LMALTNAME [split $cdlmalt_part ":"]

set ans [list]
lappend ans [list setpath MODULES_LMALTNAME $cdlmalt]
lappend ans [list setpath LOADEDMODULES $cdlm]
lappend ans [list setpath _LMFILES_ $cdlmf]

testouterr_cmd_re "sh" "restore" $ans "Unloading loc_dv2/2.0\nLoading loc_dv2/1.0"


#
# test restoring collection that only adds path to use and mods to load
#

# fake environment state: default collection restored
setenv_loaded_module [split $cdlm ":"] [split $cdlmf ":"]
eval setenv_path_var MODULES_LMALTNAME [split $cdlmalt ":"]

set ans [list]
lappend ans [list setpath MODULES_LMALTNAME $c1lmalt]
lappend ans [list setpath MODULEPATH $c1modpath]
lappend ans [list setpath LOADEDMODULES $c1lm $c1lmnodefault]
lappend ans [list setpath _LMFILES_ $c1lmf $c1lmfnodefault]

testouterr_cmd_re "ALL" "restore $coll1" $ans "$c1errmsg"


#
# test restoring exact same collection, nothing should happen
#

# fake environment state: $coll1 collection restored
eval setenv_path_var MODULEPATH [split $c1modpath ":"]
setenv_loaded_module [split $c1lm ":"] [split $c1lmf ":"]
eval setenv_path_var MODULES_LMALTNAME [split $c1lmalt ":"]

testouterr_cmd "ALL" "restore $coll1" "OK" ""


#
# test restoring collection unload some modules
# to reload them in correct order
#

set ans [list]
lappend ans [list setpath LOADEDMODULES $c2lm]
lappend ans [list setpath _LMFILES_ $c2lmf]

testouterr_cmd_re "ALL" "restore $coll2" $ans "$c2errmsg"


#
# test restoring collection that reorder used paths
# no change on loaded modules
#

# fake environment state: $coll2 collection restored
eval setenv_path_var MODULEPATH [split $c2modpath ":"]
setenv_loaded_module [split $c2lm ":"] [split $c2lmf ":"]
eval setenv_path_var MODULES_LMALTNAME [split $c2lmalt ":"]

set ans [list]
lappend ans [list setpath MODULEPATH $c3modpath]

testouterr_cmd_re "ALL" "restore $coll3" $ans "$c3errmsg"


#
# test restoring collection specified as filepath
#

set ans [list]
lappend ans [list setpath LOADEDMODULES $c1lm]
lappend ans [list setpath _LMFILES_ $c1lmf]

testouterr_cmd_re "ALL" "restore $coll1fp" $ans "$c1errmsgf2"


#
# test restoring collection specified as filepath when
# MODULES_COLLECTION_TARGET is set. target should be ignored
#

# setup environment state
if { $verbose > 0 } {
    send_user "\tSetup MODULES_COLLECTION_TARGET = $colltarget\n"
}
set env(MODULES_COLLECTION_TARGET) "$colltarget"

testouterr_cmd_re "ALL" "restore $coll1fp" $ans "$c1errmsgf2"


#
# test restoring collection not mentionning module to load
# when MODULES_COLLECTION_TARGET set
#

set ans [list]
lappend ans [list unset _LMFILES__modshare]
lappend ans [list unset LOADEDMODULES_modshare]
lappend ans "(.*)"
lappend ans "(.*)"
lappend ans "(.*)"
lappend ans [list unset _LMFILES_]
lappend ans [list unset LOADEDMODULES]
lappend ans "(.*)"

testouterr_cmd_re "ALL" "restore $coll4" $ans "$c4errmsg"


#
# test restoring same collection than before but with a modulepath
# prepended rather appended
#

testouterr_cmd_re "ALL" "restore $coll5fp" $ans "$c5errmsg"


#
# test restoring collection mixing virtual and deep modules spread through
# different modulepaths to check correct default version is restored
#

# restore environment
unsetenv_path_var MODULEPATH
unsetenv_loaded_module
unsetenv_path_var MODULES_LMALTNAME

if {$install_implicitdefault eq {y}} {
    set ans [list]
    lappend ans [list set testsuite "yes"]
    lappend ans [list setpath LOADEDMODULES $c6lm]
    lappend ans [list setpath _LMFILES_ $c6lmf]
    lappend ans [list setpath MODULEPATH $c6modpath]
    lappend ans [list setpath MODULES_LMALTNAME $c6lmalt]
    set c6errmsg "Loading dvcross/dir1/1.0\nLoading dcross/dir1/3.0\nLoading cross/6.0\nLoading novercross"
} else {
    set ans [list]
    lappend ans [list set testsuite "yes"]
    lappend ans [list setpath LOADEDMODULES $c6lmnodefault]
    lappend ans [list setpath _LMFILES_ $c6lmfnodefault]
    lappend ans [list setpath MODULEPATH $c6modpath]
    lappend ans [list setpath MODULES_LMALTNAME $c6lmalt]
    lappend ans [list ERR]
    set c6errmsg "$err_nodefault'dvcross'\nLoading dcross/dir1/3.0\nLoading cross/6.0\nLoading novercross"
}
testouterr_cmd_re "sh" "restore $coll6" $ans $c6errmsg


#
# test restoring collection with empty element set in MODULEPATH, LOADEDMODULES
#

# restore environment
setenv_path_var MODULEPATH {} {}
setenv_loaded_module [list {} {}] [list {} {}]

if {$install_implicitdefault eq {y}} {
    set ans [list]
    lappend ans [list set testsuite "yes"]
    lappend ans [list setpath LOADEDMODULES "::$c6lm"]
    lappend ans [list setpath _LMFILES_ "::$c6lmf"]
    # empty dir elements are ignored but stick to the variable, they should be removed
    lappend ans [list setpath MODULEPATH "::$c6modpath"]
    lappend ans [list setpath MODULES_LMALTNAME $c6lmalt]
    set c6errmsg "Loading dvcross/dir1/1.0\nLoading dcross/dir1/3.0\nLoading cross/6.0\nLoading novercross"
} else {
    set ans [list]
    lappend ans [list set testsuite "yes"]
    lappend ans [list setpath LOADEDMODULES "::$c6lmnodefault"]
    lappend ans [list setpath _LMFILES_ "::$c6lmfnodefault"]
    # empty dir elements are ignored but stick to the variable, they should be removed
    lappend ans [list setpath MODULEPATH "::$c6modpath"]
    lappend ans [list setpath MODULES_LMALTNAME $c6lmalt]
    lappend ans [list ERR]
    set c6errmsg "$err_nodefault'dvcross'\nLoading dcross/dir1/3.0\nLoading cross/6.0\nLoading novercross"
}
testouterr_cmd_re "sh" "restore $coll6" $ans $c6errmsg


#
# test restoring collection with no modulepath and modulefiles loaded as fullpath
#

# setup environment state
unsetenv_path_var MODULEPATH
unsetenv_loaded_module

set ans [list]
lappend ans [list set testsuite "yes"]
lappend ans [list setpath LOADEDMODULES $c7lm]
lappend ans [list setpath _LMFILES_ $c7lmf]

testouterr_cmd_re "sh" "restore $coll7fp" $ans $c7errmsg


#
# test restoring collection with no modulepath and modulefiles loaded as fullpath
# starting with a defined MODULEPATH
#

setenv_path_var MODULEPATH $modpath

set ans [list]
lappend ans [list set testsuite "yes"]
lappend ans [list setpath LOADEDMODULES $c7lm]
lappend ans [list setpath _LMFILES_ $c7lmf]
lappend ans [list unsetpath MODULEPATH]

testouterr_cmd_re "sh" "restore $coll7fp" $ans $c7errmsg


#
# test restoring collection with a modulepath and modulefiles loaded as fullpath
#

unsetenv_path_var MODULEPATH

set ans [list]
lappend ans [list set testsuite "yes"]
lappend ans [list setpath LOADEDMODULES $c8lm]
lappend ans [list setpath _LMFILES_ $c8lmf]
lappend ans [list setpath MODULEPATH $c8modpath]

testouterr_cmd_re "sh" "restore $coll8fp" $ans $c8errmsg


#
# test restoring collection with some modulefiles loaded not asked by user
#

set ans [list]
lappend ans [list setpath LOADEDMODULES $c9lm]
lappend ans [list setpath _LMFILES_ $c9lmf]
lappend ans [list setpath MODULEPATH $c9modpath]
lappend ans [list setpath MODULES_LMNOTUASKED $c9lmnua]

testouterr_cmd_re "sh" "restore $coll9fp" $ans $c9errmsg


#
# test restoring collection with some modulefiles loaded not asked by user
#

set ans [list]
lappend ans [list setpath LOADEDMODULES $c9lm]
lappend ans [list setpath _LMFILES_ $c9lmf]
lappend ans [list setpath MODULEPATH $c9modpath]
lappend ans [list setpath MODULES_LMNOTUASKED $c9lmnua]

testouterr_cmd_re "sh" "restore $coll10fp" $ans $c10errmsg


#
# test restoring collection with some modulefiles loaded not asked by user
# from a situation where all modulefiles where loaded asked by user
#

eval setenv_path_var MODULEPATH [split $c9modpath ":"]
setenv_loaded_module [split $c9lm ":"] [split $c9lmf ":"]

set ans [list]
lappend ans [list setpath LOADEDMODULES $c9lm]
lappend ans [list setpath _LMFILES_ $c9lmf]
lappend ans [list setpath MODULES_LMNOTUASKED $c9lmnua]

testouterr_cmd_re "sh" "restore $coll9fp" $ans $c9errmsg2


#
# test restoring collection with some modulefiles loaded not asked by user
# from a situation where not user asked information is already correct
#

eval setenv_path_var MODULEPATH [split $c9modpath ":"]
setenv_loaded_module [split $c9lm ":"] [split $c9lmf ":"] [split $c9lmnua ":"]

testouterr_cmd_re "sh" "restore $coll9fp" "" ""


#
# test restoring collection in which a modulefile has 'module load' dependency
# to another modulefile
#

setenv_path_var MODULEPATH [split $c11modpath :]
unsetenv_loaded_module

set ans [list]
lappend ans [list setpath LOADEDMODULES $c11lm]
lappend ans [list setpath _LMFILES_ $c11lmf]
lappend ans [list setpath MODULES_LMNOTUASKED $c11lmnua]
lappend ans [list setpath MODULES_LMPREREQ $c11mod2&$c11mod1]
testouterr_cmd_re sh "restore $coll11fp" $ans $c11errmsg


#
# test restoring collection with incompatible modulefiles saved in it (which
# should not be possible)
#

eval setenv_path_var MODULEPATH [split $c9modpath ":"]
setenv_loaded_module [split $c9lm ":"] [split $c9lmf ":"]

set ans [list]
lappend ans [list setpath MODULEPATH $c12modpath]
lappend ans [list setpath LOADEDMODULES $c12lm]
lappend ans [list setpath _LMFILES_ $c12lmf]
lappend ans [list ERR]
testouterr_cmd_re sh "restore $coll12fp" $ans $c12errmsg


#
# test restoring nonexistent default collection when
# MODULES_COLLECTION_TARGET is set
#

testouterr_cmd "ALL" "restore" "ERR" "$cbadterrmsg"


#
# test unsetting HOME
#

if { $verbose > 0 } {
    send_user "\tUnset HOME \n"
}
unset env(HOME)

testouterr_cmd "sh" "restore" "ERR" $nohomeerrmsg

# restore default testsuite home
if { $verbose > 0 } {
    send_user "\tRestore HOME = $ORIG_HOME\n"
}
set env(HOME) $ORIG_HOME


#
# test when loaded environment is inconsistent
#

setenv_loaded_module [list foo bar] "/path/to/foo"

testouterr_cmd "sh" "restore $coll8fp" "ERR" "$err_loinconsist\n  LOADEDMODULES=foo bar\n  _LMFILES_=/path/to/foo"


#
# test use of restore command from a modulefile to check
# unload and load messages produced by this command in this context
#

# set HOME to location containing collections
setenv_var HOME $hometestcoll

setenv_loaded_module [split $cdlm ":"] [split $cdlmf ":"]
unsetenv_var MODULES_COLLECTION_TARGET

set ans [list]
lappend ans [list setpath MODULEPATH $modpath:$modpath.2]
lappend ans [list setpath LOADEDMODULES $c2lm:$modpath.2/restore]
lappend ans [list setpath _LMFILES_ $c2lmf:$modpath.2/restore]

testouterr_cmd_re sh "load $modpath.2/restore" $ans "Unloading loc_dv2/1.0\nunload coll/a\nUnloading coll/a\nload coll/c\nLoading coll/c\nload coll/a\nLoading coll/a\nload coll/b\nLoading coll/b"


#
# restore with implicit_default disabled a collection containing an explicit default
# expressed with pin_version disabled
#

if {![is_config_locked implicit_default] || $install_implicitdefault ne {y}} {
setenv_var MODULES_IMPLICIT_DEFAULT 0
unsetenv_var MODULEPATH
unsetenv_loaded_module

set ans [list]
lappend ans [list set LOADEDMODULES $c13lm]
lappend ans [list set _LMFILES_ $c13lmf]
lappend ans "(.*)"
lappend ans [list set MODULES_LMALTNAME $c13lmalt]
lappend ans "(.*)"
lappend ans [list set MODULES_LMALTNAME_modshare "(.*)"]
lappend ans "(.*)"
lappend ans "(.*)"
lappend ans [list set MODULEPATH $c13modpath]
lappend ans [list set LOADEDMODULES_modshare "(.*)"]
lappend ans [list set _LMFILES__modshare "(.*)"]
lappend ans [list set MODULEPATH_modshare "(.*)"]

testouterr_cmd_re sh "restore $coll13fp" $ans $c13errmsg

unsetenv_var MODULES_IMPLICIT_DEFAULT
}

#
# a module is loaded as well as its requirement declared with 'module load'
# and which was automatically loaded when main module was loaded. collection
# is then restored, main module is not part of collection but its requirement is
#

setenv_path_var MODULEPATH $modpath.deps
setenv_loaded_module [list m1 m2] [list $modpath.deps/m1 $modpath.deps/m2] [list m1]
setenv_path_var MODULES_LMPREREQ m2&m1

set ans [list]
lappend ans [list setpath LOADEDMODULES m1:m3]
lappend ans [list setpath _LMFILES_ $modpath.deps/m1:$modpath.deps/m3]
lappend ans [list setpath MODULES_LMPREREQ m3&m1]

# whether auto_handling is enabled or disabled should not impact result
setenv_var MODULES_AUTO_HANDLING 0
testouterr_cmd_re sh "restore $coll14fp" $ans $c14errmsg
setenv_var MODULES_AUTO_HANDLING 1
testouterr_cmd_re sh "restore $coll14fp" $ans $c14errmsg
unsetenv_var MODULES_AUTO_HANDLING


#
# restore collection where modulepath and module names contain space character
#

if {!$is_symlink_supported} {
    send_user "\tskipping tests over '$modpath wspace' modulepath as symbolic links are not supported on filesystem\n"
} else {

unsetenv_path_var MODULEPATH
unsetenv_loaded_module
unsetenv_path_var MODULES_LMPREREQ

set ans [list]
lappend ans [list setpath MODULEPATH $c15modpath]
lappend ans [list setpath LOADEDMODULES $c15lm]
lappend ans [list setpath _LMFILES_ $c15lmf]
lappend ans [list setpath MODULES_LMALTNAME $c15lmalt]
testouterr_cmd_re sh "restore $coll15fp" $ans $c15errmsg

set ans [list]
lappend ans [list setpath MODULEPATH $c16modpath]
lappend ans [list setpath LOADEDMODULES $c16lm]
lappend ans [list setpath _LMFILES_ $c16lmf]
lappend ans [list setpath MODULES_LMALTNAME $c16lmalt]
testouterr_cmd_re sh "restore $coll16fp" $ans $c16errmsg

}

#
# restore collection where modulepath start with a variable reference
#

set ans [list]
lappend ans [list set testsuite "yes"]
lappend ans [list setpath MODULEPATH $c17modpath]
lappend ans [list setpath LOADEDMODULES $c17lm]
lappend ans [list setpath _LMFILES_ $c17lmf]
lappend ans [list setpath MODULES_LMALTNAME loc_rc1/1.0&loc_rc1/foo]
lappend ans [list set t15 t15]
lappend ans [list unset mload]
testouterr_cmd_re sh "restore $coll17fp" $ans $c17errmsg


#
# variant tests
#

unsetenv_path_var MODULEPATH
unsetenv_loaded_module

# ensure advanced_version_spec is enabled to restore variant
setenv_var MODULES_ADVANCED_VERSION_SPEC 1
# ensure implicit default is enabled for these tests
setenv_var MODULES_IMPLICIT_DEFAULT 1

setenv_var TESTSUITE_VARIANT coll19
set ans [list]
lappend ans [list setpath MODULEPATH $c19modpath]
lappend ans [list setpath LOADEDMODULES $c19lm]
lappend ans [list setpath _LMFILES_ $c19lmf]
lappend ans [list setpath MODULES_LMVARIANT $c19lmvr]
lappend ans [list setpath MODULES_LMALTNAME $c19lmalt]
testouterr_cmd_re sh "restore $coll19fp" $ans $c19errmsg

setenv_var TESTSUITE_VARIANT coll20
set ans [list]
lappend ans [list setpath MODULEPATH $c20modpath]
lappend ans [list setpath LOADEDMODULES $c20lm]
lappend ans [list setpath _LMFILES_ $c20lmf]
lappend ans [list setpath MODULES_LMVARIANT $c20lmvr]
lappend ans [list setpath MODULES_LMALTNAME $c20lmalt]
testouterr_cmd_re sh "restore $coll20fp" $ans $c20errmsg

setenv_var TESTSUITE_VARIANT coll22
set ans [list]
lappend ans [list setpath MODULEPATH $c22modpath]
lappend ans [list setpath LOADEDMODULES $c22lm]
lappend ans [list setpath _LMFILES_ $c22lmf]
lappend ans [list setpath MODULES_LMVARIANT $c22lmvr]
lappend ans [list setpath MODULES_LMALTNAME $c22lmalt]
testouterr_cmd_re sh "restore $coll22fp" $ans $c22errmsg

setenv_var TESTSUITE_VARIANT coll26
set ans [list]
lappend ans [list setpath MODULEPATH $c26modpath]
lappend ans [list setpath LOADEDMODULES $c26lm]
lappend ans [list setpath _LMFILES_ $c26lmf]
lappend ans [list setpath MODULES_LMNOTUASKED $c26lmnua]
lappend ans [list setpath MODULES_LMVARIANT $c26lmvr]
lappend ans [list setpath MODULES_LMALTNAME $c26lmalt]
testouterr_cmd_re sh "restore $coll26fp" $ans $c26errmsg

# test restoring variant with advanced_version_spec disabled
setenv_var MODULES_ADVANCED_VERSION_SPEC 0

setenv_var TESTSUITE_VARIANT coll19
set ans [list]
lappend ans [list setpath MODULEPATH $c19modpath]
lappend ans [list setpath _LMFILES_ $c19modpath1/$c19mod2]
lappend ans [list setpath LOADEDMODULES $c19mod2]
lappend ans [list ERR]
testouterr_cmd_re sh "restore $coll19fp" $ans "[msg_load variant/1.0 [err_novarval {bar } {{} val1 val2}]]

$err_path'{bar =}'
$err_path'{fo o=v\\?l1 }'
Loading foo/1.0

[msg_load {'variant/w s'} [err_novarval b\\*r {val1 { val1} val2}]]

$err_path'{b\\*r= val1}'"

setenv_var TESTSUITE_VARIANT coll26
set ans [list]
lappend ans [list setpath MODULEPATH $c26modpath]
lappend ans [list setpath LOADEDMODULES $c26mod2:$c26mod3]
lappend ans [list setpath _LMFILES_ $c26modpath1/$c26mod2:$c26modpath1/$c26mod3]
lappend ans [list setpath MODULES_LMVARIANT "$c26mod3&b*r| val1|0|2"]
lappend ans [list setpath MODULES_LMNOTUASKED $c26mod2]
lappend ans [list ERR]
testouterr_cmd_re sh "restore $coll26fp" $ans "[escre [msg_load {variant/1.0} [err_novarval {fo o} {val1 val2 {v?l1 }}]]]

$err_path'{bar =}'
$err_path'{fo o=v\\?l1 }'
Loading foo/1.0
Loading 'variant/w s'{b\\*r= val1}
$err_path'{b\\*r= val1}'"


# restore collection where first module is already loaded with variant set
setenv_var MODULES_ADVANCED_VERSION_SPEC 1
setenv_path_var MODULEPATH $c20modpath1
setenv_loaded_module [list $c20mod1] [list $c20modpath1/$c20mod1]
setenv_path_var MODULES_LMVARIANT "$c20mod1&bar ||0|1&fo o|v?l1 |0|0"

# restore pinned-version collection with variant set with default value
setenv_var TESTSUITE_VARIANT coll20
set ans [list]
lappend ans [list setpath LOADEDMODULES $c20lm]
lappend ans [list setpath _LMFILES_ $c20lmf]
lappend ans [list setpath MODULES_LMVARIANT $c20lmvr]
lappend ans [list setpath MODULES_LMALTNAME $c20lmalt]
testouterr_cmd_re sh "restore $coll20fp" $ans [escre "Loading $c22mod2\nLoading '$c22mod3'{[join $c20mod3vr :]}"]

# restore non-pinned-version collection with variant set with default value
setenv_var TESTSUITE_VARIANT coll22
set ans [list]
lappend ans [list setpath LOADEDMODULES $c22lm]
lappend ans [list setpath _LMFILES_ $c22lmf]
lappend ans [list setpath MODULES_LMVARIANT "$c22mod1&bar ||0|1&fo o|v?l1 |0|0:$c22mod3&b*r| val1|0|2"]
lappend ans [list setpath MODULES_LMALTNAME $c22lmalt]
set tserr "Loading $c22mod2\nLoading '$c22mod3'{b\\*r= val1}"
testouterr_cmd_re sh "restore $coll22fp" $ans $tserr

# same test with icase enabled and extended_default disabled
setenv_var MODULES_ICASE always
setenv_var MODULES_EXTENDED_DEFAULT 0
testouterr_cmd_re sh "restore $coll22fp" $ans $tserr
# same test with icase enabled and extended_default enabled
setenv_var MODULES_EXTENDED_DEFAULT 1
testouterr_cmd_re sh "restore $coll22fp" $ans $tserr
# same test with icase disabled and extended_default enabled
unsetenv_var MODULES_ICASE
testouterr_cmd_re sh "restore $coll22fp" $ans $tserr
unsetenv_var MODULES_EXTENDED_DEFAULT

unsetenv_path_var MODULEPATH
unsetenv_loaded_module
unsetenv_path_var MODULES_LMVARIANT


# test restoring collection with bad module specification
testouterr_cmd_re sh "restore $coll27fp" ERR "$error_msgs: $msg_nomodnameinarg 'foo=val'"
testouterr_cmd_re sh "restore $coll28fp" ERR "$error_msgs: $msg_nomodnameinarg '@1.0'"
setenv_var TESTSUITE_VARIANT coll29
set ans [list]
lappend ans [list setpath LOADEDMODULES $c26mod2]
lappend ans [list setpath _LMFILES_ $c26modpath1/$c26mod2]
lappend ans [list setpath MODULEPATH $c26modpath1]
lappend ans [list ERR]
testouterr_cmd_re sh "restore $coll29fp" $ans [msg_load variant/1.0{unk=val} [err_unkvar unk]]\n\n[msg_load foo/1.0]


# test collection restore when different set of variant are loaded
setenv_var TESTSUITE_VARIANT coll30
setenv_path_var MODULEPATH $c30modpath1
setenv_loaded_module [list $c30mod1 $c30mod2 $c30mod3] [list $c30modpath1/$c30mod1 $c30modpath1/$c30mod2 $c30modpath1/$c30mod3]
setenv_path_var MODULES_LMVARIANT "$c30mod1&foo|val1|0|0&bar|2|0|1:$c30mod3&foo|val1|0|1&bar|3|0|0"
set ans [list]
lappend ans [list setpath LOADEDMODULES $c30lm]
lappend ans [list setpath _LMFILES_ $c30lmf]
lappend ans [list setpath MODULES_LMVARIANT $c30lmvr]
set tserr [msg_unload $c30mod3{bar=3:foo=val1}]\n[msg_unload $c30mod2]\n[msg_unload $c30mod1{bar=2:foo=val1}]\n
append tserr [msg_load $c30mod1{[join $c30mod1vr :]}]\n[msg_load $c30mod2]\n[msg_load $c30mod3{[join $c30mod3vr :]}]
testouterr_cmd_re sh "restore $coll30fp" $ans $tserr

# same test with icase enabled and extended_default disabled
setenv_var MODULES_ICASE always
setenv_var MODULES_EXTENDED_DEFAULT 0
testouterr_cmd_re sh "restore $coll30fp" $ans $tserr
# same test with icase enabled and extended_default enabled
setenv_var MODULES_EXTENDED_DEFAULT 1
testouterr_cmd_re sh "restore $coll30fp" $ans $tserr
# same test with icase disabled and extended_default enabled
unsetenv_var MODULES_ICASE
testouterr_cmd_re sh "restore $coll30fp" $ans $tserr
unsetenv_var MODULES_EXTENDED_DEFAULT

setenv_path_var MODULES_LMVARIANT "$c30mod1&foo|val1|0|0&bar|2|0|1:$c30mod3&foo|val3|0|0&bar|3|0|0"
set tserr [msg_unload $c30mod3{bar=3:foo=val3}]\n[msg_unload $c30mod2]\n[msg_unload $c30mod1{bar=2:foo=val1}]\n
append tserr [msg_load $c30mod1{[join $c30mod1vr :]}]\n[msg_load $c30mod2]\n[msg_load $c30mod3{[join $c30mod3vr :]}]
testouterr_cmd_re sh "restore $coll30fp" $ans $tserr

setenv_path_var MODULES_LMVARIANT "$c30mod1&foo|val2|0|0&bar|2|0|1:$c30mod3&foo|val1|0|1&bar|3|0|0"
set tserr [msg_unload $c30mod3{bar=3:foo=val1}]\n[msg_load $c30mod3{[join $c30mod3vr :]}]
testouterr_cmd_re sh "restore $coll30fp" $ans $tserr

# variant sort in different order in persistency var
setenv_path_var MODULES_LMVARIANT "$c30mod1&foo|val2|0|0&bar|2|0|1:$c30mod3&foo|val1|0|1&bar|3|0|0"
testouterr_cmd_re sh "restore $coll30fp" $ans $tserr

# erroneous content in variant persistency var
setenv_path_var MODULES_LMVARIANT "$c30mod1&foo|val2|str|str&bar|2|0|2:$c30mod3&foo|val1&bar|3|0|2"
set ans [list]
lappend ans [list setpath LOADEDMODULES $c30lm]
lappend ans [list setpath _LMFILES_ $c30lmf]
lappend ans [list setpath MODULES_LMVARIANT $c30mod1&foo|val2|str|str&bar|2|0|2:$c30mod3&foo|val3|0|0&bar|3|0|0]
testouterr_cmd_re sh "restore $coll30fp" $ans $tserr

# default value set in collection (bar=2) but non-default value currently loaded (bar=1)
setenv_path_var MODULES_LMVARIANT "$c30mod1&foo|val1|0|0&bar|1|0|0:$c30mod3&foo|val1|0|1&bar|3|0|0"
set ans [list]
lappend ans [list setpath LOADEDMODULES $c30lm]
lappend ans [list setpath _LMFILES_ $c30lmf]
lappend ans [list setpath MODULES_LMVARIANT $c30lmvr]
set tserr [msg_unload $c30mod3{bar=3:foo=val1}]\n[msg_unload $c30mod2]\n[msg_unload $c30mod1{bar=1:foo=val1}]\n
append tserr [msg_load $c30mod1{[join $c30mod1vr :]}]\n[msg_load $c30mod2]\n[msg_load $c30mod3{[join $c30mod3vr :]}]
testouterr_cmd_re sh "restore $coll30fp" $ans $tserr


# test collection restore when different set of variant are loaded (no pin_version)
setenv_var TESTSUITE_VARIANT coll31
setenv_var MODULES_COLLECTION_PIN_VERSION 0
setenv_path_var MODULES_LMALTNAME $c31lmalt

setenv_path_var MODULES_LMVARIANT "$c31mod1&foo|val1|0|0&bar|2|0|2:$c31mod3&foo|val1|0|1&bar|3|0|0"
set ans [list]
lappend ans [list setpath LOADEDMODULES $c31lm]
lappend ans [list setpath _LMFILES_ $c31lmf]
lappend ans [list setpath MODULES_LMALTNAME $c31lmalt]
lappend ans [list setpath MODULES_LMVARIANT $c31lmvr]
set tserr [msg_unload $c31mod3{bar=3:foo=val1}]\n[msg_unload $c31mod2]\n[msg_unload $c31mod1{bar=2:foo=val1}]\n
append tserr [msg_load $c31mod1{[join $c31mod1vr :]}]\n[msg_load $c31mod2]\n[msg_load $c31mod3{[join $c31mod3vr :]}]
testouterr_cmd_re sh "restore $coll31fp" $ans $tserr

# same test with icase enabled and extended_default disabled
setenv_var MODULES_ICASE always
setenv_var MODULES_EXTENDED_DEFAULT 0
testouterr_cmd_re sh "restore $coll31fp" $ans $tserr
# same test with icase enabled and extended_default enabled
setenv_var MODULES_EXTENDED_DEFAULT 1
testouterr_cmd_re sh "restore $coll31fp" $ans $tserr
# same test with icase disabled and extended_default enabled
unsetenv_var MODULES_ICASE
testouterr_cmd_re sh "restore $coll31fp" $ans $tserr
unsetenv_var MODULES_EXTENDED_DEFAULT

setenv_path_var MODULES_LMVARIANT "$c31mod1&foo|val1|0|0&bar|2|0|2:$c31mod3&foo|val3|0|0&bar|3|0|0"
set tserr [msg_unload $c31mod3{bar=3:foo=val3}]\n[msg_unload $c31mod2]\n[msg_unload $c31mod1{bar=2:foo=val1}]\n
append tserr [msg_load $c31mod1{[join $c31mod1vr :]}]\n[msg_load $c31mod2]\n[msg_load $c31mod3{[join $c31mod3vr :]}]
testouterr_cmd_re sh "restore $coll31fp" $ans $tserr

setenv_path_var MODULES_LMVARIANT "$c31mod1&foo|val2|0|0&bar|2|0|2:$c31mod3&foo|val1|0|1&bar|3|0|0"
set ans [list]
lappend ans [list setpath LOADEDMODULES $c31lm]
lappend ans [list setpath _LMFILES_ $c31lmf]
lappend ans [list setpath MODULES_LMVARIANT $c31lmvr]
set tserr [msg_unload $c31mod3{bar=3:foo=val1}]\n[msg_load $c31mod3{[join $c31mod3vr :]}]
testouterr_cmd_re sh "restore $coll31fp" $ans $tserr

# variant sort in different order in persistency var
setenv_path_var MODULES_LMVARIANT "$c31mod1&foo|val2|0|0&bar|2|0|2:$c31mod3&foo|val1|0|1&bar|3|0|0"
testouterr_cmd_re sh "restore $coll31fp" $ans $tserr

# erroneous content in variant persistency var
# as the is-default variant value hint is broken, first module needs reload
setenv_path_var MODULES_LMVARIANT "$c31mod1&foo|val2|str|str&bar|2|0|3:$c31mod3&foo|val1&bar|3|0|3"
set ans [list]
lappend ans [list setpath LOADEDMODULES $c31lm]
lappend ans [list setpath _LMFILES_ $c31lmf]
lappend ans [list setpath MODULES_LMALTNAME $c31lmalt]
lappend ans [list setpath MODULES_LMVARIANT $c31lmvr]
set tserr [msg_unload $c31mod3{bar=3:foo=val1}]\n[msg_unload $c31mod2]\n[msg_unload $c31mod1{bar=2:foo=val2}]\n
append tserr [msg_load $c31mod1{[join $c31mod1vr :]}]\n[msg_load $c31mod2]\n[msg_load $c31mod3{[join $c31mod3vr :]}]
testouterr_cmd_re sh "restore $coll31fp" $ans $tserr

# default value set in collection (bar=2) but non-default value currently loaded (bar=1)
setenv_path_var MODULES_LMVARIANT "$c31mod1&foo|val1|0|0&bar|1|0|0:$c31mod3&foo|val1|0|1&bar|3|0|0"
set ans [list]
lappend ans [list setpath LOADEDMODULES $c31lm]
lappend ans [list setpath _LMFILES_ $c31lmf]
lappend ans [list setpath MODULES_LMALTNAME $c31lmalt]
lappend ans [list setpath MODULES_LMVARIANT $c31lmvr]
set tserr [msg_unload $c31mod3{bar=3:foo=val1}]\n[msg_unload $c31mod2]\n[msg_unload $c31mod1{bar=1:foo=val1}]\n
append tserr [msg_load $c31mod1{[join $c31mod1vr :]}]\n[msg_load $c31mod2]\n[msg_load $c31mod3{[join $c31mod3vr :]}]
testouterr_cmd_re sh "restore $coll31fp" $ans $tserr

unsetenv_loaded_module
unsetenv_path_var MODULES_LMVARIANT
unsetenv_path_var MODULES_LMALTNAME
unsetenv_var TESTSUITE_VARIANT


# test collection restore with sticky variant module loaded (unpinned)
setenv_var MODULES_COLLECTION_PIN_VERSION 0
setenv_var TESTSUITE_VARIANT_TAG coll32
setenv_path_var MODULEPATH $c32modpath1
setenv_loaded_module [list variant/8.0] [list $c32modpath1/variant/8.0]
setenv_path_var MODULES_LMVARIANT "variant/8.0&foo|val1|0|0&bar|2|0|1"
setenv_path_var MODULES_LMTAG variant/8.0&super-sticky
set ans [list]
lappend ans [list setpath LOADEDMODULES $c32lm]
lappend ans [list setpath _LMFILES_ $c32lmf]
lappend ans [list setpath MODULES_LMTAG $c32mod1tag]
lappend ans [list setpath MODULES_LMVARIANT $c32lmvr]
set tserr [msg_unload variant/8.0{bar=2:foo=val1}]\n
append tserr [msg_load '$c32mod1'{[join $c32mod1vr :]}]\n[msg_load $c32mod2]
testouterr_cmd_re sh "restore $coll32fp" $ans $tserr

# test collection restore with sticky variant module loaded (pinned)
setenv_var MODULES_COLLECTION_PIN_VERSION 1
setenv_var TESTSUITE_VARIANT_TAG coll33
setenv_loaded_module [list variant/8.0] [list $c33modpath1/variant/8.0]
setenv_path_var MODULES_LMVARIANT "variant/8.0&foo|val1|0|0&bar|2|0|1"
setenv_path_var MODULES_LMTAG variant/8.0&super-sticky
# CORNER CASE: stickyness swap do not know that default value of variant bar matches sticky rule
set ans [list]
lappend ans [list setpath LOADEDMODULES variant/8.0:$c33lm]
lappend ans [list setpath _LMFILES_ $c33modpath1/variant/8.0:$c33lmf]
lappend ans [list setpath MODULES_LMTAG variant/8.0&super-sticky:$c33mod1tag]
lappend ans [list setpath MODULES_LMVARIANT variant/8.0&foo|val1|0|0&bar|2|0|1:$c33lmvr]
lappend ans [list ERR]
set tserr [msg_unload variant/8.0{bar=2:foo=val1} $err_superstickyunload]\n\n
append tserr [msg_load '$c33mod1'{[join $c33mod1vr :]}]\n[msg_load $c33mod2]
testouterr_cmd_re sh "restore $coll33fp" $ans $tserr

unsetenv_var MODULES_COLLECTION_PIN_VERSION
unsetenv_path_var MODULES_LMTAG
unsetenv_var TESTSUITE_VARIANT_TAG

# restore collection with boolean variants
setenv_var TESTSUITE_VARIANT coll35
eval setenv_path_var MODULEPATH [split $c35modpath :]
eval setenv_path_var MODULES_LMVARIANT [split $c35lmvr :]
setenv_loaded_module [split $c35lm :] [split $c35lmf :]
testouterr_cmd_re sh "restore $coll35fp" OK {}

eval setenv_path_var MODULES_LMVARIANT "$c35mod1&foo|0|1|0&bar|0|1|0:$c35mod2&bar|0|1|0"
set ans [list]
lappend ans [list setpath LOADEDMODULES $c35lm]
lappend ans [list setpath _LMFILES_ $c35lmf]
lappend ans [list setpath MODULES_LMVARIANT $c35lmvr]
set tserr [msg_unload variant/6.0{-bar}]\n[msg_unload variant/1.0{-bar:-foo}]\n[msg_load variant/1.0{\\+bar:-foo}]\n[msg_load variant/6.0{-bar}]
testouterr_cmd_re sh "restore $coll35fp" $ans $tserr

eval setenv_path_var MODULES_LMVARIANT "$c35mod1&foo|0|1|0&bar|1|1|0:$c35mod2&bar|1|1|0"
set tserr [msg_unload variant/6.0{\\+bar}]\n[msg_load variant/6.0{-bar}]
testouterr_cmd_re sh "restore $coll35fp" $ans $tserr

eval setenv_path_var MODULES_LMVARIANT "$c35mod1&foo|str|1|0&bar|2|1|0:$c35mod2&bar|1|str|0"
set tserr [msg_unload variant/6.0{bar=1}]\n[msg_unload variant/1.0{-bar:-foo}]\n[msg_load variant/1.0{\\+bar:-foo}]\n[msg_load variant/6.0{-bar}]
testouterr_cmd_re sh "restore $coll35fp" $ans $tserr

eval setenv_path_var MODULES_LMVARIANT "$c35mod1&foo|str&bar|2|1:$c35mod2&bar|1"
set tserr [msg_unload variant/6.0{bar=1}]\n\n[msg_unload variant/1.0{-bar:foo=str} [err_invalvarval foo str {1 0 yes no true false on off}]]\n\n[msg_load variant/1.0{\\+bar:-foo} [err_othervariantloaded -bar:foo=str]]\n\n[msg_load variant/6.0{-bar}]
set ans [list]
lappend ans [list setpath LOADEDMODULES $c35lm]
lappend ans [list setpath _LMFILES_ $c35lmf]
lappend ans [list setpath MODULES_LMVARIANT $c35mod1&foo|str&bar|2|1:$c35mod2&bar|0|1|0]
lappend ans [list ERR]
testouterr_cmd_re sh "restore $coll35fp" $ans $tserr

unsetenv_loaded_module
unsetenv_path_var MODULES_LMVARIANT

# restore collection with variant shortcut configuration defined
setenv_var TESTSUITE_VARIANT coll36
setenv_var MODULES_VARIANT_SHORTCUT foo=%
set ans [list]
lappend ans [list setpath LOADEDMODULES $c36lm]
lappend ans [list setpath _LMFILES_ $c36lmf]
lappend ans [list setpath MODULES_LMVARIANT $c36lmvr]
set tserr [msg_load variant/1.0{%val1}]
testouterr_cmd_re sh "restore $coll36fp" $ans $tserr
unsetenv_var MODULES_VARIANT_SHORTCUT

unsetenv_var TESTSUITE_VARIANT

unsetenv_var MODULES_ADVANCED_VERSION_SPEC
unsetenv_var MODULES_IMPLICIT_DEFAULT


#
# Cleanup
#

reset_test_env
