Skip to content

Commit c18caa0

Browse files
committed
Add test for dirEntType
1 parent 1f571bc commit c18caa0

File tree

3 files changed

+115
-0
lines changed

3 files changed

+115
-0
lines changed

tests/DirEnt.c

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#include <dirent.h>
2+
#include <errno.h>
3+
#include <stdio.h>
4+
#include <stdlib.h>
5+
#include <string.h>
6+
#include <sys/types.h>
7+
8+
void check_error(const char *msg) {
9+
if (errno) {
10+
perror(msg);
11+
exit(1);
12+
}
13+
}
14+
15+
int main() {
16+
printf("Testing struct dirent d_type in C\n");
17+
18+
DIR *dir = opendir(".");
19+
check_error("opendir");
20+
21+
struct dirent *de = NULL;
22+
23+
do {
24+
de = readdir(dir);
25+
check_error("readdir");
26+
} while (de && strcmp(de->d_name, ".") != 0);
27+
// We found the . dir or encountered end of dir stream
28+
29+
int status = 0;
30+
31+
if (!de) {
32+
printf("Read the whole . dir without encountering \".\"!\n");
33+
status = 1;
34+
} else if (de->d_type == DT_DIR) {
35+
printf("Got DT_DIR for d_type for \".\"\n");
36+
} else if (de->d_type == DT_UNKNOWN) {
37+
printf("Got DT_UNKNOWN for d_type for \".\"\n");
38+
// Signal that we should skip test for non-zero d_type
39+
status = 2;
40+
} else {
41+
printf("Got %d for d_type for \".\"!\n", (int)de->d_type);
42+
status = 1;
43+
}
44+
45+
closedir(dir);
46+
check_error("closedir");
47+
48+
exit(status);
49+
}

tests/DirEnt.hs

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
{-# LANGUAGE LambdaCase #-}
2+
3+
module Main (main) where
4+
5+
import Control.Exception (bracket, finally)
6+
import Foreign.C.String (peekCString)
7+
import System.Exit
8+
import System.Posix.Directory
9+
import System.Posix.Directory.Internals
10+
import System.Process (system)
11+
12+
system_x :: String -> IO ExitCode
13+
system_x cmd = system $ "set -x; " ++ cmd
14+
15+
onFailure :: IO ExitCode -> (ExitCode -> IO ()) -> IO ()
16+
action `onFailure` after = action >>= \case
17+
ExitSuccess -> return ()
18+
ec -> after ec
19+
infixr 9 `onFailure`
20+
21+
prepareTest :: IO ()
22+
prepareTest = do
23+
system_x "cc --version" `onFailure` exitWith
24+
system_x "[ -f tests/DirEnt.c ]" `onFailure` \ec -> do
25+
putStrLn "Not running tests from root of repo?"
26+
exitWith ec
27+
system_x "cc tests/DirEnt.c -o DirEnt-test" `onFailure` \_ -> do
28+
putStrLn "d_type not available? Skipping Haskell test"
29+
exitSuccess
30+
-- As written, this C code exits with 2 if it determines the Haskell test
31+
-- for broken dirEntType will be a false positive
32+
system_x "./DirEnt-test" `onFailure` \case
33+
ExitFailure 2 -> putStrLn "Skipping Haskell test" >> exitSuccess
34+
ec -> exitWith ec
35+
36+
peekDirEnt :: DirEnt -> IO (String, DirType)
37+
peekDirEnt dirEnt = do
38+
dName <- dirEntName dirEnt >>= peekCString
39+
dType <- dirEntType dirEnt
40+
return (dName, dType)
41+
42+
testDirTypeOfDot :: DirStream -> IO ()
43+
testDirTypeOfDot dirStream = go where
44+
go = readDirStreamWith peekDirEnt dirStream >>= \case
45+
Just (".", DirectoryType) -> do
46+
putStrLn "Got DirectoryType for . dir"
47+
exitSuccess
48+
Just (".", dType) -> die $ "Got " ++ show dType ++ " for . dir!"
49+
Just _ -> go
50+
Nothing -> die "Read cwd in Haskell and didn't find . dir!"
51+
52+
main :: IO ()
53+
main = do
54+
putStrLn "Preparing Haskell test of dirEntType"
55+
prepareTest `finally` system_x "rm -f DirEnt-test"
56+
57+
putStrLn "Running Haskell test of dirEntType"
58+
bracket (openDirStream ".") closeDirStream testDirTypeOfDot

unix.cabal

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -382,3 +382,11 @@ test-suite T13660
382382
else
383383
build-depends: filepath >= 1.4.100.0 && < 1.5.0.0
384384
ghc-options: -Wall
385+
386+
test-suite DirEnt
387+
hs-source-dirs: tests
388+
main-is: DirEnt.hs
389+
type: exitcode-stdio-1.0
390+
default-language: Haskell2010
391+
build-depends: base, unix, process
392+
ghc-options: -Wall

0 commit comments

Comments
 (0)