! $Id$ ! ! Earth System Modeling Framework ! Copyright (c) 2002-2023, University Corporation for Atmospheric Research, ! Massachusetts Institute of Technology, Geophysical Fluid Dynamics ! Laboratory, University of Michigan, National Centers for Environmental ! Prediction, Los Alamos National Laboratory, Argonne National Laboratory, ! NASA Goddard Space Flight Center. ! Licensed under the University of Illinois-NCSA License. ! !============================================================================== ! !------------------------------------------------------------------------------- program ESMF_StateReadWriteUTest !============================================================================== ! #include "ESMF.h" ! !BOP ! !PROGRAM: ESMF_StateReadWriteUTest - Test code which Reads/Writes States ! ! !DESCRIPTION: ! ! The code in this file drives F90 State Read/Write unit tests. ! !----------------------------------------------------------------------------- ! !USES: use ESMF_TestMod ! test methods use ESMF implicit none !------------------------------------------------------------------------------ ! The following line turns the CVS identifier string into a printable variable. character(*), parameter :: version = & '$Id$' !------------------------------------------------------------------------------ ! ! Local variables type(ESMF_State) :: state type(ESMF_Array) :: latArray, lonArray, timeArray, humidArray, & tempArray, pArray, rhArray type(ESMF_VM) :: vm integer :: localPet integer :: i integer :: rc, localrc logical :: have_netcdf character(*), parameter :: netcdf_file = 'io_netcdf_testdata.nc' character(*), parameter :: netcdf_fileout = 'io_netcdf_testdata_out.nc' integer, parameter :: narrays = 7 character(8), parameter :: arraynames(narrays) = (/ & "lat ", "lon ", "time", & "Q ", "TEMP", "p ", & "rh " & /) type(ESMF_StateItem_Flag) :: itemtype integer :: itemcount logical :: passfail ! individual test failure messages character(ESMF_MAXSTR) :: failMsg character(ESMF_MAXSTR) :: name ! cumulative result: count failures; no failures equals "all pass" integer :: result = 0 !------------------------------------------------------------------------------- ! The unit tests are divided into Sanity and Exhaustive. The Sanity tests are ! always run. When the environment variable, EXHAUSTIVE, is set to ON then ! the EXHAUSTIVE and sanity tests both run. If the EXHAUSTIVE variable is set ! to OFF, then only the sanity unit tests. ! Special strings (Non-exhaustive and exhaustive) have been ! added to allow a script to count the number and types of unit tests. !------------------------------------------------------------------------------- call ESMF_TestStart(ESMF_SRCLINE, rc=rc) if (rc /= ESMF_SUCCESS) call ESMF_Finalize(endflag=ESMF_END_ABORT) call ESMF_VMGetGlobal(vm=vm, rc=rc) call ESMF_VMGet (vm, localPet=localPet) #ifdef ESMF_TESTEXHAUSTIVE !------------------------------------------------------------------------ !EX_UTest ! Test Creation of an empty export State state = ESMF_StateCreate(name="Ocean Export", stateintent=ESMF_STATEINTENT_EXPORT, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Creating an empty export State Test" call ESMF_Test((rc.eq.ESMF_SUCCESS), & name, failMsg, result, ESMF_SRCLINE) !------------------------------------------------------------------------ !EX_UTest ! Test reading a with no file name specified call ESMF_StateRead(state, filename=' ', rc=rc) write(failMsg, *) "Did not return an error" write(name, *) "Reading a file with no file name specified" call ESMF_Test(rc /= ESMF_SUCCESS, & name, failMsg, result, ESMF_SRCLINE) !------------------------------------------------------------------------ !EX_UTest ! Test reading a netCDF file into Arrays in a State call ESMF_StateRead(state, filename=netcdf_file, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS when reading: ", netcdf_file write(name, *) "Reading netCDF file ", netcdf_file, " into Arrays in a State" call ESMF_Test((rc == ESMF_SUCCESS .or. rc == ESMF_RC_LIB_NOT_PRESENT), & name, failMsg, result, ESMF_SRCLINE) have_netcdf = rc /= ESMF_RC_LIB_NOT_PRESENT !------------------------------------------------------------------------ !EX_UTest ! Test for number of State items read from the file. call ESMF_StateGet (state, itemCount=itemcount, rc=localrc) write(failMsg, *) "Incorrect number of items read from file" write(name, *) "Checking read-in Array item count in a State test" ! Current implementation reads data on PET 0 if (localPet == 0) then passfail = itemcount == narrays else passfail = itemcount == 0 end if call ESMF_Test((rc == ESMF_SUCCESS .and. passfail) .or. .not. have_netcdf, & name, failMsg, result, ESMF_SRCLINE) !------------------------------------------------------------------------ !EX_UTest ! Test for presense of State items read from the file. if (localPet == 0) then do, i=1, narrays call ESMF_StateGet (state, itemname=arraynames(i), itemType=itemtype, rc=localrc) if (localrc /= ESMF_SUCCESS) exit if (itemtype /= ESMF_STATEITEM_ARRAY) then localrc = ESMF_RC_NOT_FOUND exit end if end do rc = merge (ESMF_SUCCESS, localrc, i>narrays) else i = 1 rc = ESMF_SUCCESS end if write(failMsg, *) "Could not find read-in Array: ", trim (arraynames(min (i, narrays))) write(name, *) "Checking read-in Array names in a State test" call ESMF_Test((rc == ESMF_SUCCESS .or. .not. have_netcdf), & name, failMsg, result, ESMF_SRCLINE) !------------------------------------------------------------------------ !EX_UTest ! Test reconciling Arrays across all PETs in a VM call ESMF_StateReconcile(state, vm=vm, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Reconciling Arrays across all PETs in a VM" call ESMF_Test((rc.eq.ESMF_SUCCESS), & name, failMsg, result, ESMF_SRCLINE) !------------------------------------------------------------------------ !EX_UTest ! Test writing Arrays with no file name specified call ESMF_StateWrite(state, filename=' ', rc=rc) write(failMsg, *) "Did not return an error" write(name, *) "Writing a file with no file name" call ESMF_Test(rc /= ESMF_SUCCESS, & name, failMsg, result, ESMF_SRCLINE) !------------------------------------------------------------------------ !EX_UTest ! Test writing Arrays in a State to a netCDF file call ESMF_StateWrite(state, filename=netcdf_fileout, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Writing netCDF file ", netcdf_fileout, " from Arrays in a State" call ESMF_Test((rc.eq.ESMF_SUCCESS.or.rc.eq.ESMF_RC_LIB_NOT_PRESENT), & name, failMsg, result, ESMF_SRCLINE) !------------------------------------------------------------------------ ! Get each Array by name from the State !------------------------------------------------------------------------ !EX_UTest ! Test getting an Array from a State call ESMF_StateGet(state, "lat", latArray, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Getting Array named 'lat' from a State" if (have_netcdf) then call ESMF_Test(rc == ESMF_SUCCESS, & name, failMsg, result, ESMF_SRCLINE) else call ESMF_Test(rc == ESMF_RC_NOT_FOUND, & name, failMsg, result, ESMF_SRCLINE) end if !------------------------------------------------------------------------ !EX_UTest ! Test getting an Array from a State call ESMF_StateGet(state, "lon", lonArray, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Getting Array named 'lon' from a State" if (have_netcdf) then call ESMF_Test(rc == ESMF_SUCCESS, & name, failMsg, result, ESMF_SRCLINE) else call ESMF_Test(rc == ESMF_RC_NOT_FOUND, & name, failMsg, result, ESMF_SRCLINE) end if !------------------------------------------------------------------------ !EX_UTest ! Test getting an Array from a State call ESMF_StateGet(state, "time", timeArray, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Getting Array named 'time' from a State" if (have_netcdf) then call ESMF_Test(rc == ESMF_SUCCESS, & name, failMsg, result, ESMF_SRCLINE) else call ESMF_Test(rc == ESMF_RC_NOT_FOUND, & name, failMsg, result, ESMF_SRCLINE) end if !------------------------------------------------------------------------ !EX_UTest ! Test getting an Array from a State call ESMF_StateGet(state, "Q", humidArray, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Getting Array named 'Q' from a State" if (have_netcdf) then call ESMF_Test(rc == ESMF_SUCCESS, & name, failMsg, result, ESMF_SRCLINE) else call ESMF_Test(rc == ESMF_RC_NOT_FOUND, & name, failMsg, result, ESMF_SRCLINE) end if !------------------------------------------------------------------------ !EX_UTest ! Test getting an Array from a State call ESMF_StateGet(state, "TEMP", tempArray, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Getting Array named 'TEMP' from a State" if (have_netcdf) then call ESMF_Test(rc == ESMF_SUCCESS, & name, failMsg, result, ESMF_SRCLINE) else call ESMF_Test(rc == ESMF_RC_NOT_FOUND, & name, failMsg, result, ESMF_SRCLINE) end if !------------------------------------------------------------------------ !EX_UTest ! Test getting an Array from a State call ESMF_StateGet(state, "p", pArray, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Getting Array named 'p' from a State" if (have_netcdf) then call ESMF_Test(rc == ESMF_SUCCESS, & name, failMsg, result, ESMF_SRCLINE) else call ESMF_Test(rc == ESMF_RC_NOT_FOUND, & name, failMsg, result, ESMF_SRCLINE) end if !------------------------------------------------------------------------ !EX_UTest ! Test getting an Array from a State call ESMF_StateGet(state, "rh", rhArray, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Getting Array named 'rh' from a State" if (have_netcdf) then call ESMF_Test(rc == ESMF_SUCCESS, & name, failMsg, result, ESMF_SRCLINE) else call ESMF_Test(rc == ESMF_RC_NOT_FOUND, & name, failMsg, result, ESMF_SRCLINE) end if !------------------------------------------------------------------------ ! Destroy the State !------------------------------------------------------------------------ !EX_UTest ! Test destroying a State call ESMF_StateDestroy(state, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Destroying a State" call ESMF_Test((rc.eq.ESMF_SUCCESS), & name, failMsg, result, ESMF_SRCLINE) !------------------------------------------------------------------------ ! Destroy the constituent Arrays !------------------------------------------------------------------------ !EX_UTest ! Test destroying an Array call ESMF_ArrayDestroy(latArray, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Destroying Array named 'lat' from a State" call ESMF_Test((rc.eq.ESMF_SUCCESS.or.rc.eq.ESMF_RC_OBJ_NOT_CREATED), & name, failMsg, result, ESMF_SRCLINE) !------------------------------------------------------------------------ !EX_UTest ! Test destroying an Array call ESMF_ArrayDestroy(lonArray, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Destroying Array named 'lon' from a State" call ESMF_Test((rc.eq.ESMF_SUCCESS.or.rc.eq.ESMF_RC_OBJ_NOT_CREATED), & name, failMsg, result, ESMF_SRCLINE) !------------------------------------------------------------------------ !EX_UTest ! Test destroying an Array call ESMF_ArrayDestroy(timeArray, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Destroying Array named 'time' from a State" call ESMF_Test((rc.eq.ESMF_SUCCESS.or.rc.eq.ESMF_RC_OBJ_NOT_CREATED), & name, failMsg, result, ESMF_SRCLINE) !------------------------------------------------------------------------ !EX_UTest ! Test destroying an Array call ESMF_ArrayDestroy(humidArray, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Destroying Array named 'Q' from a State" call ESMF_Test((rc.eq.ESMF_SUCCESS.or.rc.eq.ESMF_RC_OBJ_NOT_CREATED), & name, failMsg, result, ESMF_SRCLINE) !------------------------------------------------------------------------ !EX_UTest ! Test destroying an Array call ESMF_ArrayDestroy(tempArray, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Destroying Array named 'TEMP' from a State" call ESMF_Test((rc.eq.ESMF_SUCCESS.or.rc.eq.ESMF_RC_OBJ_NOT_CREATED), & name, failMsg, result, ESMF_SRCLINE) !------------------------------------------------------------------------ !EX_UTest ! Test destroying an Array call ESMF_ArrayDestroy(pArray, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Destroying Array named 'p' from a State" call ESMF_Test((rc.eq.ESMF_SUCCESS.or.rc.eq.ESMF_RC_OBJ_NOT_CREATED), & name, failMsg, result, ESMF_SRCLINE) !------------------------------------------------------------------------ !EX_UTest ! Test destroying an Array call ESMF_ArrayDestroy(rhArray, rc=rc) write(failMsg, *) "Did not return ESMF_SUCCESS" write(name, *) "Destroying Array named 'rh' from a State" call ESMF_Test((rc.eq.ESMF_SUCCESS.or.rc.eq.ESMF_RC_OBJ_NOT_CREATED), & name, failMsg, result, ESMF_SRCLINE) !------------------------------------------------------------------------ ! End of Exhaustive tests #endif ! return number of failures to environment; 0 = success (all pass) ! return result ! TODO: no way to do this in F90 ? call ESMF_TestEnd(ESMF_SRCLINE) end program ESMF_StateReadWriteUTest !-------------------------------------------------------------------------