From 2c4ac73dbbadcdd66e953ea601d0cf15f957440c Mon Sep 17 00:00:00 2001 From: Xavier Delaruelle Date: Fri, 14 Aug 2026 12:12:33 +0000 Subject: [PATCH 01/13] ts: cover MODULES_COLOR override and id groups-parsing branches Two branches of tcl/init.tcl.in had no test reaching them: the env-var-override path of the color config init proc (a plain 'module' invocation never overrides MODULES_COLOR, only the default and command-line paths for that option were exercised) and the id-output-groups-not-last-field path of __initStateUsergroups (the fake 'id' used across the whole suite always prints 'groups=' as its last field, so the branch handling a trailing field placed after it by some systems, e.g. a security context, was never taken). Add an unconditional MODULES_COLOR override case to 140-color.exp (placed before its skip_if_quick_mode so it always runs), and append a trailing field to testsuite/id fake output -- verified this does not change the parsed group list, since the parser stops at the last space before the next '=' either way. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Xavier Delaruelle --- testsuite/id | 2 +- testsuite/modules.00-init/140-color.exp | 8 ++++++++ 2 files changed, 9 insertions(+), 1 deletion(-) diff --git a/testsuite/id b/testsuite/id index 949911a1f..f5b70c8b5 100755 --- a/testsuite/id +++ b/testsuite/id @@ -1,5 +1,5 @@ #!/bin/sh # fake id output -echo "uid=1000(user) gid=1000(user) groups=1000(user),10(wheel),135(mock)" +echo "uid=1000(user) gid=1000(user) groups=1000(user),10(wheel),135(mock) context=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c1023" exit 0 diff --git a/testsuite/modules.00-init/140-color.exp b/testsuite/modules.00-init/140-color.exp index e9b87fbb8..64f48ad1d 100644 --- a/testsuite/modules.00-init/140-color.exp +++ b/testsuite/modules.00-init/140-color.exp @@ -183,6 +183,14 @@ if {$install_color eq {y}} { color_test_case {} 0 $sgr } +# +# ensure Modules-specific color config env var override and its internal +# representation conversion get exercised regardless of quick test mode +# +setenv_var MODULES_COLOR always +color_test_case {} 2 $sgr +unsetenv_var MODULES_COLOR + skip_if_quick_mode # environment variable or/and command-line switch override From 59d85923b9966c20ec2fcd57c12c41b094013e9e Mon Sep 17 00:00:00 2001 From: Xavier Delaruelle Date: Fri, 14 Aug 2026 12:12:50 +0000 Subject: [PATCH 02/13] ts: cover unresolved glob entry in modulespath init file The startup logic in subcmd.tcl.in that reads the site-wide .modulespath file resolves each colon-separated path entry as a glob pattern, keeping the entry as a literal path when the glob matches nothing. The install example .modulespath.in fixture only ever listed entries that do resolve, so that branch, and the module use call appending the collected paths, were never exercised. Add a third, non-existent path entry to the fixture, and extend 120-autoinit.exp expectations for every scenario that sources it, so the resulting MODULEPATH and virtual init collection now include it unresolved. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Xavier Delaruelle --- testsuite/example/.modulespath.in | 2 +- testsuite/modules.70-maint/120-autoinit.exp | 12 ++++++------ 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/testsuite/example/.modulespath.in b/testsuite/example/.modulespath.in index c2372f222..fa3dc3d76 100644 --- a/testsuite/example/.modulespath.in +++ b/testsuite/example/.modulespath.in @@ -16,5 +16,5 @@ # # location of version files @VERSIONING@@baseprefix@/$MODULE_VERSION/modulefiles # Module pkg modulefiles (if versioning) @NOTVERSIONING@@modulefilesdir@ # Module pkg modulefiles (if no versioning) -@prefix@/test/modulefiles:@prefix@/test/etc # General module files +@prefix@/test/modulefiles:@prefix@/test/etc:@prefix@/test/absent # General module files, last one unresolved #@prefix@/your_contribs # Edit for your requirements diff --git a/testsuite/modules.70-maint/120-autoinit.exp b/testsuite/modules.70-maint/120-autoinit.exp index 834d01ebb..4834e22cb 100644 --- a/testsuite/modules.70-maint/120-autoinit.exp +++ b/testsuite/modules.70-maint/120-autoinit.exp @@ -101,9 +101,9 @@ set tserr_initrc1_exinstalled [msg_load null] set lminit_modrc_exinstalled "module use --append $install_modulepath:module load null" set lminit_modrc1_exinstalled "module use --append $install_modulepath:module load null" -set lminit_modspath_modrc1_exinstalled "module use --append $install_modulepath:module use --append $install_prefix/test/modulefiles:module use --append $install_prefix/test/etc:module load null" +set lminit_modspath_modrc1_exinstalled "module use --append $install_modulepath:module use --append $install_prefix/test/modulefiles:module use --append $install_prefix/test/etc:module use --append $install_prefix/test/absent:module load null" set lminit_initrc_exinstalled "module use --append {$modpath wspace}:module use --append $modpath.deps:module load --tag=auto-loaded m1:module load m3:module load {space yc/4}" -set lminit_modspath_exinstalled "module use --append $install_modulepath:module use --append $install_prefix/test/modulefiles:module use --append $install_prefix/test/etc" +set lminit_modspath_exinstalled "module use --append $install_modulepath:module use --append $install_prefix/test/modulefiles:module use --append $install_prefix/test/etc:module use --append $install_prefix/test/absent" # check if stderr terminal attachment state is forced @@ -1281,7 +1281,7 @@ if {(!$insmodspath || $modspath_exinstalled) && (!$insmodrc || $modrc_exinstalle lappend ans [list set MODULES_CMD $modulecmd_path] lappend ans [list set MODULES_AUTO_HANDLING 0] lappend ans [list set MODULES_ML 0] - lappend ans [list set MODULEPATH "$install_modulepath:$install_prefix/test/modulefiles:$install_prefix/test/etc"] + lappend ans [list set MODULEPATH "$install_modulepath:$install_prefix/test/modulefiles:$install_prefix/test/etc:$install_prefix/test/absent"] lappend ans [list set __MODULES_LMINIT $lminit_modspath_modrc1_exinstalled] lappend ans [list set MODULES_SET_SHELL_STARTUP 0] lappend ans [list set MODULES_SHELLS_WITH_KSH_FPATH "sh:bash"] @@ -1312,7 +1312,7 @@ if {(!$insmodspath || $modspath_exinstalled) && (!$insmodrc || $modrc_exinstalle lappend ans [list set FPATH $install_initdir/ksh-functions] } lappend ans [list set __MODULES_LMINIT $lminit_modspath_modrc1_exinstalled] - lappend ans [list set MODULEPATH "$install_modulepath:$install_prefix/test/modulefiles:$install_prefix/test/etc"] + lappend ans [list set MODULEPATH "$install_modulepath:$install_prefix/test/modulefiles:$install_prefix/test/etc:$install_prefix/test/absent"] if {$install_versioning eq "y"} { lappend ans [list set MODULE_VERSION "(.*)"] } @@ -1345,7 +1345,7 @@ if {(!$insmodspath || $modspath_exinstalled) && (!$insmodrc || $modrc_exinstalle lappend ans [list set FPATH $install_initdir/ksh-functions] } lappend ans [list set __MODULES_LMINIT $lminit_modspath_exinstalled] - lappend ans [list set MODULEPATH "$install_modulepath:$install_prefix/test/modulefiles:$install_prefix/test/etc"] + lappend ans [list set MODULEPATH "$install_modulepath:$install_prefix/test/modulefiles:$install_prefix/test/etc:$install_prefix/test/absent"] if {$install_versioning eq "y"} { lappend ans [list set MODULE_VERSION "(.*)"] } @@ -2140,7 +2140,7 @@ if {$insmodspath && $modspath_exinstalled && $modspath eq "$install_etcdir/modul lappend ans [list set MODULESHOME $moduleshome] lappend ans [list set LOADEDMODULES ""] lappend ans [list set __MODULES_LMINIT $lminit_modspath_exinstalled] - lappend ans [list set MODULEPATH "$install_modulepath:$install_prefix/test/modulefiles:$install_prefix/test/etc"] + lappend ans [list set MODULEPATH "$install_modulepath:$install_prefix/test/modulefiles:$install_prefix/test/etc:$install_prefix/test/absent"] if {$install_versioning eq "y"} { lappend ans [list set MODULE_VERSION "(.*)"] } From 6def6729c1499a5a765be6056e9af223639cb705 Mon Sep 17 00:00:00 2001 From: Xavier Delaruelle Date: Fri, 14 Aug 2026 12:13:18 +0000 Subject: [PATCH 03/13] ts: cover missing-value error for module-warn trailing option The module-warn modulefile command (mfcmd.tcl) raises "Missing value for '--message' option" when --message is the last token in its argument list, with nothing left to consume as the value. The existing warn/.modulerc and warn/1 fixtures covered every other module-warn error case (no message, no module, unknown option) but not this one, since none of their scenarios ended the argument list right after a bare --message. Add a new scenario to both fixtures and a matching case to 700-module-warn.exp for each of the rc and modulefile call sites. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Xavier Delaruelle --- testsuite/modulefiles.4/warn/.modulerc | 3 +++ testsuite/modulefiles.4/warn/1 | 3 +++ testsuite/modules.50-cmds/700-module-warn.exp | 11 +++++++++++ 3 files changed, 17 insertions(+) diff --git a/testsuite/modulefiles.4/warn/.modulerc b/testsuite/modulefiles.4/warn/.modulerc index 51cfd02a5..512eb4c86 100644 --- a/testsuite/modulefiles.4/warn/.modulerc +++ b/testsuite/modulefiles.4/warn/.modulerc @@ -28,6 +28,9 @@ if {[info exists env(TESTSUITE_WARN)]} { rc_bad4 { module-warn --message text --unk warn/1 } + rc_bad5 { + module-warn --message + } user1 { module-warn --message text --user [module-info username] warn/1 } diff --git a/testsuite/modulefiles.4/warn/1 b/testsuite/modulefiles.4/warn/1 index fe8ac0408..46cea7b7f 100644 --- a/testsuite/modulefiles.4/warn/1 +++ b/testsuite/modulefiles.4/warn/1 @@ -25,5 +25,8 @@ if {[info exists env(TESTSUITE_WARN)]} { mf_bad4 { module-warn --message text --unk warn/1 } + mf_bad5 { + module-warn --message + } } } diff --git a/testsuite/modules.50-cmds/700-module-warn.exp b/testsuite/modules.50-cmds/700-module-warn.exp index e3563b443..bfa935f0b 100644 --- a/testsuite/modules.50-cmds/700-module-warn.exp +++ b/testsuite/modules.50-cmds/700-module-warn.exp @@ -218,6 +218,12 @@ set line_num [expr {[cmpversion $tclsh_version 8.6] == -1 ? 2 : 29}] set tserr [escre [msg_moderr {Invalid option '--unk'} {module-warn --message text --unk warn/1} $mp/warn/.modulerc $line_num { }]] testouterr_cmd_re bash {load warn/1} $ans $tserr +setenv_var TESTSUITE_WARN rc_bad5 + +set line_num [expr {[cmpversion $tclsh_version 8.6] == -1 ? 2 : 32}] +set tserr [escre [msg_moderr {Missing value for '--message' option} {module-warn --message} $mp/warn/.modulerc $line_num { }]] +testouterr_cmd_re bash {load warn/1} $ans $tserr + setenv_var TESTSUITE_WARN mf_bad1 set line_num [expr {[cmpversion $tclsh_version 8.6] == -1 ? 4 : 17}] set tserr [escre [msg_load warn/1 [msg_moderr {No message specified in argument} {module-warn} $mp/warn/1 $line_num]]] @@ -238,6 +244,11 @@ set line_num [expr {[cmpversion $tclsh_version 8.6] == -1 ? 4 : 26}] set tserr [escre [msg_load warn/1 [msg_moderr {Invalid option '--unk'} {module-warn --message text --unk warn/1} $mp/warn/1 $line_num]]] testouterr_cmd_re bash {load warn/1} ERR $tserr +setenv_var TESTSUITE_WARN mf_bad5 +set line_num [expr {[cmpversion $tclsh_version 8.6] == -1 ? 4 : 29}] +set tserr [escre [msg_load warn/1 [msg_moderr {Missing value for '--message' option} {module-warn --message} $mp/warn/1 $line_num]]] +testouterr_cmd_re bash {load warn/1} ERR $tserr + # user/time selection From 603e1d89ed204f8cad1206da4105e1f1977fbd98 Mon Sep 17 00:00:00 2001 From: Xavier Delaruelle Date: Fri, 14 Aug 2026 12:13:54 +0000 Subject: [PATCH 04/13] ts: cover extended_default preferring an explicit default on tie The array-key lookup helpers in modspec.tcl that back extended_default resolution (one variant used when implicit_default is on, one when it is off) resolve a partial version query matching several available versions by first checking whether the directory has an explicit default version and, only if none of the matches is that explicit default, falling back to the highest matching version. No existing fixture had a module name with two sibling versions, one of them set as default through a .version file, queried through a partial spec that matches both, so the explicit-default branch of either variant was never taken. Add a new fixture module with versions 1.0.1 and 1.0.2 where 1.0.1 is the explicit default, and a test loading it through the partial spec 1.0 with extended_default enabled, checked with implicit_default both on and off since that selects which of the two lookup variants runs. Update 140-hide-full-path.exp expected listing for the new fixture, which that test enumerates as part of the whole modulepath. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Xavier Delaruelle --- testsuite/modulefiles.4/loc_edm1/.version | 3 + testsuite/modulefiles.4/loc_edm1/1.0.1 | 2 + testsuite/modulefiles.4/loc_edm1/1.0.2 | 2 + .../modules.20-locate/140-hide-full-path.exp | 2 + .../modules.20-locate/171-multidefault.exp | 78 +++++++++++++++++++ 5 files changed, 87 insertions(+) create mode 100644 testsuite/modulefiles.4/loc_edm1/.version create mode 100644 testsuite/modulefiles.4/loc_edm1/1.0.1 create mode 100644 testsuite/modulefiles.4/loc_edm1/1.0.2 create mode 100644 testsuite/modules.20-locate/171-multidefault.exp diff --git a/testsuite/modulefiles.4/loc_edm1/.version b/testsuite/modulefiles.4/loc_edm1/.version new file mode 100644 index 000000000..67db9a299 --- /dev/null +++ b/testsuite/modulefiles.4/loc_edm1/.version @@ -0,0 +1,3 @@ +#%Module + +module-version ./1.0.1 default diff --git a/testsuite/modulefiles.4/loc_edm1/1.0.1 b/testsuite/modulefiles.4/loc_edm1/1.0.1 new file mode 100644 index 000000000..46c5a073c --- /dev/null +++ b/testsuite/modulefiles.4/loc_edm1/1.0.1 @@ -0,0 +1,2 @@ +#%Module +module-whatis loc_edm1/1.0.1 diff --git a/testsuite/modulefiles.4/loc_edm1/1.0.2 b/testsuite/modulefiles.4/loc_edm1/1.0.2 new file mode 100644 index 000000000..89eb8678a --- /dev/null +++ b/testsuite/modulefiles.4/loc_edm1/1.0.2 @@ -0,0 +1,2 @@ +#%Module +module-whatis loc_edm1/1.0.2 diff --git a/testsuite/modules.20-locate/140-hide-full-path.exp b/testsuite/modules.20-locate/140-hide-full-path.exp index 9d2f2bc14..8a2523fa2 100644 --- a/testsuite/modules.20-locate/140-hide-full-path.exp +++ b/testsuite/modules.20-locate/140-hide-full-path.exp @@ -131,6 +131,7 @@ set tserr "$modlin Aliases $modlin tag/1.1.al -> tag/1.0 $modlin Versions $modlin +loc_edm1/default -> loc_edm1/1.0.1 loc_fdv2/default -> loc_fdv2/1.2 tag/1.1.sym -> tag/1.0" @@ -168,6 +169,7 @@ set tserr "$modlin Aliases $modlin tag/1.1.al -> tag/1.0 $modlin Versions $modlin +loc_edm1/default -> loc_edm1/1.0.1 loc_fdv2/default -> loc_fdv2/1.2 tag/1.1.sym -> tag/1.0" diff --git a/testsuite/modules.20-locate/171-multidefault.exp b/testsuite/modules.20-locate/171-multidefault.exp new file mode 100644 index 000000000..5fcb3cf60 --- /dev/null +++ b/testsuite/modules.20-locate/171-multidefault.exp @@ -0,0 +1,78 @@ +############################################################################## +# Modules Revision 3.0 +# Providing a flexible user environment +# +# File: modules.20-locate/%M% +# Revision: %I% +# First Edition: 2026/08/14 +# Last Mod.: %U%, %G% +# +# Authors: Xavier Delaruelle, xavier.delaruelle@cea.fr +# +# Description: Testuite testsequence +# Command: load, display +# Modulefiles: loc_edm1 +# Sub-Command: +# +# Comment: %C{ +# Check that a partial version query resolved through the +# extended_default mechanism, which ends up matching several +# available versions, correctly prefers the version +# explicitly set as 'default' over the highest matching one, +# whether the implicit_default option is enabled or disabled +# }C% +# +############################################################################## + +# skip tests if extended_default or implicit_default option could not be +# overridden +if {[is_config_locked extended_default] || [is_config_locked\ + implicit_default]} { + send_user "\tskipping tests as extended_default or implicit_default\ + could not be overridden\n" +} else { + +# use a dedicated modulepath so this new fixture does not affect other tests +# that enumerate the whole content of the default modulepath +setenv_path_var MODULEPATH $modpath.4 + +setenv_var MODULES_EXTENDED_DEFAULT 1 + +set module "loc_edm1" +set module_default "$module/1.0.1" +set modulefile_default "$modpath.4/$module_default" +set modulefilere_default "$modpathre.4/$module_default" + +# +# loc_edm1 holds two sibling versions, 1.0.1 and 1.0.2, with 1.0.1 explicitly +# set as 'default' through a '.version' file. A partial version query like +# '1.0' matches both versions through extended_default: the resolution must +# pick the explicitly defined default (1.0.1) rather than 1.0.2, which would +# be selected if only the highest matching version was considered. This must +# hold whether implicit_default is enabled or disabled +# + +foreach implicitdefault {1 0} { + +setenv_var MODULES_IMPLICIT_DEFAULT $implicitdefault + +set ans [list] +lappend ans [list set __MODULES_LMALTNAME\ + $module_default&$module/default&$module] +lappend ans [list set _LMFILES_ $modulefile_default] +lappend ans [list set LOADEDMODULES $module_default] + +test_cmd "sh" "load $module/1.0" $ans + +testouterr_cmd_re "sh" "display $module/1.0" "OK"\ + "$modlin\n$modulefilere_default:\n\nmodule-whatis\\s+$module_default\n$modlin" + +} + +# +# Cleanup +# + +reset_test_env + +} From 2e6c5ca2b15c17bd1c634602b511bda83854ae17 Mon Sep 17 00:00:00 2001 From: Xavier Delaruelle Date: Fri, 14 Aug 2026 12:14:12 +0000 Subject: [PATCH 05/13] ts: cover wildcard flush of a nameless variant-only spec element The module-spec argument parser in modspec.tcl, when a sub-command allows a spec with no module name, flushes a variant-only element still pending when a following element starts a name of its own by substituting a wildcard name for it. No existing avail test passed a variant-only argument ahead of a named one in the same command line, so that flush branch was never taken. Add such a case to 270-adv_version_spec.exp: a variant assignment argument followed by a separate named argument, checked against the plain named lookup so the wildcard element is confirmed to have no effect on the result. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Xavier Delaruelle --- testsuite/modules.70-maint/270-adv_version_spec.exp | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/testsuite/modules.70-maint/270-adv_version_spec.exp b/testsuite/modules.70-maint/270-adv_version_spec.exp index 3ab93f79a..6b513d40c 100644 --- a/testsuite/modules.70-maint/270-adv_version_spec.exp +++ b/testsuite/modules.70-maint/270-adv_version_spec.exp @@ -157,6 +157,11 @@ testouterr_cmd_re sh {whatis extdfl@1.4.5} OK "$modlin $mpre $modlin \\s+extdfl/1.4.5: extdfl/1.4.5" testouterr_cmd sh {paths extdfl @1.4.5} [list [list text $mp/extdfl/1.4.5]] {} +# a spec made of a variant-only element (no module name) must be correctly +# flushed as a wildcard name query once a subsequent element bearing an +# actual module name starts a new spec (nonamespec-allowed sub-commands only) +testouterr_cmd sh {avail -t somevariant=val extdfl@1.4} OK "$mp:\nextdfl/1.4.5" + # test various modulefile kind: alias, symver, virtual, directory hidden testouterr_cmd sh {avail -t extdfl3@1.00} OK "$mp:\nextdfl3/1.00(@)" testouterr_cmd sh {avail -t extdfl7 @3.0} OK "$mp:\nextdfl7/2.10(3.0)" From 35f4084a0a04b5192dd74f8795b0e9d0ec96d381 Mon Sep 17 00:00:00 2001 From: Xavier Delaruelle Date: Fri, 14 Aug 2026 12:14:44 +0000 Subject: [PATCH 06/13] ts: cover extensions-sc at the default info_extension setting extensions-sc, the scan-time stand-in for the extensions modulefile command in modscan.tcl, records a provided-alias element alongside provide only when info_extension is off, the default for that option. The only existing test exercising a scanned extensions command first turned info_extension on, so the default-off case was never scanned. Add a case using the existing provide fixture ahead of that override, checking both the provide and provided-alias search results at the default setting. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Xavier Delaruelle --- testsuite/modules.51-scan/046-extra_spec-provide.exp | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/testsuite/modules.51-scan/046-extra_spec-provide.exp b/testsuite/modules.51-scan/046-extra_spec-provide.exp index 0bfad890c..dc4c29326 100644 --- a/testsuite/modules.51-scan/046-extra_spec-provide.exp +++ b/testsuite/modules.51-scan/046-extra_spec-provide.exp @@ -107,6 +107,14 @@ testouterr_cmd sh {avail -t provided-alias:foo} OK $tserr # info_extension tests # +# info_extension is off by default, so a scanned "extensions" command +# records a "provided-alias" element in addition to "provide" +setenv_var TESTSUITE_PROVIDE extensions + +set tserr provide/1 +testouterr_cmd sh {avail -t provide provide:foo/1} OK $tserr +testouterr_cmd sh {avail -t provide provided-alias:qux/1} OK $tserr + setenv_var MODULES_INFO_EXTENSION 1 setenv_var TESTSUITE_PROVIDE multiple From fa6d7ce76fb3cd5b40258a640149627e324fa08a Mon Sep 17 00:00:00 2001 From: Xavier Delaruelle Date: Fri, 14 Aug 2026 12:31:31 +0000 Subject: [PATCH 07/13] Remove unreachable else-if in getModules version symbol collection The version-handling loop in getModules (tcl/modfind.tcl.in) has carried a dead branch since it was introduced. Two commits landed back to back on 2020-10-25 while fixing an issue about global/user rc definitions not showing up in results: the first made the loop add every such rc-defined version to the found list and the module symbol list unconditionally, dropping the previous gate on whether rc definitions were asked to be included; the second, right after it, added a further else-if branch meant to still record an rc definition in the module symbol list when that inclusion flag is false, apparently written without noticing the branch above it now already fires whenever a version has an rc definition at all, flag or not. Since the main condition already covers every case the else-if checks, the else-if can never run, and it never has, from the day it was added -- confirmed by checking out the state right before that second commit in git history. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Xavier Delaruelle --- tcl/modfind.tcl.in | 3 --- 1 file changed, 3 deletions(-) diff --git a/tcl/modfind.tcl.in b/tcl/modfind.tcl.in index 30c921b7c..84832e3d6 100644 --- a/tcl/modfind.tcl.in +++ b/tcl/modfind.tcl.in @@ -3396,9 +3396,6 @@ proc getModules {dir {mod {}} {fetch_mtime 0} {search {}} {filter {}}} { # build module symbol list lappend versmod_list($versmod) $vers - # add global/user rc def to module symbol list in any cases - } elseif {!$add_rc_defs && [info exists g_rcVersion($vers)]} { - lappend versmod_list($versmod) $vers } } From 8d9bc2004aefcb8b9464be8bea39b34494903b47 Mon Sep 17 00:00:00 2001 From: Xavier Delaruelle Date: Fri, 14 Aug 2026 12:47:12 +0000 Subject: [PATCH 08/13] Remove unreachable display_list existence check in module listing The module-listing proc in tcl/report.tcl.in builds its JSON-mode display list by aliasing display_list to clean_list via 'upvar 0', then guarding with 'if {![info exists display_list]} { set display_list {} }' in case clean_list was never populated. clean_list, though, is unconditionally set to an empty list right at the top of the same proc, before the per-module loop that may or may not append to it -- so by the time the alias is created, the variable it points to already exists, and the guard can never fire. Checked out the state of modulecmd.tcl.in right before the commit that introduced this upvar/guard pair (originally for a different, now-refactored JSON-support commit) to confirm the same unconditional pre-loop initialization was already present at that point too: the guard has been dead from the day it was added, not from a later refactor. Drop the guard, keeping only the alias. This changes nothing at runtime since the branch was unreachable, so no new test is needed. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Xavier Delaruelle --- tcl/report.tcl.in | 3 --- testsuite/modules.00-init/120-siteconfig.exp | 2 +- 2 files changed, 1 insertion(+), 4 deletions(-) diff --git a/tcl/report.tcl.in b/tcl/report.tcl.in index 5658c8680..6c0e1fa2b 100644 --- a/tcl/report.tcl.in +++ b/tcl/report.tcl.in @@ -1598,9 +1598,6 @@ proc reportModules {search_queries header hsgrkey hstyle show_mtime show_idx\ if {$json} { ##nagelfar ignore Found constant upvar 0 clean_list display_list - if {![info exists display_list]} { - set display_list {} - } } else { set display_list {} foreach disp $clean_list { diff --git a/testsuite/modules.00-init/120-siteconfig.exp b/testsuite/modules.00-init/120-siteconfig.exp index 2d40f1977..c5b86b431 100644 --- a/testsuite/modules.00-init/120-siteconfig.exp +++ b/testsuite/modules.00-init/120-siteconfig.exp @@ -716,7 +716,7 @@ lappend ans { "displaySeparatorLine $header $sgrkey $extra"} lappend ans { (procedure "displayElementList" line 19)} lappend ans { invoked from within} lappend ans { "displayElementList $header $hsgrkey $hstyle $one_per_line $show_idx 1 $display_list $len_list $via_list"} -lappend ans { (procedure "reportModules" line 151)} +lappend ans { (procedure "reportModules" line 148)} lappend ans { invoked from within} lappend ans { "reportModules $args $dir mp $hstyle $show_mtime 0 $one_per_line $theader_cols hidden-loaded"} lappend ans { (procedure "cmdModuleAvail" line 43)} From 916803422254a89ddddc6817ca8411424d989125 Mon Sep 17 00:00:00 2001 From: Xavier Delaruelle Date: Fri, 14 Aug 2026 12:47:42 +0000 Subject: [PATCH 09/13] ts: cover array-key lookup variant redefinition via siteconfig The array-key lookup helpers in modspec.tcl are backed by two alternative proc bodies, swapped in under a single common name by a definer proc depending on whether implicit_default is on. Its rename-the-previous-variant-back branch only runs on a second call with a different value than the first, and nothing in the normal command dispatch path ever calls it more than once per process -- its only caller runs exactly once per top-level command. A site configuration script, though, runs in the same interpreter with full access to every internal proc, and the suite already uses that access to cover the identical rename-back branch of three sibling helpers through the existing on-the-fly-procedure-redefinition case in siteconfig.tcl-1 -- the array-key lookup definer was simply missing from that coverage. Add a matching case: call the definer with implicit_default 0, then 1, then 0 again, reporting a lookup through the active variant after each call to confirm it still resolves correctly once swapped both ways. Verified against a probe copy of the built interpreter that the added middle and third calls do reach the rename-back branch (confirmed by a temporary print statement there, since a local coverage-instrumented run was out of scope here), and with 'TESTSUITE_ENABLE_SITECONFIG=1 script/mt 00/120' per the existing convention for exercising this siteconfig fixture locally (a real install is otherwise required, since the primary siteconfig option has no environment-variable override). Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Xavier Delaruelle --- testsuite/example/siteconfig.tcl-1 | 11 +++++++++++ testsuite/modules.00-init/120-siteconfig.exp | 10 ++++++++++ 2 files changed, 21 insertions(+) diff --git a/testsuite/example/siteconfig.tcl-1 b/testsuite/example/siteconfig.tcl-1 index d50e768a6..e3fdf1bc0 100644 --- a/testsuite/example/siteconfig.tcl-1 +++ b/testsuite/example/siteconfig.tcl-1 @@ -331,6 +331,17 @@ if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_REDEFONTHEFLYPROCS)]} { report [modEq foo fOo equal] } +# defineGetEqArrayKeyProc redefinition coverage test +if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_REDEFGETEQARRAYKEYPROC)]} { + array set arr {foo/1.0 {version foo/1.0}} + defineGetEqArrayKeyProc 0 + report [getEqArrayKey arr foo/1.0] + defineGetEqArrayKeyProc 1 + report [getEqArrayKey arr foo/1.0] + defineGetEqArrayKeyProc 0 + report [getEqArrayKey arr foo/1.0] +} + # specific tests to improve formatErrStackTrace proc coverage if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_FORMATERRSTACKTRACE)]} { set errmsg {error message diff --git a/testsuite/modules.00-init/120-siteconfig.exp b/testsuite/modules.00-init/120-siteconfig.exp index c5b86b431..71a0cbceb 100644 --- a/testsuite/modules.00-init/120-siteconfig.exp +++ b/testsuite/modules.00-init/120-siteconfig.exp @@ -589,6 +589,16 @@ lappend ans $vers_reportre testouterr_cmd_re sh -V OK [join $ans \n] unsetenv_var TESTSUITE_ENABLE_SITECONFIG_REDEFONTHEFLYPROCS +# test redefinition of defineGetEqArrayKeyProc, called twice in a row with a +# different implicit_default value each time, to demonstrate it renaming the +# previously active variant back before renaming the new one in +setenv_var TESTSUITE_ENABLE_SITECONFIG_REDEFGETEQARRAYKEYPROC 1 +set ans [list] +lappend ans foo/1.0 foo/1.0 foo/1.0 +lappend ans $vers_reportre +testouterr_cmd_re sh -V OK [join $ans \n] +unsetenv_var TESTSUITE_ENABLE_SITECONFIG_REDEFGETEQARRAYKEYPROC + # specific tests to improve formatErrStackTrace proc coverage setenv_var TESTSUITE_ENABLE_SITECONFIG_FORMATERRSTACKTRACE 1 set ans [list] From 53e877cbcf2baafd9727d10752a9543974d35c1c Mon Sep 17 00:00:00 2001 From: Xavier Delaruelle Date: Fri, 14 Aug 2026 12:56:52 +0000 Subject: [PATCH 10/13] ts: cover generic config value validation/conversion shapes The generic env-var/command-line override handling inside getConf (tcl/init.tcl.in) has two branches no current config option is shaped to reach: the single-element validvallist case of its validation switch, meant for a Tcl 'string is ' check rather than a fixed value list, since every option using an unkeyed validvallist today either has zero elements or two or more; and the generic intvallist conversion at the end of that same block, since the only option that sets intvallist, color, also sets an initproc that supersedes this whole path before reaching it. Both branches are reachable by giving an option that different shape at runtime, and the suite already does exactly that for other options through g_config_defs overrides in siteconfig.tcl-1 (see the existing bad-default-value cases for tag_abbrev and variant_shortcut, and the init_envvars case right below the new ones). Add two more: superseding run_quarantine with a single-element 'integer' validvallist and an overridden environment variable to exercise the string-is class check, and superseding csh_limit (which has no environment variable of its own to fake) with a two-element validvallist and intvallist to exercise the generic conversion on its plain default value. Verified with 'TESTSUITE_ENABLE_SITECONFIG=1 script/mt 00/120' per the existing convention for exercising this siteconfig fixture locally (a real install is otherwise required, since the primary siteconfig option has no environment-variable override), plus the same file without that variable set and the Tcl lint check, all matching pre-change results other than the two new passing cases. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Xavier Delaruelle --- .hunspell.en.dic | 4 ++++ testsuite/example/siteconfig.tcl-1 | 18 ++++++++++++++++++ testsuite/modules.00-init/120-siteconfig.exp | 18 ++++++++++++++++++ 3 files changed, 40 insertions(+) diff --git a/.hunspell.en.dic b/.hunspell.en.dic index 6989c8ffa..0eab552da 100644 --- a/.hunspell.en.dic +++ b/.hunspell.en.dic @@ -516,6 +516,7 @@ initdir initializations initlist initprepend +initproc initrc initrm initswitch @@ -523,6 +524,7 @@ instopt intbe intelmpi interp +intvallist io isExtraMatchSearchRequired isModuleEvaluated @@ -903,6 +905,7 @@ unix unixtime unixtimestamp unk +unkeyed unlink unloadable unprefixed @@ -925,6 +928,7 @@ userlvl usr utitilies va +validvallist variantifspec variantname vectorization diff --git a/testsuite/example/siteconfig.tcl-1 b/testsuite/example/siteconfig.tcl-1 index e3fdf1bc0..8e8696a30 100644 --- a/testsuite/example/siteconfig.tcl-1 +++ b/testsuite/example/siteconfig.tcl-1 @@ -371,6 +371,24 @@ if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_BADVARIANTSHORTCUTDFLVALUE)]} { set g_config_defs(variant_shortcut) {MODULES_VARIANT_SHORTCUT {foo} 0 l {} {} initConfVariantShortcut} } +# exercise the single-element validvallist "string is" class check path in +# getConf, not used by any current config option, by superseding an existing +# lockable option's definition with that shape +if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_VALIDVALLISTSTRINGIS)]} { + set ::g_config_defs(run_quarantine) {MODULES_RUN_QUARANTINE default 0 s\ + integer} + set env(MODULES_RUN_QUARANTINE) 42 + report [getConf run_quarantine] +} + +# exercise the generic intvallist conversion path in getConf when no initproc +# is set, not used by any current config option (the only option using +# intvallist, color, has an initproc superseding this path) +if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_INTVALLISTCONV)]} { + set ::g_config_defs(csh_limit) {{} val2 0 s {val1 val2} {10 20}} + report [getConf csh_limit] +} + # specific tests to improve getModuleDesignation procs coverage if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_GETMODULEDESIGNATION)]} { # test disabled sgr mode diff --git a/testsuite/modules.00-init/120-siteconfig.exp b/testsuite/modules.00-init/120-siteconfig.exp index 71a0cbceb..0e066d022 100644 --- a/testsuite/modules.00-init/120-siteconfig.exp +++ b/testsuite/modules.00-init/120-siteconfig.exp @@ -599,6 +599,24 @@ lappend ans $vers_reportre testouterr_cmd_re sh -V OK [join $ans \n] unsetenv_var TESTSUITE_ENABLE_SITECONFIG_REDEFGETEQARRAYKEYPROC +# test the single-element validvallist "string is" class check path in +# getConf, not exercised by any current config option's own shape +setenv_var TESTSUITE_ENABLE_SITECONFIG_VALIDVALLISTSTRINGIS 1 +set ans [list] +lappend ans 42 +lappend ans $vers_reportre +testouterr_cmd_re sh -V OK [join $ans \n] +unsetenv_var TESTSUITE_ENABLE_SITECONFIG_VALIDVALLISTSTRINGIS + +# test the generic intvallist conversion path in getConf when no initproc is +# set, not exercised by any current config option's own shape +setenv_var TESTSUITE_ENABLE_SITECONFIG_INTVALLISTCONV 1 +set ans [list] +lappend ans 20 +lappend ans $vers_reportre +testouterr_cmd_re sh -V OK [join $ans \n] +unsetenv_var TESTSUITE_ENABLE_SITECONFIG_INTVALLISTCONV + # specific tests to improve formatErrStackTrace proc coverage setenv_var TESTSUITE_ENABLE_SITECONFIG_FORMATERRSTACKTRACE 1 set ans [list] From f1b7e7e1a420964c0c372352d0fe7f2ab2973321 Mon Sep 17 00:00:00 2001 From: Xavier Delaruelle Date: Fri, 14 Aug 2026 13:17:34 +0000 Subject: [PATCH 11/13] ts: cover tag deduplicate skip path and fix redefinition test gap Corrected understanding of what Nagelfar/Codecov actually flag on a bare closing brace of an else-less if: it means the condition never evaluated false in any run, not that the block was never entered. Two consequences: The array-key lookup helper collecting matching tags checks "$tag ni $tag_list" to skip a tag root already recorded earlier in the same call, but that check can never observe a duplicate, since the proc that populates the underlying tag structure always deduplicates by tag name before appending -- so this skip branch is unreachable through module-tag/module-hide/module-forbid. Force the shape directly through the global tag structures from siteconfig.tcl-1 instead, the same way the suite already does for config option shapes: two identical tag entries at different indices, so the second lookup observes the tag already recorded by the first. The array-key definer redefinition case added earlier only ever called it with a value different from the one before, so it never exercised the no-op branch where the currently active variant already matches what is being asked for -- add a same-value call at the start, matching the shape the existing on-the-fly-procedure- redefinition case already uses for its own sibling helpers (same value twice, then different twice). Also add a case for the available-version-list lookup helper's unregistered-argument path: its only real caller always passes an argument already registered through the module-spec parser, so call it directly with one that was never registered. Verified with 'TESTSUITE_ENABLE_SITECONFIG=1 script/mt 00/120' (65 passes) plus the same file without that variable set and the Tcl lint check, not the full suite. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Xavier Delaruelle --- .hunspell.en.dic | 2 ++ testsuite/example/siteconfig.tcl-1 | 29 +++++++++++++++++++- testsuite/modules.00-init/120-siteconfig.exp | 29 +++++++++++++++++--- 3 files changed, 55 insertions(+), 5 deletions(-) diff --git a/.hunspell.en.dic b/.hunspell.en.dic index 0eab552da..72cfc360d 100644 --- a/.hunspell.en.dic +++ b/.hunspell.en.dic @@ -607,6 +607,7 @@ modEq modEqStatic modStartNb modVariantCmp +modarg modetype modfile modquar @@ -659,6 +660,7 @@ netcdf netlib newfstatat nglfar +ni noLoadIntel nocaseatall noclobber diff --git a/testsuite/example/siteconfig.tcl-1 b/testsuite/example/siteconfig.tcl-1 index 8e8696a30..75a21d6ef 100644 --- a/testsuite/example/siteconfig.tcl-1 +++ b/testsuite/example/siteconfig.tcl-1 @@ -331,17 +331,44 @@ if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_REDEFONTHEFLYPROCS)]} { report [modEq foo fOo equal] } -# defineGetEqArrayKeyProc redefinition coverage test +# defineGetEqArrayKeyProc redefinition coverage test: the first two calls +# use the same implicit_default value in a row to exercise the no-op path +# where the currently active variant already matches what is being asked +# for; the following two calls switch value each time, to exercise the +# rename-the-previous-variant-back path in both directions if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_REDEFGETEQARRAYKEYPROC)]} { array set arr {foo/1.0 {version foo/1.0}} defineGetEqArrayKeyProc 0 report [getEqArrayKey arr foo/1.0] + defineGetEqArrayKeyProc 0 + report [getEqArrayKey arr foo/1.0] defineGetEqArrayKeyProc 1 report [getEqArrayKey arr foo/1.0] defineGetEqArrayKeyProc 0 report [getEqArrayKey arr foo/1.0] } +# getMatchingTagList coverage test: force a duplicate tag entry directly in +# the global tag structures (setModspecTag itself always dedupes by tag +# name, so this shape cannot occur through module-tag/module-hide/ +# module-forbid) to exercise the "tag already seen earlier in this same +# call" skip path, which normal usage never reaches +if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_DUPTAGROOT)]} { + defineModEqProc 0 0 + set ::g_moduleTagRoot(duptagtest) [list sometag sometag] + set ::g_moduleTagRootSpec(duptagtest) [list [list duptagtest/1.0 {}]\ + [list duptagtest/1.0 {}]] + report [getMatchingTagList duptagtest/1.0] +} + +# getAvailListFromVersSpec coverage test: its only caller (the extra-match +# search dispatch in modscan.tcl) always passes a modarg already registered +# through parseModuleSpecification, so the unregistered-modarg path is +# exercised directly here instead +if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_AVAILLISTUNREG)]} { + report [string length [getAvailListFromVersSpec neverregisteredmodarg]] +} + # specific tests to improve formatErrStackTrace proc coverage if {[info exists env(TESTSUITE_ENABLE_SITECONFIG_FORMATERRSTACKTRACE)]} { set errmsg {error message diff --git a/testsuite/modules.00-init/120-siteconfig.exp b/testsuite/modules.00-init/120-siteconfig.exp index 0e066d022..59dfaf291 100644 --- a/testsuite/modules.00-init/120-siteconfig.exp +++ b/testsuite/modules.00-init/120-siteconfig.exp @@ -589,16 +589,37 @@ lappend ans $vers_reportre testouterr_cmd_re sh -V OK [join $ans \n] unsetenv_var TESTSUITE_ENABLE_SITECONFIG_REDEFONTHEFLYPROCS -# test redefinition of defineGetEqArrayKeyProc, called twice in a row with a -# different implicit_default value each time, to demonstrate it renaming the -# previously active variant back before renaming the new one in +# test redefinition of defineGetEqArrayKeyProc: the same implicit_default +# value called twice in a row is a no-op (the currently active variant +# already matches), then a different value each time demonstrates renaming +# the previously active variant back before renaming the new one in setenv_var TESTSUITE_ENABLE_SITECONFIG_REDEFGETEQARRAYKEYPROC 1 set ans [list] -lappend ans foo/1.0 foo/1.0 foo/1.0 +lappend ans foo/1.0 foo/1.0 foo/1.0 foo/1.0 lappend ans $vers_reportre testouterr_cmd_re sh -V OK [join $ans \n] unsetenv_var TESTSUITE_ENABLE_SITECONFIG_REDEFGETEQARRAYKEYPROC +# test getMatchingTagList's "tag already seen earlier in this same call" +# skip path, forced through a duplicate tag entry directly in the global tag +# structures since normal module-tag usage always dedupes by tag name +setenv_var TESTSUITE_ENABLE_SITECONFIG_DUPTAGROOT 1 +set ans [list] +lappend ans sometag +lappend ans $vers_reportre +testouterr_cmd_re sh -V OK [join $ans \n] +unsetenv_var TESTSUITE_ENABLE_SITECONFIG_DUPTAGROOT + +# test getAvailListFromVersSpec's unregistered-modarg path, not reachable +# through its only real caller since every modarg reaching it there is +# already registered through parseModuleSpecification +setenv_var TESTSUITE_ENABLE_SITECONFIG_AVAILLISTUNREG 1 +set ans [list] +lappend ans 0 +lappend ans $vers_reportre +testouterr_cmd_re sh -V OK [join $ans \n] +unsetenv_var TESTSUITE_ENABLE_SITECONFIG_AVAILLISTUNREG + # test the single-element validvallist "string is" class check path in # getConf, not exercised by any current config option's own shape setenv_var TESTSUITE_ENABLE_SITECONFIG_VALIDVALLISTSTRINGIS 1 From ff8fcd6326c8e3a32c92ee31a39fb1e5ef29e1b2 Mon Sep 17 00:00:00 2001 From: Xavier Delaruelle Date: Fri, 14 Aug 2026 13:25:51 +0000 Subject: [PATCH 12/13] Remove unreachable existence guard in unmet dependency cleanup The unmet-dependency cleanup loop in unsetModuleDependency checked "[info exists ::g_unmetDepHash($ummod)]" before touching that entry, but the two structures it reads from, g_moduleUnmetDep(mod) and g_unmetDepHash(ummod), are only ever written together, in the same statement pair in setModuleDependency (one lappend per unmet occurrence to each, always paired), and only ever cleared together, in this exact loop. Nothing else in the file touches either structure, so every module referenced in g_moduleUnmetDep(mod) is guaranteed to still have a corresponding g_unmetDepHash entry when this loop runs -- the guard can never evaluate false. Drop the guard, keeping its body unconditional. This changes nothing at runtime since the branch was unreachable, so no new test is needed; verified with the dependency-related test files (377-cyclic, 712/713- require_via, 121-prereq-module, 515-depends-on, 516-prereq-all, 517- always-load) plus the Tcl lint check, not the full suite. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Xavier Delaruelle --- .hunspell.en.dic | 4 ++++ tcl/modfind.tcl.in | 12 +++++------- 2 files changed, 9 insertions(+), 7 deletions(-) diff --git a/.hunspell.en.dic b/.hunspell.en.dic index 72cfc360d..3e6a8890a 100644 --- a/.hunspell.en.dic +++ b/.hunspell.en.dic @@ -615,6 +615,7 @@ modrc modscan modshare modspec +moduleUnmetDep moduleVersSpec modulecache modulecmd @@ -897,12 +898,14 @@ tweakable txt ubuntu umask +ummod un unalias uname uncomplete undef unhide +unmetDepHash unix unixtime unixtimestamp @@ -912,6 +915,7 @@ unlink unloadable unprefixed unsetConf +unsetModuleDependency unsetState unsetenv unsets diff --git a/tcl/modfind.tcl.in b/tcl/modfind.tcl.in index 84832e3d6..7b7f02eca 100644 --- a/tcl/modfind.tcl.in +++ b/tcl/modfind.tcl.in @@ -2490,13 +2490,11 @@ proc unsetModuleDependency {mod} { # unset eventual registered unmet dependencies if {[info exists ::g_moduleUnmetDep($mod)]} { foreach ummod $::g_moduleUnmetDep($mod) { - if {[info exists ::g_unmetDepHash($ummod)]} { - set idx [lsearch -exact $::g_unmetDepHash($ummod) $mod] - set ::g_unmetDepHash($ummod) [lreplace $::g_unmetDepHash($ummod)\ - $idx $idx+1] - if {![llength $::g_unmetDepHash($ummod)]} { - unset ::g_unmetDepHash($ummod) - } + set idx [lsearch -exact $::g_unmetDepHash($ummod) $mod] + set ::g_unmetDepHash($ummod) [lreplace $::g_unmetDepHash($ummod)\ + $idx $idx+1] + if {![llength $::g_unmetDepHash($ummod)]} { + unset ::g_unmetDepHash($ummod) } } reportDebug "unset unmet requirements for '$mod'" From 96835198c2e3c5f982392d5a3c7f555b652a636e Mon Sep 17 00:00:00 2001 From: Xavier Delaruelle Date: Fri, 14 Aug 2026 13:26:26 +0000 Subject: [PATCH 13/13] ts: cover autosymbol skip when latest is already an error entry The autosymbol block in getModules only defines an auto "latest" symbol for a directory element when no entry already exists for that name, or an existing one is in error -- in which case it still leaves the existing entry alone and only attempts resolution again. No existing fixture had a real "latest" symbolic version that was itself also forbidden, so the branch handling an existing (error) entry, as opposed to the plain not-found case, was never taken. Add autosym10: a module whose real "2" version is also named "latest" through an explicit module-version, with that exact symbolic name targeted by both module-forbid and a hard module-hide. Querying or loading it by the real name still resolves normally, but the "latest" name itself stays access-denied rather than falling back to an autosymbol pointing at the same module, since found_list already carries an (error) entry for it by the time the autosymbol phase runs. Verified with 'script/mt 70/274' (229 passes), plus the tests that enumerate this fixture's modulepath wholesale (avail/spider long listings, extra-spec/json/output tests) to confirm the new fixture does not change their expected output, not the full suite. Assisted-by: Claude:claude-sonnet-5 Signed-off-by: Xavier Delaruelle --- .hunspell.en.dic | 3 ++ testsuite/modulefiles.4/autosym10/.modulerc | 4 ++ testsuite/modulefiles.4/autosym10/1 | 2 + testsuite/modulefiles.4/autosym10/2 | 2 + .../modules.51-scan/033-scan_eval-spider.exp | 2 +- .../274-adv_version_spec-autosym.exp | 38 +++++++++++++++++++ 6 files changed, 50 insertions(+), 1 deletion(-) create mode 100644 testsuite/modulefiles.4/autosym10/.modulerc create mode 100644 testsuite/modulefiles.4/autosym10/1 create mode 100644 testsuite/modulefiles.4/autosym10/2 diff --git a/.hunspell.en.dic b/.hunspell.en.dic index 3e6a8890a..e2ea9fdfa 100644 --- a/.hunspell.en.dic +++ b/.hunspell.en.dic @@ -256,6 +256,9 @@ autoload automake autopoint autoreconf +autosym +autosym10 +autosymbol autotools availabilities avx diff --git a/testsuite/modulefiles.4/autosym10/.modulerc b/testsuite/modulefiles.4/autosym10/.modulerc new file mode 100644 index 000000000..73575a0f4 --- /dev/null +++ b/testsuite/modulefiles.4/autosym10/.modulerc @@ -0,0 +1,4 @@ +#%Module +module-version /2 latest +module-forbid autosym10/latest +module-hide --hard autosym10/latest diff --git a/testsuite/modulefiles.4/autosym10/1 b/testsuite/modulefiles.4/autosym10/1 new file mode 100644 index 000000000..ed9fe06b6 --- /dev/null +++ b/testsuite/modulefiles.4/autosym10/1 @@ -0,0 +1,2 @@ +#%Module +module-whatis [module-info name] diff --git a/testsuite/modulefiles.4/autosym10/2 b/testsuite/modulefiles.4/autosym10/2 new file mode 100644 index 000000000..ed9fe06b6 --- /dev/null +++ b/testsuite/modulefiles.4/autosym10/2 @@ -0,0 +1,2 @@ +#%Module +module-whatis [module-info name] diff --git a/testsuite/modules.51-scan/033-scan_eval-spider.exp b/testsuite/modules.51-scan/033-scan_eval-spider.exp index 71bf9075f..a2ec6229b 100644 --- a/testsuite/modules.51-scan/033-scan_eval-spider.exp +++ b/testsuite/modules.51-scan/033-scan_eval-spider.exp @@ -190,7 +190,7 @@ scan/2.1{foo=val1,val2,val3}" testouterr_cmd sh {spider -t -o tag:variant:sym:alias scan} OK $tserr set tserr ".* -Get modules: {foo/globalsym scan/globalsym foo/globalunk scan/globalunk} matching 'foo=val4' in '' +Get modules: {(foo/globalsym|scan/globalsym|foo/globalunk|scan/globalunk) (foo/globalsym|scan/globalsym|foo/globalunk|scan/globalunk) (foo/globalsym|scan/globalsym|foo/globalunk|scan/globalunk) (foo/globalsym|scan/globalsym|foo/globalunk|scan/globalunk)} matching 'foo=val4' in '' .* Get modules: {((source|scan|foo).* )*(source|scan|foo).*} matching 'foo=val4' in '$mpre' scan/1.0{foo=val1,val2,val3,val4}\\\(globalsym:sym\\\) diff --git a/testsuite/modules.70-maint/274-adv_version_spec-autosym.exp b/testsuite/modules.70-maint/274-adv_version_spec-autosym.exp index 3099d237a..0ac7d11de 100644 --- a/testsuite/modules.70-maint/274-adv_version_spec-autosym.exp +++ b/testsuite/modules.70-maint/274-adv_version_spec-autosym.exp @@ -416,6 +416,44 @@ unsetenv_loaded_module unsetenv_var __MODULES_LMALTNAME +# autosymbol name matches an explicit symbolic version that is itself +# targeted by a module-forbid command coupled to a module-hide --hard one: +# the entry already found (in error) for this name short-circuits autosymbol +# creation, yet resolution to the forbidden module is still attempted +# +# uses modulefiles.4 rather than modulefiles.2, so this fixture does not show +# up in the other tests that enumerate modulefiles.2's entire content + +set mp_saved $mp +set mp "$modpath.4" +setenv_path_var MODULEPATH $mp + +testouterr_cmd sh {avail -t autosym10@default} OK $mp:\nautosym10/2 +testouterr_cmd sh {avail -t autosym10@latest} OK {} +testouterr_cmd sh {avail -t autosym10/latest} OK {} +set ans [list] +lappend ans [list set __MODULES_LMALTNAME autosym10/2&as|autosym10/latest&as|autosym10/default] +lappend ans [list set _LMFILES_ $mp/autosym10/2] +lappend ans [list set LOADEDMODULES autosym10/2] +testouterr_cmd sh {load autosym10} $ans {} +testouterr_cmd sh {load autosym10/default} $ans {} +testouterr_cmd sh {load autosym10@latest} ERR [err_accessdenied autosym10/latest] +testouterr_cmd sh {load autosym10/latest} ERR [err_accessdenied autosym10/latest] +testouterr_cmd sh {whatis autosym10@latest} ERR [err_accessdenied autosym10/latest] +testouterr_cmd sh {is-loaded autosym10/default} ERR {} +testouterr_cmd sh {is-loaded autosym10@latest} ERR {} +setenv_loaded_module [list autosym10/2] [list $mp/autosym10/2] +setenv_var __MODULES_LMALTNAME autosym10/2&as|autosym10/latest&as|autosym10/default +testouterr_cmd sh {is-loaded autosym10/default} OK {} +testouterr_cmd sh {is-loaded autosym10@latest} OK {} +testouterr_cmd sh {list} OK "$cur_loaded\n 1) autosym10/2" +unsetenv_loaded_module +unsetenv_var __MODULES_LMALTNAME + +set mp $mp_saved +setenv_path_var MODULEPATH $mp + + # use in requirements set ans [list]