Skip to content

Commit

Permalink
simplifies raven-runs-raven magic variable handling and tester comman…
Browse files Browse the repository at this point in the history
…d modification
  • Loading branch information
j-bryan committed Mar 29, 2024
1 parent 30730f7 commit 8c67f36
Show file tree
Hide file tree
Showing 22 changed files with 69 additions and 288 deletions.
7 changes: 4 additions & 3 deletions developer_tools/check_pip_packages.sh
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ conda activate python39_pip
python -m pip uninstall -y raven_framework || echo not installed
python -m pip install dist/raven_framework*cp39*.whl || exit -1

# Run some tests to check that the installed package is working. The user_guide
# tests are all pretty simple, and there are only a few of them, so we'll use those.
$RAVEN_DIR/run_tests --re="user_guide" --tester-command RavenFramework $(which raven_framework) RavenErrors $(which raven_framework) --python-command $(which python)

echo
echo Checking Python 3.10
Expand All @@ -42,6 +45,4 @@ conda activate python310_pip
python -m pip uninstall -y raven_framework || echo not installed
python -m pip install dist/raven_framework*cp310*.whl || exit -1

# Run some tests to check that the installed package is working. The user_guide
# tests are all pretty simple, and there are only a few of them, so we'll use those.
$RAVEN_DIR/run_tests --use-pip --re="user_guide"
$RAVEN_DIR/run_tests --re="user_guide" --tester-command RavenFramework $(which raven_framework) RavenErrors $(which raven_framework) --python-command $(which python)
20 changes: 2 additions & 18 deletions ravenframework/CodeInterfaceClasses/RAVEN/RAVENInterface.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,6 @@
@author: alfoa
"""
import sys
import os
import numpy as np
from sys import platform
Expand Down Expand Up @@ -73,7 +72,7 @@ def _readMoreXML(self, xmlNode):
@ Out, None.
"""
baseName = os.path.basename(xmlNode.find("executable").text)
if baseName not in ['raven_framework','raven_framework.py','%RAVENFRAMEWORK%']:
if baseName not in ['raven_framework','raven_framework.py', '%RAVENEXECUTABLE%']:
raise IOError(self.printTag+' ERROR: executable must be "raven_framework" (in whatever location)! Got "'+baseName+'"!')

