Skip to content

Conversation

@TerrenceMcGuinness-NOAA
Copy link
Collaborator

Pull Request: Add C48_ATM CTests for Rocoto Job Validation

Summary

This PR extends the Global Workflow CTest framework with new atmospheric (C48_ATM) test cases for validating individual Rocoto jobs. The tests leverage Rocoto's new --dryrun mode to extract job submission commands without spawning actual workflow daemons, enabling isolated job-level testing in CI/CD pipelines.

New Test Cases

Test Name Job Description
C48_ATM-gfs_stage_ic JGFS_ATMOS_STAGE_IC Validate initial condition staging from ICSDIR to COMROOT
C48_ATM-gfs_tracker JGFS_ATMOS_CYCLONE_TRACKER Tropical cyclone tracking algorithm
C48_ATM-gfs_genesis JGFS_ATMOS_CYCLONE_GENESIS Tropical cyclone genesis detection

Rocoto Dryrun Integration (separate PR in Rocoto)

The execute phase leverages Rocoto's --dryrun mode to extract job submission commands:

# Extract job card without submitting or spawning daemons
rocotoboot --dryrun -d workflow.db -w workflow.xml -c CYCLE -t TASK 2> jobcard

# Job card is wrapped in {{...}}, extract it
sed -n '/^{{/,/^}}/p' < jobcard | sed '1d;$d' > job.sub

# Submit extracted job directly
sbatch job.sub

This approach:

  • ✅ Avoids spawning persistent Rocoto daemon processes
  • ✅ Enables job card extraction for CI/CD pipelines
  • ✅ Works with existing workflow XML configurations
  • ✅ Preserves all environment variables and job settings

Files Changed

New Test Case YAML Files

File Purpose
dev/ctests/cases/C48_ATM-gfs_stage_ic.yaml Stage IC inputs and validate output files
dev/ctests/cases/C48_ATM-gfs_genesis.yaml Genesis detector inputs (21 GRIB2 files) and vitals outputs
dev/ctests/cases/C48_ATM-gfs_tracker.yaml Tracker inputs (21 GRIB2 files) and ATCF track outputs

Updated CMakeLists.txt

Added new AddJJOBTest() calls for each C48_ATM test case:

AddJJOBTest(
  CASE "C48_ATM"
  JOB "gfs_stage_ic"
  TEST_DATE "2021032312"
)

AddJJOBTest(
  CASE "C48_ATM"
  JOB "gfs_tracker"
  TEST_DATE "2021032312"
)

AddJJOBTest(
  CASE "C48_ATM"
  JOB "gfs_genesis"
  TEST_DATE "2021032312"
)

Updated Execute Script

Enhanced execute.sh.in to:

  • Support custom ROCOTO_PATH for dryrun-enabled Rocoto builds
  • Extract job cards using --dryrun mode
  • Monitor SLURM job status with timeout handling

Platform Configuration Updates

File Changes
dev/ci/platforms/config.hera Added ROCOTO_PATH, STAGED_CTESTS settings
dev/ci/platforms/config.hercules Added ROCOTO_PATH, STAGED_CTESTS settings
dev/ci/platforms/config.orion Added ROCOTO_PATH, STAGED_CTESTS settings
dev/ci/platforms/config.wcoss2 Added ROCOTO_PATH, STAGED_CTESTS settings
dev/ci/platforms/config.gaeac6 Added ROCOTO_PATH, STAGED_CTESTS settings
dev/ci/platforms/config.ursa Added ROCOTO_PATH, STAGED_CTESTS settings

GitLab CI Integration

File Changes
.gitlab-ci.yml Added CTest include
dev/ci/gitlab-ci-ctests.yml CTest setup and execution templates
dev/ci/gitlab-ci-cases.yml CTest case label definitions

Usage

Local Execution

# Source platform configuration
source $HOMEgfs/ush/detect_machine.sh
source $HOMEgfs/dev/ci/platforms/config.$MACHINE_ID

# Build CTests
cd $HOMEgfs/dev/ctests
mkdir -p build && cd build
cmake -S "$HOMEgfs"

# List available tests
ctest -N

# Run all C48_ATM tests at once
ctest -L C48_ATM -j5 --output-on-failure

# Run specific test
ctest -L C48_ATM-gfs_genesis -VV

YAML Test Definition Format

Test cases use Jinja2 templating for flexible file path generation:

{% set cyc = TEST_DATE | strftime('%H') %}
{% set PDY = TEST_DATE | to_YMD %}
{% set SRC_DIR = STAGED_CTESTS + '/COMROOT/' + PSLOT %}
{% set DST_DIR = RUNTESTS + '/COMROOT/' + TEST_NAME %}

input_files:
    mkdir:
        - {{ DST_GRIB_DIR }}
    copy:
        - [{{ SRC_GRIB_DIR }}/file.grib2, {{ DST_GRIB_DIR }}/file.grib2]

output_files:
    cmpfiles:
        - [{{ SRC_OUTPUT }}/result.txt, {{ DST_OUTPUT }}/result.txt]

How has this been tested?

