Skip to content

Commit f9bf304

Browse files
committed
fix tests to be cross-platform
1 parent 6fbc2e6 commit f9bf304

File tree

4 files changed

+55
-10
lines changed

4 files changed

+55
-10
lines changed

src/stdlib_system.F90

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ module stdlib_system
1313
public :: is_running
1414
public :: update
1515
public :: wait
16+
public :: elapsed
17+
public :: has_win32
1618

1719
! CPU clock ticks storage
1820
integer, parameter, private :: TICKS = int64
@@ -122,4 +124,11 @@ module subroutine sleep(millisec)
122124
end subroutine sleep
123125
end interface sleep
124126

127+
!! version: experimental
128+
!!
129+
interface
130+
module logical function has_win32()
131+
end function has_win32
132+
end interface
133+
125134
end module stdlib_system

src/stdlib_system_subprocess.F90

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -56,6 +56,12 @@ type(c_ptr) function process_null_device(len) bind(C,name='process_null_device')
5656
implicit none
5757
integer(c_int), intent(out) :: len
5858
end function process_null_device
59+
60+
! Utility: check if _WIN32 is defined in the C compiler
61+
logical(c_bool) function process_has_win32() bind(C,name='process_has_win32')
62+
import c_bool
63+
implicit none
64+
end function process_has_win32
5965

6066
end interface
6167

@@ -455,6 +461,13 @@ function null_device()
455461

456462
end function null_device
457463

464+
!> Returns the file path of the null device for the current operating system.
465+
!>
466+
!> Version: Helper function.
467+
module logical function has_win32()
468+
has_win32 = logical(process_has_win32())
469+
end function has_win32
470+
458471
!> Reads a whole ASCII file and loads its contents into an allocatable character string..
459472
!> The function handles error states and optionally deletes the file after reading.
460473
!> Temporarily uses `linalg_state_type` in lieu of the generalized `state_type`.

src/stdlib_system_subprocess.c

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -263,3 +263,14 @@ const char* process_null_device(int* len)
263263
return "/dev/null";
264264
#endif
265265
}
266+
267+
// Returns a boolean flag if macro _WIN32 is defined
268+
bool process_has_win32()
269+
{
270+
#ifdef _WIN32
271+
return true;
272+
#else
273+
return false;
274+
#endif // _WIN32
275+
}
276+

test/system/test_subprocess.f90

Lines changed: 22 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
module test_subprocess
22
use testdrive, only : new_unittest, unittest_type, error_type, check, skip_test
3-
use stdlib_system, only: process_type, run, is_running, wait, update
3+
use stdlib_system, only: process_type, run, is_running, wait, update, elapsed, has_win32
44

55
implicit none
66

@@ -27,27 +27,36 @@ subroutine test_run_synchronous(error)
2727
process = run(command, wait=.true., want_stdout=.true.)
2828
call check(error, process%completed)
2929
if (allocated(error)) return
30-
31-
call check(error, trim(process%stdout) == "Hello")
30+
31+
call check(error, trim(process%stdout) == "Hello", "stdout=<"//trim(process%stdout)//">, expected <Hello>")
3232
end subroutine test_run_synchronous
3333

3434
!> Test running an asynchronous process
3535
subroutine test_run_asynchronous(error)
3636
type(error_type), allocatable, intent(out) :: error
3737
type(process_type) :: process
3838
logical :: running
39-
character(len=*), parameter :: command = "sleep 1"
4039

41-
process = run(command, wait=.false.)
42-
call check(error, .not. process%completed)
40+
! The closest possible to a cross-platform command that waits
41+
if (has_win32()) then
42+
process = run("ping -n 2 127.0.0.1", wait=.false.)
43+
else
44+
process = run("ping -c 2 127.0.0.1", wait=.false.)
45+
endif
46+
! Should not be immediately completed
47+
call check(error, .not. process%completed, "ping process should not complete immediately")
4348
if (allocated(error)) return
4449

4550
running = is_running(process)
46-
call check(error, running)
51+
call check(error, running, "ping process should still be running immediately after started")
4752
if (allocated(error)) return
4853

4954
call wait(process)
50-
call check(error, process%completed)
55+
call check(error, process%completed, "process should be complete after `call wait`")
56+
if (allocated(error)) return
57+
58+
call check(error, elapsed(process)>1.0e-4, "There should be a non-zero elapsed time")
59+
5160
end subroutine test_run_asynchronous
5261

5362
!> Test updating and checking process state
@@ -62,10 +71,13 @@ subroutine test_process_state(error)
6271
call check(error, process%completed)
6372
if (allocated(error)) return
6473

65-
call check(error, process%exit_code == 0)
74+
call check(error, process%exit_code == 0, "Check zero exit code")
75+
if (allocated(error)) return
76+
77+
call check(error, len_trim(process%stderr) == 0, "Check no stderr output")
6678
if (allocated(error)) return
6779

68-
call check(error, trim(process%stdout) == "Testing")
80+
call check(error, trim(process%stdout) == "Testing", "stdout=<"//trim(process%stdout)//">, expected <Testing>")
6981
if (allocated(error)) return
7082
end subroutine test_process_state
7183

0 commit comments

Comments
 (0)