diff --git a/CIME/Tools/xmlchange b/CIME/Tools/xmlchange index cc6b216a825..ed141994d84 100755 --- a/CIME/Tools/xmlchange +++ b/CIME/Tools/xmlchange @@ -192,7 +192,7 @@ def parse_command_line(args, description): def xmlchange_single_value( - case, xmlid, xmlval, subgroup, append, force, dryrun, env_test + case, xmlid, xmlval, subgroup, append, force, dryrun, env_test, caseroot, xmlfile ): if xmlid in [ "THREAD_COUNT", @@ -227,7 +227,12 @@ def xmlchange_single_value( expect(result is not None, 'No variable "%s" found' % xmlid) - check_lockedfiles(case, skip=["env_case"]) + if xmlfile is not None: + xmlfile = [xmlfile] + # Pass caseroot, in cases where --file is used and case does not have access to env_case.xml + check_lockedfiles( + case, skip=["env_case"], quiet=True, caseroot=caseroot, whitelist=xmlfile + ) else: logger.warning("'%s' = '%s'", xmlid, xmlval) @@ -283,11 +288,29 @@ def xmlchange( ) (xmlid, xmlval) = pair xmlchange_single_value( - case, xmlid, xmlval, subgroup, append, force, dryrun, env_test + case, + xmlid, + xmlval, + subgroup, + append, + force, + dryrun, + env_test, + caseroot, + xmlfile, ) else: xmlchange_single_value( - case, xmlid, xmlval, subgroup, append, force, dryrun, env_test + case, + xmlid, + xmlval, + subgroup, + append, + force, + dryrun, + env_test, + caseroot, + xmlfile, ) if not noecho: diff --git a/CIME/data/config/cesm/config_files.xml b/CIME/data/config/cesm/config_files.xml index 688a8ad5437..0d5fa48bb68 100644 --- a/CIME/data/config/cesm/config_files.xml +++ b/CIME/data/config/cesm/config_files.xml @@ -28,7 +28,7 @@ char $SRCROOT/ccs_config/config_grids.xml - $SRCROOT/ccs_config/config_grids_nuopc.xml + $SRCROOT/ccs_config/config_grids_nuopc.xml case_last env_case.xml @@ -122,12 +122,10 @@ char - $SRCROOT/components/cdeps/datm - $SRCROOT/components/cpl7/components/data_comps_$COMP_INTERFACE/datm - $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/satm - $SRCROOT/components/cpl7/components/stub_comps_$COMP_INTERFACE/satm - $CIMEROOT/CIME/non_py/src/components/xcpl_comps_$COMP_INTERFACE/xatm - $SRCROOT/components/cpl7/components/xcpl_comps_$COMP_INTERFACE/xatm + $SRCROOT/components/cdeps/datm + $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/satm + $CIMEROOT/CIME/non_py/src/components/xcpl_comps_$COMP_INTERFACE/xatm + $SRCROOT/components/cam/ $SRCROOT/components/fv3/ @@ -140,12 +138,9 @@ char - $SRCROOT/components/cmeps - $SRCROOT/components/cmeps - $SRCROOT/components/cmeps - $SRCROOT/components/cpl7/driver - $SRCROOT/components/cpl7/driver - $SRCROOT/components/cpl7/driver + $SRCROOT/components/cmeps + $SRCROOT/components/cmeps + $SRCROOT/components/cmeps case_comps env_case.xml @@ -161,12 +156,9 @@ $SRCROOT/components/mom/ $SRCROOT/components/nemo/ $SRCROOT/components/blom/ - $SRCROOT/components/cpl7/components/data_comps_$COMP_INTERFACE/docn - $SRCROOT/components/cdeps/docn - $SRCROOT/components/cpl7/components/stub_comps_$COMP_INTERFACE/socn - $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/socn - $SRCROOT/components/cpl7/components/xcpl_comps_$COMP_INTERFACE/xocn - $CIMEROOT/CIME/non_py/src/components/xcpl_comps_$COMP_INTERFACE/xocn + $SRCROOT/components/cdeps/docn + $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/socn + $CIMEROOT/CIME/non_py/src/components/xcpl_comps_$COMP_INTERFACE/xocn case_comps env_case.xml @@ -178,13 +170,10 @@ char unset - $SRCROOT/components/ww3/ - $SRCROOT/components/cpl7/components/data_comps_$COMP_INTERFACE/dwav - $SRCROOT/components/cdeps/dwav - $SRCROOT/components/cpl7/components/stub_comps_$COMP_INTERFACE/swav - $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/swav - $SRCROOT/components/cpl7/components/xcpl_comps_$COMP_INTERFACE/xwav - $CIMEROOT/CIME/non_py/src/components/xcpl_comps_$COMP_INTERFACE/xwav + $SRCROOT/components/ww3/ + $SRCROOT/components/cdeps/dwav + $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/swav + $CIMEROOT/CIME/non_py/src/components/xcpl_comps_$COMP_INTERFACE/xwav case_comps env_case.xml @@ -197,12 +186,9 @@ unset $SRCROOT/components/cism/ - $SRCROOT/components/cpl7/components/data_comps_$COMP_INTERFACE/dglc - $SRCROOT/components/cdeps/dglc - $SRCROOT/components/cpl7/components/stub_comps_$COMP_INTERFACE/sglc - $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/sglc - $SRCROOT/components/cpl7/components/xcpl_comps_$COMP_INTERFACE/xglc - $CIMEROOT/CIME/non_py/src/components/xcpl_comps_$COMP_INTERFACE/xglc + $SRCROOT/components/cdeps/dglc + $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/sglc + $CIMEROOT/CIME/non_py/src/components/xcpl_comps_$COMP_INTERFACE/xglc case_comps env_case.xml @@ -216,12 +202,9 @@ $SRCROOT/components/cice5/ $SRCROOT/components/cice/ - $SRCROOT/components/cpl7/components/data_comps_$COMP_INTERFACE/dice - $SRCROOT/components/cdeps/dice - $SRCROOT/components/cpl7/components/stub_comps_$COMP_INTERFACE/sice - $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/sice - $SRCROOT/components/cpl7/components/xcpl_comps_$COMP_INTERFACE/xice - $CIMEROOT/CIME/non_py/src/components/xcpl_comps_$COMP_INTERFACE/xice + $SRCROOT/components/cdeps/dice + $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/sice + $CIMEROOT/CIME/non_py/src/components/xcpl_comps_$COMP_INTERFACE/xice case_comps env_case.xml @@ -236,12 +219,9 @@ $SRCROOT/components/rtm/ $SRCROOT/components/mosart/ $SRCROOT/components/mizuRoute/ - $SRCROOT/components/cpl7/components/data_comps_$COMP_INTERFACE/drof - $SRCROOT/components/cdeps/drof - $SRCROOT/components/cpl7/components/stub_comps_$COMP_INTERFACE/srof - $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/srof - $SRCROOT/components/cpl7/components/xcpl_comps_$COMP_INTERFACE/xrof - $CIMEROOT/CIME/non_py/src/components/xcpl_comps_$COMP_INTERFACE/xrof + $SRCROOT/components/cdeps/drof + $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/srof + $CIMEROOT/CIME/non_py/src/components/xcpl_comps_$COMP_INTERFACE/xrof case_comps env_case.xml @@ -255,12 +235,9 @@ $SRCROOT/components/clm/ $SRCROOT/components/slim/ - $SRCROOT/components/cpl7/components/data_comps_$COMP_INTERFACE/dlnd - $SRCROOT/components/cdeps/dlnd - $SRCROOT/components/cpl7/components/stub_comps_$COMP_INTERFACE/slnd - $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/slnd - $SRCROOT/components/cpl7/components/xcpl_comps_$COMP_INTERFACE/xlnd - $CIMEROOT/CIME/non_py/src/components/xcpl_comps_$COMP_INTERFACE/xlnd + $SRCROOT/components/cdeps/dlnd + $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/slnd + $CIMEROOT/CIME/non_py/src/components/xcpl_comps_$COMP_INTERFACE/xlnd case_comps env_case.xml @@ -272,10 +249,8 @@ char unset - $SRCROOT/components/cpl7/components/stub_comps_$COMP_INTERFACE/siac - $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/siac - $SRCROOT/components/cpl7/components/xcpl_comps_$COMP_INTERFACE/xiac - $CIMEROOT/CIME/non_py/src/components/xcpl_comps_$COMP_INTERFACE/xiac + $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/siac + $CIMEROOT/CIME/non_py/src/components/xcpl_comps_$COMP_INTERFACE/xiac case_comps env_case.xml @@ -287,10 +262,8 @@ char unset - $SRCROOT/components/cpl7/components/data_comps_$COMP_INTERFACE/desp - $CIMEROOT/CIME/non_py/src/components/data_comps_$COMP_INTERFACE/desp - $SRCROOT/components/cpl7/components/stub_comps_$COMP_INTERFACE/sesp - $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/sesp + $CIMEROOT/CIME/non_py/src/components/data_comps_$COMP_INTERFACE/desp + $CIMEROOT/CIME/non_py/src/components/stub_comps_$COMP_INTERFACE/sesp case_comps env_case.xml @@ -452,13 +425,13 @@ $COMP_ROOT_DIR_OCN/cime_config/testdefs/testmods_dirs $COMP_ROOT_DIR_OCN/cime_config/testdefs/testmods_dirs $COMP_ROOT_DIR_OCN/cime_config/testdefs/testmods_dirs - $SRCROOT/components/cdeps/datm/cime_config/testdefs/testmods_dirs - $SRCROOT/components/cdeps/dice/cime_config/testdefs/testmods_dirs - $SRCROOT/components/cdeps/dlnd/cime_config/testdefs/testmods_dirs - $SRCROOT/components/cdeps/docn/cime_config/testdefs/testmods_dirs - $SRCROOT/components/cdeps/drof/cime_config/testdefs/testmods_dirs - $SRCROOT/components/cdeps/dglc/cime_config/testdefs/testmods_dirs - $SRCROOT/components/cdeps/dwav/cime_config/testdefs/testmods_dirs + $SRCROOT/components/cdeps/datm/cime_config/testdefs/testmods_dirs + $SRCROOT/components/cdeps/dice/cime_config/testdefs/testmods_dirs + $SRCROOT/components/cdeps/dlnd/cime_config/testdefs/testmods_dirs + $SRCROOT/components/cdeps/docn/cime_config/testdefs/testmods_dirs + $SRCROOT/components/cdeps/drof/cime_config/testdefs/testmods_dirs + $SRCROOT/components/cdeps/dglc/cime_config/testdefs/testmods_dirs + $SRCROOT/components/cdeps/dwav/cime_config/testdefs/testmods_dirs case_last env_case.xml @@ -543,8 +516,7 @@ char - $SRCROOT/components/cmeps/cime_config/config_component_$MODEL.xml --> - $SRCROOT/components/cpl7/driver/cime_config/config_component_$MODEL.xml --> + $SRCROOT/components/cmeps/cime_config/config_component_$MODEL.xml --> case_last env_case.xml diff --git a/CIME/locked_files.py b/CIME/locked_files.py index 178a8af6942..3be6f9c3573 100644 --- a/CIME/locked_files.py +++ b/CIME/locked_files.py @@ -1,4 +1,3 @@ -import glob from pathlib import Path from CIME.utils import safe_copy @@ -55,7 +54,7 @@ def is_locked(filename, caseroot): return os.path.exists(os.path.join(caseroot, LOCKED_DIR, filename)) -def check_lockedfiles(case, skip=None): +def check_lockedfiles(case, skip=None, quiet=False, caseroot=None, whitelist=None): """ Check that all lockedfiles match what's in case @@ -66,28 +65,35 @@ def check_lockedfiles(case, skip=None): elif isinstance(skip, str): skip = [skip] - caseroot = case.get_value("CASEROOT") + if caseroot is None: + caseroot = case.get_value("CASEROOT") + + locked_path = Path(caseroot, LOCKED_DIR) - lockedfiles = glob.glob(os.path.join(caseroot, LOCKED_DIR, "*.xml")) + lockedfiles = locked_path.glob("*.xml") + + # filter based on whitelist + if whitelist is not None: + lockedfiles = [x for x in lockedfiles if x.stem in whitelist] for file_path in lockedfiles: - filename = os.path.basename(file_path) + filename = file_path.name # Skip files used for tests e.g. env_mach_pes.ERP1.xml or included in skip list if filename.count(".") > 1 or any([filename.startswith(x) for x in skip]): continue - check_lockedfile(case, filename, caseroot=caseroot) + check_lockedfile(case, f"{filename}", caseroot=caseroot, quiet=quiet) -def check_lockedfile(case, filebase, caseroot=None): +def check_lockedfile(case, filebase, caseroot=None, quiet=False): if caseroot is None: caseroot = case.get_value("CASEROOT") env_name, diff = diff_lockedfile(case, caseroot, filebase) if diff: - check_diff(case, filebase, env_name, diff) + check_diff(case, filebase, env_name, diff, quiet=quiet) def diff_lockedfile(case, caseroot, filename): @@ -138,7 +144,7 @@ def _get_case_env(case, caseroot, locked_file, env_name): return l_env, r_env -def check_diff(case, filename, env_name, diff): +def check_diff(case, filename, env_name, diff, quiet=False): logger.warning("Detected diff in locked file {!r}".format(filename)) # Remove BUILD_COMPLETE, invalid entry in diff @@ -207,4 +213,7 @@ def check_diff(case, filename, env_name, diff): message = f"{message}./case.build {clean_targets}\n./case.build" - expect(False, message) + if quiet: + logger.info(message) + else: + expect(False, message) diff --git a/CIME/tests/base.py b/CIME/tests/base.py index 524900fac82..b2845575455 100644 --- a/CIME/tests/base.py +++ b/CIME/tests/base.py @@ -211,7 +211,7 @@ def _create_test( driver = utils.get_cime_default_driver() if driver == "nuopc" and "cime_developer" in extra_args: extra_args.append( - " ^SMS_Ln3.T42_T42.S ^PRE.f19_f19.ADESP_TEST ^PRE.f19_f19.ADESP ^DAE.ww3a.ADWAV" + " ^SMS_Ln3.T42_T42.S ^PRE.f19_f19.ADESP_TEST ^PRE.f19_f19.ADESP ^DAE.ww3a.ADWAV ^IRT_N2_Vmct_Ln9.f19_g16_rx1.A" ) test_id = ( diff --git a/CIME/tests/test_sys_create_newcase.py b/CIME/tests/test_sys_create_newcase.py index a0f07a001b6..800e690bb74 100644 --- a/CIME/tests/test_sys_create_newcase.py +++ b/CIME/tests/test_sys_create_newcase.py @@ -318,7 +318,10 @@ def test_e_xmlquery(self): self.assertTrue(output == str(STOP_N), msg="%s != %s" % (output, STOP_N)) cmd = xmlquery + " --non-local BUILD_COMPLETE --value" output = utils.run_cmd_no_fail(cmd, from_dir=casedir) - self.assertTrue(output == "TRUE", msg="%s != %s" % (output, BUILD_COMPLETE)) + output = output == "TRUE" + self.assertTrue( + output == BUILD_COMPLETE, msg="%s != %s" % (output, BUILD_COMPLETE) + ) # we expect DOCN_MODE to be undefined in this X compset # this test assures that we do not try to resolve this as a compvar cmd = xmlquery + " --non-local DOCN_MODE --value" diff --git a/CIME/tests/test_sys_full_system.py b/CIME/tests/test_sys_full_system.py index 854e782ac1f..22a6708436b 100644 --- a/CIME/tests/test_sys_full_system.py +++ b/CIME/tests/test_sys_full_system.py @@ -47,6 +47,7 @@ def test_full_system(self): "PRE.f19_f19.ADESP_TEST", "PRE.f19_f19.ADESP", "DAE.ww3a.ADWAV", + "IRT_N2_Vmct_Ln9.f19_g16_rx1.A", ] tests = get_tests.get_test_suite( "cime_developer", @@ -54,7 +55,8 @@ def test_full_system(self): compiler=self._compiler, skip_tests=skip_tests, ) - + print(f"tests are {tests}") + self.assertTrue(False, msg="Stop here") for test in tests: casedir = self.get_casedir(test, cases) diff --git a/CIME/tests/test_unit_locked_files.py b/CIME/tests/test_unit_locked_files.py index 05b2e9952dc..fc871e3b768 100644 --- a/CIME/tests/test_unit_locked_files.py +++ b/CIME/tests/test_unit_locked_files.py @@ -262,6 +262,17 @@ def test_check_lockedfiles(self): with self.assertRaises(CIMEError): locked_files.check_lockedfiles(case) + def test_check_lockedfiles_quiet(self): + case = mock.MagicMock() + + with tempfile.TemporaryDirectory() as tempdir: + case.get_value.side_effect = (tempdir,) + + create_fake_env(tempdir) + + # Should not raise exception + locked_files.check_lockedfiles(case, quiet=True) + def test_is_locked(self): with tempfile.TemporaryDirectory() as tempdir: src_path = Path(tempdir, locked_files.LOCKED_DIR, "env_case.xml")