Skip to content

Add main branch testing automation#774

Draft
forsyth2 wants to merge 32 commits into
mainfrom
automate-main-branch-testing
Draft

Add main branch testing automation#774
forsyth2 wants to merge 32 commits into
mainfrom
automate-main-branch-testing

Conversation

@forsyth2

Copy link
Copy Markdown
Collaborator

Summary

Objectives:

  • Automate the testing workflow. Specifically, using the latest workflow, as described in the 2025-12-30 test.

Issue resolution:

Select one: This pull request is...

  • a bug fix: increment the patch version
  • a small improvement: increment the minor version
  • a new feature: increment the minor version
  • an incompatible (non-backwards compatible) API change: increment the major version

Small Change

  • To merge, I will use "Squash and merge". That is, this change should be a single commit.
  • Logic: I have visually inspected the entire pull request myself.
  • Pre-commit checks: All the pre-commits checks have passed.

@forsyth2 forsyth2 self-assigned this Jan 23, 2026
@forsyth2 forsyth2 added Testing Files in `tests` modified semver: small improvement Small improvement (will increment patch version) labels Jan 23, 2026
@forsyth2

Copy link
Copy Markdown
Collaborator Author

Current status: made it to the end of phase 1 (launched jobs), but the MPAS-Analysis jobs didn't have sufficient wall times allocated. (Note: because of #764, it is usually better to rerun from scratch in this case).

Action items:

  • Rerun automated workflow, iterating until it reaches completion without failing.

@forsyth2
forsyth2 force-pushed the automate-main-branch-testing branch from f33b563 to ed8e6fc Compare January 26, 2026 20:44
@forsyth2 forsyth2 mentioned this pull request Jan 26, 2026
7 tasks
@forsyth2

Copy link
Copy Markdown
Collaborator Author

Using the latest commit (88cdcb2), I've made it to phase 2. It turns out I needed to update LEGACY_BUNDLES_OUTPUT to be "${OUTPUT_WORKSPACE}/zppy_weekly_legacy_3.0.0_bundles_output/${UNIQUE_ID}/v3.LR.historical_0051/post/scripts" (it was missing a / before), as that caused phase 2 to crash. After making that fix, I restarted from the phase 2 start point, but ran into the following error on job launch:

Traceback (most recent call last):
  File "/gpfs/fs1/home/ac.forsyth2/miniforge3/envs/test-zppy-test-fixes-20260126_run4/bin/zppy", line 7, in <module>
    sys.exit(main())
             ~~~~^^
  File "/gpfs/fs1/home/ac.forsyth2/miniforge3/envs/test-zppy-test-fixes-20260126_run4/lib/python3.14/site-packages/zppy/__main__.py", line 43, in main
    user_config, plugins = _handle_plugins(user_config, default_config, args)
                           ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/gpfs/fs1/home/ac.forsyth2/miniforge3/envs/test-zppy-test-fixes-20260126_run4/lib/python3.14/site-packages/zppy/__main__.py", line 106, in _handle_plugins
    if "plugins" in user_config["default"].keys():
                    ~~~~~~~~~~~^^^^^^^^^^^
  File "/gpfs/fs1/home/ac.forsyth2/miniforge3/envs/test-zppy-test-fixes-20260126_run4/lib/python3.14/site-packages/configobj/__init__.py", line 549, in __getitem__
    val = dict.__getitem__(self, key)
KeyError: 'default'

@forsyth2

Copy link
Copy Markdown
Collaborator Author

I've run through phase 3 now. There are a number of issues to resolve before fully switching from the manual testing workflow to this one.

Immediate KeyError on later zppy runs

I cannot get Phase 2 to work in an automated manner. I can launch zppy -c manually but running from Phase 2, I get:

[2026-01-30 14:52:37] Submitting bundles part 2...
2026-01-30 14:52:38,000 [INFO]: __main__.py(main:33) >> For help, please see https://e3sm-project.github.io/zppy. Ask questions at https://github.com/E3SM-Project/zppy/discussions/categories/q-a.
2026-01-30 14:52:38,000 [INFO]: __main__.py(main:33) >> For help, please see https://e3sm-project.github.io/zppy. Ask questions at https://github.com/E3SM-Project/zppy/discussions/categories/q-a.
Traceback (most recent call last):
  File "/gpfs/fs1/home/ac.forsyth2/miniforge3/envs/test-zppy-test-fixes-20260126_run4/bin/zppy", line 7, in <module>
    sys.exit(main())
             ~~~~^^
  File "/gpfs/fs1/home/ac.forsyth2/miniforge3/envs/test-zppy-test-fixes-20260126_run4/lib/python3.14/site-packages/zppy/__main__.py", line 43, in main
    user_config, plugins = _handle_plugins(user_config, default_config, args)
                           ~~~~~~~~~~~~~~~^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
  File "/gpfs/fs1/home/ac.forsyth2/miniforge3/envs/test-zppy-test-fixes-20260126_run4/lib/python3.14/site-packages/zppy/__main__.py", line 106, in _handle_plugins
    if "plugins" in user_config["default"].keys():
                    ~~~~~~~~~~~^^^^^^^^^^^
  File "/gpfs/fs1/home/ac.forsyth2/miniforge3/envs/test-zppy-test-fixes-20260126_run4/lib/python3.14/site-packages/configobj/__init__.py", line 549, in __getitem__
    val = dict.__getitem__(self, key)
KeyError: 'default'

Status file errors

I'm not sure how these could possibly be real failures (i.e., not caused by this branch), considering the last change to zppy was on 12/23 (according to the commit log), which was before the 12/30 test.

To be certain though, I will have to do the usual workflow and see if the same thing happens or not.

/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/zppy_main_branch_test_20260126_run4/v2.LR.historical_0201/post/scripts
global_time_series_1980-1990.status:WAITING 1135590
mpas_analysis_ts_1980-1984_climo_1980-1984.status:RUNNING 1135588
mpas_analysis_ts_1980-1990_climo_1985-1990.status:WAITING 1135589

/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.0.0_comprehensive_v2_output/zppy_main_branch_test_20260126_run4/v2.LR.historical_0201/post/scripts
global_time_series_1980-1990.status:WAITING 1135670
mpas_analysis_ts_1980-1984_climo_1980-1984.status:RUNNING 1135668
mpas_analysis_ts_1980-1990_climo_1985-1990.status:WAITING 1135669

/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v3_output/zppy_main_branch_test_20260126_run4/v3.LR.historical_0051/post/scripts
pcmdi_diags_synthetic_plots_model_vs_obs.status:WAITING 1135638
pcmdi_diags_variability_modes_atm_model_vs_obs_1985-1994.status:ERROR (14)

MPAS Analysis errors

cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/zppy_main_branch_test_20260126_run4/v2.LR.historical_0201/post/scripts
cat mpas_analysis_ts_1980-1984_climo_1980-1984.o1135588

gives:

Output
===== SET UP MPAS-ANALYSIS DIRECTORY STRUCTURE =====

sending incremental file list

sent 62 bytes  received 12 bytes  148.00 bytes/sec
total size is 0  speedup is 0.00
sending incremental file list

sent 62 bytes  received 12 bytes  148.00 bytes/sec
total size is 0  speedup is 0.00
sending incremental file list

sent 62 bytes  received 12 bytes  148.00 bytes/sec
total size is 0  speedup is 0.00
cp: cannot stat 'cache/timeseries/mpasIndexOcean.nc': No such file or directory
cp: cannot stat 'cache/timeseries/mpasTimeSeriesOcean.nc': No such file or directory
cp: cannot stat 'cache/timeseries/seaIceAreaVolNH.nc': No such file or directory
cp: cannot stat 'cache/timeseries/seaIceAreaVolSH.nc': No such file or directory

