-
Notifications
You must be signed in to change notification settings - Fork 94
Fix struct dirent d_type macro test #348
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
base: master
Are you sure you want to change the base?
Conversation
Credit to Andrew Gunnerson (@chenxiaolong)
@sjshuck could you add a test please? |
I'm a little stuck on how to skip the test if Do all test containers have a |
I think so, these are generic CI machines, not bare minimum containers. Is |
I'm not sure TBH. I don't know how standard of a macro that is, how much it has to do with GNU, Linux, ... I did the test another way, compiling optimistically with |
a459fc8
to
9eb439b
Compare
9eb439b
to
c18caa0
Compare
tests/DirEnt.c
Outdated
} | ||
} | ||
|
||
int main() { |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I don't understand the purpose of this. We check for headers and library functions in configure.ac
Lines 30 to 66 in eced23b
AC_STRUCT_DIRENT_D_TYPE | |
FP_CHECK_CONST([DT_UNKNOWN], [ | |
#if HAVE_STRUCT_DIRENT_D_TYPE | |
#include <dirent.h> | |
#endif], [-1]) | |
FP_CHECK_CONST([DT_FIFO], [ | |
#if HAVE_STRUCT_DIRENT_D_TYPE | |
#include <dirent.h> | |
#endif], [-2]) | |
FP_CHECK_CONST([DT_CHR], [ | |
#if HAVE_STRUCT_DIRENT_D_TYPE | |
#include <dirent.h> | |
#endif], [-3]) | |
FP_CHECK_CONST([DT_DIR], [ | |
#if HAVE_STRUCT_DIRENT_D_TYPE | |
#include <dirent.h> | |
#endif], [-4]) | |
FP_CHECK_CONST([DT_BLK], [ | |
#if HAVE_STRUCT_DIRENT_D_TYPE | |
#include <dirent.h> | |
#endif], [-5]) | |
FP_CHECK_CONST([DT_REG], [ | |
#if HAVE_STRUCT_DIRENT_D_TYPE | |
#include <dirent.h> | |
#endif], [-6]) | |
FP_CHECK_CONST([DT_LNK], [ | |
#if HAVE_STRUCT_DIRENT_D_TYPE | |
#include <dirent.h> | |
#endif], [-7]) | |
FP_CHECK_CONST([DT_SOCK], [ | |
#if HAVE_STRUCT_DIRENT_D_TYPE | |
#include <dirent.h> | |
#endif], [-8]) | |
FP_CHECK_CONST([DT_WHT], [ | |
#if HAVE_STRUCT_DIRENT_D_TYPE | |
#include <dirent.h> | |
#endif], [-9]) |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Explaining in a comment in the code.
tests/DirEnt.c
Outdated
* The purpose of this C program is to do one of 4 things. Which one it does, | ||
* indicates to the DirEnt test suite something it ought to do. | ||
* | ||
* fail to compile |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This can be done in configure.ac
via AC_LINK_IFELSE
and AC_LANG_PROGRAM
, no?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I'm not sure; this is beyond the limit of my C build chain knowledge.
tests/DirEnt.c
Outdated
* exit with status 0 | ||
* This means the "." entry in the DIR stream opened at ".", guaranteed to be | ||
* a directory, has a d_type of DT_DIR. We should proceed with a test for it | ||
* in Haskell. | ||
* exit with status 1 | ||
* This means something unexpected went wrong. Fail the Haskell test also. | ||
* exit with stauts 2 | ||
* This means the "." entry has a d_type of DT_UNKNOWN. This is valid; no | ||
* filesystem or operating system is required to yield a useful d_type. | ||
* We should skip testing for non-DT_UNKNOWN values in Haskell. |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Why can't we do this check in Haskell?
tests/DirEnt.hs
Outdated
|
||
prepareTest :: IO () | ||
prepareTest = do | ||
system_x "cc --version" `onFailure` exitWith |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is highly non-portable. I'd prefer to remove the c-tests altogether, do "static" checks in configure.ac
and do additional runtime checks (whether the kernel just returns DT_UNKNOWN
) in the Haskell code itself.
If we really want to run C code, we can compile it properly through cabal and use the C FFI to run the appropriate function. I do not understand why we compile manually in the test suite and produce a binary here.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The thing being tested is: When d_type
is defined and the filesystem supports non-zero values for it, test that dirEntType
works and doesn't return 0 because someone defined it wrong in cbits/HsUnix.c
. Because that's what happened. I can't think of any other way to test for that than what I did.
I don't know how autotools works, but intuitively, doing checks in configure.ac
is testing a macro with a macro, which doesn't buy us anything. We can't check if the kernel returns DT_UNKNOWN
because kernels are always allowed to return two values for any node, DT_THE_ACTUAL_TYPE
and DT_UNKNOWN
—you can't fix that by configuring the CI image. We need to know what the kernel thinks the d_type
is, and check if dirEntType
agrees with that, hence the non-Haskell (C) program. We can't compile it via Cabal because it should be allowed to fail to compile, unless there's an "allow-fail" option I'm not aware of. We can guard against compilation failures by doing the appropriate macro test in C, but again, that doesn't buy us anything.
My opinion: #347 is below the threshold of testability. In practice that happens sometimes. However, if we're going to change the thing being tested from what I wrote above to something else, and implement that test, I'm all for it. I just want to know what we're testing. cc @Bodigrim
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
When d_type is defined and the filesystem supports non-zero values for it,
Yes, these absolutely can be tested for in configure.ac
. I think one of my comments got swallowed by GitHub.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Okay, you had alluded to it above. I need to take a break from this for a while.
Meanwhile, something that occurred to me that could actually be the sweet spot for trade-off between complexity and correctness in testing: Assume that for Linux, GitHub CI and Hackage CI always make .
have d_type
DT_DIR
, and test exactly that with dirEntType
, and only run it under Linux. If it returns UnknownType
or some other value, fail the test noisily, running mount(8)
, and deal with that when that happens. I bet you it never will. Let me know what you think
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Assume that for Linux, GitHub CI and Hackage CI always make
.
haved_type
DT_DIR
, and test exactly that withdirEntType
, and only run it under Linux. If it returnsUnknownType
or some other value, fail the test noisily, runningmount(8)
, and deal with that when that happens.
I think it's good enough and strikes a good balance. Although I do not get what mount(8)
reference is about.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Cool. When I get a chance I'll make that change. I was talking about dumping mount points to the console to analyze if the CI container had changed to some exotic fs that didn't support non-zero d_type
s. Although I think I'll use /proc/self
's dirent instead of .
's, since that's as guaranteed to fully support d_type
as anything.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
It's technically a non-portable test and so I think it should be guarded behind a cabal flag. Maybe non-portable-tests
?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
@hasufell I disabled it for non-Linux in unix.cabal
but maybe that's not what you're talking about. I set "Allow edits by maintainers" so please feel free to add any Cabal flags.
…Type /proc/self is guaranteed to exist as a symlink on Linux and procfs has emitted its d_type for decades.
Temporarily changed back to the incorrect
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Awesome!
Fixes #347. Credit to Andrew Gunnerson (@chenxiaolong).
Test program:
Output for unix-2.8.7.0:
Output with this change: