##############################################################################
#   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 'save' command
#		}C%
#
##############################################################################


set baddotmod "$env(HOME)/.module"
set baddotmodfp "$baddotmod/$collbadn"
set baddotmoderrmsg "$error_msgs: $baddotmod exists but is not a directory"
set emptyenverrmsg "$error_msgs: Nothing to save in a collection"

#
# test saving when HOME/.module is not directory
#

# create HOME/.module as empty file
if { $verbose > 0 } {
    send_user "\tCreate $baddotmod as an empty file\n"
}
set baddotmodfd [open $baddotmod w]
close $baddotmodfd

testouterr_cmd "ALL" "save" "ERR" "$baddotmoderrmsg"


#
# test saving to an impossible filepath
#

testouterr_cmd "ALL" "save $baddotmodfp" "ERR" "$baddotmoderrmsg"

# delete created HOME/.module empty file
if { $verbose > 0 } {
    send_user "\tDelete $baddotmod\n"
}
file delete $baddotmod


#
# test saving empty collection
#

# set home to unexistent directory for tests
# will automatically be created by save command
if { $verbose > 0 } {
    send_user "\tSetup HOME = $hometestcoll\n"
}
set env(HOME) "$hometestcoll"

# setup an empty environment state
unsetenv_path_var MODULEPATH

testouterr_cmd "ALL" "save" "ERR" "$emptyenverrmsg"


#
# test saving default collection
# with module version pinned or not
#

# setup environment state
if { $verbose > 0 } {
    send_user "\tSetup MODULES_COLLECTION_PIN_VERSION = 0\n"
}
set env(MODULES_COLLECTION_PIN_VERSION) "0"
eval setenv_path_var MODULEPATH [split $cdmodpath ":"]
setenv_loaded_module [split $cdlm ":"] [split $cdlmf ":"]
eval setenv_path_var MODULES_LMALTNAME [split $cdlmalt ":"]

# test only sh shell as this test does not produce shell output
testoutfile_cmd "sh" "save" "OK" "$hometestdotmod/default" "$cdcont"

# now test save with module version pinning enabled
if { $verbose > 0 } {
    send_user "\tSetup MODULES_COLLECTION_PIN_VERSION = 1\n"
}
set env(MODULES_COLLECTION_PIN_VERSION) "1"
testoutfile_cmd "sh" "save" "OK" "$hometestdotmod/default" "$cdcontpin"


#
# test saving named collection
#

# setup environment state
if { $verbose > 0 } {
    send_user "\tUnset MODULES_COLLECTION_PIN_VERSION\n"
}
unset env(MODULES_COLLECTION_PIN_VERSION)
eval setenv_path_var MODULEPATH [split $c1modpath ":"]
setenv_loaded_module [split $c1lm ":"] [split $c1lmf ":"]
eval setenv_path_var MODULES_LMALTNAME [split $c1lmalt ":"]

# test only sh shell as this test does not produce shell output
testoutfile_cmd "sh" "save $coll1" "OK" "$hometestdotmod/$coll1" "$c1cont1"

#
# test saving to an already existing collection
#

# setup environment state
eval setenv_path_var MODULEPATH [split $c2modpath ":"]
setenv_loaded_module [split $c2lm ":"] [split $c2lmf ":"]
eval setenv_path_var MODULES_LMALTNAME [split $c2lmalt ":"]

# test only sh shell as this test does not produce shell output
testoutfile_cmd "sh" "save $coll1" "OK" "$hometestdotmod/$coll1" "$c1cont2"


#
# test saving to a given filepath
#

# test only sh shell as this test does not produce shell output
testoutfile_cmd "sh" "save $hometestdotmod/$coll2" "OK" "$hometestdotmod/$coll2" "$c1cont2"


#
# test saving to a given 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"

# test only sh shell as this test does not produce shell output
testoutfile_cmd "sh" "save $hometestdotmod/$coll3" "OK" "$hometestdotmod/$coll3" "$c1cont2"


