Test_ExtDataUpdatePointer.pf Source File


This file depends on

sourcefile~~test_extdataupdatepointer.pf~~EfferentGraph sourcefile~test_extdataupdatepointer.pf Test_ExtDataUpdatePointer.pf sourcefile~extdataupdatepointer.f90 ExtDataUpdatePointer.F90 sourcefile~test_extdataupdatepointer.pf->sourcefile~extdataupdatepointer.f90 sourcefile~mapl_exceptionhandling.f90 MAPL_ExceptionHandling.F90 sourcefile~test_extdataupdatepointer.pf->sourcefile~mapl_exceptionhandling.f90 sourcefile~extdataupdatepointer.f90->sourcefile~mapl_exceptionhandling.f90 sourcefile~keywordenforcer.f90 KeywordEnforcer.F90 sourcefile~extdataupdatepointer.f90->sourcefile~keywordenforcer.f90 sourcefile~mapl_comms.f90 MAPL_Comms.F90 sourcefile~extdataupdatepointer.f90->sourcefile~mapl_comms.f90 sourcefile~timestringconversion.f90 TimeStringConversion.F90 sourcefile~extdataupdatepointer.f90->sourcefile~timestringconversion.f90 sourcefile~errorhandling.f90 ErrorHandling.F90 sourcefile~mapl_exceptionhandling.f90->sourcefile~errorhandling.f90 sourcefile~mapl_throw.f90 MAPL_Throw.F90 sourcefile~mapl_exceptionhandling.f90->sourcefile~mapl_throw.f90 sourcefile~errorhandling.f90->sourcefile~mapl_throw.f90 sourcefile~mapl_comms.f90->sourcefile~mapl_exceptionhandling.f90 sourcefile~base_base.f90 Base_Base.F90 sourcefile~mapl_comms.f90->sourcefile~base_base.f90 sourcefile~constants.f90 Constants.F90 sourcefile~mapl_comms.f90->sourcefile~constants.f90 sourcefile~shmem.f90 Shmem.F90 sourcefile~mapl_comms.f90->sourcefile~shmem.f90 sourcefile~timestringconversion.f90->sourcefile~mapl_exceptionhandling.f90 sourcefile~timestringconversion.f90->sourcefile~keywordenforcer.f90 sourcefile~base_base.f90->sourcefile~keywordenforcer.f90 sourcefile~base_base.f90->sourcefile~constants.f90 sourcefile~mapl_range.f90 MAPL_Range.F90 sourcefile~base_base.f90->sourcefile~mapl_range.f90 sourcefile~maplgrid.f90 MaplGrid.F90 sourcefile~base_base.f90->sourcefile~maplgrid.f90 sourcefile~internalconstants.f90 InternalConstants.F90 sourcefile~constants.f90->sourcefile~internalconstants.f90 sourcefile~mathconstants.f90 MathConstants.F90 sourcefile~constants.f90->sourcefile~mathconstants.f90 sourcefile~physicalconstants.f90 PhysicalConstants.F90 sourcefile~constants.f90->sourcefile~physicalconstants.f90 sourcefile~shmem.f90->sourcefile~constants.f90

Source Code

#include "MAPL_Generic.h"
#if defined(I_AM_PFUNIT)
#  undef I_AM_PFUNIT
#endif
#define I_AM_PFUNIT

module Test_ExtDataUpdatePointer
   use MAPL_ExtDataPointerUpdate
   use funit
   use esmf
   use MAPL_ExceptionHandling
   implicit none

   integer, parameter :: SUCCESS = 0
   integer, parameter :: TIME_STEP_IN_SECONDS = 1
   integer, parameter :: REFERENCE_TIME_FIELDS(*) = [2024, 12, 31, 20, 0, 0]
   integer, parameter :: NF = size(REFERENCE_TIME_FIELDS)
   integer, parameter :: START_TIME_FIELDS(*) = [2024, 01, 01, 0, 0, 0] 
   integer, parameter :: DEFAULT_TIME_FIELDS(*) = [REFERENCE_TIME_FIELDS(1:3), 0, 0, 0]
   integer, parameter :: UPDATE_TIME_FIELDS(*) = [0, 1, 1, REFERENCE_TIME_FIELDS(4:)]
   integer, parameter :: STRLEN = 32
   character(len=*), parameter :: UPDATE_TIMESTRING = 'T20:00:00'
   character(len=*), parameter :: UPDATE_FREQ_STRING = '-'
   character(len=*), parameter :: ERR_MSG = 'Actual offset does match expected offset.'
   type(ESMF_Time) :: start_time
   type(ESMF_TimeInterval) :: timestep
   type(ESMF_Clock) :: clock
   type(ESMF_Time) :: default_time
   type(ESMF_TimeInterval) :: time_interval
   type(ESMF_Time) :: update_time
   type(ESMF_Time) :: reference_time

