on master help sign in
Added test case for System.system (#3281)

* Add test case to reproduce error with System.system. * Extract exit status with WIFEXITED/WEXITSTATUS. It seems that extracting the exit status is more complicated than simply looking at the `int` returned from `system`. I've wrapped `WIFEXITED` and `WEXITSTATUS` in FFI_C in the test case to show that it can be done. - See http://pubs.opengroup.org/onlinepubs/9699919799/functions/system.html - and http://pubs.opengroup.org/onlinepubs/9699919799/functions/waitpid.html Tests POSIX functionality, Windows skips it.

commit2e70b6c04066283ed9d73677fa12caaa9a275614 authorSteven Shaw <steven@steshaw.org> dateWed 3 Aug 2016, 07:07 (10 years ago) parent46c1cd5
10 files changed+132−1
idris.cabal+9 test/TestData.hs+2−1 test/base001/Makefile+11 test/base001/base001.idr+35 test/base001/base001.ipkg+5 test/base001/exit1.c+17 test/base001/expected+25 test/base001/run+10 test/base001/sys.c+11 test/base001/sys.h+7
idris.cabal+9
@@ -293,6 +293,15 @@ Extra-source-files:
293293 test/reg075/*.idr
294294 test/reg075/expected
295295
296+ test/base001/Makefile
297+ test/base001/base001.idr
298+ test/base001/base001.ipkg
299+ test/base001/exit1.c
300+ test/base001/expected
301+ test/base001/run
302+ test/base001/sys.c
303+ test/base001/sys.h
304+
296305 test/basic001/run
297306 test/basic001/*.idr
298307 test/basic001/expected
test/TestData.hs+2−1
@@ -50,6 +50,8 @@ testFamiliesForCodegen codegen =
5050-- The third column is the data for each test
5151testFamiliesData :: [(String, String, [(Index, CompatCodegen)])]
5252testFamiliesData = [
53+ ("base", "Base",
54+ [ ( 1, C_CG )]),
5355 ("basic", "Basic",
5456 [ ( 1, ANY ),
5557 ( 2, ANY ),
@@ -299,4 +301,3 @@ testFamiliesData = [
299301 [ ( 1, ANY ),
300302 ( 2, ANY ),
301303 ( 3, C_CG )])]
302−
test/base001/Makefilenew file+11
@@ -0,0 +1,11 @@
1+.PHONY:
2+all: exit1 sys.o
3+
4+exit1:
5+ @gcc -Wall -o exit1 exit1.c
6+
7+sys.o:
8+ @gcc -Wall -c sys.c
9+
10+clean:
11+ -@rm exit1 sys.o
test/base001/base001.idrnew file+35
@@ -0,0 +1,35 @@
1+module Main
2+
3+import System
4+
5+%include C "sys.h"
6+%link C "sys.o"
7+
8+WIFEXITED : (status : Int) -> IO Bool
9+WIFEXITED status = do
10+ r <- foreign FFI_C "WIFEXITED_" (Int -> IO Int) status
11+ pure $ r /= 0
12+
13+WEXITSTATUS : (status : Int) -> IO Int
14+WEXITSTATUS status = foreign FFI_C "WEXITSTATUS_" (Int -> IO Int) status
15+
16+execute : (cmd : String) -> (expectedStatus : Int) -> IO ()
17+execute cmd expectedStatus = do
18+ putStrLn "-------------------------------------------"
19+ putStrLn $ "Executing '" ++ cmd ++ "'"
20+ status1 <- system cmd
21+ putStrLn $ "raw status = " ++ show status1 -- XXX: Probably not portable.
22+ exited <- WIFEXITED status1
23+ if exited
24+ then do
25+ exitStatus <- WEXITSTATUS status1
26+ putStrLn $ "exit status = " ++ show exitStatus
27+ printLn $ exitStatus == expectedStatus
28+ else pure ()
29+ putStrLn ""
30+
31+main : IO ()
32+main = do
33+ execute "exit 1" 1
34+ execute "./exit1" 1
35+ execute "./does-not-exist" 127
test/base001/base001.ipkgnew file+5
@@ -0,0 +1,5 @@
1+package base001
2+
3+executable = base001
4+main = base001
5+makefile = Makefile
test/base001/exit1.cnew file+17
@@ -0,0 +1,17 @@
1+#include <stdio.h>
2+#include <stdlib.h>
3+
4+void doSystem(const char cmd[]) {
5+ printf("exit1: Executing cmd '%s'\n", cmd);
6+ int exitStatus = system(cmd);
7+ printf("exit1: raw exitStatus = %d\n", exitStatus); // XXX: Probably not portable (hide from expected file).
8+ if (WIFEXITED(exitStatus)) {
9+ printf("exit1: WEXITSTATUS(exitStatus) = %d\n", WEXITSTATUS(exitStatus));
10+ }
11+}
12+
13+int main() {
14+ doSystem("exit 1");
15+ doSystem("./does-not-exist");
16+ return 1;
17+}
test/base001/expectednew file+25
@@ -0,0 +1,25 @@
1+Type checking ./base001.idr
2+exit1: Executing cmd 'exit 1'
3+exit1: raw exitStatus = 256
4+exit1: WEXITSTATUS(exitStatus) = 1
5+exit1: Executing cmd './does-not-exist'
6+exit1: raw exitStatus = 32512
7+exit1: WEXITSTATUS(exitStatus) = 127
8+-------------------------------------------
9+Executing 'exit 1'
10+raw status = 256
11+exit status = 1
12+True
13+
14+-------------------------------------------
15+Executing './exit1'
16+raw status = 256
17+exit status = 1
18+True
19+
20+-------------------------------------------
21+Executing './does-not-exist'
22+raw status = 32512
23+exit status = 127
24+True
25+
test/base001/runnew file+10
@@ -0,0 +1,10 @@
1+#!/usr/bin/env bash
2+
3+if [[ ${OSTYPE} = 'msys' ]]; then
4+ cat expected # skip this test on Windows
5+else
6+ ${IDRIS:-idris} $@ --build base001.ipkg | grep -v 'make.*:'
7+ ./base001
8+ make clean | grep -v 'make.*:'
9+ rm -f *.ibc base001
10+fi
test/base001/sys.cnew file+11
@@ -0,0 +1,11 @@
1+#include "sys.h"
2+
3+#include <stdlib.h>
4+
5+int WIFEXITED_(int status) {
6+ return WIFEXITED(status);
7+}
8+
9+int WEXITSTATUS_(int status) {
10+ return WEXITSTATUS(status);
11+}
test/base001/sys.hnew file+7
@@ -0,0 +1,7 @@
1+#ifndef SYS_H
2+#define SYS_H
3+
4+int WIFEXITED_(int status);
5+int WEXITSTATUS_(int status);
6+
7+#endif