Skip to content
Open
Show file tree
Hide file tree
Changes from 10 commits
Commits
Show all changes
30 commits
Select commit Hold shift + click to select a range
c5c11ce
Move from PYTHONPATH in the modulefile to using sys.path modification…
hagertnl Apr 30, 2026
ea83cf4
Implement Jinja2+YAML template functionality. Basic checks passing
hagertnl Apr 30, 2026
144df39
Re-organizing scheduler and rgt_test classes, moving sole class from …
hagertnl Apr 30, 2026
32cfb93
Updating __init__.py for new directory names
hagertnl Apr 30, 2026
1e53cfd
Removing IBM POWER9 type, since it can easily be covered by linux_x86…
hagertnl Apr 30, 2026
2d5f3ae
Removing unnecessarily-spec'd replacements
hagertnl Apr 30, 2026
f9b3f20
Removing RunTimeEnvironment options and new_environment functionality…
hagertnl Apr 30, 2026
1dca02d
Fixing issue 168, logging build_end when CTRL+C'd. Still need to impr…
hagertnl Apr 30, 2026
ae0bd27
Fix template extension detection
hagertnl May 1, 2026
d20b921
Fully implement a fix for issue #168, CTRL+C behavior
hagertnl May 4, 2026
e4802ad
Merged devel into nick-issue219-yaml-jinja2
hagertnl May 5, 2026
c8f00b8
Switch all user-facing script path additions to use modern pathlib
hagertnl May 5, 2026
4ddd390
Make several conversions from os.path to pathlib
hagertnl May 5, 2026
9fdf15c
Small typo/bug/merge fixes
hagertnl May 5, 2026
aee3597
Replacing low-hanging os.path.exists fruit with the equivalent Path
hagertnl May 5, 2026
0f17a4d
More os.path.exists to Path conversions
hagertnl May 5, 2026
80c9e79
Small pathlib-related fixes
hagertnl May 5, 2026
a776c1f
Implemented variables and replacements blocks (with string formatting…
hagertnl May 8, 2026
f18d0be
Updating user guide
hagertnl May 11, 2026
f0161f8
Re-building docs with latest content, added sphinx-design dependency …
hagertnl May 11, 2026
1b389b1
Fixed typo in update_databases.py, made report_cmd optional
hagertnl May 11, 2026
62bc5f0
A few more 'import sys' bug fixes
hagertnl May 11, 2026
2611a25
Removed lone reference to OLCF_HARNESS_DIR envvar, replaced with a Pa…
hagertnl May 12, 2026
99a2780
Merge branch 'nick-issue219-yaml-jinja2' of github.com:hagertnl/olcf-…
hagertnl May 12, 2026
af2e6ff
Add a much better default value in status_file if PATH_TO_RGT_PACKAGE…
hagertnl May 12, 2026
641b8f5
Merge remote-tracking branch 'olcf/devel' into nick-issue219-yaml-jinja2
hagertnl May 15, 2026
5b68bd3
Merged upstream app/test filters into YAML branch
hagertnl May 15, 2026
c583350
Updating docs to cover app-filter and test-filter
hagertnl May 21, 2026
f6028d2
Re-build docs
hagertnl May 21, 2026
7b860ff
Hot-fix for un-handled Jinja2 import error in linux_utilities.py
hagertnl May 21, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions harness/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
"bin",
"libraries",
"utilities",
"fundamental_types",
"machine_types"
"machine_types",
"schedulers"
]

version = 3.1
5 changes: 5 additions & 0 deletions harness/bin/check_executable_driver.py
Comment thread
hagertnl marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@
import getopt
import string

prefix = os.path.normpath(
os.path.join(os.path.abspath(os.path.dirname(__file__)), '..')
)
sys.path = [prefix] + sys.path

# Harness imports
from libraries.apptest import subtest
from libraries.subtest_factory import SubtestFactory
Expand Down
5 changes: 5 additions & 0 deletions harness/bin/log_binary_execution_time.py
Comment thread
hagertnl marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,11 @@
import sys
import os

prefix = os.path.normpath(
os.path.join(os.path.abspath(os.path.dirname(__file__)), '..')
)
sys.path = [prefix] + sys.path

from libraries.subtest_factory import SubtestFactory
from libraries.status_file_factory import StatusFileFactory
from libraries.status_file import StatusFile
Expand Down
5 changes: 5 additions & 0 deletions harness/bin/runtests.py
Comment thread
hagertnl marked this conversation as resolved.
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,11 @@
import os
import sys

prefix = os.path.normpath(
os.path.join(os.path.abspath(os.path.dirname(__file__)), '..')
)
sys.path = [prefix] + sys.path

