Skip to content

Commit 2ccb4d0

Browse files
RafaelPalomarjcfr
authored andcommitted
ENH: Add SlicerStartupModuleTest.py and helper files
This adds a new python test which tries to (1) modify `sys.path` on module load and (2) verify preservation of the changes after slicer startup.
1 parent ab2d062 commit 2ccb4d0

File tree

5 files changed

+146
-0
lines changed

5 files changed

+146
-0
lines changed

Applications/SlicerApp/Testing/Python/CMakeLists.txt

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -434,6 +434,14 @@ add_test(
434434
${Slicer_LAUNCHER_EXECUTABLE}
435435
)
436436

437+
# Check that modules can configure environment on load
438+
add_test(
439+
NAME py_module_configuration_startup
440+
COMMAND ${PYTHON_EXECUTABLE}
441+
${CMAKE_CURRENT_SOURCE_DIR}/SlicerStartupModuleTest.py
442+
${Slicer_LAUNCHER_EXECUTABLE}
443+
)
444+
437445
# Check that stand-alone Python interpreter, without PythonQt support, can `import slicer` safely (#945)
438446
add_test(
439447
NAME py_standalonepython_import_slicer
Lines changed: 99 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,99 @@
1+
#!/usr/bin/env python
2+
3+
#
4+
# Program: 3D Slicer
5+
#
6+
# Copyright (c) Kitware Inc.
7+
#
8+
# See COPYRIGHT.txt
9+
# or http://www.slicer.org/copyright/copyright.txt for details.
10+
#
11+
# Unless required by applicable law or agreed to in writing, software
12+
# distributed under the License is distributed on an "AS IS" BASIS,
13+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
# See the License for the specific language governing permissions and
15+
# limitations under the License.
16+
#
17+
# This file was originally developed by Jean-Christophe Fillion-Robin, Kitware Inc.
18+
# and was partially funded by NIH grant 1U24CA194354-01
19+
#
20+
21+
import os
22+
import sys
23+
import tempfile
24+
25+
from SlicerAppTesting import *
26+
27+
"""
28+
This test verifies that a python module can add/modify python variables
29+
which will be preserved after Slicer startup is completed.
30+
31+
This test was based on SlicerStartupCompletedTest.py and it relies on
32+
SlicerStartupModuleTestHelperModule.py and the SlicerStartupModuleTestHelperPackage
33+
python package
34+
35+
It uses an output file for communication because on Windows,
36+
standard output is not always enabled.
37+
38+
Usage:
39+
SlicerStartupModuleTest.py /path/to/Slicer
40+
"""
41+
42+
if __name__ == "__main__":
43+
debug = False
44+
# Set to True to:
45+
# * display the path of the expected test output file
46+
# * avoid deleting the created temporary directory
47+
48+
if len(sys.argv) != 2:
49+
print(os.path.basename(sys.argv[0]) + " /path/to/Slicer")
50+
exit(EXIT_FAILURE)
51+
52+
temporaryModuleDirPath = tempfile.mkdtemp().replace("\\", "/")
53+
os.makedirs(temporaryModuleDirPath + "/SlicerStartupModuleTestHelperScript", exist_ok=True)
54+
try:
55+
# Copy helper module that creates a file when startup completed event is received
56+
currentDirPath = os.path.dirname(__file__).replace("\\", "/")
57+
from shutil import copyfile,copytree
58+
copyfile(currentDirPath + "/SlicerStartupModuleTestHelperModule.py",
59+
temporaryModuleDirPath + "/SlicerStartupModuleTestHelperModule.py")
60+
copytree(currentDirPath + "/SlicerStartupModuleTestHelperPackage",
61+
temporaryModuleDirPath + "/SlicerStartupModuleTestHelperPackage" )
62+
copyfile(currentDirPath + "/SlicerStartupModuleTestHelperScript.py",
63+
temporaryModuleDirPath + "/SlicerStartupModuleTestHelperScript/SlicerStartupModuleTestHelperScript.py")
64+
65+
slicer_executable = os.path.expanduser(sys.argv[1])
66+
common_args = [
67+
"--testing",
68+
"--disable-builtin-cli-modules",
69+
"--disable-builtin-loadable-modules",
70+
"--disable-builtin-scripted-loadable-modules",
71+
"--additional-module-path", temporaryModuleDirPath,
72+
"--python-script", temporaryModuleDirPath + "/SlicerStartupModuleTestHelperScript/SlicerStartupModuleTestHelperScript.py",
73+
]
74+
75+
test_output_file = temporaryModuleDirPath + "/StartupModuleTest.out"
76+
os.environ["SLICER_STARTUP_MODULE_TEST_OUTPUT"] = test_output_file
77+
if debug:
78+
print("SLICER_STARTUP_MODULE_TEST_OUTPUT=%s" % test_output_file)
79+
80+
# Test startupCompleted with main window
81+
args = list(common_args)
82+
(returnCode, stdout, stderr) = runSlicer(slicer_executable, args)
83+
assert returnCode == EXIT_SUCCESS
84+
assert os.path.isfile(test_output_file)
85+
os.remove(test_output_file)
86+
print("Test startupCompleted with main window - passed\n")
87+
88+
# Test startupCompleted without main window
89+
args = list(common_args)
90+
args.extend(["--no-main-window"])
91+
(returnCode, stdout, stderr) = runSlicer(slicer_executable, args)
92+
assert os.path.isfile(test_output_file)
93+
assert returnCode == EXIT_SUCCESS
94+
print("Test startupCompleted without main window - passed\n")
95+
96+
finally:
97+
if not debug:
98+
import shutil
99+
shutil.rmtree(temporaryModuleDirPath)
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
import os
2+
import sys
3+
4+
from slicer.ScriptedLoadableModule import *
5+
6+
this_dir = os.path.dirname(os.path.abspath(__file__))
7+
sys.path.insert(0, this_dir)
8+
9+
from SlicerStartupModuleTestHelperPackage import *
10+
11+
class SlicerStartupModuleTestHelperModule(ScriptedLoadableModule):
12+
def __init__(self, parent):
13+
ScriptedLoadableModule.__init__(self, parent)
14+
self.parent.title = "SlicerStartupModuleTest"
15+
self.parent.categories = ["Testing.TestCases"]
16+
self.parent.contributors = ["Rafael Palomar (Oslo University Hospital), Jean-Christophe Fillion-Robin (Kitware), Andras Lasso (PerkLab)"]
17+
self.parent.widgetRepresentationCreationEnabled = False
18+
19+
self.testOutputFileName = os.environ["SLICER_STARTUP_MODULE_TEST_OUTPUT"]
20+
if os.path.isfile(self.testOutputFileName):
21+
os.remove(self.testOutputFileName)
22+
23+
print("SlicerStartupModuleTestHelperModule initialized")
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
import sys
2+
3+
sys.path.insert(0, "/test/directory")
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
import sys
2+
import os
3+
4+
testOutputFileName = os.environ["SLICER_STARTUP_MODULE_TEST_OUTPUT"]
5+
6+
if "/test/directory" not in sys.path:
7+
raise RuntimeError("/test/directory not in sys.path as expected")
8+
9+
with open(testOutputFileName, "w") as file:
10+
file.write("SlicerSTartypModuleTestHelperScript.py generated this file")
11+
file.write("/test/directory found in sys.path")
12+
13+
exit(EXIT_SUCCESS)

0 commit comments

Comments
 (0)