===== RUN MPAS-ANALYSIS =====

Detected E3SM supported machine: chrysalis
Using the following config files:
   /lcrc/soft/climate/e3sm-unified/e3smu_1_12_0/chrysalis/conda/envs/e3sm_unified_1.12.0_compute/lib/python3.13/site-packages/mpas_analysis/default.cfg
   /lcrc/soft/climate/e3sm-unified/e3smu_1_12_0/chrysalis/conda/envs/e3sm_unified_1.12.0_compute/lib/python3.13/site-packages/mache/machines/chrysalis.cfg
   /lcrc/soft/climate/e3sm-unified/e3smu_1_12_0/chrysalis/conda/envs/e3sm_unified_1.12.0_compute/lib/python3.13/site-packages/mpas_analysis/configuration/chrysalis.cfg
   /lcrc/soft/climate/e3sm-unified/e3smu_1_12_0/chrysalis/conda/envs/e3sm_unified_1.12.0_compute/lib/python3.13/site-packages/mpas_analysis/__main__.py
   /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/zppy_main_branch_test_20260126_run4/v2.LR.historical_0201/post/analysis/mpas_analysis/cfg/mpas_analysis_ts_1980-1984_climo_1980-1984.cfg
copying /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/zppy_main_branch_test_20260126_run4/v2.LR.historical_0201/post/analysis/mpas_analysis/cfg/mpas_analysis_ts_1980-1984_climo_1980-1984.cfg to HTML dir.
Atlantic
 * merging features
 * combining features
Pacific
 * merging features
 * combining features
Indian
 * merging features
 * combining features
Arctic
 * merging features
 * combining features
Southern_Ocean
 * merging features
 * combining features
Mediterranean
 * merging features
 * combining features

[1769470584.390866] [chr-0159:3633137:0]     ucp_context.c:1951 UCX  WARN  UCP API version is incompatible: required >= 1.16, actual 1.14.0 (loaded from /usr/lib64/libucp.so.0)
[1769470584.472043] [chr-0159:3633137:0]     ucp_context.c:1951 UCX  WARN  UCP API version is incompatible: required >= 1.16, actual 1.14.0 (loaded from /usr/lib64/libucp.so.0)
 Starting weight generation with these inputs: 
   Source File: /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/zppy_main_branch_test_20260126_run4/v2.LR.historical_0201/post/analysis/mpas_analysis/ts_1980-1984_climo_1980-1984/mapping/tmpilna9gk5/src_mesh.nc
   Destination File: /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/zppy_main_branch_test_20260126_run4/v2.LR.historical_0201/post/analysis/mpas_analysis/ts_1980-1984_climo_1980-1984/mapping/tmpilna9gk5/dst_mesh.nc
   Weight File: /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/zppy_main_branch_test_20260126_run4/v2.LR.historical_0201/post/scripts/../analysis/mpas_analysis/ts_1980-1984_climo_1980-1984/mapping/map_EC30to60E2r2_to_AntShip_transects_5km_bilinear.nc
   Source File is in SCRIP format
   Source Grid is a regional grid
   Source Grid is an unstructured grid
   Use the center coordinates of the source grid to do the regrid
   Destination File is in SCRIP format
   Destination Grid is a regional grid
   Destination Grid is an unstructured grid
   Use the center coordinates of the destination grid to do the regrid
   Regrid Method: bilinear
   Pole option: NONE
   Ignore unmapped destination points
   Output weight file in NetCDF4 file format
   Line Type: cartesian
   Norm Type: dstarea
   Extrap. Method: none

srun: error: chr-0159: task 0: Segmentation fault
srun: Job step aborted: Waiting up to 92 seconds for job step to finish.
slurmstepd: error: *** STEP 1135588.0 ON chr-0159 CANCELLED AT 2026-01-26T19:34:17 DUE TO TIME LIMIT ***
slurmstepd: error: *** JOB 1135588 ON chr-0159 CANCELLED AT 2026-01-26T19:34:17 DUE TO TIME LIMIT ***
srun: got SIGCONT
srun: forcing job termination

I had extended the time limit (here) because it was hitting the time limit, but it turns out the time limit isn't the problem at all. The job stays active even after the segmentation fault, but doesn't actually do anything to recover from it.

Notes:

  • global_time_series never runs because this job is a dependency.
  • legacy v2 has the equivalent error.

PCMDI Diags errors

cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v3_output/zppy_main_branch_test_20260126_run4/v3.LR.historical_0051/post/scripts
cat pcmdi_diags_variability_modes_atm_model_vs_obs_1985-1994.o1135637

gives:

Output
create_links_ts: linking from /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v3_output/zppy_main_branch_test_20260126_run4/v3.LR.historical_0051/post/atm/180x360_aave/cmip_ts/monthly to ts
ncap2: WARNING ncap_def_dim(): dim "bnds" - already exists in input/output.
Linking observational data into obs_link...
Linking observational data using SLURM...
Running a zi-pcmdi command: zi-pcmdi-link-observation --model_name_ref obs.historical.put_model_here.00 --tableID_ref Amon --vars=psl --obs_sets alternate2 --obs_ts /lcrc/soft/climate/e3sm_diags_data/obs_for_e3sm_diags/time-series --obstmp_dir obs_link --debug false
[Info] Linked psl → obs_link/obs.historical.NOAA-20C.00.Amon.psl.183601-201512.nc

real	0m26.226s
user	0m15.557s
sys	0m0.558s
create_links_ts_obs: linking from /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v3_output/zppy_main_branch_test_20260126_run4/v3.LR.historical_0051/post/scripts/tmp.pcmdi_diags_variability_modes_atm_model_vs_obs_1985-1994.1135637.Jp6U/obs_link to ts_ref
create_links_ts_obs: checking if nc file: obs.historical.NOAA-20C.00.Amon.psl.183601-201512.nc
create_links_ts_obs: processing /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v3_output/zppy_main_branch_test_20260126_run4/v3.LR.historical_0051/post/scripts/tmp.pcmdi_diags_variability_modes_atm_model_vs_obs_1985-1994.1135637.Jp6U/obs_link/obs.historical.NOAA-20C.00.Amon.psl.183601-201512.nc
ncrcat successful
Adding missing calendar attribute to time...
ncatted successful
ncap2: WARNING ncap_def_dim(): dim "bnds" - already exists in input/output.
ncap2 successful
About to create parameterfile.py, which will be passed in with -p
The current directory is: /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v3_output/zppy_main_branch_test_20260126_run4/v3.LR.historical_0051/post/scripts/tmp.pcmdi_diags_variability_modes_atm_model_vs_obs_1985-1994.1135637.Jp6U

===== RUN PCMDI DIAGS =====