# My harness package imports
from libraries import input_files
from libraries import regression_test
Expand Down
25 changes: 18 additions & 7 deletions harness/bin/test_harness_driver.py
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,11 @@

from shlex import split

prefix = os.path.normpath(
Comment thread
hagertnl marked this conversation as resolved.
Outdated
os.path.join(os.path.abspath(os.path.dirname(__file__)), '..')
)
sys.path = [prefix] + sys.path

# Harness imports
from libraries.subtest_factory import SubtestFactory
from libraries.layout_of_apps_directory import apptest_layout as layout
Expand All @@ -35,7 +40,6 @@
from libraries import status_file
from libraries.rgt_loggers import rgt_logger_factory
from machine_types.machine_factory import MachineFactory
from machine_types.base_machine import SetBuildRTEError

MODULE_THRESHOLD_LOG_LEVEL = "DEBUG"
"""str : The logging level for this module. """
Expand Down Expand Up @@ -160,15 +164,22 @@ def auto_generated_scripts(harness_config,
build_exit_value = 0
if actions['build']:
# Build the executable for this test on the specified machine
scripts_dir = os.getcwd()
jstatus.log_event(status_file.StatusFile.EVENT_BUILD_START)
try:
build_exit_value = mymachine.build_executable()
except SetBuildRTEError as error:
message = f"Unable to set the build runtime environnment."
message += error.message
a_logger.doCriticalLogging(message)
finally:
jstatus.log_event(status_file.StatusFile.EVENT_BUILD_END, build_exit_value)
except KeyboardInterrupt:
a_logger.doCriticalLogging(f"Detected CTRL+C, aborting build.")
os.chdir(scripts_dir)
build_exit_value = 21
pass
except Exception:
a_logger.doCriticalLogging(f"Exception generated during build, aborting test launch.")
os.chdir(scripts_dir)
build_exit_value = 1
pass

jstatus.log_event(status_file.StatusFile.EVENT_BUILD_END, build_exit_value)
#-----------------------------------------------------
# In this section we run the the binary. -
# -
Expand Down
5 changes: 0 additions & 5 deletions harness/fundamental_types/__init__.py

This file was deleted.

3 changes: 2 additions & 1 deletion harness/libraries/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,8 @@
'regression_test',
'status_file',
'repositories',
'rgt_loggers'
'rgt_loggers',
'rgt_state',
'command_line',
'get_machine_name',
'status_file_factory',
Expand Down
3 changes: 0 additions & 3 deletions harness/libraries/apptest.py
Original file line number Diff line number Diff line change
Expand Up @@ -533,9 +533,6 @@ def _start_test(self,
message = ( "The command '{cmd}' has exited with a failure.\n"
"The exit return value is {value}.\n").format(cmd=starttestcomand,value=exit_status)
self.logger.doCriticalLogging(message)


string1 = "Command failed: " + starttestcomand
return 1
else:
message = "'{cmd}' has executed sucessfully.\n".format(cmd=starttestcomand)
Expand Down
13 changes: 10 additions & 3 deletions harness/libraries/layout_of_apps_directory.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@ class apptest_layout:
app_info_filename = 'application_info.txt'
test_info_filename = 'test_info.txt'
test_input_ini_filename = 'rgt_test_input.ini'
test_input_yaml_filename = 'rgt_test_input.yaml'
test_kill_filename = '.kill_test'
test_rc_filename = '.testrc'
test_status_filename = 'rgt_status.txt'
Expand Down Expand Up @@ -73,6 +74,7 @@ class apptest_layout:
'runarchive_dir' : os.path.join("${pdir}", "${app}", "${test}", test_run_archive_dirname, "${id}"),
'scripts_dir' : os.path.join("${pdir}", "${app}", "${test}", test_scripts_dirname),
'test_input_ini' : os.path.join("${pdir}", "${app}", "${test}", test_scripts_dirname, test_input_ini_filename),
'test_input_yaml' : os.path.join("${pdir}", "${app}", "${test}", test_scripts_dirname, test_input_yaml_filename),
'kill_file' : os.path.join("${pdir}", "${app}", "${test}", test_scripts_dirname, test_kill_filename),
'status_dir' : os.path.join("${pdir}", "${app}", "${test}", test_status_dirname, "${id}"),
'job_id_file' : os.path.join("${pdir}", "${app}", "${test}", test_status_dirname, "${id}", job_id_filename),
Expand Down Expand Up @@ -126,7 +128,8 @@ def check_paths(self):
self.__logger.doErrorLogging(f"Could not find the Scripts directory for App={self.__appname}, Test={self.__testname}.")
return False
# Check that the an rgt_test_ini.ini file exists
if not (os.path.exists(self.__apptest_layout['test_input_ini'])):
if not (os.path.exists(self.__apptest_layout['test_input_ini']) or \
Comment thread
hagertnl marked this conversation as resolved.
Outdated
os.path.exists(self.__apptest_layout['test_input_yaml'])):
self.__logger.doErrorLogging(f"Could not find the test input file for App={self.__appname}, Test={self.__testname}.")
return False
return True
Expand All @@ -136,10 +139,14 @@ def get_harness_id(self):
return self.__testid

@property
def path_of_test_input_file(self):
"""Returns the path to the subtest INI input file. """
def path_of_test_input_file_ini(self):
"""Returns the path to the subtest input file. """
return self.__apptest_layout['test_input_ini']

@property
def path_of_test_input_file_yaml(self):
"""Returns the path to the subtest input file. """
return self.__apptest_layout['test_input_yaml']

@property
def path_to_logfile(self) :
Expand Down
57 changes: 34 additions & 23 deletions harness/libraries/regression_test.py
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
# Harness package imports.
from libraries import apptest
from libraries.subtest_factory import SubtestFactory
from fundamental_types.rgt_state import RgtState
from libraries.rgt_state import RgtState
from libraries.rgt_loggers import rgt_logger_factory
from machine_types.machine_factory import MachineFactory

Expand Down Expand Up @@ -262,37 +262,48 @@ def __run_subtests_asynchronously(self):
# Submit futures by means of thread pool.
with concurrent.futures.ThreadPoolExecutor(max_workers=self.__num_workers) as executor:
for subtest in self.__app_subtests:
future = executor.submit(apptest.do_application_tasks,
# gracefully handle keyboard interrupts in main thread
try:
future = executor.submit(apptest.do_application_tasks,
self.__launch_id,
subtest,
self.__tasks,
self.__stdout_stderr,
self.__separate_build_stdio,
self.__reuse_first_build,
self.__reuse_build_from_id)
future_to_appname[future] = f'{subtest.getNameOfApplication()}.{subtest.getNameOfSubtest()}'
future_to_appname[future] = f'{subtest.getNameOfApplication()}.{subtest.getNameOfSubtest()}'
except KeyboardInterrupt:
pass

# Log when all job tasks are initiated.
for my_future in concurrent.futures.as_completed(future_to_appname):
# appname is appname.testname, as set above
appname = future_to_appname[my_future]

# Check if an exception has been raised
my_future_exception = my_future.exception()
if my_future_exception:
message = "Test {} exception encountered:\n{}".format(appname, my_future_exception)
self.__myLogger.doCriticalLogging(message)

subtest_result = my_future.result()
if subtest_result:
self.__launched_tests += 1
message = "Test {} is launched.\n\n".format(appname)
self.__myLogger.doErrorLogging(message)
else:
self.__failed_tests += 1
self.__failed_test_list.append(appname)
message = "Test {} failed to launch.\n\n".format(appname)
self.__myLogger.doErrorLogging(message)
all_finished = False
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Unsure of what you are trying to accomplish here. It looks like it would restart the build when there is a keyboard interrupt.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

So this code block is the main thread. In the main thread, it submits a bunch of tasks to the executor, then waits for each to finish in this for-loop. So what we're doing is keeping the main thread alive so that other build tasks that have been submitted can run. It may be a bit clunky in practice, but it's a clean/explainable result of CTRL+C that I would find helpful to, for example, skip a test that I don't want to run and get to a subsequent test that I would find more interesting.

In the future, we could refine handling of CTRL+C to add some rate-limiting for "CTRL+C twice in 5 seconds if you wish to exit), but I don't think we have to worry about that yet.

while not all_finished:
# gracefully handle keyboard interrupts in main thread
try:
for my_future in concurrent.futures.as_completed(future_to_appname):
# appname is appname.testname, as set above
appname = future_to_appname[my_future]

# Check if an exception has been raised
my_future_exception = my_future.exception()
if my_future_exception:
message = "Test {} exception encountered:\n{}".format(appname, my_future_exception)
self.__myLogger.doCriticalLogging(message)

subtest_result = my_future.result()
if subtest_result:
self.__launched_tests += 1
message = "Test {} is launched.\n\n".format(appname)
self.__myLogger.doErrorLogging(message)
else:
self.__failed_tests += 1
self.__failed_test_list.append(appname)
message = "Test {} failed to launch.\n\n".format(appname)
self.__myLogger.doErrorLogging(message)
all_finished = True
except KeyboardInterrupt:
pass

message = "All tests are launched. Yahoo!!"
self.__myLogger.doInfoLogging(message)
Expand Down
File renamed without changes.
Loading