linkedDataObjects = xmlNode.find("outputExportOutStreams")
Expand Down Expand Up @@ -174,22 +173,7 @@ def generateCommand(self,inputFiles,executable,clargs=None,fargs=None, preExec=N
# executable command will be: "python <path>/raven_framework.py"
# in which case make sure executable ends with .py
# Note that for raven_framework to work, it needs to be in the path.
# (j-bryan, 2024-03-05) A raven_framework script may also be the command used to run RAVEN, such
# as when using a prebuilt executable of RAVEN.
if executable == '%RAVENFRAMEWORK%':
# We want to reuse the same executable as was used to run this RAVEN instance.
if sys.executable.endswith('raven_framework'): # using a RAVEN executable
self.preCommand = ''
executable = sys.executable
elif sys.argv[0].endswith('raven_framework'): # using a RAVEN script
self.preCommand = ''
executable = sys.argv[0]
elif sys.argv[0].endswith('raven_framework.py'): # using a python file
executable = sys.argv[0]
else:
raise(IOError(f'{self.printTag} ERROR: Could not determine the RAVEN executable to use. '
f'sys.executable is "{sys.executable}" and sys.argv[0] is "{sys.argv[0]}"'))
elif executable.endswith('raven_framework'):
if executable == 'raven_framework' or executable == '%RAVENEXECUTABLE%':
self.preCommand = ''
elif not executable.endswith(".py"):
executable += ".py"
Expand Down
27 changes: 8 additions & 19 deletions ravenframework/Models/Code.py
Original file line number Diff line number Diff line change
Expand Up @@ -142,19 +142,6 @@ def _readMoreXML(self,xmlNode):
for child in paramInput.subparts:
if child.getName() =='executable':
self.executable = child.value if child.value is not None else ''
# Special case: the executable was specified as %RAVENFRAMEWORK%, which means the executable should be
# whatever was used to run RAVEN in the first place. This can happen in a couple of ways:
# 1. (most common) The user is running RAVEN from the command line with python
# 2. (less common) The user is using a prebuilt RAVEN executable
# These cases as distinguishable by the value of sys.executable
if self.executable == '%RAVENFRAMEWORK%':
if (sys.executable.endswith('python') or sys.executable.endswith('python.exe')) and sys.argv[0].endswith('.py'):
self.executable = sys.argv[0] # sys.argv[0] is the name of the script that was run
elif sys.executable.endswith('raven_framework'):
self.executable = sys.executable
else:
self.raiseAnError(IOError, 'The executable was specified as %RAVENFRAMEWORK%, but the framework was '
'not found in sys.executable or sys.argv[0]')
if child.getName() =='walltime':
self.maxWallTime = child.value
if child.getName() =='preexec':
Expand Down Expand Up @@ -242,12 +229,12 @@ def _readMoreXML(self,xmlNode):
self.raiseAnError(IOError,'filearg type '+argtype+' not recognized!')
if self.executable == '':
self.raiseAWarning('The node "<executable>" was not found in the body of the code model '+str(self.name)+' so no code will be run...')
elif self.executable == '%RAVENFRAMEWORK%':
# Special case: the executable was specified as %RAVENFRAMEWORK%, which means the executable should be
# whatever was used to run RAVEN in the first place. Figuring out what that should be is handled in the
# ravenframework.CodeInterfaceClasses.RAVEN.RAVENInterface.RAVEN class. For now, we just print a message.
self.raiseADebug('The node "<executable>" was found to be "%RAVENFRAMEWORK%" in the body of the code model ' + str(self.name) +
' so the code will be run using the same executable that is running RAVEN...')
# elif self.executable == '%RAVENFRAMEWORK%':
# # Special case: the executable was specified as %RAVENFRAMEWORK%, which means the executable should be
# # whatever was used to run RAVEN in the first place. Figuring out what that should be is handled in the
# # ravenframework.CodeInterfaceClasses.RAVEN.RAVENInterface.RAVEN class. For now, we just print a message.
# self.raiseADebug('The node "<executable>" was found to be "%RAVENFRAMEWORK%" in the body of the code model ' + str(self.name) +
# ' so the code will be run using the same executable that is running RAVEN...')
else:
if utils.stringIsFalse(os.environ.get('RAVENinterfaceCheck','False')):
if '~' in self.executable:
Expand Down Expand Up @@ -580,6 +567,8 @@ def evaluateSample(self, myInput, samplerType, kwargs):
command = command.replace("%METHOD%",kwargs['METHOD'])
command = command.replace("%NUM_CPUS%",kwargs['NUM_CPUS'])
command = command.replace("%PYTHON%", sys.executable)
command = command.replace("%RAVENEXECUTABLE%",
sys.executable if "raven_framework" in sys.executable else sys.argv[0])

self.raiseAMessage('Execution command submitted:',command)
if platform.system() == 'Windows':
Expand Down
54 changes: 17 additions & 37 deletions rook/Tester.py
Original file line number Diff line number Diff line change
Expand Up @@ -329,7 +329,6 @@ class Tester:
__default_run_type_set = set(["normal"])
__non_default_run_type_set = set()
__base_current_run_type = None
__install_type = "source" # type of raven installation being used

@classmethod
def add_default_run_type(cls, run_type):
Expand Down Expand Up @@ -392,8 +391,6 @@ def get_valid_params():
params.add_param('needed_executable', '',
'Only run test if needed executable is on path.')
params.add_param('skip_if_OS', '', 'Skip test if the operating system defined')
params.add_param('skip_if_install_type', '', 'Skip test depending on the raven '+
'installation type')
return params

def __init__(self, _name, params):
Expand All @@ -408,6 +405,7 @@ def __init__(self, _name, params):
self.results = TestResult()
self._needed_executable = self.specs['needed_executable']
self.__command_prefix = ""
self.__test_command = None
self.__python_command = sys.executable
if os.name == "nt":
#Command is python on windows in conda and Python.org install
Expand Down Expand Up @@ -444,23 +442,6 @@ def set_only_run_types(cls, run_types):
cls.__non_default_run_type_set))
cls.__base_current_run_type = set(run_types)

@classmethod
def set_install_type(cls, install_type):
"""
Sets the install type of the raven installation
@ In, install_type, string, the install type
@ Out, None
"""
cls.__install_type = install_type

def get_install_type(self):
"""
Returns the install type of the raven installation
@ In, None
@ Out, __install_type, string, the install type
"""
return self.__install_type

def get_differ_remove_files(self):
"""
Returns the files that need to be removed for testing.
Expand Down Expand Up @@ -506,6 +487,14 @@ def set_command_prefix(self, command_prefix):
"""
self.__command_prefix = command_prefix

def set_test_command(self, command):
"""
Sets the tester command. This is the command that will be used to run the test.
@ In, command, string, the command to run
@ Out, None
"""
self.__test_command = command

def set_python_command(self, python_command):
"""
Sets the python command. This is used to run python commands.
Expand Down Expand Up @@ -568,10 +557,6 @@ def _run_backend(self, _):
if current_os in skip_os:
self.set_skip('skipped (OS is "{}")'.format(current_os))
return self.results
## Install type
if not self.check_install_type():
self.set_skip('skipped (install type is "{}")'.format(self.__install_type))
return self.results

if self.specs['min_python_version'].strip().lower() != 'none':
major, minor = self.specs['min_python_version'].strip().split(".")
Expand Down Expand Up @@ -691,19 +676,6 @@ def check_runnable(self):
"""
return True