#
# test saving collection with no module loaded (only paths set)
# and with a MODULES_COLLECTION_TARGET set
#

# setup environment state
eval setenv_path_var MODULEPATH [split $c4modpath ":"]
unsetenv_loaded_module

# test only sh shell as this test does not produce shell output
testoutfile_cmd "sh" "save $coll4" "OK" "$hometestdotmod/$coll4f" "$c4cont"


#
# test saving collection mixing virtual and deep modules spread through
# different modulepaths to check correct defaults detection
#

# setup environment state
eval setenv_path_var MODULEPATH [split $c6modpath ":"]
setenv_loaded_module [split $c6lm ":"] [split $c6lmf ":"]
eval setenv_path_var MODULES_LMALTNAME [split $c6lmalt ":"]

# test only sh shell as this test does not produce shell output
testoutfile_cmd "sh" "save $coll6" "OK" "$hometestdotmod/$coll6f" "$c6cont"


#
# test saving collection with empty element set in MODULEPATH, LOADEDMODULES, _LMFILES_
#

# setup environment state
eval setenv_path_var MODULEPATH [split ":$c6modpath" ":"]
setenv_loaded_module [split $c6lm ":"] [split $c6lmf ":"]

# test only sh shell as this test does not produce shell output
testoutfile_cmd "sh" "save $coll6" "OK" "$hometestdotmod/$coll6f" "$c6cont"


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

# setup environment state
eval setenv_path_var MODULEPATH [split $c7modpath ":"]
setenv_loaded_module [split $c7lm ":"] [split $c7lmf ":"]
unsetenv_path_var MODULES_LMALTNAME

# test only sh shell as this test does not produce shell output
testoutfile_cmd "sh" "save $coll7" "OK" "$hometestdotmod/$coll7f" "$c7cont"


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

# setup environment state
eval setenv_path_var MODULEPATH [split $c8modpath ":"]
setenv_loaded_module [split $c8lm ":"] [split $c8lmf ":"]

# test only sh shell as this test does not produce shell output
testoutfile_cmd "sh" "save $coll8" "OK" "$hometestdotmod/$coll8f" "$c8cont"


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

# setup environment state
eval setenv_path_var MODULEPATH [split $c9modpath ":"]
setenv_loaded_module [split $c9lm ":"] [split $c9lmf ":"] [split $c9lmnua ":"]

# test only sh shell as this test does not produce shell output
testoutfile_cmd "sh" "save $coll9" "OK" "$hometestdotmod/$coll9f" "$c9cont"


#
# test saving collection with some modulefiles loaded not asked by user
# and loaded by 'module load' commands
#

# setup environment state
eval setenv_path_var MODULEPATH [split $c11modpath :]
setenv_loaded_module [split $c11lm :] [split $c11lmf :] [split $c11lmnua :]
setenv_path_var MODULES_LMPREREQ $c11mod2&$c11mod1

# test only sh shell as this test does not produce shell output
testoutfile_cmd sh "save $coll11" OK $hometestdotmod/$coll11f $c11cont


#
# test when current environment has modulepath and module names containing space
#

unsetenv_path_var MODULES_LMPREREQ
eval setenv_path_var MODULEPATH [split $c15modpath :]
eval setenv_path_var MODULES_LMALTNAME [split $c15lmalt :]
setenv_loaded_module [split $c15lm :] [split $c15lmf :]

testoutfile_cmd sh "save $coll15" OK $hometestdotmod/$coll15f $c15cont

unsetenv_path_var MODULES_LMALTNAME


#
# test modulepath starting with a reference to a variable
#

setenv_path_var MODULEPATH $c17modpath1
setenv_loaded_module [split $c17lm :] [split $c17lmf :]
testoutfile_cmd sh "save $coll17" OK $hometestdotmod/$coll17f $c17cont


#
# variant tests
#

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

# test with collection_pin_version enabled
setenv_var MODULES_COLLECTION_PIN_VERSION 1

