Unit testing with `testthat` on functions that write/read files, or a Fortran error

456 views Asked by At

What is the best way to make unit testing with testthat on functions that read and write files?

Apologies for asking a complicated question, but I am not sure what is wrong here.

I have implemented a number of functions in Fortran, that reads and writes files. They are compiled in an R package cf. Writing R Extension manual. My unit testing with testthat generates random content that is written to temporary files with tempfile(). Running R CMD check on the R package works on my local Windows machine.

Running with R-devel fails however because it cannot detect Rtools for R-3.5.0 (devel). So I submitted to win-builder.

http://win-builder.r-project.org/ however fails with the following error:

  At line 9 of file auxil.f95
Fortran runtime error: Actual string length is shorter than the declared one for dummy argument 'fn' (96/255)

with corresponding Fortran source:

subroutine get_nlines(fn, nlines, stat) !line 9
  implicit none

  !! Arguments
  character(255), intent(in) :: fn
  integer, intent(out) :: nlines, stat

  !! Local variables
  character(len=1) :: one

  nlines = 0
  open(40, file=fn, status='OLD')
  do
    read(40, *, iostat=stat) one
    if (stat /= 0) exit
    nlines = nlines + 1
  end do
  close(40)

end subroutine

The Fortran code is stored in the src subdirectory of the R package, and is called with

get_nlines <- function(fn) {
  stopifnot(file.exists(fn))
  res <- .Fortran('get_nlines', fn=as.character(fn), nlines=integer(1), stat=integer(1))
  if (res$nlines == 0 & res$stat != 0) {
    warning(paste0('get_nlines did not read lines; IOSTAT error ', res$stat, '.'))
    return(structure(NA, code=res$stat))
  }
  res$nlines
}

So there it is. I don't know if my Fortran code is wrong, or if it's something that occurs on the win-builder server.

1

There are 1 answers

4
Vladimir F Героям слава On

"I don't know if my Fortran code is wrong" I still simply don't understand from your question if the code you have shown is "the" your code or if it is inside some R package you are using.

If it is the Fortran code you are speaking about (you didn't show anything else), then you should try character(*) instead of character(255), because there is no apparent reason for the exact fixed length 255. That is exactly what the error message complains about, that fn is not exactly 255 chars long as you require in get_nlines().