def check_install_type(self):
"""
Checks if the install type is allowed
@ In, None
@ Out, check_install_type, boolean, True if the install type is allowed
"""
if len(self.specs['skip_if_install_type']) == 0: # no skip_if_install_type specified
return True
skip_install_types = self.specs['skip_if_install_type'].split(',')
skip_install_types = [install_type.lower() for install_type in skip_install_types]
allowed_install_types = set(['source', 'pip', 'binary']) - set(skip_install_types)
return self.__install_type.lower() in allowed_install_types

def set_success(self):
"""
Called by subclasses if this was a success.
Expand Down Expand Up @@ -770,6 +742,14 @@ def _get_python_command(self):
"""
return self.__python_command

def _get_test_command(self):
"""
Returns the command set by the user to run the test
@ In, None
@ Out, get_command, string, string command to run.
"""
return self.__test_command

def get_command(self):
"""
returns the command used to run the test
Expand Down
34 changes: 9 additions & 25 deletions rook/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -95,18 +95,17 @@ class NoColors:
dest='add_non_default_run_types',
help='add a run type that is not run by default')

parser.add_argument('--tester-command', nargs='*', dest='tester_commands',
help='Command to run. The first argument is the tester name, the second is the '
'command to run for that tester. Any number of (tester, command) pairs may '
'be specified. The tester name must be the name of a tester class.')

parser.add_argument('--command-prefix', dest='command_prefix',
help='prefix for the test commands')

parser.add_argument('--python-command', dest='python_command',
help='command to run python')

alt_framework_args = parser.add_mutually_exclusive_group(required=False)
alt_framework_args.add_argument('--use-pip', dest='use_pip', action='store_true',
help='use the pip-installed version of ravenframework')
alt_framework_args.add_argument('--use-binary', nargs=1, dest='use_binary',
help='use a specified binary version of ravenframework')

parser.add_argument('--config-file', dest='config_file',
help='Configuration file location')

Expand Down Expand Up @@ -322,10 +321,6 @@ def process_result(index, _input_data, output_data):
test=process_test_name))

if __name__ == "__main__":
if args.use_binary and not os.path.exists(args.use_binary[0]):
print("The specified binary does not exist:", args.use_binary[0])
sys.exit(-1)

if args.unkillable:
def term_handler(signum, _):
"""
Expand Down Expand Up @@ -407,21 +402,6 @@ def term_handler(signum, _):
print(differ.get_valid_params())
print()

# The ravenframework installation may be of type "source", "pip", or "binary". Let the testers
# know which type of installation we are using.
if args.use_pip:
installType = 'pip'
elif args.use_binary:
# Specify an absolute path so we don't have to worry about where we are now vs where when
# we try to run the binary.
testers['RavenFramework'].set_binary_location(os.path.abspath(args.use_binary[0]))
installType = 'binary'
else:
installType = 'source'

for tester in testers.values():
tester.set_install_type(installType)

tester_params = {}
for tester_key, tester_value in testers.items():
#Note as a side effect, testers can add run types to
Expand Down Expand Up @@ -467,6 +447,10 @@ def term_handler(signum, _):
params = dict(node.attrib)
params['test_dir'] = test_dir
tester = testers[node.attrib['type']](test_name, params)
if args.tester_commands is not None:
for i in range(0, len(args.tester_commands), 2):
if args.tester_commands[i] == node.attrib['type']:
tester.set_test_command(args.tester_commands[i+1])
if args.command_prefix is not None:
tester.set_command_prefix(args.command_prefix)
if args.python_command is not None:
Expand Down
7 changes: 1 addition & 6 deletions run_tests
Original file line number Diff line number Diff line change
Expand Up @@ -44,12 +44,7 @@ for A in "$@"; do
esac
done
echo 'Loading libraries ...'
if [[ " ${ARGS[@]} " =~ " --use-pip " ]];
then
echo "Using the current python environment"
PYTHON_COMMAND=$(which python)
echo "Python command: $PYTHON_COMMAND"
elif [[ "$INSTALLATION_MANAGER" == "CONDA" ]];
if [[ "$INSTALLATION_MANAGER" == "CONDA" ]];
then
source $SCRIPT_DIR/scripts/establish_conda_env.sh --load
elif [[ "$INSTALLATION_MANAGER" == "PIP" ]];
Expand Down
4 changes: 4 additions & 0 deletions scripts/TestHarness/testers/CrowPython.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,6 +49,10 @@ def get_command(self):
@ In, None
@ Out, get_command, string, string command to use.
"""
# If the test command has been specified, use it
if (command := self._get_test_command()) is not None:
return ' '.join([command, self.specs['input']])

if len(self.specs["python_command"]) == 0:
pythonCommand = self._get_python_command()
else:
Expand Down
5 changes: 5 additions & 0 deletions scripts/TestHarness/testers/RavenErrors.py
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,11 @@ def get_command(self):
ravenflag = ''
if self.specs['test_interface_only'].lower() == 'true':
ravenflag = 'interfaceCheck '

# If the test command has been specified, use it
if (command := self._get_test_command()) is not None:
return ' '.join([command, ravenflag, self.specs["input"]])

return ' '.join([self._get_python_command(), raven, ravenflag,
self.specs["input"]])

Expand Down
19 changes: 6 additions & 13 deletions scripts/TestHarness/testers/RavenFramework.py
Original file line number Diff line number Diff line change
Expand Up @@ -118,24 +118,17 @@ def get_command(self):
@ In, None
@ Out, command, string, command to run.
"""
ravenflag = ''
flags = []
if self.specs['test_interface_only']:
ravenflag += ' interfaceCheck '
flags.append('interfaceCheck')

