Skip to content

Commit

Permalink
check error codes in fortran tests
Browse files Browse the repository at this point in the history
  • Loading branch information
mattldawson committed Apr 25, 2024
1 parent 90bb045 commit 2e16335
Show file tree
Hide file tree
Showing 4 changed files with 89 additions and 18 deletions.
2 changes: 1 addition & 1 deletion .github/workflows/mac.yml
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ jobs:
- uses: actions/checkout@v3

- uses: actions/setup-python@v5
- run: pip install -r python/requirements.txt
- run: pip3 install -r python/requirements.txt

- name: Run Cmake
run: cmake -S . -B build -D CMAKE_BUILD_TYPE=${{ matrix.build_type }} -D MUSICA_ENABLE_PYTHON_LIBRARY=ON
Expand Down
33 changes: 20 additions & 13 deletions fortran/test/fetch_content_integration/test_micm_fort_api.F90
Original file line number Diff line number Diff line change
Expand Up @@ -2,14 +2,16 @@ program test_micm_fort_api
use, intrinsic :: iso_c_binding
use, intrinsic :: ieee_arithmetic
use micm_core, only: micm_t, mapping_t
use musica_util, only: assert, error_t_c
use musica_util, only: assert, error_t_c, is_error, is_success

implicit none
#include "micm/util/error.hpp"

#define ASSERT( expr ) call assert( expr, __FILE__, __LINE__ )
#define ASSERT_EQ( a, b ) call assert( a == b, __FILE__, __LINE__ )
#define ASSERT_NE( a, b ) call assert( a /= b, __FILE__, __LINE__ )

implicit none

type(micm_t), pointer :: micm
real(c_double) :: time_step
real(c_double) :: temperature
Expand Down Expand Up @@ -38,7 +40,7 @@ program test_micm_fort_api

write(*,*) "[test micm fort api] Creating MICM solver..."
micm => micm_t(config_path, error)
ASSERT_EQ( error%code_, 0_c_int )
ASSERT( is_success( error ) )

do i = 1, micm%species_ordering_length
the_mapping = micm%species_ordering(i)
Expand All @@ -54,34 +56,39 @@ program test_micm_fort_api
write(*,*) "[test micm fort api] Solving starts..."
call micm%solve(time_step, temperature, pressure, num_concentrations, concentrations, &
num_user_defined_reaction_rates, user_defined_reaction_rates, error)
ASSERT_EQ( error%code_, 0_c_int )
ASSERT( is_success( error ) )

write(*,*) "[test micm fort api] After solving, concentrations", concentrations

string_value = micm%get_species_property_string( "O3", "__long name", error )
ASSERT_EQ( error%code_, 0_c_int )
ASSERT( is_success( error ) )
ASSERT_EQ( string_value, "ozone" )
double_value = micm%get_species_property_double( "O3", "molecular weight [kg mol-1]", error )
ASSERT_EQ( error%code_, 0_c_int )
ASSERT( is_success( error ) )
ASSERT_EQ( double_value, 0.048_c_double )
int_value = micm%get_species_property_int( "O3", "__atoms", error )
ASSERT_EQ( error%code_, 0_c_int )
ASSERT( is_success( error ) )
ASSERT_EQ( int_value, 3_c_int )
bool_value = micm%get_species_property_bool( "O3", "__do advect", error )
ASSERT_EQ( error%code_, 0_c_int )
ASSERT( is_success( error ) )
ASSERT( logical( bool_value ) )

