got a first basic test passing

This commit is contained in:
Arnaud Bailly 2019-07-25 09:43:33 +02:00
parent b5cc727f3b
commit 055a5f2449
No known key found for this signature in database
GPG Key ID: 389CC2BC5448321E
7 changed files with 77 additions and 58 deletions

View File

@ -1,50 +1,50 @@
module Main
import System
import Network.Socket
import Network.Socket.Data
import Network.Socket.Raw
runServer : IO (Either String (Port, Maybe ThreadID))
%cg chez libidris_net.dylib
runServer : IO (Either String (Port, ThreadID))
runServer = do
osock <- socket AF_INET Stream 0
case osock of
Left fail => pure (Left $ "Failed to open socket: " ++ show fail)
Right sock => do
putStrLn "success"
pure $ Right (0,Nothing)
-- do
-- res <- bind sock (Just (Hostname "localhost")) 0
-- if res /= 0
-- then pure (Left $ "Failed to bind socket with error: " ++ show res)
-- else do
-- port <- getSockPort sock
-- res <- listen sock
-- if res /= 0
-- then pure (Left $ "Failed to listen on socket with error: " ++ show res)
-- else do
-- forked <- fork (serve sock)
-- pure $ Right (port, forked)
res <- bind sock (Just (Hostname "localhost")) 0
if res /= 0
then pure (Left $ "Failed to bind socket with error: " ++ show res)
else do
port <- getSockPort sock
res <- listen sock
if res /= 0
then pure (Left $ "Failed to listen on socket with error: " ++ show res)
else do
forked <- fork (serve port sock)
pure $ Right (port, forked)
-- where
-- serve : Socket -> IO ()
-- serve sock = do
-- res <- accept sock
-- case res of
-- Left err => do
-- putStrLn ("Failed to accept on socket with error: " ++ show err)
-- Right (s, _) => do
-- received <- recv s 1024
-- case received of
-- Left err => do
-- putStrLn ("Failed to accept on socket with error: " ++ show err)
-- Right (str, _) => do
-- putStrLn ("Received: " ++ str)
-- sent <- send s ("echo: " ++ str)
-- case sent of
-- Left err => do
-- putStrLn ("Server failed to send data with error: " ++ show err)
-- Right n =>
-- putStrLn ("Server sent " ++ show n ++ " bytes")
where
serve : Port -> Socket -> IO ()
serve port sock = do
res <- accept sock
case res of
Left err => do
putStrLn ("Failed to accept on socket with error: " ++ show err)
Right (s, _) => do
received <- recv s 1024
case received of
Left err => do
putStrLn ("Failed to accept on socket with error: " ++ show err)
Right (str, _) => do
putStrLn ("Received: " ++ str)
sent <- send s ("echo: " ++ str)
case sent of
Left err => do
putStrLn ("Server failed to send data with error: " ++ show err)
Right n =>
putStrLn ("Server sent " ++ show n ++ " bytes")
runClient : Port -> IO ()
runClient serverPort = do
@ -54,7 +54,7 @@ runClient serverPort = do
Right sock => do
res <- connect sock (Hostname "localhost") serverPort
if res /= 0
then putStrLn ("Failed to connect client to port " ++ show serverPort)
then putStrLn ("Failed to connect client to port " ++ show serverPort ++ ": " ++ show res)
else do
sent <- send sock ("hello world!")
case sent of
@ -69,9 +69,10 @@ runClient serverPort = do
Right (str, _) => do
putStrLn ("Received: " ++ str)
-- main : IO ()
-- main = do
-- server <- runServer
-- case server of
-- Left err => putStrLn $ "[server] " ++ err
-- Right (serverPort, tid) => runClient serverPort
main : IO ()
main = do
server <- runServer
case server of
Left err => putStrLn $ "[server] " ++ err
Right (serverPort, tid) => do
runClient serverPort

View File

@ -29,16 +29,17 @@ LIBNAME=idris_net
OBJS = $(LIBNAME).o
HDRS = $(LIBNAME).h
CFLAGS := $(CFLAGS)
IDRIS_SRCS = Network/Socket.idr Network/Socket/Data.idr Network/Socket/Raw.idr
ifneq ($(OS), windows)
CFLAGS += -fPIC
endif
DYLIBTARGET = lib$(LIBNAME)$(SHLIB_SUFFIX)
DYLIBTARGET = $(LIBNAME)$(SHLIB_SUFFIX)
LIBTARGET = $(LIBNAME).a
TARGET=${HOME}/.idris2
build: $(DYLIBTARGET)
build: $(DYLIBTARGET) $(IDRIS_SRCS)
@if ! [ -d build ]; then echo "creating 'build' directory"; mkdir build ; else echo "directory 'build' exists"; fi
@if [ -z "${IDRIS2}" ]; then echo 'variable $$IDRIS2 is not set, aborting'; exit 1; fi
${IDRIS2} --build network.ipkg
@ -53,13 +54,15 @@ install:
clean :
rm -rf $(OBJS) $(LIBTARGET) $(DYLIBTARGET) build
test: $(DYLIBTARGET)
test: build test.c
$(CC) -o network-tests -L. -I. -l$(LIBNAME) test.c
./network-tests
${IDRIS2} --exec main Echo.idr > build/output
@if ! [ -z "$(diff build/output expected)" ]; then echo "TEST FAILURE: unexpected build/output"; exit 2; else echo "TEST SUCCESS"; fi
$(OBJS): $(HDRS)
all: $(DYLIBTARGET) $(LIBTARGET)
${IDRIS2} --build network.ipkg
.PHONY: build install clean
.PHONY: install clean

