clm5/cime_config/SystemTests/systemtest_utils.py
2024-05-09 15:14:01 +08:00

87 lines
3.4 KiB
Python

"""
Reduce code duplication by putting reused functions here.
"""
import os, subprocess
def cmds_to_setup_conda(caseroot):
# Add specific commands needed on different machines to get conda available
# Use semicolon here since it's OK to fail
#
conda_setup_commands = ". " + caseroot + "/.env_mach_specific.sh; "
# Setting CONDA_PREFIX to empty ensures that this works even if called from
# a shell with a conda environment activated
conda_setup_commands += "CONDA_PREFIX=; "
# Execute the module unload/load when "which conda" fails
# eg on cheyenne
try:
subprocess.run("which conda", shell=True, check=True)
except subprocess.CalledProcessError:
# Remove python and add conda to environment for cheyennne
unload_python_load_conda = "module unload python; module load conda;"
# Make sure that adding this actually loads conda
subprocess.run(unload_python_load_conda + "which conda", shell=True, check=True)
# Save
conda_setup_commands += " " + unload_python_load_conda
return conda_setup_commands
def cmds_to_run_via_conda(caseroot, conda_run_call, command):
# Run in the specified conda environment
conda_setup_commands = cmds_to_setup_conda(caseroot)
conda_setup_commands += " " + conda_run_call
# Finish with Python script call
command = conda_setup_commands + " " + command
print(f"command: {command}")
return command
def run_python_script(caseroot, this_conda_env, command_in, tool_path):
# First, try with "conda run -n"
command = cmds_to_run_via_conda(caseroot, f"conda run -n {this_conda_env}", command_in)
# Run with logfile
tool_name = os.path.split(tool_path)[-1]
try:
with open(tool_name + ".log", "w") as f:
subprocess.run(
command, shell=True, check=True, text=True, stdout=f, stderr=subprocess.STDOUT
)
except subprocess.CalledProcessError as error:
# Retry with the original "conda activate" method
command = cmds_to_run_via_conda(
caseroot,
f"conda activate {this_conda_env} && ",
command_in,
)
try:
with open(tool_name + ".log2", "w") as f:
subprocess.run(
command, shell=True, check=True, text=True, stdout=f, stderr=subprocess.STDOUT
)
except subprocess.CalledProcessError as error:
print("ERROR while getting the conda environment and/or ")
print(f"running the {tool_name} tool: ")
print(f"(1) If your {this_conda_env} environment is out of date or you ")
print(f"have not created the {this_conda_env} environment, yet, you may ")
print("get past this error by running ./py_env_create ")
print("in your ctsm directory and trying this test again. ")
print("(2) If conda is not available, install and load conda, ")
print("run ./py_env_create, and then try this test again. ")
print("(3) If (1) and (2) are not the issue, then you may be ")
print(f"getting an error within {tool_name} itself. ")
print("Default error message: ")
print(error.output)
raise
except:
print(f"ERROR trying to run {tool_name}.")
raise
except:
print(f"ERROR trying to run {tool_name}.")
raise