diff --git a/.github/workflows/prebuild.yaml b/.github/workflows/prebuild.yaml
index f65e6811..3ccce8fc 100644
--- a/.github/workflows/prebuild.yaml
+++ b/.github/workflows/prebuild.yaml
@@ -55,3 +55,12 @@ jobs:
cmake ..
make
./test_blocked_data.x
+ - name: ccpp-prebuild chunked data tests
+ run: |
+ cd test_prebuild/test_chunked_data
+ python3 ../../scripts/ccpp_prebuild.py --config=ccpp_prebuild_config.py --builddir=build
+ cd build
+ cmake ..
+ make
+ ./test_chunked_data.x
+
diff --git a/scripts/ccpp_prebuild.py b/scripts/ccpp_prebuild.py
index 4a66cc5e..a1623867 100755
--- a/scripts/ccpp_prebuild.py
+++ b/scripts/ccpp_prebuild.py
@@ -70,7 +70,7 @@ def import_config(configfile, builddir):
if not os.path.isfile(configfile):
logging.error("Configuration file {0} not found".format(configfile))
success = False
- return
+ return(success, config)
# Import the host-model specific CCPP prebuild config;
# split into path and module name for import
diff --git a/scripts/ccpp_track_variables.py b/scripts/ccpp_track_variables.py
index 819b8e60..60d31c1e 100755
--- a/scripts/ccpp_track_variables.py
+++ b/scripts/ccpp_track_variables.py
@@ -57,7 +57,6 @@ def parse_suite(sdf, run_env):
the ordered list of schemes for the suite specified by the provided sdf"""
run_env.logger.info(f'Reading sdf {sdf} and populating Suite object')
suite = Suite(sdf_name=sdf)
- run_env.logger.info(f'Reading sdf {sdf} and populating Suite object')
success = suite.parse(make_call_tree=True)
if not success:
raise Exception(f'Parsing suite definition file {sdf} failed.')
@@ -100,9 +99,6 @@ def create_var_graph(suite, var, config, metapath, run_env):
run_env.logger.debug(f"reading .meta files in path:\n {metapath}")
metadata_dict=create_metadata_filename_dict(metapath)
- run_env.logger.debug(f"reading metadata files for schemes defined in config file: "
- f"{config['scheme_files']}")
-
# Loop through call tree, find matching filename for scheme via dictionary schemes_in_files,
# then parse that metadata file to find variable info
partial_matches = {}
@@ -170,20 +166,29 @@ def create_var_graph(suite, var, config, metapath, run_env):
return (success,var_graph)
-def main():
+def track_variables(sdf,metadata_path,config,variable,debug):
"""Main routine that traverses a CCPP suite and outputs the list of schemes that use given
- variable, broken down by group"""
+ variable, broken down by group
- args = parse_arguments()
+ Args:
+ sdf (str) : The full path of the suite definition file to parse
+ metadata_path (str) : path to CCPP scheme metadata files
+ config (str) : path to CCPP prebuild configuration file
+ variable (str) : variable to track through CCPP suite
+ debug (bool) : Enable extra output for debugging
+
+ Returns:
+ None
+"""
- logger = setup_logging(args.debug)
+ logger = setup_logging(debug)
#Use new capgen class CCPPFrameworkEnv
run_env = CCPPFrameworkEnv(logger, host_files="", scheme_files="", suites="")
- suite = parse_suite(args.sdf,run_env)
+ suite = parse_suite(sdf,run_env)
- (success, config) = import_config(args.config, None)
+ (success, config) = import_config(config, None)
if not success:
raise Exception('Call to import_config failed.')
@@ -194,10 +199,10 @@ def main():
if not success:
raise Exception('Call to gather_variable_definitions failed.')
- (success, var_graph) = create_var_graph(suite, args.variable, config, args.metadata_path, run_env)
+ (success, var_graph) = create_var_graph(suite, variable, config, metadata_path, run_env)
if success:
print(f"For suite {suite.sdf_name}, the following schemes (in order for each group) "
- f"use the variable {args.variable}:")
+ f"use the variable {variable}:")
for group in var_graph:
if var_graph[group]:
print(f"In group {group}")
@@ -206,4 +211,7 @@ def main():
if __name__ == '__main__':
- main()
+
+ args = parse_arguments()
+
+ track_variables(args.sdf,args.metadata_path,args.config,args.variable,args.debug)
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt
index 98736432..eaa78afe 100644
--- a/src/CMakeLists.txt
+++ b/src/CMakeLists.txt
@@ -28,7 +28,7 @@ set(${PACKAGE}_LIB_DIRS
#------------------------------------------------------------------------------
# Define the executable and what to link
add_library(ccpp_framework STATIC ${SOURCES_F90})
-target_link_libraries(ccpp_framework LINK_PUBLIC ${LIBS} ${CMAKE_DL_LIBS})
+target_link_libraries(ccpp_framework PUBLIC MPI::MPI_Fortran)
set_target_properties(ccpp_framework PROPERTIES VERSION ${PROJECT_VERSION}
SOVERSION ${PROJECT_VERSION_MAJOR}
LINK_FLAGS ${CMAKE_Fortran_FLAGS})
diff --git a/test_prebuild/test_track_variables.py b/test_prebuild/test_track_variables.py
new file mode 100755
index 00000000..6f2b1963
--- /dev/null
+++ b/test_prebuild/test_track_variables.py
@@ -0,0 +1,130 @@
+#! /usr/bin/env python3
+"""
+-----------------------------------------------------------------------
+ Description: Contains unit tests for ccpp_track_variables.py script
+
+ Assumptions: Assumes user has correct environment for running ccpp_track_variables.py script.
+ This script should not be run directly, but rather invoked with pytest.
+
+ Command line arguments: none
+
+ Usage: pytest test_track_variables.py # run the unit tests
+-----------------------------------------------------------------------
+"""
+import sys
+import os
+import pytest
+
+TEST_DIR = os.path.dirname(os.path.abspath(__file__))
+SCRIPTS_DIR = os.path.abspath(os.path.join(TEST_DIR, os.pardir, "scripts"))
+SAMPLE_FILES_DIR = "test_track_variables"
+SUITE_FILE = f'{SAMPLE_FILES_DIR}/suite_TEST_SUITE.xml'
+SMALL_SUITE_FILE = f'{SAMPLE_FILES_DIR}/suite_small_suite.xml'
+CONFIG_FILE = f'{SAMPLE_FILES_DIR}/ccpp_prebuild_config.py'
+if not os.path.exists(SCRIPTS_DIR):
+ raise ImportError(f"Cannot find scripts directory {SCRIPTS_DIR}")
+
+sys.path.append(SCRIPTS_DIR)
+
+from ccpp_track_variables import track_variables
+
+def test_successful_match(capsys):
+ """Tests whether test_track_variables.py produces expected output from sample suite and
+ metadata files for a case with a successful match (user provided a variable that exists
+ within the schemes specified by the test suite)"""
+ expected_output = """For suite test_track_variables/suite_small_suite.xml, the following schemes (in order for each group) use the variable air_pressure:
+In group group1
+ scheme_1_run (intent in)
+ scheme_1_run (intent in)"""
+ track_variables(SMALL_SUITE_FILE,SAMPLE_FILES_DIR,CONFIG_FILE,'air_pressure',False)
+ streams = capsys.readouterr()
+ expected_output_list = expected_output.splitlines()
+ streams_err_list = streams.err.splitlines()
+ for (err, expected) in zip(streams_err_list, expected_output_list):
+ assert err.strip() == expected.strip()
+
+def test_successful_match_with_subcycles(capsys):
+ """Tests whether test_track_variables.py produces expected output from sample suite and
+ metadata files for a case with a successful match (user provided a variable that exists
+ within the schemes specified by the test suite). In this case, the test suite file
+ contains subcycles, so the output should reflect this."""
+
+ expected_output = """For suite test_track_variables/suite_TEST_SUITE.xml, the following schemes (in order for each group) use the variable surface_air_pressure:
+In group group1
+ scheme_3_run (intent inout)
+ scheme_3_timestep_finalize (intent inout)
+ scheme_3_timestep_finalize (intent out)
+ scheme_4_run (intent in)
+ scheme_3_run (intent inout)
+ scheme_3_timestep_finalize (intent inout)
+ scheme_3_timestep_finalize (intent out)
+ scheme_4_run (intent in)
+In group group2
+ scheme_4_run (intent in)
+ scheme_4_run (intent in)
+ scheme_4_run (intent in)"""
+ track_variables(SUITE_FILE,SAMPLE_FILES_DIR,CONFIG_FILE,'surface_air_pressure',False)
+ streams = capsys.readouterr()
+ expected_output_list = expected_output.splitlines()
+ streams_err_list = streams.err.splitlines()
+ for (err, expected) in zip(streams_err_list, expected_output_list):
+ assert err.strip() == expected.strip()
+
+
+def test_partial_match(capsys):
+ """Tests whether test_track_variables.py produces expected output from sample suite and
+ metadata files for a case with a partial match: user provided a variable that does not
+ exist in the test suite, but is a substring of one or more other variables that do
+ exist."""
+
+ expected_output = """Variable surface not found in any suites for sdf test_track_variables/suite_TEST_SUITE.xml
+
+ERROR:ccpp_track_variables:Variable surface not found in any suites for sdf test_track_variables/suite_TEST_SUITE.xml
+
+Did find partial matches that may be of interest:
+
+In scheme_2_init found variable(s) ['surface_emissivity_data_file']
+In scheme_2_run found variable(s) ['surface_roughness_length', 'surface_ground_temperature_for_radiation', 'surface_air_temperature_for_radiation', 'surface_skin_temperature_over_ice', 'baseline_surface_longwave_emissivity', 'surface_longwave_emissivity', 'surface_albedo_components', 'surface_albedo_for_diffused_shortwave_on_radiation_timestep']
+In scheme_3_init found variable(s) ['flag_for_mellor_yamada_nakanishi_niino_surface_layer_scheme']
+In scheme_3_timestep_init found variable(s) ['flag_for_mellor_yamada_nakanishi_niino_surface_layer_scheme']
+In scheme_3_run found variable(s) ['do_compute_surface_scalar_fluxes', 'do_compute_surface_diagnostics', 'surface_air_pressure', 'reference_air_pressure_normalized_by_surface_air_pressure']
+In scheme_3_timestep_finalize found variable(s) ['surface_air_pressure']
+In scheme_4_run found variable(s) ['surface_air_pressure']
+In scheme_B_run found variable(s) ['flag_nonzero_wet_surface_fraction', 'sea_surface_temperature', 'surface_skin_temperature_after_iteration_over_water']
+"""
+ track_variables(SUITE_FILE,SAMPLE_FILES_DIR,CONFIG_FILE,'surface',False)
+ streams = capsys.readouterr()
+ expected_output_list = expected_output.splitlines()
+ streams_err_list = streams.err.splitlines()
+ for (err, expected) in zip(streams_err_list, expected_output_list):
+ assert err.strip() == expected.strip()
+
+
+def test_no_match(capsys):
+ """Tests whether test_track_variables.py produces expected output from sample suite and
+ metadata files for a case with no match (user provided a variable that does not exist
+ within the schemes specified by the test suite)"""
+
+ expected_output = """Variable abc not found in any suites for sdf test_track_variables/suite_TEST_SUITE.xml
+
+ERROR:ccpp_track_variables:Variable abc not found in any suites for sdf test_track_variables/suite_TEST_SUITE.xml"""
+ track_variables(SUITE_FILE,SAMPLE_FILES_DIR,CONFIG_FILE,'abc',False)
+ streams = capsys.readouterr()
+ expected_output_list = expected_output.splitlines()
+ streams_err_list = streams.err.splitlines()
+ for (err, expected) in zip(streams_err_list, expected_output_list):
+ assert err.strip() == expected.strip()
+
+
+def test_bad_config(capsys):
+ """Tests whether test_track_variables.py fails gracefully when provided a config file that does
+ not exist."""
+ with pytest.raises(Exception) as excinfo:
+ track_variables(SUITE_FILE,SAMPLE_FILES_DIR,f'{SAMPLE_FILES_DIR}/nofile','abc',False)
+ assert str(excinfo.value) == "Call to import_config failed."
+
+
+if __name__ == "__main__":
+ print("This test file is designed to be run with pytest; can not be run directly")
+ sys.exit(1)
+
diff --git a/test_prebuild/test_track_variables/ccpp_prebuild_config.py b/test_prebuild/test_track_variables/ccpp_prebuild_config.py
new file mode 100755
index 00000000..83b20fd1
--- /dev/null
+++ b/test_prebuild/test_track_variables/ccpp_prebuild_config.py
@@ -0,0 +1,69 @@
+#!/usr/bin/env python
+
+# CCPP prebuild config for CCPP track variables tool test
+
+
+###############################################################################
+# Definitions #
+###############################################################################
+
+HOST_MODEL_IDENTIFIER = "TEST"
+
+# Add all files with metadata tables on the host model side and in CCPP,
+# relative to basedir = top-level directory of host model. This includes
+# kind and type definitions used in CCPP physics. Also add any internal
+# dependencies of these files to the list.
+VARIABLE_DEFINITION_FILES = [
+ # actual variable definition files
+ '../src/ccpp_types.F90',
+ ]
+
+# Add all physics scheme files relative to basedir
+SCHEME_FILES = [ ]
+
+# Default build dir, relative to current working directory,
+# if not specified as command-line argument
+DEFAULT_BUILD_DIR = 'build'
+
+# Auto-generated makefile/cmakefile snippets that contain all type definitions
+TYPEDEFS_MAKEFILE = '{build_dir}/CCPP_TYPEDEFS.mk'
+TYPEDEFS_CMAKEFILE = '{build_dir}/CCPP_TYPEDEFS.cmake'
+TYPEDEFS_SOURCEFILE = '{build_dir}/CCPP_TYPEDEFS.sh'
+
+# Auto-generated makefile/cmakefile snippets that contain all schemes
+SCHEMES_MAKEFILE = '{build_dir}/CCPP_SCHEMES.mk'
+SCHEMES_CMAKEFILE = '{build_dir}/CCPP_SCHEMES.cmake'
+SCHEMES_SOURCEFILE = '{build_dir}/CCPP_SCHEMES.sh'
+
+# Auto-generated makefile/cmakefile snippets that contain all caps
+CAPS_MAKEFILE = '{build_dir}/CCPP_CAPS.mk'
+CAPS_CMAKEFILE = '{build_dir}/CCPP_CAPS.cmake'
+CAPS_SOURCEFILE = '{build_dir}/CCPP_CAPS.sh'
+
+# Directory where to put all auto-generated physics caps
+CAPS_DIR = '{build_dir}'
+
+# Directory where the suite definition files are stored
+SUITES_DIR = '.'
+
+# Optional arguments - only required for schemes that use
+# optional arguments. ccpp_prebuild.py will throw an exception
+# if it encounters a scheme subroutine with optional arguments
+# if no entry is made here. Possible values are: 'all', 'none',
+# or a list of standard_names: [ 'var1', 'var3' ].
+OPTIONAL_ARGUMENTS = {}
+
+# Directory where to write static API to
+STATIC_API_DIR = '{build_dir}'
+STATIC_API_CMAKEFILE = '{build_dir}/CCPP_API.cmake'
+STATIC_API_SOURCEFILE = '{build_dir}/CCPP_API.sh'
+
+# Directory for writing HTML pages generated from metadata files
+METADATA_HTML_OUTPUT_DIR = '{build_dir}'
+
+# HTML document containing the model-defined CCPP variables
+HTML_VARTABLE_FILE = '{build_dir}/CCPP_VARIABLES_BLOCKED_DATA.html'
+
+# LaTeX document containing the provided vs requested CCPP variables
+LATEX_VARTABLE_FILE = '{build_dir}/CCPP_VARIABLES_BLOCKED_DATA.tex'
+
diff --git a/test_prebuild/test_track_variables/scheme_1.meta b/test_prebuild/test_track_variables/scheme_1.meta
new file mode 100644
index 00000000..8ee0800a
--- /dev/null
+++ b/test_prebuild/test_track_variables/scheme_1.meta
@@ -0,0 +1,25 @@
+[ccpp-table-properties]
+ name = scheme_1
+ type = scheme
+ dependencies = ../../hooks/machine.F
+
+########################################################################
+[ccpp-arg-table]
+ name = scheme_1_run
+ type = scheme
+[p_lay]
+ standard_name = air_pressure
+ long_name = mean layer pressure
+ units = Pa
+ dimensions = (horizontal_loop_extent,vertical_layer_dimension)
+ type = real
+ kind = kind_phys
+ intent = in
+[p_lev]
+ standard_name = air_pressure_at_interface
+ long_name = air pressure at model layer interfaces
+ units = Pa
+ dimensions = (horizontal_loop_extent,vertical_interface_dimension)
+ type = real
+ kind = kind_phys
+ intent = in
diff --git a/test_prebuild/test_track_variables/scheme_2.meta b/test_prebuild/test_track_variables/scheme_2.meta
new file mode 100644
index 00000000..143bc2c6
--- /dev/null
+++ b/test_prebuild/test_track_variables/scheme_2.meta
@@ -0,0 +1,87 @@
+[ccpp-table-properties]
+ name = scheme_2
+ type = scheme
+ relative_path = ../../
+ dependencies = hooks/machine.F
+
+########################################################################
+[ccpp-arg-table]
+ name = scheme_2_init
+ type = scheme
+[semis_file]
+ standard_name = surface_emissivity_data_file
+ long_name = surface emissivity data file for radiation
+ units = none
+ dimensions = ()
+ type = character
+ kind = len=26
+ intent = in
+
+########################################################################
+[ccpp-arg-table]
+ name = scheme_2_run
+ type = scheme
+[zorl]
+ standard_name = surface_roughness_length
+ long_name = surface roughness length
+ units = cm
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ intent = in
+[tsfg]
+ standard_name = surface_ground_temperature_for_radiation
+ long_name = surface ground temperature for radiation
+ units = K
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ intent = in
+[tsfa]
+ standard_name = surface_air_temperature_for_radiation
+ long_name = lowest model layer air temperature for radiation
+ units = K
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ intent = in
+[tisfc]
+ standard_name = surface_skin_temperature_over_ice
+ long_name = surface_skin_temperature_over_ice
+ units = K
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ intent = in
+[semisbase]
+ standard_name = baseline_surface_longwave_emissivity
+ long_name = baseline surface lw emissivity in fraction
+ units = frac
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ intent = inout
+[semis]
+ standard_name = surface_longwave_emissivity
+ long_name = surface lw emissivity in fraction
+ units = frac
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ intent = inout
+[sfcalb]
+ standard_name = surface_albedo_components
+ long_name = surface albedo IR/UV/VIS components
+ units = frac
+ dimensions = (horizontal_loop_extent,number_of_components_for_surface_albedo)
+ type = real
+ kind = kind_phys
+ intent = inout
+[sfc_alb_dif]
+ standard_name = surface_albedo_for_diffused_shortwave_on_radiation_timestep
+ long_name = mean surface diffused sw albedo
+ units = frac
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ intent = inout
diff --git a/test_prebuild/test_track_variables/scheme_3.meta b/test_prebuild/test_track_variables/scheme_3.meta
new file mode 100644
index 00000000..eb1fe80b
--- /dev/null
+++ b/test_prebuild/test_track_variables/scheme_3.meta
@@ -0,0 +1,143 @@
+[ccpp-table-properties]
+ name = scheme_3
+ type = scheme
+ dependencies = ../../hooks/machine.F,../../hooks/physcons.F90,module_sf_mynn.F90
+########################################################################
+[ccpp-arg-table]
+ name = scheme_3_init
+ type = scheme
+[do_mynnsfclay]
+ standard_name = flag_for_mellor_yamada_nakanishi_niino_surface_layer_scheme
+ long_name = flag to activate MYNN surface layer
+ units = flag
+ dimensions = ()
+ type = logical
+ intent = in
+[errmsg]
+ standard_name = ccpp_error_message
+ long_name = error message for error handling in CCPP
+ units = none
+ dimensions = ()
+ type = character
+ kind = len=*
+ intent = out
+[errflg]
+ standard_name = ccpp_error_code
+ long_name = error code for error handling in CCPP
+ units = 1
+ dimensions = ()
+ type = integer
+ intent = out
+
+########################################################################
+[ccpp-arg-table]
+ name = scheme_3_timestep_init
+ type = scheme
+[do_mynnsfclay]
+ standard_name = flag_for_mellor_yamada_nakanishi_niino_surface_layer_scheme
+ long_name = flag to activate MYNN surface layer
+ units = flag
+ dimensions = ()
+ type = logical
+ intent = in
+[errmsg]
+ standard_name = ccpp_error_message
+ long_name = error message for error handling in CCPP
+ units = none
+ dimensions = ()
+ type = character
+ kind = len=*
+ intent = out
+[errflg]
+ standard_name = ccpp_error_code
+ long_name = error code for error handling in CCPP
+ units = 1
+ dimensions = ()
+ type = integer
+ intent = out
+
+########################################################################
+[ccpp-arg-table]
+ name = scheme_3_run
+ type = scheme
+[sfclay_compute_flux]
+ standard_name = do_compute_surface_scalar_fluxes
+ long_name = flag for computing surface scalar fluxes in mynnsfclay
+ units = flag
+ dimensions = ()
+ type = logical
+ intent = in
+[sfclay_compute_diag]
+ standard_name = do_compute_surface_diagnostics
+ long_name = flag for computing surface diagnostics in mynnsfclay
+ units = flag
+ dimensions = ()
+ type = logical
+ intent = in
+[prsl]
+ standard_name = air_pressure
+ long_name = mean layer pressure
+ units = Pa
+ dimensions = (horizontal_loop_extent,vertical_layer_dimension)
+ type = real
+ kind = kind_phys
+ intent = inout
+[ps]
+ standard_name = surface_air_pressure
+ long_name = surface pressure
+ units = Pa
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ intent = inout
+[pr_ps]
+ standard_name = reference_air_pressure_normalized_by_surface_air_pressure
+ long_name = reference pressure normalized by surface pressure
+ units = cm
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ intent = out
+
+########################################################################
+[ccpp-arg-table]
+ name = scheme_3_timestep_finalize
+ type = scheme
+[prsl]
+ standard_name = air_pressure
+ long_name = mean layer pressure
+ units = Pa
+ dimensions = (horizontal_loop_extent,vertical_layer_dimension)
+ type = real
+ kind = kind_phys
+ intent = out
+[ps]
+ standard_name = surface_air_pressure
+ long_name = surface pressure
+ units = Pa
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ intent = inout
+
+########################################################################
+[ccpp-arg-table]
+ name = scheme_3_timestep_finalize
+ type = scheme
+[prsl]
+ standard_name = air_pressure
+ long_name = mean layer pressure
+ units = Pa
+ dimensions = (horizontal_loop_extent,vertical_layer_dimension)
+ type = real
+ kind = kind_phys
+ intent = out
+[ps]
+ standard_name = surface_air_pressure
+ long_name = surface pressure
+ units = Pa
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ intent = out
+
diff --git a/test_prebuild/test_track_variables/scheme_4.meta b/test_prebuild/test_track_variables/scheme_4.meta
new file mode 100644
index 00000000..5464693b
--- /dev/null
+++ b/test_prebuild/test_track_variables/scheme_4.meta
@@ -0,0 +1,31 @@
+[ccpp-table-properties]
+ name = scheme_4
+ type = scheme
+
+########################################################################
+[ccpp-arg-table]
+ name = scheme_4_run
+ type = scheme
+[ps]
+ standard_name = surface_air_pressure
+ long_name = surface pressure
+ units = Pa
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ intent = in
+[errmsg]
+ standard_name = ccpp_error_message
+ long_name = error message for error handling in CCPP
+ units = none
+ dimensions = ()
+ type = character
+ kind = len=*
+ intent = out
+[errflg]
+ standard_name = ccpp_error_code
+ long_name = error code for error handling in CCPP
+ units = 1
+ dimensions = ()
+ type = integer
+ intent = out
diff --git a/test_prebuild/test_track_variables/scheme_A.meta b/test_prebuild/test_track_variables/scheme_A.meta
new file mode 100644
index 00000000..4fc6118c
--- /dev/null
+++ b/test_prebuild/test_track_variables/scheme_A.meta
@@ -0,0 +1,31 @@
+########################################################################
+[ccpp-table-properties]
+ name = scheme_A
+ type = scheme
+
+########################################################################
+[ccpp-arg-table]
+ name = scheme_A_run
+ type = scheme
+[im]
+ standard_name = horizontal_loop_extent
+ long_name = horizontal loop extent
+ units = count
+ dimensions = ()
+ type = integer
+ intent = in
+[errmsg]
+ standard_name = ccpp_error_message
+ long_name = error message for error handling in CCPP
+ units = none
+ dimensions = ()
+ type = character
+ kind = len=*
+ intent = out
+[errflg]
+ standard_name = ccpp_error_code
+ long_name = error code for error handling in CCPP
+ units = 1
+ dimensions = ()
+ type = integer
+ intent = out
diff --git a/test_prebuild/test_track_variables/scheme_B.meta b/test_prebuild/test_track_variables/scheme_B.meta
new file mode 100644
index 00000000..3bd0f070
--- /dev/null
+++ b/test_prebuild/test_track_variables/scheme_B.meta
@@ -0,0 +1,48 @@
+########################################################################
+[ccpp-table-properties]
+ name = scheme_B
+ type = scheme
+ dependencies = ../../hooks/machine.F,module_nst_parameters.f90,module_nst_water_prop.f90
+
+########################################################################
+[ccpp-arg-table]
+ name = scheme_B_run
+ type = scheme
+[im]
+ standard_name = horizontal_loop_extent
+ long_name = horizontal loop extent
+ units = count
+ dimensions = ()
+ type = integer
+ intent = in
+[wet]
+ standard_name = flag_nonzero_wet_surface_fraction
+ long_name = flag indicating presence of some ocean or lake surface area fraction
+ units = flag
+ dimensions = (horizontal_loop_extent)
+ type = logical
+ intent = in
+[tgice]
+ standard_name = freezing_point_temperature_of_seawater
+ long_name = freezing point temperature of seawater
+ units = K
+ dimensions = ()
+ type = real
+ kind = kind_phys
+ intent = in
+[tsfco]
+ standard_name = sea_surface_temperature
+ long_name = sea surface temperature
+ units = K
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ intent = in
+[tsurf_wat]
+ standard_name = surface_skin_temperature_after_iteration_over_water
+ long_name = surface skin temperature after iteration over water
+ units = K
+ dimensions = (horizontal_loop_extent)
+ type = real
+ kind = kind_phys
+ intent = inout
diff --git a/test_prebuild/test_track_variables/suite_TEST_SUITE.xml b/test_prebuild/test_track_variables/suite_TEST_SUITE.xml
new file mode 100644
index 00000000..92d7af46
--- /dev/null
+++ b/test_prebuild/test_track_variables/suite_TEST_SUITE.xml
@@ -0,0 +1,24 @@
+
+
+
+
+
+ scheme_1
+ scheme_2
+
+
+ scheme_3
+ scheme_4
+
+
+
+
+ scheme_1
+ scheme_A
+
+
+ scheme_B
+ scheme_4
+
+
+
diff --git a/test_prebuild/test_track_variables/suite_small_suite.xml b/test_prebuild/test_track_variables/suite_small_suite.xml
new file mode 100644
index 00000000..057936b3
--- /dev/null
+++ b/test_prebuild/test_track_variables/suite_small_suite.xml
@@ -0,0 +1,14 @@
+
+
+
+
+
+ scheme_1
+
+
+
+
+ scheme_4
+
+
+