string_value = micm%get_species_property_string( "O3", "missing property", error )
ASSERT_NE( error%code_, 0_c_int )
ASSERT( is_error( error, MICM_ERROR_CATEGORY_SPECIES, \
MICM_SPECIES_ERROR_CODE_PROPERTY_NOT_FOUND ) )
double_value = micm%get_species_property_double( "O3", "missing property", error )
ASSERT_NE( error%code_, 0_c_int )
ASSERT( is_error( error, MICM_ERROR_CATEGORY_SPECIES, \
MICM_SPECIES_ERROR_CODE_PROPERTY_NOT_FOUND ) )
int_value = micm%get_species_property_int( "O3", "missing property", error )
ASSERT_NE( error%code_, 0_c_int )
ASSERT( is_error( error, MICM_ERROR_CATEGORY_SPECIES, \
MICM_SPECIES_ERROR_CODE_PROPERTY_NOT_FOUND ) )
bool_value = micm%get_species_property_bool( "O3", "missing property", error )
ASSERT_NE( error%code_, 0_c_int )
ASSERT( is_error( error, MICM_ERROR_CATEGORY_SPECIES, \
MICM_SPECIES_ERROR_CODE_PROPERTY_NOT_FOUND ) )
deallocate( micm )
micm => micm_t( "configs/invalid", error )
ASSERT_NE( error%code_, 0_c_int )
ASSERT( is_error( error, MICM_ERROR_CATEGORY_CONFIGURATION, \
MICM_CONFIGURATION_ERROR_CODE_INVALID_FILE_PATH ) )
ASSERT( .not. associated( micm ) )

write(*,*) "[test micm fort api] Finished."
Expand Down
Original file line number Diff line number Diff line change
@@ -1,13 +1,15 @@
program test_micm_api
use, intrinsic :: iso_c_binding
use musica_util, only: assert
use musica_util, only: assert, is_error

implicit none
#include "micm/util/error.hpp"

#define ASSERT( expr ) call assert( expr, __FILE__, __LINE__ )
#define ASSERT_EQ( a, b ) call assert( a == b, __FILE__, __LINE__ )
#define ASSERT_NE( a, b ) call assert( a /= b, __FILE__, __LINE__ )

implicit none

call test_micm_fort_api_invalid()

contains
Expand All @@ -26,7 +28,8 @@ subroutine test_micm_fort_api_invalid()

write(*,*) "[test micm fort api] Creating MICM solver..."
micm => micm_t(config_path, error)
ASSERT_NE( error%code_, 0_c_int )
ASSERT( is_error( error, MICM_ERROR_CATEGORY_CONFIGURATION, \
MICM_CONFIGURATION_ERROR_CODE_INVALID_FILE_PATH ) )

end subroutine

Expand Down
63 changes: 62 additions & 1 deletion fortran/util.F90
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,8 @@ module musica_util
implicit none
private

public :: string_t_c, error_t_c, to_c_string, to_f_string, assert
public :: string_t_c, error_t_c, to_c_string, to_f_string, assert, &
is_success, is_error, code, category, message

!> Wrapper for a c string
type, bind(c) :: string_t_c
Expand Down Expand Up @@ -88,6 +89,66 @@ subroutine assert( condition, file, line, error_message )
end subroutine assert


!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

!> Check if an error_t_c object represents a success condition
logical function is_success( error )

type(error_t_c), intent(in) :: error

is_success = error%code_ == 0_c_int

end function is_success

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

!> Check if an error_t_c object matches a specific error condition
logical function is_error( error, category, code )

type(error_t_c), intent(in) :: error
character(len=*), intent(in) :: category
integer, intent(in) :: code

is_error = int( error%code_ ) == code .and. &
to_f_string( error%category_ ) == category

end function is_error

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

!> Extract the error code from an error_t_c object
integer function code( error )

type(error_t_c), intent(in) :: error

code = int( error%code_ )

end function code

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

!> Extract the error category from an error_t_c object
function category( error )

type(error_t_c), intent(in) :: error
character(len=:), allocatable :: category

category = to_f_string( error%category_ )

end function category

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

!> Extract the error message from an error_t_c object
function message( error )

type(error_t_c), intent(in) :: error
character(len=:), allocatable :: message

message = to_f_string( error%message_ )

end function message

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!

end module musica_util

0 comments on commit 2e16335

Please sign in to comment.