if self.specs['interactive']:
ravenflag += ' interactiveCheck '
flags.append('interactiveCheck')

installType = self.get_install_type()
if installType == 'source':
command = self._get_python_command() + " " + self.driver + " " + ravenflag + self.specs["input"]
elif installType == 'pip':
command = "raven_framework " + ravenflag + self.specs["input"]
elif installType == 'binary':
command = self._binaryLocation + " " + ravenflag + self.specs["input"]
if (command := self._get_test_command()) is not None:
return ' '.join([command, *flags, self.specs["input"]])
else:
raise ValueError('Unknown install type: {}'.format(self.__install_type))

return command
return ' '.join([self._get_python_command(), self.driver, *flags, self.specs["input"]])

def __make_differ(self, specName, differClass, extra=None):
"""
Expand Down
4 changes: 4 additions & 0 deletions scripts/TestHarness/testers/RavenPython.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,6 +82,10 @@ def get_command(self):
@ In, None
@ Out, get_command, string, command to run.
"""
# If the test command has been specified, use it
if (command := self._get_test_command()) is not None:
return ' '.join([command, self.specs["input"]])

if len(self.specs["python_command"]) == 0:
pythonCommand = self._get_python_command()
else:
Expand Down
2 changes: 1 addition & 1 deletion tests/cluster_tests/RavenRunsRaven/code_dask.xml
Original file line number Diff line number Diff line change
Expand Up @@ -61,7 +61,7 @@

<Models>
<Code name="rrr" subType="RAVEN">
<executable>%RAVENFRAMEWORK%</executable>
<executable>%RAVENEXECUTABLE%</executable>
<outputExportOutStreams>inner_out</outputExportOutStreams>
<alias type="input" variable="a">Samplers|MonteCarlo|constant@name:a</alias>
<alias type="input" variable="b">Samplers|MonteCarlo|constant@name:b</alias>
Expand Down
2 changes: 1 addition & 1 deletion tests/cluster_tests/RavenRunsRaven/code_ray.xml
Original file line number Diff line number Diff line change
Expand Up @@ -60,7 +60,7 @@

<Models>
<Code name="rrr" subType="RAVEN">
<executable>%RAVENFRAMEWORK%</executable>
<executable>%RAVENEXECUTABLE%</executable>
<outputExportOutStreams>inner_out</outputExportOutStreams>
<alias type="input" variable="a">Samplers|MonteCarlo|constant@name:a</alias>
<alias type="input" variable="b">Samplers|MonteCarlo|constant@name:b</alias>
Expand Down
2 changes: 1 addition & 1 deletion tests/cluster_tests/RavenRunsRaven/rom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@
<!-- MODELS -->
<Models>
<Code name="raven_running_rom" subType="RAVEN">
<executable>%RAVENFRAMEWORK%</executable>
<executable>%RAVENEXECUTABLE%</executable>
<outputExportOutStreams>outputMontecarloRom_dump,outputMontecarloRomHS_dump</outputExportOutStreams>
<conversion>
<module source="testConversionModule.py">
Expand Down
2 changes: 1 addition & 1 deletion tests/framework/CodeInterfaceTests/RAVEN/basic.xml
Original file line number Diff line number Diff line change
Expand Up @@ -43,7 +43,7 @@

<Models>
<Code name="raven" subType="RAVEN">
<executable>%RAVENFRAMEWORK%</executable>
<executable>%RAVENEXECUTABLE%</executable>
<outputExportOutStreams>inner_out</outputExportOutStreams>
<alias variable="innerLowerBound" type="input">Distributions|Uniform@name:dist|lowerBound</alias>
<alias variable="innerUpperBound" type="input">
Expand Down
Loading

0 comments on commit 8c67f36

Please sign in to comment.