From b29fa5a40e04f4243c15391b70c37ebce0198fc1 Mon Sep 17 00:00:00 2001 From: Sergey Kudryashov Date: Mon, 4 Aug 2014 18:11:55 +0400 Subject: Add async_ports test --- erts/emulator/test/Makefile | 1 + erts/emulator/test/async_ports_SUITE.erl | 117 +++++++++++++++++++++ .../test/async_ports_SUITE_data/Makefile.src | 5 + erts/emulator/test/async_ports_SUITE_data/cport.c | 65 ++++++++++++ 4 files changed, 188 insertions(+) create mode 100644 erts/emulator/test/async_ports_SUITE.erl create mode 100644 erts/emulator/test/async_ports_SUITE_data/Makefile.src create mode 100644 erts/emulator/test/async_ports_SUITE_data/cport.c (limited to 'erts/emulator/test') diff --git a/erts/emulator/test/Makefile b/erts/emulator/test/Makefile index 0b0568c31a..dfbe47786a 100644 --- a/erts/emulator/test/Makefile +++ b/erts/emulator/test/Makefile @@ -31,6 +31,7 @@ MODULES= \ a_SUITE \ after_SUITE \ alloc_SUITE \ + async_ports_SUITE \ beam_SUITE \ beam_literals_SUITE \ bif_SUITE \ diff --git a/erts/emulator/test/async_ports_SUITE.erl b/erts/emulator/test/async_ports_SUITE.erl new file mode 100644 index 0000000000..9e0cc8ffab --- /dev/null +++ b/erts/emulator/test/async_ports_SUITE.erl @@ -0,0 +1,117 @@ +-module(async_ports_SUITE). + +-include_lib("common_test/include/ct.hrl"). + +-compile(export_all). + +-define(PACKET_SIZE, (10 * 1024 * 8)). +-define(CPORT_DELAY, 100). +-define(TEST_LOOPS_COUNT, 100000). +-define(SLEEP_BEFORE_CHECK, 1000). +-define(TEST_PROCS_COUNT, 2). +-define(TC_TIMETRAP_SECONDS, 10). + + +all() -> + [ + permanent_busy_test + ]. + +permanent_busy_test(Config) -> + ct:timetrap({seconds, ?TC_TIMETRAP_SECONDS}), + ExePath = filename:join(?config(data_dir, Config), "cport"), + + Self = self(), + spawn_link( + fun() -> + Block = <<0:?PACKET_SIZE>>, + + Port = open_port(ExePath), + + Testers = + lists:map( + fun(_) -> + erlang:spawn_link(?MODULE, run_loop, + [Self, + Port, + Block, + ?TEST_LOOPS_COUNT, + 0]) + end, + lists:seq(1, ?TEST_PROCS_COUNT)), + Self ! {test_info, Port, Testers}, + endless_flush(Port) + end), + + receive + {test_info, Port, Testers} -> + MaxWaitTime = round(0.7 * ?TC_TIMETRAP_SECONDS * 1000), + ct:log("wait testers, maximum ~w mcsec~n", [MaxWaitTime]), + ok = wait_testers(MaxWaitTime, Testers), + timer:sleep(?SLEEP_BEFORE_CHECK), + case erlang:port_command(Port, <<"test">>, [nosuspend]) of + false -> + exit(port_dead); + true -> + ok + end + end. + +wait_testers(Timeout, Testers) -> + lists:foldl( + fun(Pid, AccIn) -> + StartWait = os:timestamp(), + receive + {Pid, port_dead} -> + recalc_timeout(AccIn, StartWait) + after AccIn -> + Pid ! stop, + recalc_timeout(AccIn, StartWait) + end + end, Timeout, Testers), + ok. + +recalc_timeout(TimeoutIn, WaitStart) -> + erlang:max(0, TimeoutIn - round(timer:now_diff(os:timestamp(), WaitStart)) div 1000). + +open_port(ExePath) -> + erlang:open_port({spawn, ExePath ++ " 100"}, [{packet, 4}, eof, exit_status, use_stdio, binary]). + +run_loop(RootProc, Port, Block, CheckLimit, BusyCnt) -> + receive + stop -> + ok + after 0 -> + case erlang:port_command(Port, Block, [nosuspend]) of + true -> + run_loop(RootProc, Port, Block, CheckLimit, 0); + false -> + if + BusyCnt + 1 > CheckLimit -> + check_dead(RootProc, Port, Block, CheckLimit); + true -> + run_loop(RootProc, Port, Block, CheckLimit, BusyCnt + 1) + end + end + end. + +check_dead(RootProc, Port, Block, CheckLimit) -> + ct:log("~p: check port dead~n", [self()]), + timer:sleep(?SLEEP_BEFORE_CHECK), + case erlang:port_command(Port, Block, [nosuspend]) of + true -> + ct:log("not dead~n"), + run_loop(RootProc, Port, Block, CheckLimit, 0); + false -> + ct:log("port dead: ~p~n", [Port]), + RootProc ! {self(), port_dead}, + ok + end. + +endless_flush(Port) -> + receive + {Port, {data, _}} -> + endless_flush(Port); + {Port, SomethingWrong} -> + erlang:error({someting_wrong, SomethingWrong}) + end. diff --git a/erts/emulator/test/async_ports_SUITE_data/Makefile.src b/erts/emulator/test/async_ports_SUITE_data/Makefile.src new file mode 100644 index 0000000000..17e6a6ee6a --- /dev/null +++ b/erts/emulator/test/async_ports_SUITE_data/Makefile.src @@ -0,0 +1,5 @@ +all: busy_drv@dll@ hard_busy_drv@dll@ soft_busy_drv@dll@ scheduling_drv@dll@ + +@SHLIB_RULES@ + +cport@obj@: cport.c diff --git a/erts/emulator/test/async_ports_SUITE_data/cport.c b/erts/emulator/test/async_ports_SUITE_data/cport.c new file mode 100644 index 0000000000..179cdc4b8b --- /dev/null +++ b/erts/emulator/test/async_ports_SUITE_data/cport.c @@ -0,0 +1,65 @@ +#include +#include +#include +#include +#include +#include + +typedef unsigned char byte; + +int read_cmd(byte *buf) +{ + int len; + if (read_exact(buf, 4) != 4) + return(-1); + + len = (buf[0] << 24) | (buf[1] << 16) | (buf[2] << 8) | buf[3]; + return read_exact(buf, len); +} + +int write_cmd(byte *buf, int len) +{ + byte li[4]; + li[0] = (len >> 24) & 0xff; + li[1] = (len >> 16) & 0xff; + li[2] = (len >> 8) & 0xff; + li[3] = len & 0xff; + write_exact(&li, 4); + + return write_exact(buf, len); +} + +int read_exact(byte *buf, int len) +{ + int i, got=0; + do { + if ((i = read(0, buf+got, len-got)) <= 0) + { + return(i); + } + got += i; + } while (got 0) { + usleep(sleep_time); + write_cmd(buf, len); + } +} -- cgit v1.2.3 From ace34ce01c9378525d024246c7d76ab01add4a8d Mon Sep 17 00:00:00 2001 From: kudryashov-sv Date: Mon, 4 Aug 2014 20:55:17 +0400 Subject: Update Makefile.src --- erts/emulator/test/async_ports_SUITE_data/Makefile.src | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'erts/emulator/test') diff --git a/erts/emulator/test/async_ports_SUITE_data/Makefile.src b/erts/emulator/test/async_ports_SUITE_data/Makefile.src index 17e6a6ee6a..d2cd90f5b3 100644 --- a/erts/emulator/test/async_ports_SUITE_data/Makefile.src +++ b/erts/emulator/test/async_ports_SUITE_data/Makefile.src @@ -1,4 +1,4 @@ -all: busy_drv@dll@ hard_busy_drv@dll@ soft_busy_drv@dll@ scheduling_drv@dll@ +all: cport@obj@ @SHLIB_RULES@ -- cgit v1.2.3 From cde6c2e042834d66649308093d5522c1a2001949 Mon Sep 17 00:00:00 2001 From: Rickard Green Date: Tue, 5 Aug 2014 18:04:46 +0200 Subject: Fix build of test port program --- erts/emulator/test/async_ports_SUITE.erl | 1 + .../test/async_ports_SUITE_data/Makefile.src | 14 ++++++++++++-- erts/emulator/test/async_ports_SUITE_data/cport.c | 22 +++++++++++++++++++--- 3 files changed, 32 insertions(+), 5 deletions(-) (limited to 'erts/emulator/test') diff --git a/erts/emulator/test/async_ports_SUITE.erl b/erts/emulator/test/async_ports_SUITE.erl index 9e0cc8ffab..c89b3655ff 100644 --- a/erts/emulator/test/async_ports_SUITE.erl +++ b/erts/emulator/test/async_ports_SUITE.erl @@ -11,6 +11,7 @@ -define(TEST_PROCS_COUNT, 2). -define(TC_TIMETRAP_SECONDS, 10). +suite() -> [{ct_hooks,[ts_install_cth]}]. all() -> [ diff --git a/erts/emulator/test/async_ports_SUITE_data/Makefile.src b/erts/emulator/test/async_ports_SUITE_data/Makefile.src index d2cd90f5b3..56da3fbe12 100644 --- a/erts/emulator/test/async_ports_SUITE_data/Makefile.src +++ b/erts/emulator/test/async_ports_SUITE_data/Makefile.src @@ -1,5 +1,15 @@ -all: cport@obj@ +CC = @CC@ +LD = @LD@ +CFLAGS = @CFLAGS@ @DEFS@ +CROSSLDFLAGS = @CROSSLDFLAGS@ -@SHLIB_RULES@ +PROGS = cport@exe@ + + +all: $(PROGS) + +cport@exe@: cport@obj@ + $(LD) $(CROSSLDFLAGS) -o cport cport@obj@ @LIBS@ cport@obj@: cport.c + $(CC) -c -o cport@obj@ $(CFLAGS) cport.c diff --git a/erts/emulator/test/async_ports_SUITE_data/cport.c b/erts/emulator/test/async_ports_SUITE_data/cport.c index 179cdc4b8b..033aff382a 100644 --- a/erts/emulator/test/async_ports_SUITE_data/cport.c +++ b/erts/emulator/test/async_ports_SUITE_data/cport.c @@ -1,9 +1,13 @@ #include #include -#include #include #include -#include +#ifdef __WIN32__ +# include "windows.h" +# include "winbase.h" +#else +# include +#endif typedef unsigned char byte; @@ -53,13 +57,25 @@ int write_exact(byte *buf, int len) return len; } +byte static_buf[31457280]; // 30 mb + int main(int argc, char **argv) { int sleep_time = atoi(argv[1]); int fn, arg, res; - byte *buf = malloc(31457280); // 30 mb + byte *buf = &static_buf[0]; int len = 0; + if (sleep_time <= 0) + sleep_time = 0; +#ifdef __WIN32__ + else + sleep_time = ((sleep_time - 1) / 1000) + 1; /* Milli seconds */ +#endif while ((len = read_cmd(buf)) > 0) { +#ifdef __WIN32__ + Sleep((DWORD) sleep_time); +#else usleep(sleep_time); +#endif write_cmd(buf, len); } } -- cgit v1.2.3