Terry.McGuinness (hfe07) build (add_ctests_jobs-rocoto_update_test) $ ctest -L C48_ATM -j5
Test project /scratch3/NCEPDEV/global/Terry.McGuinness/global-workflow_forked/dev/ctests/build
      Start  1: test_C48_ATM-gfs_stage_ic_setup
      Start  5: test_C48_ATM-gfs_fcst_seg0_setup
      Start  9: test_C48_ATM-gfs_atmos_prod_f000-f002_setup
      Start 13: test_C48_ATM-gfs_tracker_setup
      Start 17: test_C48_ATM-gfs_genesis_setup
 1/20 Test #17: test_C48_ATM-gfs_genesis_setup ...................   Passed    4.56 sec
      Start 18: test_C48_ATM-gfs_genesis_stage
 2/20 Test  #9: test_C48_ATM-gfs_atmos_prod_f000-f002_setup ......   Passed    4.57 sec
      Start 10: test_C48_ATM-gfs_atmos_prod_f000-f002_stage
 3/20 Test  #5: test_C48_ATM-gfs_fcst_seg0_setup .................   Passed    4.57 sec
      Start  6: test_C48_ATM-gfs_fcst_seg0_stage
 4/20 Test  #1: test_C48_ATM-gfs_stage_ic_setup ..................   Passed    4.58 sec
      Start  2: test_C48_ATM-gfs_stage_ic_stage
 5/20 Test #13: test_C48_ATM-gfs_tracker_setup ...................   Passed    4.58 sec
      Start 14: test_C48_ATM-gfs_tracker_stage
 6/20 Test  #2: test_C48_ATM-gfs_stage_ic_stage ..................   Passed    2.63 sec
      Start  3: test_C48_ATM-gfs_stage_ic_execute
 7/20 Test #10: test_C48_ATM-gfs_atmos_prod_f000-f002_stage ......   Passed    2.77 sec
      Start 11: test_C48_ATM-gfs_atmos_prod_f000-f002_execute
 8/20 Test  #6: test_C48_ATM-gfs_fcst_seg0_stage .................   Passed    4.00 sec
      Start  7: test_C48_ATM-gfs_fcst_seg0_execute
 9/20 Test #18: test_C48_ATM-gfs_genesis_stage ...................   Passed   10.40 sec
      Start 19: test_C48_ATM-gfs_genesis_execute
10/20 Test #14: test_C48_ATM-gfs_tracker_stage ...................   Passed   10.38 sec
      Start 15: test_C48_ATM-gfs_tracker_execute
11/20 Test  #3: test_C48_ATM-gfs_stage_ic_execute ................   Passed   62.11 sec
      Start  4: test_C48_ATM-gfs_stage_ic_validate
12/20 Test  #4: test_C48_ATM-gfs_stage_ic_validate ...............   Passed    1.41 sec
13/20 Test #15: test_C48_ATM-gfs_tracker_execute .................   Passed  121.53 sec
      Start 16: test_C48_ATM-gfs_tracker_validate
14/20 Test #16: test_C48_ATM-gfs_tracker_validate ................   Passed    1.35 sec
15/20 Test #11: test_C48_ATM-gfs_atmos_prod_f000-f002_execute ....   Passed  302.06 sec
      Start 12: test_C48_ATM-gfs_atmos_prod_f000-f002_validate
16/20 Test #12: test_C48_ATM-gfs_atmos_prod_f000-f002_validate ...   Passed    2.61 sec
17/20 Test #19: test_C48_ATM-gfs_genesis_execute .................   Passed  541.81 sec
      Start 20: test_C48_ATM-gfs_genesis_validate
18/20 Test #20: test_C48_ATM-gfs_genesis_validate ................   Passed    1.31 sec
19/20 Test  #7: test_C48_ATM-gfs_fcst_seg0_execute ...............   Passed  1562.10 sec
      Start  8: test_C48_ATM-gfs_fcst_seg0_validate
20/20 Test  #8: test_C48_ATM-gfs_fcst_seg0_validate ..............   Passed    1.68 sec

100% tests passed, 0 tests failed out of 20

Label Time Summary:
C48_ATM-gfs_atmos_prod_f000-f002    = 312.01 sec*proc (4 tests)
C48_ATM-gfs_fcst_seg0               = 1572.35 sec*proc (4 tests)
C48_ATM-gfs_genesis                 = 558.07 sec*proc (4 tests)
C48_ATM-gfs_stage_ic                =  70.73 sec*proc (4 tests)
C48_ATM-gfs_tracker                 = 137.84 sec*proc (4 tests)

Total Test time (real) = 1572.37 sec
Terry.McGuinness (hfe07) build (add_ctests_jobs-rocoto_update_test) $ 

Dependencies

Rocoto Dryrun Feature

This PR depends on Rocoto's --dryrun feature which is currently in development:

Checklist

  • New YAML test definitions follow framework conventions
  • CMakeLists.txt updated with new test cases
  • Execute script uses Rocoto --dryrun mode
  • Platform configurations updated with required paths
  • GitLab CI templates support CTest execution
  • README documentation updated
  • Tested on Hera with C48_ATM cases
  • Rocoto dryrun PR merged upstream (blocking for production use)

Author: Terry McGuinness (@TerrenceMcGuinness-NOAA)
Target Branch: develop
Source Branch: add_C48_ATM_CTests
Related PR: Rocoto Dryrun Feature

The gfs_tracker job expects GRIB2 input files in products/atmos/grib2/0p25, but the test case was previously staging NetCDF history files to model/atmos/history. This mismatch would cause the data_check_gfs.sh script to fail.

This commit updates the test case to stage the correct gfs.t{cyc}z.pgrb2.0p25.f* files to the expected directory, ensuring the test environment matches the job's requirements.
The gfs_genesis job expects GRIB2 input files in products/atmos/grib2/0p25, but the test case was previously staging NetCDF history files to model/atmos/history.

Updated to stage gfs.t{cyc}z.pgrb2.0p25.f* files to the correct directory, matching the job's COM_ATMOS_GRIB_GRID_TMPL expectations.
@TerrenceMcGuinness-NOAA TerrenceMcGuinness-NOAA changed the title Add c48 atm c tests Add additional C48_ATM Rocoto Job CTests Dec 10, 2025
@TerrenceMcGuinness-NOAA TerrenceMcGuinness-NOAA added the CI/CD Issue related to CI/CD label Dec 10, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

CI/CD Issue related to CI/CD

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant