From 9361a83f0fa3f6a01f7a51faf0d121626664b724 Mon Sep 17 00:00:00 2001 From: Matthew Cawood Date: Mon, 13 Jan 2025 11:55:36 -0600 Subject: [PATCH] added handling of bad mode_select input, added tests --- messageDir/en.lua | 8 +++ .../mf/Core/empty_mode_test/1.0.lua | 3 + .../mf/Core/invalid_mode_test/1.0.lua | 3 + .../mf/Core/mixed_both_test/1.0.lua | 13 ++++ .../mf/Core/mixed_load_test/1.0.lua | 10 +++ rt/mode_select/mf/Core/mixed_test/1.0.lua | 25 -------- .../mf/Core/mixed_unload_test/1.0.lua | 10 +++ rt/mode_select/mf/Core/nil_mode_test/1.0.lua | 3 + rt/mode_select/mode_select.tdesc | 64 ++++++++++++------- src/modfuncs.lua | 31 +++++++++ 10 files changed, 121 insertions(+), 49 deletions(-) create mode 100644 rt/mode_select/mf/Core/empty_mode_test/1.0.lua create mode 100644 rt/mode_select/mf/Core/invalid_mode_test/1.0.lua create mode 100644 rt/mode_select/mf/Core/mixed_both_test/1.0.lua create mode 100644 rt/mode_select/mf/Core/mixed_load_test/1.0.lua delete mode 100644 rt/mode_select/mf/Core/mixed_test/1.0.lua create mode 100644 rt/mode_select/mf/Core/mixed_unload_test/1.0.lua create mode 100644 rt/mode_select/mf/Core/nil_mode_test/1.0.lua diff --git a/messageDir/en.lua b/messageDir/en.lua index 66923a39e..29fa42a68 100644 --- a/messageDir/en.lua +++ b/messageDir/en.lua @@ -511,5 +511,13 @@ The following modules match your search criteria: "%{module_list}" namedCollList = "Named collection list %{msgHdr}:\n", noModsLoaded = "No modules loaded\n", specific_hlp = "Module Specific Help for \"%{fullName}\"", + + -- Add new error messages for mode selector + e_Mode_Not_Set = [==[Syntax error in file: %{fn} + with command: %{cmdName}, mode must be specified when using mode selector. +]==], + e_Invalid_Mode = [==[Syntax error in file: %{fn} + with command: %{cmdName}, invalid mode "%{mode}". Valid modes are: "load" and "unload". +]==], } } diff --git a/rt/mode_select/mf/Core/empty_mode_test/1.0.lua b/rt/mode_select/mf/Core/empty_mode_test/1.0.lua new file mode 100644 index 000000000..c79f69261 --- /dev/null +++ b/rt/mode_select/mf/Core/empty_mode_test/1.0.lua @@ -0,0 +1,3 @@ +-- Test module for empty mode table error case +-- This should error because the mode table is empty +setenv{"TEST_EMPTY_MODE", "value", mode={}} -- Should error: empty mode table \ No newline at end of file diff --git a/rt/mode_select/mf/Core/invalid_mode_test/1.0.lua b/rt/mode_select/mf/Core/invalid_mode_test/1.0.lua new file mode 100644 index 000000000..f1e6c1941 --- /dev/null +++ b/rt/mode_select/mf/Core/invalid_mode_test/1.0.lua @@ -0,0 +1,3 @@ +-- Test module for invalid mode error case +-- This should error because "invalid" is not a valid mode +setenv{"TEST_INVALID_MODE", "value", mode={"invalid"}} -- Should error: invalid mode \ No newline at end of file diff --git a/rt/mode_select/mf/Core/mixed_both_test/1.0.lua b/rt/mode_select/mf/Core/mixed_both_test/1.0.lua new file mode 100644 index 000000000..dfd1764b4 --- /dev/null +++ b/rt/mode_select/mf/Core/mixed_both_test/1.0.lua @@ -0,0 +1,13 @@ +-- Test module for operations that work in both modes +-- Tests combination of dual-mode and normal operations + +-- Operations that work in both load and unload modes +setenv{"MIXED_ENV_BOTH", "env_both", mode={"load", "unload"}} +prepend_path{"MIXED_PATH", "/mixed/bin/both", mode={"load", "unload"}} + +-- Stack operations with mode selection +pushenv{"MIXED_STACK", "stack_both", mode={"load", "unload"}} + +-- Normal operations (should execute in both modes) +setenv("MIXED_NORMAL_ENV", "normal_env") +append_path("MIXED_LIB", "/mixed/lib/normal") \ No newline at end of file diff --git a/rt/mode_select/mf/Core/mixed_load_test/1.0.lua b/rt/mode_select/mf/Core/mixed_load_test/1.0.lua new file mode 100644 index 000000000..f8f715afb --- /dev/null +++ b/rt/mode_select/mf/Core/mixed_load_test/1.0.lua @@ -0,0 +1,10 @@ +-- Test module for mixed load operations +-- Tests combination of load-specific and normal operations + +-- Load-specific operations +setenv{"MIXED_ENV_LOAD", "env_load", mode={"load"}} +prepend_path{"MIXED_PATH", "/mixed/bin/load", mode={"load"}} + +-- Normal operations (should execute in load mode) +setenv("MIXED_NORMAL_ENV", "normal_env") +append_path("MIXED_LIB", "/mixed/lib/normal") \ No newline at end of file diff --git a/rt/mode_select/mf/Core/mixed_test/1.0.lua b/rt/mode_select/mf/Core/mixed_test/1.0.lua deleted file mode 100644 index b35762972..000000000 --- a/rt/mode_select/mf/Core/mixed_test/1.0.lua +++ /dev/null @@ -1,25 +0,0 @@ --- Test module for mixed mode and non-mode operations - --- Test environment and path operations mixed together -setenv{"MIXED_ENV_LOAD", "env_load", mode={"load"}} -prepend_path{"MIXED_PATH", "/mixed/bin/load", mode={"load"}} - -setenv{"MIXED_ENV_UNLOAD", "env_unload", mode={"unload"}} -append_path{"MIXED_PATH", "/mixed/bin/unload", mode={"unload"}} - --- Test normal operations mixed with mode operations -setenv("MIXED_NORMAL_ENV", "normal_env") -prepend_path{"MIXED_PATH", "/mixed/bin/both", mode={"load", "unload"}} - --- Test pushenv with path operations -pushenv{"MIXED_STACK", "stack_load", mode={"load"}} -append_path("MIXED_LIB", "/mixed/lib/normal") - --- Test complex combinations -setenv{"MIXED_COMPLEX", "complex_load", mode={"load"}} -prepend_path{"MIXED_COMPLEX_PATH", "/complex/bin", delim=";", priority=100, mode={"load"}} -pushenv{"MIXED_COMPLEX_STACK", "complex_both", mode={"load", "unload"}} - --- Test error cases -setenv{"MIXED_ERROR", "error_value", mode={}} -- Empty mode table -prepend_path{"MIXED_ERROR_PATH", "/error/bin", mode={"invalid_mode"}} -- Invalid mode \ No newline at end of file diff --git a/rt/mode_select/mf/Core/mixed_unload_test/1.0.lua b/rt/mode_select/mf/Core/mixed_unload_test/1.0.lua new file mode 100644 index 000000000..ccac07119 --- /dev/null +++ b/rt/mode_select/mf/Core/mixed_unload_test/1.0.lua @@ -0,0 +1,10 @@ +-- Test module for mixed unload operations +-- Tests combination of unload-specific and normal operations + +-- Unload-specific operations +setenv{"MIXED_ENV_UNLOAD", "env_unload", mode={"unload"}} +append_path{"MIXED_PATH", "/mixed/bin/unload", mode={"unload"}} + +-- Normal operations (should execute in unload mode) +setenv("MIXED_NORMAL_ENV", "normal_env") +append_path("MIXED_LIB", "/mixed/lib/normal") \ No newline at end of file diff --git a/rt/mode_select/mf/Core/nil_mode_test/1.0.lua b/rt/mode_select/mf/Core/nil_mode_test/1.0.lua new file mode 100644 index 000000000..82ecef40f --- /dev/null +++ b/rt/mode_select/mf/Core/nil_mode_test/1.0.lua @@ -0,0 +1,3 @@ +-- Test module for nil mode error case +-- This should error because no mode is specified +setenv{"TEST_NIL_MODE", "value"} -- Should error: no mode specified \ No newline at end of file diff --git a/rt/mode_select/mode_select.tdesc b/rt/mode_select/mode_select.tdesc index c7e8438c2..753e84c98 100644 --- a/rt/mode_select/mode_select.tdesc +++ b/rt/mode_select/mode_select.tdesc @@ -11,7 +11,10 @@ testdescript = { Tests include: 1. Basic mode-specific operations 2. Mixed mode and non-mode operations - 3. Error cases and edge conditions + 3. Error cases: + - Missing mode specification + - Invalid mode strings + - Empty mode table ]], keywords = {testName}, @@ -35,29 +38,42 @@ testdescript = { mkdir -p $HOME/.cache/lmod buildSpiderT $MODULEPATH > $HOME/.cache/lmod/spiderT.lua - # Test Environment Variable Operations - runLmod load env_test # 1 (Test mode-specific setenv) - runLmod list # 2 (Verify environment variables) - runLmod unload env_test # 3 (Test unload behavior) - runLmod list # 4 (Verify cleanup) - - # Test Path Operations - runLmod load path_test # 5 (Test mode-specific path operations) - runLmod list # 6 (Verify path modifications) - runLmod unload path_test # 7 (Test path cleanup) - runLmod list # 8 (Verify path restoration) - - # Test Mixed Operations - runLmod load mixed_test # 9 (Test mixed mode and non-mode operations) - runLmod list # 10 (Verify mixed state) - runLmod unload mixed_test # 11 (Test mixed cleanup) - runLmod list # 12 (Verify final state) - - # Test Load/Unload Operations - runLmod load load_test # 13 (Test mode-specific module loading) - runLmod list # 14 (Verify loaded modules) - runLmod unload load_test # 15 (Test mode-specific module unloading) - runLmod list # 16 (Verify final state) + # Helper function to cleanup environment + module purge + + # Test Error Cases - Each in isolation + runLmod load nil_mode_test # 1 (Test missing mode specification) + runLmod list # 2 (Verify state after nil mode error) + module purge + + runLmod load invalid_mode_test # 3 (Test invalid mode string) + runLmod list # 4 (Verify state after invalid mode error) + module purge + + runLmod load empty_mode_test # 5 (Test empty mode table) + runLmod list # 6 (Verify state after empty mode error) + module purge + + # Test Mixed Load Operations + runLmod load mixed_load_test # 7 (Test load-specific operations) + runLmod list # 8 (Verify load state) + runLmod unload mixed_load_test # 9 (Test cleanup) + runLmod list # 10 (Verify state after unload) + module purge + + # Test Mixed Unload Operations + runLmod load mixed_unload_test # 11 (Test unload-specific operations) + runLmod list # 12 (Verify initial state) + runLmod unload mixed_unload_test # 13 (Test unload behavior) + runLmod list # 14 (Verify final state) + module purge + + # Test Mixed Both Operations + runLmod load mixed_both_test # 15 (Test dual-mode operations during load) + runLmod list # 16 (Verify load state) + runLmod unload mixed_both_test # 17 (Test dual-mode operations during unload) + runLmod list # 18 (Verify final state) + module purge HOME=$ORIG_HOME diff --git a/src/modfuncs.lua b/src/modfuncs.lua index c5ea89d47..c816e62cc 100644 --- a/src/modfuncs.lua +++ b/src/modfuncs.lua @@ -187,6 +187,31 @@ local function l_validateModules(cmdName, ...) return allGood end +-------------------------------------------------------------------------- +-- Validate mode selector input +-- @param cmdName The command which is getting its arguments validated. +-- @param t The table containing mode selector input +local function l_validateModeSelector(cmdName, t) + if (t.mode == nil) then + mcp:report{msg="e_Mode_Not_Set", fn = myFileName(), cmdName = cmdName} + return false + end + + if (#t.mode == 0) then + mcp:report{msg="e_Mode_Not_Set", fn = myFileName(), cmdName = cmdName} + return false + end + + local validModes = {load = true, unload = true} + for i = 1, #t.mode do + if not validModes[t.mode[i]] then + mcp:report{msg="e_Invalid_Mode", fn = myFileName(), cmdName = cmdName, mode = t.mode[i]} + return false + end + end + return true +end + -------------------------------------------------------------------------- -- Convert all function arguments to table form -- first_elem seperated from args for type test @@ -201,6 +226,12 @@ local function l_list_2_Tbl(first_elem, ...) t.kind = "table" local my_mode = mode() local modeA = t.mode or {} + + -- Validate mode selector input + if not l_validateModeSelector(t.cmdName or "unknown", t) then + return MCPQ, t + end + for i = 1,#modeA do if (my_mode == modeA[i]) then action = true