contains

   @Before
   subroutine set_up()
      integer :: status, rc
      logical :: uninitialized

      status = SUCCESS
      uninitialized = .not. ESMF_IsInitialized(_RC)
      if(uninitialized) then
         call ESMF_Initialize(defaultCalKind=ESMF_CALKIND_GREGORIAN, logKindFlag=ESMF_LOGKIND_NONE, defaultLogKindFlag=ESMF_LOGKIND_NONE, _RC)
      end if
      call ESMF_TimeIntervalSet(time_interval, _RC)
      call ESMF_TimeIntervalSet(timestep, s=TIME_STEP_IN_SECONDS, _RC)
      call make_esmf_time(START_TIME_FIELDS, start_time, _RC)
      call make_esmf_time(DEFAULT_TIME_FIELDS, default_time, _RC)
      call make_esmf_time(UPDATE_TIME_FIELDS, update_time, _RC)
      call make_esmf_time(REFERENCE_TIME_FIELDS, reference_time, _RC)
      clock = ESMF_ClockCreate(timestep=timestep, startTime=start_time, _RC)

   end subroutine set_up

   @After
   subroutine tear_down()
      integer :: status, rc

      call ESMF_TimeSet(start_time, _RC)
      call ESMF_TimeIntervalSet(timestep, _RC)
      call ESMF_ClockDestroy(clock, _RC)
      call ESMF_TimeSet(default_time, _RC)
      call ESMF_TimeIntervalSet(time_interval, _RC)
      call ESMF_TimeSet(update_time, _RC)
      call ESMF_TimeSet(reference_time, _RC)

   end subroutine tear_down

   ! Set ESMF_Time using an integer array of datetime fields.
   subroutine make_esmf_time(f, datetime, rc)
      integer, intent(in) :: f(NF)
      type(ESMF_Time), intent(inout) :: datetime
      integer, optional, intent(out) :: rc
      integer :: status

      status = 0
      call ESMF_TimeSet(datetime, yy=f(1), mm=f(2), dd=f(3), h=f(4), m=f(5), s=f(6), _RC)
      _RETURN(_SUCCESS)
         
   end subroutine make_esmf_time

   ! Put ESMF_Time output args into an integer array.
   subroutine get_int_time(datetime, n, rc)
      type(ESMF_Time), intent(in) :: datetime
      integer, intent(inout) :: n(NF)
      integer, optional, intent(out) :: rc
      integer :: status

      status = 0
      n = -1
      call ESMF_TimeGet(datetime, yy=n(1), mm=n(2), dd=n(3), h=n(4), m=n(5), s=n(6), _RC)

      _RETURN(_SUCCESS)

   end subroutine get_int_time

   subroutine make_offset_string(offset, offset_string, rc)
      integer, intent(in) :: offset
      character(len=*), intent(out) :: offset_string
      integer, optional, intent(out) :: rc
      integer :: status

      write(offset_string, fmt='("PT", I03, "S")', iostat=status) offset
      _VERIFY(status)

   end subroutine make_offset_string
      
   @Test
   subroutine test_get_adjusted_time
      type(ExtDataPointerUpdate) :: ex
      integer :: status, rc
      character(len=STRLEN) :: offset_string
      type(ESMF_TimeInterval) :: offset
      integer :: ios
      integer, parameter :: OFFSET_IN_SECONDS = 300
      integer :: expected(NF), actual(NF)

      write(offset_string, fmt='("PT", I03, "S")', iostat=ios) OFFSET_IN_SECONDS
      _VERIFY(ios)
      call ESMF_TimeIntervalSet(offset, s=OFFSET_IN_SECONDS, _RC)
      call get_int_time(default_time+offset, expected, _RC)
      call ex%create_from_parameters(UPDATE_TIMESTRING, UPDATE_FREQ_STRING, offset_string, default_time, clock, _RC)
      call get_int_time(ex%get_adjusted_time(default_time), actual, _RC)
      @assertEqual(expected, actual, 'Adjusted time does match expected time.')

   end subroutine test_get_adjusted_time

   @Test
   subroutine test_create_from_parameters_string_positive()
      type(ExtDataPointerUpdate) :: ex
      integer :: status, rc
      character(len=STRLEN) :: offset_string
      integer, parameter :: OFFSET_IN_SECONDS = 300
      integer :: expected, actual
      type(ESMF_TimeInterval) :: interval

      call make_offset_string(OFFSET_IN_SECONDS, offset_string, _RC)
      expected = OFFSET_IN_SECONDS
      call ex%create_from_parameters(UPDATE_TIMESTRING, UPDATE_FREQ_STRING, offset_string, default_time, clock, _RC)
      interval = ex%get_offset()
      call ESMF_TimeIntervalGet(interval, s=actual, _RC)
      @assertEqual(expected, actual, ERR_MSG)

   end subroutine test_create_from_parameters_string_positive
     
   @Test
   subroutine test_create_from_parameters_string_negative()
      type(ExtDataPointerUpdate) :: ex
      integer :: status, rc
      character(len=STRLEN) :: offset_string
      integer, parameter :: OFFSET_IN_SECONDS = 300
      integer :: expected, actual
      type(ESMF_TimeInterval) :: interval

      call make_offset_string(OFFSET_IN_SECONDS, offset_string, _RC)
      offset_string = '-' // offset_string
      expected = -OFFSET_IN_SECONDS
      call ex%create_from_parameters(UPDATE_TIMESTRING, UPDATE_FREQ_STRING, offset_string, default_time, clock, _RC)
      interval = ex%get_offset()
      call ESMF_TimeIntervalGet(interval, s=actual, _RC)
      @assertEqual(expected, actual, ERR_MSG)

   end subroutine test_create_from_parameters_string_negative

   @Test
   subroutine test_create_from_parameters_heartbeat_positive()
      type(ExtDataPointerUpdate) :: ex
      integer :: status, rc
      character(len=*), parameter :: OFFSET_STRING = HEARTBEAT_STRING
      type(ESMF_TimeInterval) :: offset, interval
      integer :: expected, actual

      offset = timestep
      call ESMF_TimeIntervalGet(offset, s=expected, _RC)
      call ex%create_from_parameters(UPDATE_TIMESTRING, UPDATE_FREQ_STRING, OFFSET_STRING, default_time, clock, _RC)
      interval = ex%get_offset()
      call ESMF_TimeIntervalGet(interval, s=actual, _RC)
      @assertEqual(expected, actual, ERR_MSG)

   end subroutine test_create_from_parameters_heartbeat_positive

   @Test
   subroutine test_create_from_parameters_heartbeat_negative()
      type(ExtDataPointerUpdate) :: ex
      integer :: status, rc
      character(len=*), parameter :: OFFSET_STRING = '-' // HEARTBEAT_STRING
      type(ESMF_TimeInterval) :: offset, interval
      integer :: expected, actual

      offset = -timestep
      call ESMF_TimeIntervalGet(offset, s=expected, _RC)
      call ex%create_from_parameters(UPDATE_TIMESTRING, UPDATE_FREQ_STRING, OFFSET_STRING, default_time, clock, _RC)
      interval = ex%get_offset()
      call ESMF_TimeIntervalGet(interval, s=actual, _RC)
      @assertEqual(expected, actual, ERR_MSG)

   end subroutine test_create_from_parameters_heartbeat_negative

   @Test
   subroutine test_compare_positive_string_to_positive_heartbeat()
      type(ExtDataPointerUpdate) :: ex_str, ex_hb
      integer :: status, rc
      type(ESMF_TimeInterval) :: intv_str, intv_hb
      integer :: expected, actual
      character(len=STRLEN) :: offset_string

      call make_offset_string(TIME_STEP_IN_SECONDS, offset_string, _RC)

      call ex_str%create_from_parameters(UPDATE_TIMESTRING, UPDATE_FREQ_STRING, offset_string, default_time, clock, _RC)
      intv_str = ex_str%get_offset()
      call ESMF_TimeIntervalGet(intv_str, s=expected, _RC)

      call ex_hb%create_from_parameters(UPDATE_TIMESTRING, UPDATE_FREQ_STRING, HEARTBEAT_STRING, default_time, clock, _RC)
      intv_hb = ex_hb%get_offset()
      call ESMF_TimeIntervalGet(intv_hb, s=actual, _RC)

      @assertEqual(expected, actual, ERR_MSG)

   end subroutine test_compare_positive_string_to_positive_heartbeat

   @Test
   subroutine test_compare_negative_string_to_negative_heartbeat()
      type(ExtDataPointerUpdate) :: ex_str, ex_hb
      integer :: status, rc
      type(ESMF_TimeInterval) :: intv_str, intv_hb
      integer :: expected, actual
      character(len=STRLEN) :: offset_string

      call make_offset_string(TIME_STEP_IN_SECONDS, offset_string, _RC)
      offset_string = '-' // offset_string

      call ex_str%create_from_parameters(UPDATE_TIMESTRING, UPDATE_FREQ_STRING, offset_string, default_time, clock, _RC)
      intv_str = ex_str%get_offset()
      call ESMF_TimeIntervalGet(intv_str, s=expected, _RC)

      call ex_hb%create_from_parameters(UPDATE_TIMESTRING, UPDATE_FREQ_STRING, '-' // HEARTBEAT_STRING, default_time, clock, _RC)
      intv_hb = ex_hb%get_offset()
      call ESMF_TimeIntervalGet(intv_hb, s=actual, _RC)

      @assertEqual(expected, actual, ERR_MSG)

   end subroutine test_compare_negative_string_to_negative_heartbeat

   @Test
   subroutine test_create_from_parameters_heartbeat_positive_explicit()
      type(ExtDataPointerUpdate) :: ex
      integer :: status, rc
      character(len=*), parameter :: OFFSET_STRING = '+' // HEARTBEAT_STRING
      type(ESMF_TimeInterval) :: offset, interval
      integer :: expected, actual

      offset = timestep
      call ESMF_TimeIntervalGet(offset, s=expected, _RC)
      call ex%create_from_parameters(UPDATE_TIMESTRING, UPDATE_FREQ_STRING, OFFSET_STRING, default_time, clock, _RC)
      interval = ex%get_offset()
      call ESMF_TimeIntervalGet(interval, s=actual, _RC)
      @assertEqual(expected, actual, ERR_MSG)

   end subroutine test_create_from_parameters_heartbeat_positive_explicit

   @Test
   subroutine test_create_from_parameters_heartbeat_positive_negative()
      type(ExtDataPointerUpdate) :: ex
      integer :: status, rc
      character(len=*), parameter :: OFFSET_STRING = '+-' // HEARTBEAT_STRING
      type(ESMF_TimeInterval) :: offset, interval
      integer :: expected, actual

      offset = timestep
      call ESMF_TimeIntervalGet(offset, s=expected, _RC)
      call ex%create_from_parameters(UPDATE_TIMESTRING, UPDATE_FREQ_STRING, OFFSET_STRING, default_time, clock, rc=status)
      @assertFalse(status == 0, 'An exception should have been thrown.')

   end subroutine test_create_from_parameters_heartbeat_positive_negative

   @Test
   subroutine test_create_from_parameters_heartbeat_negative_positive()
      type(ExtDataPointerUpdate) :: ex
      integer :: status, rc
      character(len=*), parameter :: OFFSET_STRING = '-+' // HEARTBEAT_STRING
      type(ESMF_TimeInterval) :: offset, interval
      integer :: expected, actual

      offset = timestep
      call ESMF_TimeIntervalGet(offset, s=expected, _RC)
      call ex%create_from_parameters(UPDATE_TIMESTRING, UPDATE_FREQ_STRING, OFFSET_STRING, default_time, clock, rc=status)
      @assertFalse(status == 0, 'An exception should have been thrown.')

   end subroutine test_create_from_parameters_heartbeat_negative_positive

end module Test_ExtDataUpdatePointer