About to set up a zi-pcmdi command
The current directory is: /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v3_output/zppy_main_branch_test_20260126_run4/v3.LR.historical_0051/post/scripts/tmp.pcmdi_diags_variability_modes_atm_model_vs_obs_1985-1994.1135637.Jp6U
Running a zi-pcmdi command: zi-pcmdi-variability-modes --num_workers 24 --multiprocessing True --subsection variability_modes_atm --climo_ts_dir_primary ts --climo_ts_dir_ref ts_ref --model_name e3sm.historical.v3-LR.0051 --model_tableID Amon --figure_format png  --run_type model_vs_obs --obs_sets alternate2 --model_name_ref obs.historical.put_model_here.00 --vars psl --tableID_ref Amon --generate_sftlf True --case_id v20260126 --results_dir model_vs_obs --debug false --var_modes NAM,NAO,PNA,NPO,SAM,PSA1,PSA2
The current directory is: /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v3_output/zppy_main_branch_test_20260126_run4/v3.LR.historical_0051/post/scripts/tmp.pcmdi_diags_variability_modes_atm_model_vs_obs_1985-1994.1135637.Jp6U
2026-01-26 18:07:46,241 [INFO]: pcmdi_setup.py(build_catalogues:76) >> DataCatalogueBuilder's vars: ['psl']
2026-01-26 18:07:46,241 [INFO]: pcmdi_setup.py(build_catalogues:78) >> Building catalogue for psl
2026-01-26 18:07:46,241 [INFO]: pcmdi_setup.py(build_catalogues:80) >> Looking for psl, the base var name of psl
2026-01-26 18:07:46,241 [INFO]: pcmdi_setup.py(build_catalogues:81) >> Finding test files in ts
2026-01-26 18:07:46,241 [INFO]: pcmdi_setup.py(build_catalogues:85) >> Finding ref files in ts_ref
2026-01-26 18:07:46,244 [INFO]: pcmdi_setup.py(build_catalogues:96) >> Extracting & assigining metadata for psl, the base var name of psl
2026-01-26 18:07:46,244 [INFO]: pcmdi_setup.py(_extract_metadata:135) >> Extracting metadata from e3sm.historical.v3-LR.0051.Amon.psl.198501-199412.nc, dervied from ts/e3sm.historical.v3-LR.0051.Amon.psl.198501-199412.nc
2026-01-26 18:07:46,244 [INFO]: pcmdi_setup.py(_extract_metadata:148) >> Parsing e3sm.historical.v3-LR.0051.Amon.psl.198501-199412.nc, determined mip=e3sm, exp=historical, model=v3-LR, realization=0051, tableID=Amon, yymms=198501, yymme=199412
2026-01-26 18:07:46,246 [INFO]: pcmdi_setup.py(_extract_metadata:135) >> Extracting metadata from obs.historical.NOAA-20C.00.Amon.psl.198501-199412.nc, dervied from ts_ref/obs.historical.NOAA-20C.00.Amon.psl.198501-199412.nc
2026-01-26 18:07:46,246 [INFO]: pcmdi_setup.py(_extract_metadata:148) >> Parsing obs.historical.NOAA-20C.00.Amon.psl.198501-199412.nc, determined mip=obs, exp=historical, model=NOAA-20C, realization=00, tableID=Amon, yymms=198501, yymme=199412
2026-01-26 18:07:46,246 [INFO]: pcmdi_setup.py(build_catalogues:111) >> test_files=['ts/e3sm.historical.v3-LR.0051.Amon.psl.198501-199412.nc']
2026-01-26 18:07:46,246 [INFO]: pcmdi_setup.py(build_catalogues:112) >> ref_files=['ts_ref/obs.historical.NOAA-20C.00.Amon.psl.198501-199412.nc']
2026-01-26 18:07:46,246 [INFO]: pcmdi_setup.py(build_catalogues:114) >> test_files[0]=ts/e3sm.historical.v3-LR.0051.Amon.psl.198501-199412.nc
2026-01-26 18:07:46,246 [INFO]: pcmdi_setup.py(build_catalogues:116) >> ref_files[0]=ts_ref/obs.historical.NOAA-20C.00.Amon.psl.198501-199412.nc
2026-01-26 18:07:46,246 [INFO]: pcmdi_setup.py(_save_catalogue:184) >> Saving catalogue pcmdi_diags/ts_variability_modes_atm_catalogue.json, absolute path /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v3_output/zppy_main_branch_test_20260126_run4/v3.LR.historical_0051/post/scripts/tmp.pcmdi_diags_variability_modes_atm_model_vs_obs_1985-1994.1135637.Jp6U/pcmdi_diags/ts_variability_modes_atm_catalogue.json
2026-01-26 18:07:46,248 [INFO]: pcmdi_setup.py(_save_catalogue:184) >> Saving catalogue pcmdi_diags/ts_ref_variability_modes_atm_catalogue.json, absolute path /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v3_output/zppy_main_branch_test_20260126_run4/v3.LR.historical_0051/post/scripts/tmp.pcmdi_diags_variability_modes_atm_model_vs_obs_1985-1994.1135637.Jp6U/pcmdi_diags/ts_ref_variability_modes_atm_catalogue.json
2026-01-26 18:07:47,798 [WARNING]: bounds.py(create_bounds:983) >> The 'lat' coordinate variable is missing a 'units' attribute. Assuming 'units' is 'degrees_north'.
2026-01-26 18:07:47,998 [WARNING]: bounds.py(create_bounds:983) >> The 'lat' coordinate variable is missing a 'units' attribute. Assuming 'units' is 'degrees_north'.
2026-01-26 18:07:48,017 [INFO]: pcmdi_setup.py(set_up:354) >> out_path=model_vs_obs/%(group_type)
2026-01-26 18:07:48,042 [INFO]: utils.py(run_parallel_jobs:61) >> Running 7 subprocesses...
2026-01-26 18:07:59,224 [ERROR]: utils.py(run_parallel_jobs:67) >> ERROR: Process failed: 'variability_modes_driver.py -p parameterfile.py --variability_mode NAM --eofn_mod 1 --eofn_obs 1 --varOBS psl --osyear 1985 --oeyear 1994 --reference_data_name NOAA-20C --reference_data_path ts_ref/obs.historical.NOAA-20C.00.Amon.psl.198501-199412.nc --case_id v20260126'
Error: /gpfs/fs1/home/ac.forsyth2/miniforge3/envs/test-zi-main-20260126_run4/lib/python3.13/site-packages/xcdat/temporal.py:2223: UserWarning: The 'unit' keyword is only used when the Timedelta input is an integer or float, not timedelta64. To specify the storage unit of the output use `td.as_unit(unit)`
  median_delta = pd.to_timedelta(np.median(time_deltas), unit="ns")