eval setenv_path_var MODULEPATH [split $c18modpath :]
eval setenv_path_var MODULES_LMVARIANT [split $c18lmvr :]
setenv_loaded_module [split $c18lm :] [split $c18lmf :]
testoutfile_cmd sh "save $coll18" OK $hometestdotmod/$coll18f $c18cont

# special chars or empty val in variant name or value
eval setenv_path_var MODULEPATH [split $c19modpath :]
eval setenv_path_var MODULES_LMVARIANT [split $c19lmvr :]
setenv_loaded_module [split $c19lm :] [split $c19lmf :]
testoutfile_cmd sh "save $coll19" OK $hometestdotmod/$coll19f $c19cont

# badly set lmvariant
eval setenv_path_var MODULES_LMVARIANT [split $c19lmvrbad1 :]
testoutfile_cmd sh "save $coll19" OK $hometestdotmod/$coll19f $c19cont
eval setenv_path_var MODULES_LMVARIANT [split $c19lmvrbad2 :]
testoutfile_cmd sh "save $coll19" OK $hometestdotmod/$coll19f $c19cont
eval setenv_path_var MODULES_LMVARIANT [split $c19lmvrbad3 :]
testoutfile_cmd sh "save $coll19" OK $hometestdotmod/$coll19f $c19cont

# variant set with default value
eval setenv_path_var MODULEPATH [split $c20modpath :]
eval setenv_path_var MODULES_LMVARIANT [split $c20lmvr :]
setenv_loaded_module [split $c20lm :] [split $c20lmf :]
testoutfile_cmd sh "save $coll20" OK $hometestdotmod/$coll20f $c20cont


# test with collection_pin_version disabled
setenv_var MODULES_COLLECTION_PIN_VERSION 0

eval setenv_path_var MODULEPATH [split $c18modpath :]
eval setenv_path_var MODULES_LMVARIANT [split $c18lmvr :]
setenv_loaded_module [split $c18lm :] [split $c18lmf :]
testoutfile_cmd sh "save $coll18" OK $hometestdotmod/$coll18f $c18cont

# special chars or empty val in variant name or value
eval setenv_path_var MODULEPATH [split $c21modpath :]
eval setenv_path_var MODULES_LMVARIANT [split $c21lmvr :]
setenv_loaded_module [split $c21lm :] [split $c21lmf :]
eval setenv_path_var MODULES_LMALTNAME [split $c21lmalt :]
testoutfile_cmd sh "save $coll21" OK $hometestdotmod/$coll21f $c21cont

# badly set lmvariant
eval setenv_path_var MODULES_LMVARIANT [split $c21lmvrbad1 :]
testoutfile_cmd sh "save $coll21" OK $hometestdotmod/$coll21f $c21cont
eval setenv_path_var MODULES_LMVARIANT [split $c21lmvrbad2 :]
testoutfile_cmd sh "save $coll21" OK $hometestdotmod/$coll21f $c21cont
eval setenv_path_var MODULES_LMVARIANT [split $c21lmvrbad3 :]
testoutfile_cmd sh "save $coll21" OK $hometestdotmod/$coll21f $c21cont

# variant set with default value
eval setenv_path_var MODULEPATH [split $c22modpath :]
eval setenv_path_var MODULES_LMVARIANT [split $c22lmvr :]
eval setenv_path_var MODULES_LMALTNAME [split $c22lmalt :]
setenv_loaded_module [split $c22lm :] [split $c22lmf :]
testoutfile_cmd sh "save $coll22" OK $hometestdotmod/$coll22f $c22cont

# variant duplicately set in environment with default value as last entry
eval setenv_path_var MODULEPATH [split $c34modpath :]
eval setenv_path_var MODULES_LMVARIANT [split $c34lmvr :]
unsetenv_path_var MODULES_LMALTNAME
setenv_loaded_module [split $c34lm :] [split $c34lmf :]
testoutfile_cmd sh "save $coll34" OK $hometestdotmod/$coll34f $c34cont