View File

@ -60,7 +60,7 @@ EAGAIN =
export
getErrno : IO SocketError
getErrno = cCall SocketError "idrnet_errno" []
getErrno = cCall Int "idrnet_errno" []
export
nullPtr : Ptr -> IO Bool

View File

@ -40,7 +40,7 @@ sock_alloc bl = map BPtr $ cCall Ptr "idrnet_malloc" [bl]
||| Retrieves the port the given socket is bound to
export
getSockPort : Socket -> IO Port
getSockPort sock = cCall Port "idrnet_sockaddr_port" [descriptor sock]
getSockPort sock = cCall Int "idrnet_sockaddr_port" [descriptor sock]
||| Retrieves a socket address from a sockaddr pointer
@ -101,7 +101,7 @@ recvBuf : (sock : Socket)
-> (len : ByteLength)
-> IO (Either SocketError ResultCode)
recvBuf sock (BPtr ptr) len = do
recv_res <- cCall ResultCode "idrnet_recv_buf" [ descriptor sock, ptr, len ]
recv_res <- cCall Int "idrnet_recv_buf" [ descriptor sock, ptr, len ]
if (recv_res == (-1))
then map Left getErrno
@ -125,7 +125,7 @@ sendToBuf : (sock : Socket)
-> (len : ByteLength)
-> IO (Either SocketError ResultCode)
sendToBuf sock addr p (BPtr dat) len = do
sendto_res <- cCall ResultCode "idrnet_sendto_buf"
sendto_res <- cCall Int "idrnet_sendto_buf"
[ descriptor sock, dat, len, show addr, p, toCode $ family sock ]
if sendto_res == (-1)

4
libs/network/expected Normal file
View File

@ -0,0 +1,4 @@
Client sent 12 bytes
Received: hello world!
Server sent 18 bytes
Received: echo: hello world!

View File

@ -92,7 +92,7 @@ int idrnet_getaddrinfo(struct addrinfo** address_res, char* host, int port,
}
int idrnet_bind(int sockfd, int family, int socket_type, char* host, int port) {
struct addrinfo* address_res;
struct addrinfo *address_res;
int addr_res = idrnet_getaddrinfo(&address_res, host, port, family, socket_type);
if (addr_res != 0) {
//printf("Lib err: bind getaddrinfo\n");
@ -128,9 +128,9 @@ int idrnet_sockaddr_port(int sockfd) {
switch(address.sa_family) {
case AF_INET:
return ((struct sockaddr_in*)&address)->sin_port;
return ntohs(((struct sockaddr_in*)&address)->sin_port);
case AF_INET6:
return ((struct sockaddr_in6*)&address)->sin6_port;
return ntohs(((struct sockaddr_in6*)&address)->sin6_port);
default:
return -1;
}

View File

@ -11,9 +11,7 @@ void test_eagain() {
}
void test_bind_to_0_assigns_random_port() {
struct sockaddr_in address;
socklen_t addrlen = sizeof(struct sockaddr);
void test_sockaddr_port_returns_random_port_when_bind_port_is_0() {
int sock = idrnet_socket(AF_INET, 1, 0);
assert(sock > 0);
@ -23,14 +21,27 @@ void test_bind_to_0_assigns_random_port() {
res = idrnet_sockaddr_port(sock);
assert(res > 0);
printf("socket bound to %d\n",res);
close(sock);
}
void test_sockaddr_port_returns_explicitly_assigned_port() {
int sock = idrnet_socket(AF_INET, 1, 0);
assert(sock > 0);
int res = idrnet_bind(sock, AF_INET, 1, "127.0.0.1", 34567);
assert(res == 0);
res = idrnet_sockaddr_port(sock);
assert(res == 34567);
close(sock);
}
int main(int argc, char**argv) {
test_eagain();
test_bind_to_0_assigns_random_port();
test_sockaddr_port_returns_explicitly_assigned_port();
test_sockaddr_port_returns_random_port_when_bind_port_is_0();
printf("network library tests SUCCESS\n");
return 0;