Traceback (most recent call last):
  File "/gpfs/fs1/home/ac.forsyth2/miniforge3/envs/test-zi-main-20260126_run4/bin/variability_modes_driver.py", line 338, in <module>
    obs_timeseries_season = adjust_timeseries(
        obs_timeseries, obs_var, mode, season, regions_specs, RmDomainMean
    )
  File "/gpfs/fs1/home/ac.forsyth2/miniforge3/envs/test-zi-main-20260126_run4/lib/python3.13/site-packages/pcmdi_metrics/variability_mode/lib/adjust_timeseries.py", line 36, in adjust_timeseries
    ds_anomaly = get_anomaly_timeseries(ds, data_var, season)
  File "/gpfs/fs1/home/ac.forsyth2/miniforge3/envs/test-zi-main-20260126_run4/lib/python3.13/site-packages/pcmdi_metrics/variability_mode/lib/adjust_timeseries.py", line 75, in get_anomaly_timeseries
    ds_anomaly_all_seasons = ds_anomaly.temporal.departures(
        data_var,
    ...<2 lines>...
        season_config={"dec_mode": "DJF", "drop_incomplete_djf": True},
    )
  File "/gpfs/fs1/home/ac.forsyth2/miniforge3/envs/test-zi-main-20260126_run4/lib/python3.13/site-packages/xcdat/temporal.py", line 869, in departures
    ds = self._preprocess_dataset(ds)
  File "/gpfs/fs1/home/ac.forsyth2/miniforge3/envs/test-zi-main-20260126_run4/lib/python3.13/site-packages/xcdat/temporal.py", line 1219, in _preprocess_dataset
    ds = self._shift_djf_decembers(ds)
  File "/gpfs/fs1/home/ac.forsyth2/miniforge3/envs/test-zi-main-20260126_run4/lib/python3.13/site-packages/xcdat/temporal.py", line 1364, in _shift_djf_decembers
    time_coords.values[dec_indexes] = [
    ~~~~~~~~~~~~~~~~~~^^^^^^^^^^^^^
ValueError: assignment destination is read-only
Land mask estimated using regionmask method.
Land mask estimated using regionmask method.
Execution failed: Subprocess failed: variability_modes_driver.py -p parameterfile.py --variability_mode NAM --eofn_mod 1 --eofn_obs 1 --varOBS psl --osyear 1985 --oeyear 1994 --reference_data_name NOAA-20C --reference_data_path ts_ref/obs.historical.NOAA-20C.00.Amon.psl.198501-199412.nc --case_id v20260126
successfully finish all jobs....

real	0m24.830s
user	0m32.299s
sys	0m2.342s

===== COPY FILES TO WEB SERVER =====

rsync: [sender] link_stat "/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v3_output/zppy_main_branch_test_20260126_run4/v3.LR.historical_0051/post/scripts/tmp.pcmdi_diags_variability_modes_atm_model_vs_obs_1985-1994.1135637.Jp6U/model_vs_obs" failed: No such file or directory (2)
rsync error: some files/attrs were not transferred (see previous errors) (code 23) at main.c(1338) [sender=3.4.1]

Relevant lines, though I'm not sure why they aren't working:

  • ValueError: assignment destination is read-only
  • rsync: [sender] link_stat "/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v3_output/zppy_main_branch_test_20260126_run4/v3.LR.historical_0051/post/scripts/tmp.pcmdi_diags_variability_modes_atm_model_vs_obs_1985-1994.1135637.Jp6U/model_vs_obs" failed: No such file or directory (2)

Notes:

  • pcmdi_diags_synthetic_plots_model_vs_obs never runs because this job is a dependency.

@forsyth2

Copy link
Copy Markdown
Collaborator Author

After running the standard manual weekly test, I've confirmed the mpas_analysis error is an issue with this branch but that the pcmdi_diags error is a real issue.

That means this branch for automated testing has two major issues to resolve:

  1. The mpas_analysis segmentation fault
  2. The KeyError when running Bundles Part 2

@forsyth2

forsyth2 commented Apr 2, 2026

Copy link
Copy Markdown
Collaborator Author

#803 has some helper functions that can at least partially automate the process until this more complete automation is merged.

@forsyth2 forsyth2 mentioned this pull request Jun 5, 2026
7 tasks
@forsyth2
forsyth2 force-pushed the automate-main-branch-testing branch from b35347d to fa6f2bb Compare June 9, 2026 22:28
@forsyth2

forsyth2 commented Jun 9, 2026

Copy link
Copy Markdown
Collaborator Author

I gave Claude the updated testing documentation of #839 (specifically this file), the helper functions of #803, and tests/main_branch_testing/run_integration_test.bash of this PR (noting the 2 errors: The mpas_analysis segmentation fault; The KeyError when running Bundles Part 2).

I then had it update tests/main_branch_testing/run_integration_test.bash & tests/main_branch_testing/README.md.

I've rebased this PR off the latest main and added in the new Claude updates. These are reflected in the latest commit: fa6f2bb

Remaining action items:

  • Visually inspect new changes (fa6f2bb)
  • Actually run the automated test script and get it to complete successfully.

@forsyth2

Copy link
Copy Markdown
Collaborator Author

Results from 06/11-06/12 run

I've completed a run of this test script. A few notes:

  • Phase 1 timed out, but that doesn't cancel the jobs. Once they finished, I was able to manually restart at phase 2.
  • There were a few errors in the output directory (post/scripts) and in the image check tests. Described below.
  • The other tests have errors that are likely to be expected based on recent PRs.

e3sm_diags

post/scripts results: 2 jobs have RUNNING status

/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/e3sm_diags_atm_monthly_180x360_aave_mvm_model_vs_model_1980-1981_vs_1980-1981.status:RUNNING 1234499

/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.0.0_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/e3sm_diags_atm_monthly_180x360_aave_model_vs_obs_1982-1983.status:RUNNING 1234561

Failing image checks:

Test name Total images Correct images Missing images Mismatched images
legacy_3.1.0_comprehensive_v2_e3sm_diags 3806 2555 1251 (list) 0
legacy_3.0.0_comprehensive_v2_e3sm_diags 3806 2122 1684 (list) 0

Debugging:

grep -in error /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/e3sm_diags_atm_monthly_180x360_aave_mvm_model_vs_model_1980-1981_vs_1980-1981.o1234499  | wc -l
# 2021
grep -in error /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/e3sm_diags_atm_monthly_180x360_aave_mvm_model_vs_model_1980-1981_vs_1980-1981.o1234499 | tail -n 7
# 35122:    raise IOError(
# 35125:OSError: No files found for target variable FLUT or derived variables ([('rlut',), ('LW_flux_up_at_model_top',), ('olr',)]) in /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/atm/180x360_aave/ts/daily/2yr.
# 35126:2026-06-12 00:47:41,055 [ERROR]: core_parameter.py(_run_diag:418) >> Error in e3sm_diags.driver.tropical_subseasonal_driver
# 35139:    raise IOError(
# 35142:OSError: No files found for target variable U850 or derived variables ([('U_at_850hPa',)]) in /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/atm/180x360_aave/ts/daily/2yr.
# 35144:slurmstepd: error: *** STEP 1234499.0 ON chr-0232 CANCELLED AT 2026-06-12T05:21:59 DUE TO TIME LIMIT ***
# 35145:slurmstepd: error: *** JOB 1234499 ON chr-0232 CANCELLED AT 2026-06-12T05:21:59 DUE TO TIME LIMIT ***

grep -in error /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.0.0_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/e3sm_diags_atm_monthly_180x360_aave_model_vs_obs_1982-1983.o1234561 | wc -l
# 2387
grep -in error /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.0.0_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/e3sm_diags_atm_monthly_180x360_aave_model_vs_obs_1982-1983.o1234561 | tail -n 7
# 40511:    raise IOError(
# 40514:OSError: The dataset file has no matching source variables for LWCF06_FRAC and could not be derived using [('LWCF06_FRAC',), ('LWCF06', 'LWCF'), ('FLSU06', 'FLSUCLR06', 'FLUT', 'FLUTC'), ('olr_band06', 'olr_clr_band06', 'olr', 'olr_clr')].
# 40516:2026-06-12 02:25:17,122 [ERROR]: core_parameter.py(_run_diag:418) >> Error in e3sm_diags.driver.lat_lon_driver
# 40527:    raise IOError(
# 40530:OSError: The dataset file has no matching source variables for LWCF06_FRAC and could not be derived using [('LWCF06_FRAC',), ('LWCF06', 'LWCF'), ('FLSU06', 'FLSUCLR06', 'FLUT', 'FLUTC'), ('olr_band06', 'olr_clr_band06', 'olr', 'olr_clr')].
# 41094:slurmstepd: error: *** STEP 1234561.0 ON chr-0159 CANCELLED AT 2026-06-12T06:42:29 DUE TO TIME LIMIT ***
# 41095:slurmstepd: error: *** JOB 1234561 ON chr-0159 CANCELLED AT 2026-06-12T06:42:29 DUE TO TIME LIMIT ***

mpas_analysis

post/scripts results: 3 jobs have RUNNING status, 3 jobs have WAITING status.

/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/mpas_analysis_ts_1980-1984_climo_1980-1984.status:RUNNING 1234421

/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/mpas_analysis_ts_1980-1990_climo_1985-1990.status:WAITING 1234422

/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/mpas_analysis_ts_1980-1984_climo_1980-1984.status:RUNNING 1234501

/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/mpas_analysis_ts_1980-1990_climo_1985-1990.status:WAITING 1234502

/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.0.0_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/mpas_analysis_ts_1980-1984_climo_1980-1984.status:RUNNING 1234564

/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.0.0_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/mpas_analysis_ts_1980-1990_climo_1985-1990.status:WAITING 1234565

That matches up with the 3 mpas_analysis jobs having unsatisfied dependencies:

ac.forsy    e3sm    1   compute 1234422 PD Dependency       0:00      30:00 mpas_analysis_ts_1980-1990_climo_1985-1990
ac.forsy    e3sm    1   compute 1234502 PD Dependency       0:00      30:00 mpas_analysis_ts_1980-1990_climo_1985-1990
ac.forsy    e3sm    1   compute 1234565 PD Dependency       0:00      30:00 mpas_analysis_ts_1980-1990_climo_1985-1990

Failing image checks:

Test name Total images Correct images Missing images Mismatched images
comprehensive_v2_mpas_analysis 856 0 856 (list) 0
comprehensive_v3_mpas_analysis 1280 568 0 712 (list, grid)
legacy_3.1.0_comprehensive_v2_mpas_analysis 856 0 856 (list) 0
legacy_3.0.0_comprehensive_v2_mpas_analysis 856 0 856 (list) 0
legacy_3.0.0_comprehensive_v3_mpas_analysis 856 379 0 477 (list, grid)

The 3 missing-images rows make sense based on the 3 E3SMv2 mpas_analysis jobs couldn't run (because of the earlier 3 failed mpas_analysis jobs).

The 2 mismatched-images rows look to be actual changes based on recent PRs (i.e., we should probably update the expected results)

Debugging:

grep -in error /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/mpas_analysis_ts_1980-1984_climo_1980-1984.o1234421
# 71:srun: error: chr-0232: task 0: Segmentation fault
# 73:slurmstepd: error: *** STEP 1234421.0 ON chr-0232 CANCELLED AT 2026-06-11T14:44:50 DUE TO TIME LIMIT ***
# 74:slurmstepd: error: *** JOB 1234421 ON chr-0232 CANCELLED AT 2026-06-11T14:44:50 DUE TO TIME LIMIT ***

grep -in error /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/mpas_analysis_ts_1980-1984_climo_1980-1984.o1234501 
# 80:srun: error: chr-0232: task 0: Segmentation fault
# 82:slurmstepd: error: *** STEP 1234501.0 ON chr-0232 CANCELLED AT 2026-06-11T16:09:50 DUE TO TIME LIMIT ***
# 83:slurmstepd: error: *** JOB 1234501 ON chr-0232 CANCELLED AT 2026-06-11T16:09:50 DUE TO TIME LIMIT ***

grep -in error /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.0.0_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/mpas_analysis_ts_1980-1984_climo_1980-1984.o1234564 
# 71:srun: error: chr-0232: task 0: Segmentation fault
# 73:slurmstepd: error: *** STEP 1234564.0 ON chr-0232 CANCELLED AT 2026-06-11T16:59:50 DUE TO TIME LIMIT ***
# 74:slurmstepd: error: *** JOB 1234564 ON chr-0232 CANCELLED AT 2026-06-11T16:59:50 DUE TO TIME LIMIT ***

So, we're still encountering the segfault issue we were seeing when we first tried automating the script ~6 months ago.

global_time_series

post/scripts results: 3 jobs have WAITING status.

/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/global_time_series_1980-1990.status:WAITING 1234423

/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/global_time_series_1980-1990.status:WAITING 1234503

/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.0.0_comprehensive_v2_output/zppy_main_branch_test_20260611_run5/v2.LR.historical_0201/post/scripts/global_time_series_1980-1990.status:WAITING 1234566

That matches up with the 3 global_time_series jobs having unsatisfied dependencies:

ac.forsy    e3sm    1     debug 1234423 PD Dependency       0:00      30:00 global_time_series_1980-1990
ac.forsy    e3sm    1     debug 1234503 PD Dependency       0:00      30:00 global_time_series_1980-1990
ac.forsy    e3sm    1     debug 1234566 PD Dependency       0:00      30:00 global_time_series_1980-1990

Failing image checks:

Test name Total images Correct images Missing images Mismatched images
comprehensive_v2_global_time_series 12 0 12 (list) 0
legacy_3.1.0_comprehensive_v2_global_time_series 12 0 12 (list) 0
legacy_3.0.0_comprehensive_v2_global_time_series 12 0 12 (list) 0

It makes sense the images are missing, since the 3 E3SMv2 global_time_series jobs couldn't run (because of the unsatisified mpas_analysis dependencies).

pcmdi_diags

Failing image checks:

Test name Total images Correct images Missing images Mismatched images
comprehensive_v3_pcmdi_diags 647 493 0 154 (list, grid)

These look to be actual changes based on recent PRs (i.e., we should probably update the expected results)

@forsyth2

Copy link
Copy Markdown
Collaborator Author

Hi @xylar -- I'm having a lot of difficulty debugging a segfault in mpas_analysis and I appear to have even stumped the AI. Can you take a look at the following and see if anything is obviously wrong to you? Thanks!

This segfault only ever occurs when I try to automate the integration testing process. I don't think I've ever seen it when I've run the test manually. That leads me to believe it's an environment setup issue.

Manual tests

I documented the manual testing process I used throughout the Spring Unified testing period on the new docs of #839 (latest rendering here).

Initial attempt at automation

This segfault first showed up when I first started this automation PR in January. (See above comment's "MPAS Analysis errors" section).

Latest attempt at automation

This segfault hasn't gone away despite making the test script match my manual process as much as possible. I even have it using bash subshells now for more environment isolation.

Output from automated test script

cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v2_output/zppy_main_branch_test_20260615_run6/v2.LR.historical_0201/post/scripts
grep -v "OK" *status
# mpas_analysis_ts_1980-1984_climo_1980-1984.status:RUNNING 1236065
# mpas_analysis_ts_1980-1990_climo_1985-1990.status:WAITING 1236066

# The first job says RUNNING, but that's because it hit the time limit before it could update the status file.

tail mpas_analysis_ts_1980-1984_climo_1980-1984.o1236065

gives:

   Line Type: cartesian
   Norm Type: dstarea
   Extrap. Method: none

srun: error: chr-0223: task 0: Segmentation fault
slurmstepd: error: *** STEP 1236065.0 ON chr-0223 CANCELLED AT 2026-06-15T19:27:21 DUE TO TIME LIMIT ***
srun: Job step aborted: Waiting up to 92 seconds for job step to finish.
slurmstepd: error: *** JOB 1236065 ON chr-0223 CANCELLED AT 2026-06-15T19:27:21 DUE TO TIME LIMIT ***
srun: got SIGCONT
srun: forcing job termination

So, the segfault is still occurring on my latest automation attempt. It's also important to note that the segfault occurs ~10-15 minutes before the time limit hits, so the script is just hanging after the segfault.

Output from manual sbatch run

sbatch mpas_analysis_ts_1980-1984_climo_1980-1984.bash
tail -f mpas_analysis_ts_1980-1984_climo_1980-1984.o1236067

cat mpas_analysis_ts_1980-1984_climo_1980-1984.status
# OK

This works!

Output from manual zppy run

# Remove status file so zppy will rerun this job:
rm mpas_analysis_ts_1980-1984_climo_1980-1984.status

cd /lcrc/group/e3sm/ac.forsyth2/zppy_main_branch_test_dirs/zppy/
lcrc_conda
conda activate env_the_script_used
zppy -c tests/integration/generated/test_weekly_legacy_3.1.0_comprehensive_v2_chrysalis.cfg
sq
# USER     ACCOUNT NODE PARTITION JOBID   ST     REASON       TIME TIME_LIMIT NAME
# ac.forsy    e3sm    1   compute 1236069 PD   Priority       0:00      30:00 mpas_analysis_ts_1980-1984_climo_1980-1984
cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v2_output/zppy_main_branch_test_20260615_run6/v2.LR.historical_0201/post/scripts
tail -f mpas_analysis_ts_1980-1984_climo_1980-1984.o1236069

cat mpas_analysis_ts_1980-1984_climo_1980-1984.status
# OK

This works!

@xylar

xylar commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

@forsyth2, I'm on vacation for 2 weeks. I can take a look when I get back on the 29th.

@forsyth2

Copy link
Copy Markdown
Collaborator Author

Ok thanks @xylar!

@xylar

xylar commented Jun 16, 2026

Copy link
Copy Markdown
Collaborator

At a glance, the information you posted doesn't give me any useful clues about what's wrong. I'd have to reproduce the problem and debug myself.

Copilot AI left a comment

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.

⚠️ Not ready to approve

The legacy 3.1.0 bundles template contains invalid/misapplied expansion lines and the automation script currently masks failures (status/pytest), which can cause false “success” runs.

Pull request overview

This PR adds a repeatable, phase-based automation workflow under tests/main_branch_testing/ to orchestrate the existing “main branch” integration testing process for zppy and related repos on supported HPC machines, and updates the weekly integration-test templates/utilities to support task/dependency activation via expansion flags.

Changes:

  • Add a configurable run_integration_test.bash driver (with a companion zppy_test.cfg and README) to automate environment setup, cfg generation, SLURM submission, and validation phases.
  • Extend tests/integration/utils.py with more granular “active_*” expansion flags to model dependencies between tasks.
  • Update the 9 weekly integration template cfgs to use the new expansion flags (and add missing environment settings where needed).
File summaries
File Description
tests/main_branch_testing/zppy_test.cfg Adds a sourced bash-style config for the automation script.
tests/main_branch_testing/run_integration_test.bash Adds a multi-phase automation script for running the weekly + legacy integration workflow.
tests/main_branch_testing/README.md Documents how to use/configure the automation script and phases.
tests/integration/utils.py Adds finer-grained dependency activation expansions used by weekly templates.
tests/integration/template_weekly_bundles.cfg Updates subsection activation to use new dependency expansion flags.
tests/integration/template_weekly_comprehensive_v2.cfg Updates subsection activation to use new dependency expansion flags.
tests/integration/template_weekly_comprehensive_v3.cfg Updates subsection activation to use new dependency expansion flags (incl. livvkit-specific deps).
tests/integration/template_weekly_legacy_3.1.0_bundles.cfg Updates activation flags for legacy 3.1.0 bundle workflow templates.
tests/integration/template_weekly_legacy_3.1.0_comprehensive_v2.cfg Updates activation flags and mpas_analysis env settings for legacy 3.1.0 v2 comprehensive template.
tests/integration/template_weekly_legacy_3.1.0_comprehensive_v3.cfg Updates activation flags and mpas_analysis env settings for legacy 3.1.0 v3 comprehensive template.
tests/integration/template_weekly_legacy_3.0.0_bundles.cfg Updates activation flags for legacy 3.0.0 bundle workflow templates.
tests/integration/template_weekly_legacy_3.0.0_comprehensive_v2.cfg Updates activation flags for legacy 3.0.0 v2 comprehensive template.
tests/integration/template_weekly_legacy_3.0.0_comprehensive_v3.cfg Updates activation flags for legacy 3.0.0 v3 comprehensive template.

Copilot's findings

  • Files reviewed: 13/13 changed files
  • Comments generated: 6

Note

Your feedback helps us improve the quality of this feature.
Please use 👍 or 👎 to tell us whether this assessment is correct.


💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.

Comment thread tests/integration/template_weekly_legacy_3.1.0_bundles.cfg Outdated
Comment thread tests/integration/template_weekly_legacy_3.1.0_bundles.cfg Outdated
Comment thread tests/main_branch_testing/run_integration_test.bash
Comment thread tests/main_branch_testing/run_integration_test.bash Outdated
Comment thread tests/main_branch_testing/run_integration_test.bash Outdated
Comment thread tests/main_branch_testing/run_integration_test.bash
@forsyth2

Copy link
Copy Markdown
Collaborator Author

This segfault only ever occurs when I try to automate the integration testing process. I don't think I've ever seen it when I've run the test manually.

Just to confirm for sure, I did a manual run and indeed it completed successfully, so it really does only happen when trying to run the automated script.

Manual Run

Following the testing documentation here:

# Step 3: Set up environments for called packages
bash
source ~/.bashrc
cd ~/ez/MPAS-Analysis
git status
# On branch test_mpas_20260615_run4
# nothing to commit, working tree clean
git fetch upstream develop # This assumes you've named your remote for the main repo as "upstream"
git checkout develop
git reset --hard upstream/develop
git log --oneline | head -n 1
# 22956fd31 Merge pull request #1150 from MPAS-Dev/dependabot/github_actions/prefix-dev/setup-pixi-0.9.6
# Good, matches https://github.com/MPAS-Dev/MPAS-Analysis/commits/develop/
lcrc_conda # Function to activate conda
rm -rf build
conda clean --all --y
conda create --name mpas-analysis-develop-20260616 --file dev-spec.txt --yes
conda activate mpas-analysis-develop-20260616
python -m pip install .
exit # Exit bash subshell

# Step 4: Set up zppy environment
cd ~/ez/zppy
git status
git fetch upstream automate-main-branch-testing
git checkout -b zppy-automate-main-branch-testing-20260616 upstream/automate-main-branch-testing
git log --oneline | head -n 1
# 69f8212d Address comments
# Good, matches https://github.com/E3SM-Project/zppy/pull/774/commits
lcrc_conda # Function to activate conda
rm -rf build
conda clean --all --y 
conda env create -f conda/dev.yml -n zppy-automate-main-branch-testing-20260616
conda activate zppy-automate-main-branch-testing-20260616
pre-commit run --all-files # Confirm this passes
conda list python # 3.14.6

# Step 5: Launch zppy jobs
emacs tests/integration/utils.py
TEST_SPECIFICS: Dict[str, Any] = {
    # This is the NCO path.
    # Keep as "" to use the production-version NCO commands.
    # Set to a specific path to use development-version NCO commands.
    "nco_path": "",
    # These are custom environment_commands for specific tasks.
    # Never set these to "", because they will print the line
    # `environment_commands = ""` for the corresponding task,
    # thus overriding the value set higher up in the cfg.
    # That is, there will be no environment set.
    # (`environment_commands = ""` only redirects to Unified
    # if specified under the [default] task)
    "e3sm_to_cmip_environment_commands": "source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh",
    "diags_environment_commands": "source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh",
    "mpas_analysis_environment_commands": "source /gpfs/fs1/home/ac.forsyth2/miniforge3/etc/profile.d/conda.sh; conda activate mpas-analysis-develop-20260616",
    "global_time_series_environment_commands": "source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh",
    "livvkit_environment_commands": "source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh",
    "pcmdi_diags_environment_commands": "source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh",
    # This is the environment setup for other tasks.
    # Leave as "" to use the latest Unified environment.
    "environment_commands": "source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh",
    # For a complete test, run the set of latest cfgs and at least one set of legacy cfgs
    "cfgs_to_run": [
        # "weekly_bundles",
        # "weekly_comprehensive_v2",
        # "weekly_comprehensive_v3",
        # "weekly_legacy_3.1.0_bundles",
        "weekly_legacy_3.1.0_comprehensive_v2",
        # "weekly_legacy_3.1.0_comprehensive_v3",
        # "weekly_legacy_3.0.0_bundles",
        # "weekly_legacy_3.0.0_comprehensive_v2",
        # "weekly_legacy_3.0.0_comprehensive_v3",
    ],
    "tasks_to_run": [
        # "e3sm_diags",
        "mpas_analysis",
        # "global_time_series",
        # "ilamb",
        # "livvkit",
        # "pcmdi_diags",
    ],
    "unique_id": "test_mpas_analysis_manual",
}
git diff # Check that the diff looks as you expect
python tests/integration/utils.py
# CFG FILES HAVE BEEN GENERATED FROM TEMPLATES WITH THESE SETTINGS:
# UNIQUE_ID=test_mpas_analysis_manual
# nco_path=
# Reminder: `nco_path=''` => the production-version NCO commands will be used
# e3sm_to_cmip_environment_commands=source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh
# diags_environment_commands=source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh
# mpas_analysis_environment_commands=source /gpfs/fs1/home/ac.forsyth2/miniforge3/etc/profile.d/conda.sh; conda activate mpas-analysis-develop-20260616
# global_time_series_environment_commands=source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh
# livvkit_environment_commands=source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh
# pcmdi_diags_environment_commands=source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh
# environment_commands=source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh
# Reminder: `environment_commands=''` => the latest E3SM Unified environment will be used

sq
python -m pip install .
zppy -c tests/integration/generated/test_weekly_legacy_3.1.0_comprehensive_v2_chrysalis.cfg
sq
# USER     ACCOUNT NODE PARTITION JOBID   ST     REASON       TIME TIME_LIMIT NAME
# ac.forsy    e3sm    1   compute 1236588 PD   Priority       0:00      30:00 mpas_analysis_ts_1980-1984_climo_1980-1984
# ac.forsy    e3sm    1   compute 1236589 PD Dependency       0:00      30:00 mpas_analysis_ts_1980-1990_climo_1985-199

cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v2_output/test_mpas_analysis_manual/v2.LR.historical_0201/post/scripts
tail -f mpas_analysis_ts_1980-1984_climo_1980-1984.o1236588

sq
# USER     ACCOUNT NODE PARTITION JOBID   ST     REASON       TIME TIME_LIMIT NAME
# ac.forsy    e3sm    1   compute 1236589 PD Dependency       0:00      30:00 mpas_analysis_ts_1980-1990_climo_1985-1990
# ac.forsy    e3sm    1   compute 1236588 CG       None      14:30      30:00 mpas_analysis_ts_1980-1984_climo_1980-1984

# It completes successfully, well before hitting the walltime!

sq
# USER     ACCOUNT NODE PARTITION JOBID   ST     REASON       TIME TIME_LIMIT NAME
# ac.forsy    e3sm    1   compute 1236589  R       None       0:26      30:00 mpas_analysis_ts_1980-1990_climo_1985-1990
cat mpas_analysis_ts_1980-1984_climo_1980-1984.o1236588

@xylar

xylar commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator

@forsyth2, sorry I haven't had time to look at this. I'm not sure if I'll get to it before I travel again on Monday.

MPAS-Analysis doesn't use esmpy, so there shouldn't be any need to install it.

@forsyth2

forsyth2 commented Jul 1, 2026

Copy link
Copy Markdown
Collaborator Author

@xylar That's ok, thanks though!

MPAS-Analysis doesn't use esmpy, so there shouldn't be any need to install it.

Indeed, trying to add it causes a LibMambaUnsatisfiableError.

@xylar

xylar commented Jul 3, 2026

Copy link
Copy Markdown
Collaborator

@forsyth2, when you're back, could you provide me with a smaller reproducer of the issue? I'm not that familiar with this workflow.

@forsyth2

Copy link
Copy Markdown
Collaborator Author

Recap of what's going wrong

I've updated the official zppy documentation to include my manual testing process. That manual testing process works totally fine. (Note: I did notice that that doc page needs to have its mpas-analysis conda environment creation command updated). It covers what I did all throughout E3SM Unified testing in the Spring.

Trying to automate it, as in this PR, keeps causing a segfault in MPAS-Analysis. This has been a persistent issue, first appearing when I first attempted this test automation in January. After many many debugging iterations with multiple AI chat interfaces, I'm at a complete loss as to why this happens.

I suspect it must have something to do with the environment setup in the script versus when I do it manually. Another theory is that maybe the automated script is launching things so much faster than a human would manually that it's causing issues.

Steps to reproduce

could you provide me with a smaller reproducer of the issue?

@xylar I've tried to trim down the full test script to the bare minimum to reproduce the issue here. I apologize that is is still rather long. I didn't have much luck with Claude in trying to make it any more concise.

Instructions

# Edit paths/parameters in these instructions and the bash/cfg provided below to match your workspace.

# I recommend creating scratch copies of the repos since the script changes branches.
# Alternatively, just make sure you don't have uncommitted changes in either the MPAS-Analysis or zppy repos.
# (In any case, the function ensure_test_branch in the script should check this.)

# Use scratch copies of the repos to avoid interference:
cd /lcrc/group/e3sm/ac.forsyth2/zppy_main_branch_test_dirs/MPAS-Analysis && git status
# Good -- nothing to commit, working tree clean
cd /lcrc/group/e3sm/ac.forsyth2/zppy_main_branch_test_dirs/zppy && git status
# Good -- nothing to commit, working tree clean

squeue -u $USER # Good -- No jobs queued (Not required, just makes it easier to track jobs)

WORK_DIR=~/ez/zppy_main_branch_tests/debug_mpas2 # Whatever you want; this is just what I used most recently
cd ${WORK_DIR}
# Copy the bash/cfg provided below into this dir
head -n 18 debug_mpas_analysis.bash # Check the date stamp and run number are what you expect:
# DATE_STAMP="20260721"
# RUN_NUMBER=1

screen
cd ${WORK_DIR}
head -n 18 debug_mpas_analysis.bash # Good, matches previous look
time ./debug_mpas_analysis.bash 2>&1 | tee debug_mpas_20260721_run1.log
# Ctrl-A D to detach from screen
tail -f debug_mpas_20260721_run1.log
# Takes about ~25-30 minutes, so you might not even want to bother with using `screen`
# Segfault usually appears 5-15 minutes after the mpas-analysis job launches (well before the time limit hits)

Bash file

debug_mpas_analysis.bash:

#!/bin/bash
# zppy Integration Test Automation Script
#
# Usage: Run `./debug_mpas_analysis.bash` (outside of the zppy repo)

# This script is a reduced version of `run_integration_test.bash`

set -e  # Exit on error
set -u  # Exit on undefined variable

# Change accordingly when running this debugging script #######################
# Function to activate conda:
CONDA_ACTIVATION_CMD="lcrc_conda" # Defined in my .bashrc
CONDA_PROFILE="$HOME/miniforge3/etc/profile.d/conda.sh"
# Dir where you have a zppy repo & a mpas-analysis repo: 
EZ_DIR=/lcrc/group/e3sm/ac.forsyth2/zppy_main_branch_test_dirs/ 
DATE_STAMP="20260721"
RUN_NUMBER=1

# Constants ###################################################################
TAG="${DATE_STAMP}_run${RUN_NUMBER}"
UNIQUE_ID="zppy_main_branch_test_${TAG}"
SCRIPT_RUN_DIR="$PWD"
CFG_PATH="${SCRIPT_RUN_DIR}/debug_mpas_analysis.cfg"
UNIFIED_ENV_CMD="source /lcrc/soft/climate/e3sm-unified/load_latest_e3sm_unified_chrysalis.sh"

MPAS_ANALYSIS_DIR="$EZ_DIR/MPAS-Analysis"
MPAS_BASE_BRANCH="develop"
MPAS_ENV="test-mpas-${MPAS_BASE_BRANCH}-${TAG}"

ZPPY_DIR="$EZ_DIR/zppy"
ZPPY_BASE_BRANCH="main"
ZPPY_ENV="test-zppy-${ZPPY_BASE_BRANCH}-${TAG}"

# Colors for output
BLUE='\033[0;34m'
NC='\033[0m' # No Color

# Functions ###################################################################
log() {
    echo -e "${BLUE}[$(date +'%Y-%m-%d %H:%M:%S')]${NC} $*"
}

# Checkout test branch, creating it from upstream/<base> if it doesn't exist.
# Stashes/commits any in-progress work first.
ensure_test_branch() {
    local test_branch="$1"
    local base_branch="$2"
    local current_branch
    current_branch=$(git rev-parse --abbrev-ref HEAD 2>/dev/null)

    if [ "$current_branch" = "$test_branch" ]; then
        log "Already on branch '$test_branch'"
        return 0
    fi

    log "Saving current work before switching branches..."
    git add -A
    git commit -m "Auto-save before test" --no-verify || true

    if git show-ref --verify --quiet "refs/heads/$test_branch"; then
        log "Checking out existing branch '$test_branch'..."
        git checkout "$test_branch"
    else
        log "Creating new branch '$test_branch' from upstream/${base_branch}..."
        git fetch upstream "${base_branch}"
        git checkout -b "$test_branch" "upstream/${base_branch}"
    fi
    log "On branch '$test_branch'"
}

# Activate conda and (optionally) a named environment.
activate_env() {
    local env_name="${1:-}"
    set +u
    # shellcheck disable=SC1090
    source ~/.bashrc
    $CONDA_ACTIVATION_CMD  # Machine-specific conda init

    if [ -n "$env_name" ]; then
        conda activate "$env_name"
        log "Installing/updating package in '$env_name'..."
        python -m pip install .
    fi
    set -u
}

# `main` ######################################################################

log "TAG:          $TAG"
log "Unique ID:   $UNIQUE_ID"
log "Setting up MPAS-Analysis..."

(
    cd "$MPAS_ANALYSIS_DIR"
    ensure_test_branch "test_mpas_${TAG}" "$MPAS_BASE_BRANCH"

    log "Latest MPAS-Analysis commit (should match https://github.com/MPAS-Dev/MPAS-Analysis/commits/${MPAS_BASE_BRANCH}):"
    git log -1 --oneline
    activate_env  # Ensure conda itself is available
    rm -rf build
    conda clean --all --yes
    conda create --name "$MPAS_ENV" --file dev-spec.txt --yes
    activate_env "$MPAS_ENV"
)

log "Setting up zppy..."

(
    cd "$ZPPY_DIR"
    ensure_test_branch "test_zppy_${TAG}" "$ZPPY_BASE_BRANCH"

    log "Latest zppy commit (should match https://github.com/E3SM-Project/zppy/commits/${ZPPY_BASE_BRANCH}):"
    git log -1 --oneline
    activate_env  # Ensure conda itself is available
    rm -rf build
    conda clean --all --yes
    conda env create -f "conda/dev.yml" -n "$ZPPY_ENV"
    activate_env "$ZPPY_ENV"
)

cd "$ZPPY_DIR"
activate_env "$ZPPY_ENV"
ensure_test_branch "test_zppy_${TAG}" "$ZPPY_BASE_BRANCH"

log "Submitting SLURM jobs for: $CFG_PATH"
zppy -c "$CFG_PATH"

job_count=$(squeue -u "${USER}" | wc -l)
job_count=$((job_count - 1))
log "Submitted jobs. Current queue depth: $job_count"
log "Once MPAS-Analysis job runs for ~10 minutes, run:"
log "cd /lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v2_output/${UNIQUE_ID}/v2.LR.historical_0201/post/scripts/"
log 'grep -v "OK" *status'
log "There should be no matches. If there are, look at the matching .o file."

Cfg

debug_mpas_analysis.cfg:

[default]
case = "v2.LR.historical_0201"
fail_on_dependency_skip = True
input = /lcrc/group/e3sm/ac.forsyth2/E3SMv2/v2.LR.historical_0201
input_subdir = archive/atm/hist
mapping_file = "map_ne30pg2_to_cmip6_180x360_aave.20200201.nc"
nco_path = ""
output = "/lcrc/group/e3sm/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v2_output/zppy_main_branch_test_20260721_run1/v2.LR.historical_0201"
www = "/lcrc/group/e3sm/public_html/diagnostic_output/ac.forsyth2/zppy_weekly_legacy_3.1.0_comprehensive_v2_www/zppy_main_branch_test_20260721_run1"
years = "1980:1984:2",

[mpas_analysis]
active = True
anomalyRefYear = 1980
climo_years ="1980-1984", "1985-1990",
enso_years = "1980-1984", "1985-1990",
environment_commands = "source $HOME/miniforge3/etc/profile.d/conda.sh; conda activate test-mpas-develop-20260721_run1"
mesh = "EC30to60E2r2"
parallelTaskCount = 6
partition = "compute"
qos = "regular"
shortTermArchive = True
ts_years = "1980-1984", "1980-1990",
walltime = "00:30:00"

@xylar

xylar commented Jul 21, 2026

Copy link
Copy Markdown
Collaborator

@forsyth2, thanks! That's concise enough for me to be able to work with it. I'll keep you posted.

@forsyth2

Copy link
Copy Markdown
Collaborator Author

Thanks Xylar!!

@xylar

xylar commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

@forsyth2, I adapted the script to my own paths and ran it. The whole deal is in:

/lcrc/group/e3sm/ac.xylar/zppy-debug

Creating the conda environments took a long time but everything ran without a hitch for me. The second zppy job is still finishing up but there's no sign of trouble.

I will try a few more runs since you indicated that it might be an intermittent problem.

@xylar

xylar commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

@forsyth2, I have run my version of the reproducer 3 times without reproducing the problem. Do you have further suggestions on what I can do to see it?

@xylar

xylar commented Jul 23, 2026

Copy link
Copy Markdown
Collaborator

One question, do you run the debug bash script itself on a login or a compute node? I was running on a login node.

@forsyth2

Copy link
Copy Markdown
Collaborator Author

@xylar Thanks for debugging!

it might be an intermittent problem.
I have run my version of the reproducer 3 times without reproducing the problem

Hmm, this is confusing me even more. It actually hasn't been intermittent for me. It always works manually and always fails when I try to automate it.

do you run the debug bash script itself on a login or a compute node? I was running on a login node.

I run from a login node. I typically always launch zppy from a login node. Then it takes care of launching jobs on compute nodes.

I'll take a look at /lcrc/group/e3sm/ac.xylar/zppy-debug and see if there's any obvious differences in setup between our runs.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

semver: small improvement Small improvement (will increment patch version) Testing Files in `tests` modified

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Further automate tests

3 participants