From 9ca98004d739bf2b3443ea36365753cdbbddb38e Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Tue, 4 Oct 2022 16:16:31 -0700 Subject: [PATCH 1/7] feat: add minimalistic Vegetables replacement This commit adds module/submodule pairs defining an abstract test_t type and a non-abstract test_result_t type that encapsulate test methods and results-reporting. --- src/test_m.F90 | 44 +++++++++++++++++++++++++++++++++++++++++++ src/test_result_m.f90 | 40 +++++++++++++++++++++++++++++++++++++++ src/test_result_s.f90 | 15 +++++++++++++++ src/test_s.F90 | 29 ++++++++++++++++++++++++++++ 4 files changed, 128 insertions(+) create mode 100644 src/test_m.F90 create mode 100644 src/test_result_m.f90 create mode 100644 src/test_result_s.f90 create mode 100644 src/test_s.F90 diff --git a/src/test_m.F90 b/src/test_m.F90 new file mode 100644 index 00000000..7568f14b --- /dev/null +++ b/src/test_m.F90 @@ -0,0 +1,44 @@ +module test_m + !! Define an abstract test_t type with deferred bindings ("subject" and "results") + !! used by a type-bound procedure ("report") for reporting test results. The "report" + !! procedure thus represents an implementation of the Template Method pattern. + use test_result_m, only : test_result_t + implicit none + + private + public :: test_t + + type, abstract :: test_t + !! Facilitate testing and test reporting + contains + procedure(subject_interface), nopass, deferred :: subject + procedure(results_interface), nopass, deferred :: results + procedure :: report + end type + + abstract interface + + pure function subject_interface() result(specimen) + !! The result is the name of the test specimen (the subject of testing) + character(len=:), allocatable :: specimen + end function + + function results_interface() result(test_results) + !! The result is an array of test outcomes for reporting + import test_result_t + type(test_result_t), allocatable :: test_results(:) + end function + + end interface + + interface + + module subroutine report(test) + !! Report test results + implicit none + class(test_t), intent(in) :: test + end subroutine + + end interface + +end module test_m diff --git a/src/test_result_m.f90 b/src/test_result_m.f90 new file mode 100644 index 00000000..d78013fb --- /dev/null +++ b/src/test_result_m.f90 @@ -0,0 +1,40 @@ +module test_result_m + !! Define an abstraction for describing test intentions and results + implicit none + + private + public :: test_result_t + + type test_result_t + !! Encapsulate test descriptions and outcomes and reporting + private + character(len=:), allocatable :: description_ + logical outcome_ + contains + procedure :: characterize + end type + + interface test_result_t + + pure module function construct(description, outcome) result(test_result) + !! The result is a test_result_t object with the components defined by the dummy arguments + implicit none + character(len=*), intent(in) :: description + logical, intent(in) :: outcome + type(test_result_t) test_result + end function + + end interface + + interface + + pure module function characterize(self) result(characterization) + !! The result is a character test description and its outcome + implicit none + class(test_result_t), intent(in) :: self + character(len=:), allocatable :: characterization + end function + + end interface + +end module test_result_m diff --git a/src/test_result_s.f90 b/src/test_result_s.f90 new file mode 100644 index 00000000..516a1c3e --- /dev/null +++ b/src/test_result_s.f90 @@ -0,0 +1,15 @@ +submodule(test_result_m) test_result_s + implicit none + +contains + + module procedure construct + test_result%description_ = description + test_result%outcome_ = outcome + end procedure + + module procedure characterize + characterization = merge("Pass: ", "Fail: ", self%outcome_) // self%description_ + end procedure + +end submodule test_result_s diff --git a/src/test_s.F90 b/src/test_s.F90 new file mode 100644 index 00000000..b4d23f85 --- /dev/null +++ b/src/test_s.F90 @@ -0,0 +1,29 @@ +submodule(test_m) test_s +#ifdef XLF + use test_result_m, only : test_result_t +#endif + implicit none + +contains + + module procedure report + integer i +#ifdef XLF + type(test_result_t), allocatable :: test_results(:) + test_results = test%results() +#else + associate(test_results => test%results()) +#endif + + print * + print *, test%subject() + + do i=1,size(test_results) + print *," ",test_results(i)%characterize() + end do +#ifndef XLF + end associate +#endif + end procedure + +end submodule test_s From 9033c720cbcc4c996d8747190a716b4b0691b098 Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Tue, 4 Oct 2022 17:00:27 -0700 Subject: [PATCH 2/7] feat: rm user_defined_collectives from test/main This is the first step in replacing the Vegetables tests with Sourcery's own minimalistic testing infrastructure. --- src/test_m.F90 | 4 +- src/test_result_m.f90 | 8 +-- src/test_result_s.f90 | 4 +- src/test_s.F90 | 2 +- tests/main.f90 | 18 +++-- ...t_interface_test.f90 => object_m_test.f90} | 0 tests/test-driver.f90 | 8 +++ tests/user_defined_collectives_test.f90 | 70 ++++++++++--------- 8 files changed, 65 insertions(+), 49 deletions(-) rename tests/{object_interface_test.f90 => object_m_test.f90} (100%) create mode 100644 tests/test-driver.f90 diff --git a/src/test_m.F90 b/src/test_m.F90 index 7568f14b..00ccf565 100644 --- a/src/test_m.F90 +++ b/src/test_m.F90 @@ -6,7 +6,7 @@ module test_m implicit none private - public :: test_t + public :: test_t, test_result_t type, abstract :: test_t !! Facilitate testing and test reporting @@ -24,7 +24,7 @@ pure function subject_interface() result(specimen) end function function results_interface() result(test_results) - !! The result is an array of test outcomes for reporting + !! The result is an array of test results for subsequent reporting in the "report" type-bound procedure import test_result_t type(test_result_t), allocatable :: test_results(:) end function diff --git a/src/test_result_m.f90 b/src/test_result_m.f90 index d78013fb..8ce3f5fe 100644 --- a/src/test_result_m.f90 +++ b/src/test_result_m.f90 @@ -9,18 +9,18 @@ module test_result_m !! Encapsulate test descriptions and outcomes and reporting private character(len=:), allocatable :: description_ - logical outcome_ + logical passed_ contains procedure :: characterize end type interface test_result_t - pure module function construct(description, outcome) result(test_result) + pure module function construct(description, passed) result(test_result) !! The result is a test_result_t object with the components defined by the dummy arguments implicit none character(len=*), intent(in) :: description - logical, intent(in) :: outcome + logical, intent(in) :: passed type(test_result_t) test_result end function @@ -29,7 +29,7 @@ pure module function construct(description, outcome) result(test_result) interface pure module function characterize(self) result(characterization) - !! The result is a character test description and its outcome + !! The result is a character description of the test and its outcome implicit none class(test_result_t), intent(in) :: self character(len=:), allocatable :: characterization diff --git a/src/test_result_s.f90 b/src/test_result_s.f90 index 516a1c3e..ab0a3b2e 100644 --- a/src/test_result_s.f90 +++ b/src/test_result_s.f90 @@ -5,11 +5,11 @@ module procedure construct test_result%description_ = description - test_result%outcome_ = outcome + test_result%passed_ = passed end procedure module procedure characterize - characterization = merge("Pass: ", "Fail: ", self%outcome_) // self%description_ + characterization = merge("Passes on ", "Fails on ", self%passed_) // self%description_ // "." end procedure end submodule test_result_s diff --git a/src/test_s.F90 b/src/test_s.F90 index b4d23f85..12e16dfc 100644 --- a/src/test_s.F90 +++ b/src/test_s.F90 @@ -19,7 +19,7 @@ print *, test%subject() do i=1,size(test_results) - print *," ",test_results(i)%characterize() + print *," ",test_results(i)%characterize() end do #ifndef XLF end associate diff --git a/tests/main.f90 b/tests/main.f90 index 3262ac5a..68e35971 100644 --- a/tests/main.f90 +++ b/tests/main.f90 @@ -6,24 +6,28 @@ program main contains subroutine run() use data_partition_test, only: & - data_partition_data_partition => test_data_partition + data_partition_data_partition => & + test_data_partition use formats_test, only: & - formats_object => test_object + formats_object => & + test_object use object_m_test, only: & - object_m_object => test_object - use user_defined_collectives_test, only: & - user_defined_collectives_co_all => test_co_all + object_m_object => & + test_object use vegetables, only: test_item_t, test_that, run_tests + + type(test_item_t) :: tests - type(test_item_t) :: individual_tests(4) + type(test_item_t) :: individual_tests(3) individual_tests(1) = data_partition_data_partition() individual_tests(2) = formats_object() individual_tests(3) = object_m_object() - individual_tests(4) = user_defined_collectives_co_all() tests = test_that(individual_tests) + call run_tests(tests) + end subroutine end program diff --git a/tests/object_interface_test.f90 b/tests/object_m_test.f90 similarity index 100% rename from tests/object_interface_test.f90 rename to tests/object_m_test.f90 diff --git a/tests/test-driver.f90 b/tests/test-driver.f90 new file mode 100644 index 00000000..75ab2196 --- /dev/null +++ b/tests/test-driver.f90 @@ -0,0 +1,8 @@ +program main + use user_defined_collectives_test, only : collectives_test_t + implicit none + + type(collectives_test_t) collectives_test + + call collectives_test%report() +end program diff --git a/tests/user_defined_collectives_test.f90 b/tests/user_defined_collectives_test.f90 index 975adf5d..9adad57b 100644 --- a/tests/user_defined_collectives_test.f90 +++ b/tests/user_defined_collectives_test.f90 @@ -1,43 +1,47 @@ module user_defined_collectives_test - use Vegetables, only: Result_t, Test_Item_t, describe, it, assert_equals, assert_that, assert_not use user_defined_collectives_m, only : co_all + use test_m, only : test_t, test_result_t implicit none private - public :: test_co_all + public :: collectives_test_t + + type, extends(test_t) :: collectives_test_t + contains + procedure, nopass :: subject + procedure, nopass :: results + end type contains - function test_co_all() result(tests) - type(Test_Item_t) :: tests - - tests = describe( & - "co_all", & - [it( & - "sets all arguments to .true. when previously .true. on all images", & - check_co_all_with_all_true), & - it( & - "sets all arguments to .false. when previously .false. on image 1", & - check_co_all_with_one_false)]) - end function - - function check_co_all_with_all_true() result(result_) - type(Result_t) :: result_ - logical all_true - - all_true=.true. - - call co_all(all_true) - result_ = assert_that(all_true, "co_all argument remains .true. after call with all arguments .true.") - end function - - function check_co_all_with_one_false() result(result_) - type(Result_t) :: result_ - logical all_true - - all_true = merge(.false., .true., this_image()==1) - call co_all(all_true) - result_ = assert_not(all_true, "co_all argument is .false. after call with one argument .false.") - end function + pure function subject() result(specimen) + character(len=:), allocatable :: specimen + specimen = "The co_all subroutine" + end function + + function results() result(test_results) + type(test_result_t), allocatable :: test_results(:) + + test_results = [ & + test_result_t("setting all arguments to .true. when previously .true. on all images", check_co_all_with_all_true()), & + test_result_t("setting all arguments to .false. when previously .false. on image 1", check_co_all_with_one_false()) & + ] + end function + + function check_co_all_with_all_true() result(test_passed) + logical test_passed, all_true + + all_true=.true. + call co_all(all_true) + test_passed = all_true + end function + + function check_co_all_with_one_false() result(test_passed) + logical test_passed, all_true + + all_true = merge(.false., .true., this_image()==1) + call co_all(all_true) + test_passed = .not. all_true + end function end module user_defined_collectives_test From dc19fdd293e98acea49a453987910535329decde Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Tue, 4 Oct 2022 22:19:05 -0700 Subject: [PATCH 3/7] feat: rm object_t test from test/main --- tests/main.f90 | 6 +--- tests/object_m_test.f90 | 75 +++++++++++++++++++++-------------------- tests/test-driver.f90 | 3 ++ 3 files changed, 42 insertions(+), 42 deletions(-) diff --git a/tests/main.f90 b/tests/main.f90 index 68e35971..1f8934d1 100644 --- a/tests/main.f90 +++ b/tests/main.f90 @@ -11,19 +11,15 @@ subroutine run() use formats_test, only: & formats_object => & test_object - use object_m_test, only: & - object_m_object => & - test_object use vegetables, only: test_item_t, test_that, run_tests type(test_item_t) :: tests - type(test_item_t) :: individual_tests(3) + type(test_item_t) :: individual_tests(2) individual_tests(1) = data_partition_data_partition() individual_tests(2) = formats_object() - individual_tests(3) = object_m_object() tests = test_that(individual_tests) diff --git a/tests/object_m_test.f90 b/tests/object_m_test.f90 index 653b2e69..b976c136 100644 --- a/tests/object_m_test.f90 +++ b/tests/object_m_test.f90 @@ -1,59 +1,60 @@ module object_m_test - !! author: Damian Rouson - !! - !! summary: verify object pattern asbtract parent - use vegetables, only: & - result_t, input_t, integer_input_t, test_item_t, & ! types - describe, it, assert_equals, assert_that, assert_not ! functions - use object_m, only : object_t - implicit none + !! Verify object pattern asbtract parent + use test_m, only : test_t, test_result_t + use object_m, only : object_t + implicit none - private - public :: test_object + private + public :: object_test_t - type, extends(object_t) :: subject - contains - procedure write_formatted - end type + type, extends(test_t) :: object_test_t + contains + procedure, nopass :: subject + procedure, nopass :: results + end type + + type, extends(object_t) :: subject_t + contains + procedure write_formatted + end type contains - function test_object() result(tests) - type(test_item_t) tests + pure function subject() result(specimen) + character(len=:), allocatable :: specimen + specimen = "The object_m type" + end function + + pure function results() result(test_results) + type(test_result_t), allocatable :: test_results(:) - tests = describe( & - "object class", & - [it( & - ".not. user_defined() if only default-initialized", & - check_default_initialization), & - it( & - "user_defined() after call mark_as_defined", & - check_mark_as_defined)]) + test_results = [ & + test_result_t(".not. user_defined() if only default-initialized", check_default_initialization()), & + test_result_t("user_defined() after call mark_as_defined", check_mark_as_defined()) & + ] end function - function check_default_initialization() result(result_) + pure function check_default_initialization() result(passed) !! Verify that user_defined() is .false. for a default-initialied object - class(object_t), allocatable :: object - type(result_t) result_ - - allocate(subject :: object) + class(object_t), allocatable :: object + logical passed - result_ = assert_not(object%user_defined()) + allocate(subject_t :: object) + passed = .not. object%user_defined() end function - function check_mark_as_defined() result(result_) + pure function check_mark_as_defined() result(passed) !! Verify that mark_as_defined results in user_defined() being .true. class(object_t), allocatable :: object - type(result_t) result_ - - allocate(subject :: object) + logical passed + allocate(subject_t :: object) call object%mark_as_defined - result_ = assert_that(object%user_defined()) + passed = object%user_defined() end function subroutine write_formatted(self, unit, iotype, v_list, iostat, iomsg) - class(subject), intent(in) :: self + class(subject_t), intent(in) :: self integer, intent(in) :: unit character(*), intent(in) :: iotype integer, intent(in) :: v_list(:) @@ -67,7 +68,7 @@ subroutine write_formatted(self, unit, iotype, v_list, iostat, iomsg) iomsg = "" case default iostat = -1 - iomsg = "object_m_test: subject%write_formatted iotype received unsupported iotype " // iotype + iomsg = "object_m_test: subject_t%write_formatted iotype received unsupported iotype " // iotype end select associate( unused => v_list) diff --git a/tests/test-driver.f90 b/tests/test-driver.f90 index 75ab2196..6b27fd8c 100644 --- a/tests/test-driver.f90 +++ b/tests/test-driver.f90 @@ -1,8 +1,11 @@ program main use user_defined_collectives_test, only : collectives_test_t + use object_m_test, only : object_test_t implicit none type(collectives_test_t) collectives_test + type(object_test_t) object_test call collectives_test%report() + call object_test%report() end program From 68784547ac91b92c7f990687032f618c15bc41c6 Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Tue, 4 Oct 2022 22:41:59 -0700 Subject: [PATCH 4/7] feat: rm format strings test from test/main --- src/test_result_s.f90 | 2 +- tests/formats_test.f90 | 81 +++++++++++++++++++----------------------- tests/main.f90 | 6 +--- tests/test-driver.f90 | 3 ++ 4 files changed, 41 insertions(+), 51 deletions(-) diff --git a/src/test_result_s.f90 b/src/test_result_s.f90 index ab0a3b2e..d59500cf 100644 --- a/src/test_result_s.f90 +++ b/src/test_result_s.f90 @@ -9,7 +9,7 @@ end procedure module procedure characterize - characterization = merge("Passes on ", "Fails on ", self%passed_) // self%description_ // "." + characterization = merge("passes on ", "fails on ", self%passed_) // self%description_ // "." end procedure end submodule test_result_s diff --git a/tests/formats_test.f90 b/tests/formats_test.f90 index 24719dd8..d6216f02 100644 --- a/tests/formats_test.f90 +++ b/tests/formats_test.f90 @@ -1,80 +1,71 @@ module formats_test + !! Verify that format strings provide the desired formatting + use formats_m, only : separated_values + use test_m, only : test_t, test_result_t + implicit none - !! author: Damian Rouson - !! - !! summary: verify that format strings provide the desired formatting - use vegetables, only: & - result_t, test_item_t, & ! types - describe, it, assert_equals ! functions - use formats_m, only : separated_values - implicit none + private + public :: formats_test_t - private - public :: test_object + type, extends(test_t) :: formats_test_t + contains + procedure, nopass :: subject + procedure, nopass :: results + end type contains - function test_object() result(tests) - type(test_item_t) tests + pure function subject() result(specimen) + character(len=:), allocatable :: specimen + specimen = "The csv format" + end function + + pure function results() result(test_results) + type(test_result_t), allocatable :: test_results(:) - tests = describe( & - "csv format", & - [it( & - "yields a comma-separated list of real numbers", & - check_csv_reals), & - it( & - "yields a space-separated list of complex numbers", & - check_space_separated_complex), & - it( & - "yields a comma- and space-separated list of character values", & - check_cssv_character), & - it( & - "yields a new-line-separated list of integer numbers", & - check_new_line_separated_integers)]) + test_results = [ & + test_result_t("yielding a comma-separated list of real numbers", check_csv_reals()), & + test_result_t("yielding a space-separated list of complex numbers", check_space_separated_complex()), & + test_result_t("yielding a comma- and space-separated list of character values", check_csv_character()), & + test_result_t("yielding a new-line-separated list of integer numbers", check_new_line_separated_integers()) & + ] end function - function check_csv_reals() result(result_) - type(result_t) result_ + pure function check_csv_reals() result(test_passes) + logical test_passes character(len=*), parameter :: expected_output = "0.00000000,1.00000000,2.00000000" character(len=len(expected_output)) captured_output write(captured_output, fmt = separated_values(separator=",", mold=[integer::])) [0.,1.,2.] - - result_ = assert_equals(expected_output, captured_output) + test_passes = expected_output == captured_output end function - function check_space_separated_complex() result(result_) - type(result_t) result_ - + pure function check_space_separated_complex() result(test_passes) + logical test_passes character(len=*), parameter :: expected_output = "(0.00000000,1.00000000) (1.00000000,0.00000000)" character(len=len(expected_output)) captured_output write(captured_output, fmt = separated_values(separator=" ", mold=[complex::])) [(0.,1.),(1.,0.)] - - result_ = assert_equals(expected_output, captured_output) + test_passes = expected_output == captured_output end function - function check_new_line_separated_integers() result(result_) - type(result_t) result_ - + pure function check_new_line_separated_integers() result(test_passes) + logical test_passes character(len=*), parameter :: expected_output = ( "0" // new_line("") // "1" //new_line("") // "2") character(len=len(expected_output)) captured_output write(captured_output, fmt = separated_values(separator=new_line(""), mold=[integer::])) [0,1,2] - - result_ = assert_equals(captured_output, "0" // new_line("") // "1" //new_line("") // "2") + test_passes = captured_output == "0" // new_line("") // "1" //new_line("") // "2" end function - function check_cssv_character() result(result_) - type(result_t) result_ - + pure function check_csv_character() result(test_passes) + logical test_passes integer, parameter :: num_spaces=3 character(len=*), parameter :: expected_output = "Yodel, Ay, Hee, Hoo!" character(len=len(expected_output)+num_spaces) captured_output write(captured_output, fmt = separated_values(separator=", ", mold=[integer::])) "Yodel", "Ay", "Hee", "Hoo!" - - result_ = assert_equals(expected_output, captured_output) + test_passes= expected_output == captured_output end function end module formats_test diff --git a/tests/main.f90 b/tests/main.f90 index 1f8934d1..047d2518 100644 --- a/tests/main.f90 +++ b/tests/main.f90 @@ -8,18 +8,14 @@ subroutine run() use data_partition_test, only: & data_partition_data_partition => & test_data_partition - use formats_test, only: & - formats_object => & - test_object use vegetables, only: test_item_t, test_that, run_tests type(test_item_t) :: tests - type(test_item_t) :: individual_tests(2) + type(test_item_t) :: individual_tests(1) individual_tests(1) = data_partition_data_partition() - individual_tests(2) = formats_object() tests = test_that(individual_tests) diff --git a/tests/test-driver.f90 b/tests/test-driver.f90 index 6b27fd8c..47532edc 100644 --- a/tests/test-driver.f90 +++ b/tests/test-driver.f90 @@ -1,11 +1,14 @@ program main use user_defined_collectives_test, only : collectives_test_t use object_m_test, only : object_test_t + use formats_test, only : formats_test_t implicit none type(collectives_test_t) collectives_test type(object_test_t) object_test + type(formats_test_t) formats_test call collectives_test%report() call object_test%report() + call formats_test%report() end program From 17ac8eef5331b6bf4b4138ff56c4171f0f836664 Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Tue, 4 Oct 2022 23:20:28 -0700 Subject: [PATCH 5/7] feat: rm data=partitioning test in test/main --- src/test_result_s.f90 | 2 +- tests/data_partition_test.f90 | 144 ++++++++++++++-------------------- tests/main.f90 | 38 ++++----- tests/object_m_test.f90 | 4 +- tests/test-driver.f90 | 14 ---- 5 files changed, 75 insertions(+), 127 deletions(-) delete mode 100644 tests/test-driver.f90 diff --git a/src/test_result_s.f90 b/src/test_result_s.f90 index d59500cf..171a7d26 100644 --- a/src/test_result_s.f90 +++ b/src/test_result_s.f90 @@ -9,7 +9,7 @@ end procedure module procedure characterize - characterization = merge("passes on ", "fails on ", self%passed_) // self%description_ // "." + characterization = merge("passes on ", "FAILS on ", self%passed_) // self%description_ // "." end procedure end submodule test_result_s diff --git a/tests/data_partition_test.f90 b/tests/data_partition_test.f90 index 34f5b2f2..a8c2136c 100644 --- a/tests/data_partition_test.f90 +++ b/tests/data_partition_test.f90 @@ -1,63 +1,56 @@ module data_partition_test - !! author: Damian Rouson - !! - !! summary: verify data partitioning across images and data gathering - use vegetables, only: & - result_t, example_t, input_t, integer_input_t, test_item_t, & ! types - describe, it, assert_equals, assert_that ! functions - use data_partition_m, only : data_partition_t - use iso_fortran_env, only : real64 - implicit none - - private - public :: test_data_partition + !! verify data partitioning across images and data gathering + use data_partition_m, only : data_partition_t + use test_m, only : test_t, test_result_t + use iso_fortran_env, only : real64 + implicit none - type(data_partition_t) partition - integer, parameter :: num_particles=31, gatherer=1, num_steps=9, dummy=0 + private + public :: data_partition_test_t + + type, extends(test_t) :: data_partition_test_t + contains + procedure, nopass :: subject + procedure, nopass :: results + end type + + type(data_partition_t) partition + integer, parameter :: num_particles=31, gatherer=1, num_steps=9, dummy=0 contains - function test_data_partition() result(tests) - type(test_item_t) tests + pure function subject() result(specimen) + character(len=:), allocatable :: specimen + specimen = "The data_partition_t type" + end function + + function results() result(test_results) + type(test_result_t), allocatable :: test_results(:) - call partition%define_partitions( cardinality=num_particles) + call partition%define_partitions(cardinality=num_particles) associate( me=>this_image() ) associate( my_first=>partition%first(me), my_last=>partition%last(me) ) - tests = describe( & - "data_partition class", & - [it( & - "partitions data in nearly even blocks", & - verify_block_partitioning), & - it( & - "all data partitioned across all images without data loss", & - verify_all_particles_partitioned), & - it( & - "1D real array gathered on all images", & - [example_t(integer_input_t(dummy)), example_t(integer_input_t(dummy))], & - verify_all_gather_1D_real_array), & - it( & - "dimension 1 of 2D real array gathered on all images witout dim argument", & - [example_t(integer_input_t(dummy)), example_t(integer_input_t(dummy))], & - verify_all_gather_2D_real_array), & - it( & - "dimension 1 of 2D real array gathered on all images with dim argument", & - [example_t(integer_input_t(dummy)), example_t(integer_input_t(dummy))], & - verify_all_gather_2D_real_array_dim1), & - it( & - "dimension 1 of 2D real array gathered onto result_image with dim argument", & - [example_t(integer_input_t(dummy)), example_t(integer_input_t(dummy))], & - verify_gather_2D_real_array_dim1)]) - + test_results = [ & + test_result_t("partitioning data in nearly even blocks", verify_block_partitioning()), & + test_result_t("partitioning all data across all images without data loss", verify_all_particles_partitioned()), & + test_result_t("gathering a 1D real array onto all images", verify_all_gather_1D_real_array()), & + test_result_t("gathering dimension 1 of 2D real array onto all images witout dim argument", & + verify_all_gather_2D_real_array()), & + test_result_t("gathering dimension 1 of 2D real array onton all images with dim argument", & + verify_all_gather_2D_real_array_dim1()), & + test_result_t("gathering dimension 1 of 2D real array onto result_image with dim argument", & + verify_gather_2D_real_array_dim1()) & + ] end associate end associate end function - function verify_block_partitioning() result(result_) + function verify_block_partitioning() result(test_passes) !! Verify that the data is partitioned across images evenly to !! within a difference of one datum between any two images. type(data_partition_t) partition - type(result_t) result_ + logical test_passes integer my_particles associate( me=>this_image() ) @@ -65,91 +58,72 @@ function verify_block_partitioning() result(result_) my_particles = my_last - my_first + 1 associate( ni=>num_images() ) associate( quotient=>num_particles/ni, remainder=>mod(num_particles,ni) ) - result_ = assert_equals( quotient + merge(1, 0, me<=remainder), my_particles, "block distribution" ) + test_passes = quotient + merge(1, 0, me<=remainder) == my_particles end associate end associate end associate end associate end function - function verify_all_particles_partitioned() result(result_) + function verify_all_particles_partitioned() result(test_passes) !! Verify that the number of particles on each image sums to the !! total number of particles distributed. type(data_partition_t) partition - type(result_t) result_ + logical test_passes integer particles associate(me => this_image()) associate( my_first=>partition%first(me), my_last=>partition%last(me) ) particles = my_last - my_first + 1 call co_sum(particles) - result_ = assert_equals(num_particles, particles, "all particles distributed" ) + test_passes = num_particles == particles end associate end associate end function - function verify_all_gather_1D_real_array(unused) result(result_) + function verify_all_gather_1D_real_array() result(test_passes) type(data_partition_t) partition - class(input_t), intent(in) :: unused - type(result_t) result_ + logical test_passes real(real64) :: particle_scalar(num_particles) real(real64), parameter :: junk=-12345._real64, expected=1._real64 - associate( no_op => unused) ! eliminate unused-variable warning - end associate - associate(me => this_image()) associate( first=>partition%first(me), last=>partition%last(me) ) - particle_scalar(first:last) = expected !! values to be gathered particle_scalar(1:first-1) = junk !! values to be overwritten by the gather particle_scalar(last+1:) = junk !! values to be overwritten by the gather - call partition%gather(particle_scalar) - - result_ = assert_that( all(particle_scalar==expected), "real 1D array all-gathered" ) - + test_passes = all(particle_scalar==expected) end associate end associate end function - function verify_all_gather_2D_real_array(unused) result(result_) - class(input_t), intent(in) :: unused + function verify_all_gather_2D_real_array() result(test_passes) type(data_partition_t) partition - type(result_t) result_ + logical test_passes integer, parameter :: vec_space_dim=3 real(real64) particle_vector(vec_space_dim, num_particles) real(real64), parameter :: junk=-12345._real64, expected=1._real64 - associate( no_op => unused) ! eliminate unused-variable warning - end associate - associate(me => this_image()) associate( first=>partition%first(me), last=>partition%last(me) ) particle_vector(:, first:last) = expected !! values to be gathered particle_vector(:, 1:first-1) = junk !! values to be overwritten by the gather particle_vector(:, last+1:) = junk !! values to be overwritten by the gather - call partition%gather(particle_vector) - - result_ = assert_that(all(particle_vector==expected), "real 2D array all-gathered implicitly along dimension 1" ) - + test_passes = all(particle_vector==expected) end associate end associate end function - function verify_all_gather_2D_real_array_dim1(unused) result(result_) - class(input_t), intent(in) :: unused + function verify_all_gather_2D_real_array_dim1() result(test_passes) type(data_partition_t) partition - type(result_t) result_ + logical test_passes integer, parameter :: vec_space_dim=3 real(real64) :: vector_transpose(num_particles, vec_space_dim) real(real64), parameter :: junk=-12345._real64, expected=1._real64 - associate( no_op => unused) ! eliminate unused-variable warning - end associate - associate(me => this_image()) associate( first=>partition%first(me), last=>partition%last(me) ) @@ -159,23 +133,19 @@ function verify_all_gather_2D_real_array_dim1(unused) result(result_) call partition%gather( vector_transpose, dim=1) - result_ = assert_that(all(vector_transpose==expected), "vector_transpose gathered explicitly along dimension 1" ) + test_passes= all(vector_transpose==expected) end associate end associate end function - function verify_gather_2D_real_array_dim1(unused) result(result_) - class(input_t), intent(in) :: unused + function verify_gather_2D_real_array_dim1() result(test_passes) type(data_partition_t) partition - type(result_t) result_ + logical test_passes integer, parameter :: vec_space_dim=3 real(real64) :: vector_transpose(num_particles, vec_space_dim) real(real64), parameter :: junk=-12345._real64, expected=1._real64 - associate( no_op => unused) ! eliminate unused-variable warning - end associate - associate(me => this_image()) associate( first=>partition%first(me), last=>partition%last(me) ) @@ -186,12 +156,12 @@ function verify_gather_2D_real_array_dim1(unused) result(result_) call partition%gather( vector_transpose, result_image=gatherer, dim=1) if (me==gatherer) then - result_ = assert_that(all(vector_transpose==expected), "all( particle_vector==expected)") + test_passes = all(vector_transpose==expected) else - result_ = & - assert_that(all(vector_transpose(1:first-1,:)==junk), "lower transpose data unchanged)") .and. & - assert_that(all(vector_transpose(first:last,:)==expected), "expected transpose data gathered") .and. & - assert_that(all(vector_transpose(last+1:,:)==junk), "upper transpose data unchanged)" ) + test_passes = & + all(vector_transpose(1:first-1,:)==junk) .and. & + all(vector_transpose(first:last,:)==expected) .and. & + all(vector_transpose(last+1:,:)==junk) end if end associate diff --git a/tests/main.f90 b/tests/main.f90 index 047d2518..ac32dafd 100644 --- a/tests/main.f90 +++ b/tests/main.f90 @@ -1,25 +1,17 @@ -! Generated by make_vegetable_driver. DO NOT EDIT program main - implicit none - - call run() -contains - subroutine run() - use data_partition_test, only: & - data_partition_data_partition => & - test_data_partition - use vegetables, only: test_item_t, test_that, run_tests - - - - type(test_item_t) :: tests - type(test_item_t) :: individual_tests(1) - - individual_tests(1) = data_partition_data_partition() - tests = test_that(individual_tests) - - - call run_tests(tests) - - end subroutine + use user_defined_collectives_test, only : collectives_test_t + use data_partition_test, only : data_partition_test_t + use object_m_test, only : object_test_t + use formats_test, only : formats_test_t + implicit none + + type(data_partition_test_t) data_partition_test + type(collectives_test_t) collectives_test + type(object_test_t) object_test + type(formats_test_t) formats_test + + call data_partition_test%report() + call collectives_test%report() + call object_test%report() + call formats_test%report() end program diff --git a/tests/object_m_test.f90 b/tests/object_m_test.f90 index b976c136..a81d1b21 100644 --- a/tests/object_m_test.f90 +++ b/tests/object_m_test.f90 @@ -29,8 +29,8 @@ pure function results() result(test_results) type(test_result_t), allocatable :: test_results(:) test_results = [ & - test_result_t(".not. user_defined() if only default-initialized", check_default_initialization()), & - test_result_t("user_defined() after call mark_as_defined", check_mark_as_defined()) & + test_result_t("object being .not. user_defined() if it is only default-initialized", check_default_initialization()), & + test_result_t("object being user_defined() after call to mark_as_defined", check_mark_as_defined()) & ] end function diff --git a/tests/test-driver.f90 b/tests/test-driver.f90 deleted file mode 100644 index 47532edc..00000000 --- a/tests/test-driver.f90 +++ /dev/null @@ -1,14 +0,0 @@ -program main - use user_defined_collectives_test, only : collectives_test_t - use object_m_test, only : object_test_t - use formats_test, only : formats_test_t - implicit none - - type(collectives_test_t) collectives_test - type(object_test_t) object_test - type(formats_test_t) formats_test - - call collectives_test%report() - call object_test%report() - call formats_test%report() -end program From 224fff580b0de448b1599a87ec5c295aadb68863 Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Tue, 4 Oct 2022 23:32:50 -0700 Subject: [PATCH 6/7] build(fpm): ++version, rm vegetables, default tree renaing "tests" directory to "test" facilitates reducing the fpm manifest to boilerplate. --- fpm.toml | 16 ++++------------ {tests => test}/data_partition_test.f90 | 0 {tests => test}/formats_test.f90 | 0 {tests => test}/main.f90 | 0 {tests => test}/object_m_test.f90 | 0 .../user_defined_collectives_test.f90 | 0 6 files changed, 4 insertions(+), 12 deletions(-) rename {tests => test}/data_partition_test.f90 (100%) rename {tests => test}/formats_test.f90 (100%) rename {tests => test}/main.f90 (100%) rename {tests => test}/object_m_test.f90 (100%) rename {tests => test}/user_defined_collectives_test.f90 (100%) diff --git a/fpm.toml b/fpm.toml index f675fcb5..28a1c475 100644 --- a/fpm.toml +++ b/fpm.toml @@ -1,17 +1,9 @@ name = "sourcery" -version = "1.0.0" +version = "3.1.0" license = "BSD" author = ["Damian Rouson"] -maintainer = "damian@sourceryinstitute.org" -copyright = "2020 Sourcery Institute" +maintainer = "damian@archaeologic.codes" +copyright = "2020-2022 Sourcery Institute" [dependencies] -assert = {git = "https://github.com/sourceryinstitute/assert", tag = "1.0.0"} - -[dev-dependencies] -vegetables = {git = "https://gitlab.com/everythingfunctional/vegetables", tag = "v7.2.0"} - -[[test]] -name="unit" -source-dir="tests" -main="main.f90" +assert = {git = "https://github.com/sourceryinstitute/assert", tag = "1.4.0"} diff --git a/tests/data_partition_test.f90 b/test/data_partition_test.f90 similarity index 100% rename from tests/data_partition_test.f90 rename to test/data_partition_test.f90 diff --git a/tests/formats_test.f90 b/test/formats_test.f90 similarity index 100% rename from tests/formats_test.f90 rename to test/formats_test.f90 diff --git a/tests/main.f90 b/test/main.f90 similarity index 100% rename from tests/main.f90 rename to test/main.f90 diff --git a/tests/object_m_test.f90 b/test/object_m_test.f90 similarity index 100% rename from tests/object_m_test.f90 rename to test/object_m_test.f90 diff --git a/tests/user_defined_collectives_test.f90 b/test/user_defined_collectives_test.f90 similarity index 100% rename from tests/user_defined_collectives_test.f90 rename to test/user_defined_collectives_test.f90 From 7856deff6045f5e21586ebf95323b25efecfb55b Mon Sep 17 00:00:00 2001 From: Damian Rouson Date: Tue, 4 Oct 2022 23:42:48 -0700 Subject: [PATCH 7/7] fix(deploy-docs.yml): fix document deployment --- .github/workflows/deploy-docs.yml | 9 +++++---- doc/{ford-documentation.md => ford.md} | 0 2 files changed, 5 insertions(+), 4 deletions(-) rename doc/{ford-documentation.md => ford.md} (100%) diff --git a/.github/workflows/deploy-docs.yml b/.github/workflows/deploy-docs.yml index f9a80a76..97815272 100644 --- a/.github/workflows/deploy-docs.yml +++ b/.github/workflows/deploy-docs.yml @@ -2,9 +2,10 @@ name: Build and Deploy Documentation on: [push, pull_request] + jobs: Build: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 steps: - name: Checkout code @@ -13,13 +14,13 @@ jobs: - name: Install Dependencies Ubuntu run: | sudo apt-get update - sudo apt install -y python-dev python build-essential graphviz - sudo pip install ford + sudo apt install -y python3-dev python3 build-essential graphviz + sudo pip install ford markdown==3.3.4 - name: Build Developer Documenation run: | cd doc - ford ford-documentation.md + ford ford.md - name: Upload Documentation uses: actions/upload-artifact@v2 diff --git a/doc/ford-documentation.md b/doc/ford.md similarity index 100% rename from doc/ford-documentation.md rename to doc/ford.md