Skip to content

Commit

Permalink
Add unit test for points I/O code. (#1158)
Browse files Browse the repository at this point in the history
  • Loading branch information
edwardhartnett authored Jan 4, 2024
1 parent 88c89be commit 7bec560
Show file tree
Hide file tree
Showing 7 changed files with 376 additions and 0 deletions.
122 changes: 122 additions & 0 deletions .github/workflows/io_gnu_yml.old
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
name: io_gnu
on: [push, pull_request, workflow_dispatch]

# Cancel in-progress workflows when pushing to a branch
concurrency:
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
cancel-in-progress: true

env:
cache_key: gnu11-1
CC: gcc-10
FC: gfortran-10
CXX: g++-10


# Split into a steup step, and a WW3 build step which
# builds multiple switches in a matrix. The setup is run once and
# the environment is cached so each build of WW3 can share the dependencies.

jobs:
setup:
runs-on: ubuntu-latest

steps:
- name: checkout-ww3
if: steps.cache-env.outputs.cache-hit != 'true'
uses: actions/checkout@v3
with:
path: ww3
# Cache spack, OASIS, and compiler
# No way to flush Action cache, so key may have # appended
- name: cache-env
id: cache-env
uses: actions/cache@v3
with:
path: |
spack
~/.spack
work_oasis3-mct
key: spack-${{ runner.os }}-${{ env.cache_key }}-${{ hashFiles('ww3/model/ci/spack_gnu.yaml') }}

# Build WW3 spack environment
- name: install-dependencies-with-spack
if: steps.cache-env.outputs.cache-hit != 'true'
run: |
# Install NetCDF, ESMF, g2, etc using Spack
sudo apt install cmake
git clone -c feature.manyFiles=true https://github.com/JCSDA/spack.git
source spack/share/spack/setup-env.sh
spack env create ww3-gnu ww3/model/ci/spack_gnu.yaml
spack env activate ww3-gnu
spack compiler find
spack external find cmake
spack add mpich@3.4.2
spack concretize
spack install --dirty -v

- name: build-oasis
if: steps.cache-env.outputs.cache-hit != 'true'
run: |
source spack/share/spack/setup-env.sh
spack env activate ww3-gnu
export WWATCH3_DIR=${GITHUB_WORKSPACE}/ww3/model
export OASIS_INPUT_PATH=${GITHUB_WORKSPACE}/ww3/regtests/ww3_tp2.14/input/oasis3-mct
export OASIS_WORK_PATH=${GITHUB_WORKSPACE}/ww3/regtests/ww3_tp2.14/input/work_oasis3-mct
cd ww3/regtests/ww3_tp2.14/input/oasis3-mct/util/make_dir
cmake .
make VERBOSE=1
cp -r ${GITHUB_WORKSPACE}/ww3/regtests/ww3_tp2.14/input/work_oasis3-mct ${GITHUB_WORKSPACE}

io_gnu:
needs: setup
runs-on: ubuntu-latest

steps:
- name: install-dependencies
run: |
sudo apt-get update
sudo apt-get install doxygen gcovr valgrind

- name: checkout-ww3
uses: actions/checkout@v3
with:
path: ww3

- name: cache-env
id: cache-env
uses: actions/cache@v3
with:
path: |
spack
~/.spack
work_oasis3-mct
key: spack-${{ runner.os }}-${{ env.cache_key }}-${{ hashFiles('ww3/model/ci/spack_gnu.yaml') }}

- name: build-ww3
run: |
source spack/share/spack/setup-env.sh
spack env activate ww3-gnu
set -x
cd ww3
export CC=mpicc
export FC=mpif90
export OASISDIR=${GITHUB_WORKSPACE}/work_oasis3-mct
mkdir build && cd build
export LD_LIBRARY_PATH="/home/runner/work/WW3/WW3/spack/var/spack/environments/ww3-gnu/.spack-env/view/:$LD_LIBRARY_PATH"
cmake -DSWITCH=${GITHUB_WORKSPACE}/ww3/regtests/unittests/data/switch.io -DCMAKE_BUILD_TYPE=Debug -DCMAKE_Fortran_FLAGS="-g -fprofile-abs-path -fprofile-arcs -ftest-coverage -O0 -Wall -fno-omit-frame-pointer -fsanitize=address" -DCMAKE_C_FLAGS="-g -fprofile-abs-path -fprofile-arcs -ftest-coverage -O0 -Wall -fno-omit-frame-pointer -fsanitize=address" ..
make -j2 VERBOSE=1
./bin/ww3_grid
mv mod_def.ww3 regtests/unittests
ctest --verbose --output-on-failure --rerun-failed
gcovr --root .. -v --html-details --exclude ../regtests/unittests --exclude CMakeFiles --print-summary -o test-coverage.html &> /dev/null

- name: upload-test-coverage
uses: actions/upload-artifact@v3
with:
name: ww3-test-coverage
path: |
ww3/build/*.html
ww3/build/*.css


6 changes: 6 additions & 0 deletions CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -58,3 +58,9 @@ if(NOT CMAKE_BUILD_TYPE MATCHES "^(Debug|Release|RelWithDebInfo|MinSizeRel)$")
endif()

add_subdirectory(model)

# Turn on unit testing.
include(CTest)
if(BUILD_TESTING)
add_subdirectory(regtests/unittests)
endif()
39 changes: 39 additions & 0 deletions regtests/unittests/CMakeLists.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
# This is the CMake file for the model/tests directory in the WW3
# project.
#
# Ed Hartnett, 10/14/23

# Some very small test files may be committed to the repo. This
# function copies such a data file to the build directory.
function(copy_test_data name)
message(STATUS "Copying ${name} to ${CMAKE_CURRENT_BINARY_DIR}")
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/data/${name}"
DESTINATION ${CMAKE_CURRENT_BINARY_DIR}
FILE_PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
endfunction()

# Some very small test files may be committed to the repo. This
# function copies such a data file to the build directory.
function(copy_test_data_2 srcname destname)
message(STATUS "Copying ${srcname} to ${CMAKE_CURRENT_BINARY_DIR}/${destname}")
file(COPY "${CMAKE_CURRENT_SOURCE_DIR}/data/${srcname}"
DESTINATION "${CMAKE_BINARY_DIR}"
FILE_PERMISSIONS OWNER_READ OWNER_WRITE GROUP_READ WORLD_READ)
file(RENAME "${CMAKE_BINARY_DIR}/${srcname}" "${CMAKE_BINARY_DIR}/${destname}")
endfunction()

# Function to build and run a test.
function(unit_test name)
add_executable(${name} ${name}.F90)
target_link_libraries(${name} PRIVATE ww3_lib)
add_test(NAME ${name} COMMAND ${name})
endfunction()

# Copy test data files that are in the repo to the build directory.
copy_test_data(switch.io)
copy_test_data_2(ww3_grid.inp ww3_grid.inp)

# Build and run the tests.
unit_test(test_io_points_bin)


1 change: 1 addition & 0 deletions regtests/unittests/data/switch.io
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
NOGRB SHRD PR1 FLX2 LN0 ST0 NL0 BT0 DB0 TR0 BS0 IC0 IS0 REF0 WNT1 WNX1 CRT1 CRX1 O0 O1 O2 O3 O4 O5 O6 O7 O10 O11
48 changes: 48 additions & 0 deletions regtests/unittests/data/ww3_grid.inp
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
$ WAVEWATCH III Grid preprocessor input file
$ ------------------------------------------
'1-D REFRACTION X '
$
1.25 0.08 3 24 0.
$
F T F T F F
300. 300. 150. 300.
$
&PRO1 CFLTM = 0.75 /
&PRO2 CFLTM = 0.75 /
&PRO3 CFLTM = 0.75, WDTHCG = 0., WDTHTH = 0. /
&PRO4 CFLTM = 0.75, RNFAC = 0., RSFAC = 0. /
END OF NAMELISTS
$
'RECT' F 'NONE'
13 3
5.E3 5.E3 1.
-5.E3 -5.E3 1.
$
-1. 1. 10 -1. 2 1 '(....)' 'UNIT' 'input'
$
$ First grid
$
50 50 50 45 40 35 30 25 20 15 10 5 0
50 50 50 45 40 35 30 25 20 15 10 5 0
50 50 50 45 40 35 30 25 20 15 10 5 0
$
$ Second grid
$
$ 0 5 10 15 20 25 30 35 40 45 50 50 50
$ 0 5 10 15 20 25 30 35 40 45 50 50 50
$ 0 5 10 15 20 25 30 35 40 45 50 50 50
$
10 1 1 '(....)' 'PART' 'input'
$
$ First grid
$
2 2 F
$
$ Second grid
$
$ 12 2 F
0 0 F
0 0 F
0 0
$
0. 0. 0. 0. 0
8 changes: 8 additions & 0 deletions regtests/unittests/data/ww3_outp.inp
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
$
20100101 000000 3600 1
$
1
-1
$
4
2 30 20100101 000000 'UTC'
152 changes: 152 additions & 0 deletions regtests/unittests/test_io_points_bin.F90
Original file line number Diff line number Diff line change
@@ -0,0 +1,152 @@
! This is a test for model IO for WW3. This tests the legacy (binary)
! output of points data, done by function W3IOPO().
!
! Ed Hartnett 10/14/23
program test_io_points_bin
use w3iopomd
use w3gdatmd
use w3wdatmd
use w3odatmd
use w3iogrmd
use w3adatmd
implicit none

integer, target :: i
integer :: ndsop, iotest, ndsbul, ndsm
integer :: ndstrc, ntrace
character*7 expected_ptnme
character*6 my_fmt
real :: expected_loc_1
integer :: write_test_file

print *, 'Testing WW3 binary point file code.'

! These are mysterious but have to be called or else the IPASS
! variable does not exist and w3iopo() crashes.
call w3nmod(1, 6, 6)
call w3setg(1, 6, 6)
call w3ndat(6, 6)
call w3setw(1, 6, 6)
call w3nout(6, 6)
call w3seto(1, 6, 6)

ndsm = 20
ndsop = 20
ndsbul = 0
ndstrc = 6
ntrace = 10

! Create a point output file needed for this test.
if (write_test_file() .ne. 0) stop 1

write (ndso,900)
900 FORMAT (/15X,' *** WAVEWATCH III Point output post.*** '/ &
15X,'==============================================='/)

! 2. Read model definition file.
CALL W3IOGR('READ', NDSM)
WRITE (NDSO,920) GNAME
920 FORMAT (' Grid name : ',A/)

! This will not work. But cannot be tested because it will change the value of IPASS,
! call w3iopo('EAD', ndsop, iotest)
! if (iotest .ne. 1) stop 7

! Read the file out_pnt.ww3 from the model/tests/data directory.
call w3iopo('READ', ndsop, iotest)
if (iotest .ne. 0) stop 10
close(ndsop)

! Make sure we got the values we expected.
if (nopts .ne. 11) stop 11
expected_loc_1 = 0.0
do i = 1, nopts
! Check ptnme and ptloc arrays.
print *, ptnme(i), ptloc(1, i), ptloc(2, i)
if (i .lt. 10) then
my_fmt = '(a,i1)'
else
my_fmt = '(a,i2)'
endif
write(fmt = my_fmt, unit=expected_ptnme) 'Point', i
if (ptnme(i) .ne. expected_ptnme) stop 20
print *, expected_loc_1
if (ptloc(1, i) .ne. expected_loc_1) stop 21
expected_loc_1 = expected_loc_1 + 5000.0
if (ptloc(2, i) .ne. 0) stop 22
end do

print *, 'OK!'
print *, 'SUCCESS!'
end program test_io_points_bin

integer function write_test_file()
implicit none

integer :: ntlu, nk, nth, nopts
character(len=10), parameter :: veropt = '2021-04-06'
character(len=31), parameter :: idstr = 'WAVEWATCH III POINT OUTPUT FILE'
real :: ptloc(2,11) = reshape((/ 0., 0., 5000., 0., 10000., 0., 15000., 0., &
20000., 0., 25000., 0., 30000., 0., 35000., 0., 40000., 0., 45000., 0., 50000., 0. /), &
(/ 2, 11 /))
character*40 ptnme(11)
integer :: time(2) = (/ 19680606, 0 /)
integer :: nspec = 72
integer :: iw(11) = (/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /)
integer :: ii(11) = (/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /)
integer :: il(11) = (/ 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 /)
real :: iceo(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /)
real :: iceho(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /)
real :: icefo(11) = (/ 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000., 1000. /)
real :: dpo(11) = (/ 50., 50., 45., 40., 35., 30., 25., 20., 15., 10., 5. /)
real :: wao(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /)
real :: wdo(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /)
real :: aso(11) = (/ -999.900024, -999.900024, -999.900024, -999.900024, -999.900024, &
-999.900024, -999.900024, -999.900024, -999.900024, -999.900024, -999.900024 /)
real :: cao(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /)
real :: cdo(11) = (/ 0., 0., 0., 0., 0., 0., 0., 0., 0., 0., 0. /)
character*13 :: grdid(11)
real :: spco(72, 11)
integer :: i, j
integer :: ierr

! Initialize some values.
ntlu = 21
nk = 3
nth = 24
nopts = 11
do i = 1, nopts
if (i .le. 9) then
write(ptnme(i), '(a,i1)') 'Point', i
else
write(ptnme(i), '(a,i2)') 'Point', i
endif
grdid(i) = 'ww3 '
end do

! Open the file.
open(ntlu, file="out_pnt.ww3", form="unformatted", status="replace", &
action="write", convert="big_endian", iostat=ierr)
if (ierr .ne. 0) stop 111

! Write our values.
write (ntlu, iostat=ierr) idstr, veropt, nk, nth, nopts
if (ierr .ne. 0) stop 112
write (ntlu, iostat=ierr) ((ptloc(j,i),j=1,2),i=1,nopts), (ptnme(i),i=1,nopts)
if (ierr .ne. 0) stop 113
write (ntlu, iostat=ierr) time
if (ierr .ne. 0) stop 114
do i=1, nopts
write (ntlu, iostat=ierr) iw(i), ii(i), il(i), dpo(i), wao(i), wdo(i), &
aso(i), cao(i), cdo(i), iceo(i), iceho(i), &
icefo(i), grdid(i), (spco(j,i),j=1,nspec)
if (ierr .ne. 0) stop 115
enddo

! Close the file.
close(ntlu)

! We're done!
write_test_file = 0
end function write_test_file

0 comments on commit 7bec560

Please sign in to comment.