# test with auto loaded modules
eval setenv_path_var MODULEPATH [split $c23modpath :]
eval setenv_path_var MODULES_LMVARIANT [split $c23lmvr :]
eval setenv_path_var MODULES_LMALTNAME [split $c23lmalt :]
setenv_loaded_module [split $c23lm :] [split $c23lmf :] [split $c23lmnua :]
testoutfile_cmd sh "save $coll23" OK $hometestdotmod/$coll23f $c23cont

setenv_var MODULES_COLLECTION_PIN_VERSION 1
eval setenv_path_var MODULES_LMALTNAME [split $c24lmalt :]
eval setenv_path_var MODULEPATH [split $c24modpath :]
eval setenv_path_var MODULES_LMVARIANT [split $c24lmvr :]
setenv_loaded_module [split $c24lm :] [split $c24lmf :] [split $c24lmnua :]
testoutfile_cmd sh "save $coll24" OK $hometestdotmod/$coll24f $c24cont

# test with boolean variant
unsetenv_path_var MODULES_LMALTNAME
eval setenv_path_var MODULEPATH [split $c35modpath :]
eval setenv_path_var MODULES_LMVARIANT [split $c35lmvr :]
setenv_loaded_module [split $c35lm :] [split $c35lmf :]
testoutfile_cmd sh "save $coll35" OK $hometestdotmod/$coll35f $c35cont

# test with variant shortcut
setenv_var MODULES_VARIANT_SHORTCUT foo=%
eval setenv_path_var MODULEPATH [split $c36modpath :]
setenv_loaded_module [split $c36lm :] [split $c36lmf :]
eval setenv_path_var MODULES_LMVARIANT [split $c36lmvr :]
testoutfile_cmd sh "save $coll36" OK $hometestdotmod/$coll36f $c36cont

setenv_var MODULES_COLLECTION_PIN_VERSION 0
eval setenv_path_var MODULEPATH [split $c36modpath :]
setenv_loaded_module [split $c36lm :] [split $c36lmf :]
eval setenv_path_var MODULES_LMVARIANT [split $c36lmvr :]
testoutfile_cmd sh "save $coll36" OK $hometestdotmod/$coll36f $c36cont
unsetenv_var MODULES_VARIANT_SHORTCUT
setenv_var MODULES_COLLECTION_PIN_VERSION 1

# test recording variant with advanced_version_spec disabled
setenv_var MODULES_ADVANCED_VERSION_SPEC 0

# defined variant are recorded even if advanced_version_spec is disabled
eval setenv_path_var MODULEPATH [split $c25modpath :]
eval setenv_path_var MODULES_LMALTNAME [split $c25lmalt :]
eval setenv_path_var MODULES_LMVARIANT [split $c25lmvr :]
setenv_loaded_module [split $c25lm :] [split $c25lmf :] [split $c25lmnua :]
testoutfile_cmd sh "save $coll25" OK $hometestdotmod/$coll25f $c25cont
unsetenv_path_var MODULES_LMALTNAME

unsetenv_loaded_module
unsetenv_path_var MODULES_LMVARIANT
unsetenv_var MODULES_ADVANCED_VERSION_SPEC
unsetenv_var MODULES_COLLECTION_PIN_VERSION
unsetenv_var MODULES_IMPLICIT_DEFAULT


#
# test unsetting HOME
#

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

testouterr_cmd "sh" "save" "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"
unsetenv_path_var MODULES_LMPREREQ

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


#
# test when current environment has unsatisfied constraint
#

setenv_loaded_module [list trace/all_on conflict/full] [list $c9modpath/trace/all_on $c9modpath/conflict/full]
setenv_path_var MODULES_LMCONFLICT "conflict/full&trace/all_on"

testouterr_cmd "sh" "save" "ERR" "$error_msgs: Cannot save collection, some module constraints are not satistied"


#
# Cleanup
#

reset_test_env
