diff options
Diffstat (limited to 'erts/emulator/test')
-rw-r--r-- | erts/emulator/test/port_bif_SUITE.erl | 391 |
1 files changed, 206 insertions, 185 deletions
diff --git a/erts/emulator/test/port_bif_SUITE.erl b/erts/emulator/test/port_bif_SUITE.erl index d9c82aba0e..8feea87d7e 100644 --- a/erts/emulator/test/port_bif_SUITE.erl +++ b/erts/emulator/test/port_bif_SUITE.erl @@ -24,6 +24,7 @@ init_per_group/2,end_per_group/2, command/1, command_e_1/1, command_e_2/1, command_e_3/1, command_e_4/1, port_info1/1, port_info2/1, + port_info_os_pid/1, connect/1, control/1, echo_to_busy/1]). -export([do_command_e_1/1, do_command_e_2/1, do_command_e_4/1]). @@ -41,7 +42,7 @@ all() -> groups() -> [{command_e, [], [command_e_1, command_e_2, command_e_3, command_e_4]}, - {port_info, [], [port_info1, port_info2]}]. + {port_info, [], [port_info1, port_info2, port_info_os_pid]}]. init_per_suite(Config) -> Config. @@ -65,15 +66,15 @@ end_per_testcase(_Func, Config) when is_list(Config) -> test_server:timetrap_cancel(Dog). command(Config) when is_list(Config) -> - ?line load_control_drv(Config), - - ?line P = open_port({spawn, control_drv}, []), - ?line do_command(P, "hello"), - ?line do_command(P, <<"hello">>), - ?line do_command(P, sub_bin(<<"1234kalle">>)), - ?line do_command(P, unaligned_sub_bin(<<"blurf">>)), - ?line do_command(P, ["bl"|unaligned_sub_bin(<<"urf">>)]), - ?line true = erlang:port_close(P), + load_control_drv(Config), + + P = open_port({spawn, control_drv}, []), + do_command(P, "hello"), + do_command(P, <<"hello">>), + do_command(P, sub_bin(<<"1234kalle">>)), + do_command(P, unaligned_sub_bin(<<"blurf">>)), + do_command(P, ["bl"|unaligned_sub_bin(<<"urf">>)]), + true = erlang:port_close(P), ok. do_command(P, Data) -> @@ -94,139 +95,163 @@ do_command(P, Data) -> %% port_command/2: badarg 1st arg command_e_1(Config) when is_list(Config) -> - ?line DataDir = ?config(data_dir, Config), - ?line Program = filename:join(DataDir, "port_test"), + DataDir = ?config(data_dir, Config), + Program = filename:join(DataDir, "port_test"), process_flag(trap_exit, true), - ?line _ = spawn_link(?MODULE, do_command_e_1, [Program]), - ?line receive - {'EXIT', Pid, {badarg, _}} when is_pid(Pid) -> - ok; - Other -> - ?line test_server:fail(Other) - after 10000 -> - ?line test_server:fail(timeout) - end, + _ = spawn_link(?MODULE, do_command_e_1, [Program]), + receive + {'EXIT', Pid, {badarg, _}} when is_pid(Pid) -> + ok; + Other -> + test_server:fail(Other) + after 10000 -> + test_server:fail(timeout) + end, ok. do_command_e_1(Program) -> - ?line _ = open_port({spawn, Program}, []), - ?line erlang:port_command(apple, "plock"), + _ = open_port({spawn, Program}, []), + erlang:port_command(apple, "plock"), exit(survived). %% port_command/2: badarg 2nd arg command_e_2(Config) when is_list(Config) -> - ?line DataDir = ?config(data_dir, Config), - ?line Program = filename:join(DataDir, "port_test"), + DataDir = ?config(data_dir, Config), + Program = filename:join(DataDir, "port_test"), process_flag(trap_exit, true), - ?line _ = spawn_link(?MODULE, do_command_e_2, [Program]), - ?line receive - {'EXIT', Pid, {badarg, _}} when is_pid(Pid) -> - ok; - Other -> - ?line test_server:fail(Other) - after 10000 -> - ?line test_server:fail(timeout) - end, + _ = spawn_link(?MODULE, do_command_e_2, [Program]), + receive + {'EXIT', Pid, {badarg, _}} when is_pid(Pid) -> + ok; + Other -> + test_server:fail(Other) + after 10000 -> + test_server:fail(timeout) + end, ok. do_command_e_2(Program) -> - ?line P = open_port({spawn, Program}, []), - ?line erlang:port_command(P, 1), + P = open_port({spawn, Program}, []), + erlang:port_command(P, 1), exit(survived). %% port_command/2: Posix signals trapped command_e_3(Config) when is_list(Config) -> - ?line DataDir = ?config(data_dir, Config), - ?line Program = filename:join(DataDir, "port_test"), + DataDir = ?config(data_dir, Config), + Program = filename:join(DataDir, "port_test"), process_flag(trap_exit, true), - ?line P = open_port({spawn, Program}, [{packet, 1}]), - ?line Data = lists:duplicate(257, $a), - ?line erlang:port_command(P, Data), - ?line receive - {'EXIT', Port, einval} when is_port(Port) -> - ok; - Other -> - test_server:fail(Other) - after 10000 -> - test_server:fail(timeout) - end, + P = open_port({spawn, Program}, [{packet, 1}]), + Data = lists:duplicate(257, $a), + erlang:port_command(P, Data), + receive + {'EXIT', Port, einval} when is_port(Port) -> + ok; + Other -> + test_server:fail(Other) + after 10000 -> + test_server:fail(timeout) + end, ok. %% port_command/2: Posix exit signals not trapped command_e_4(Config) when is_list(Config) -> - ?line DataDir = ?config(data_dir, Config), - ?line Program = filename:join(DataDir, "port_test"), + DataDir = ?config(data_dir, Config), + Program = filename:join(DataDir, "port_test"), process_flag(trap_exit, true), - ?line _ = spawn_link(?MODULE, do_command_e_4, [Program]), - ?line receive - {'EXIT', Pid, {einval, _}} when is_pid(Pid) -> - ok; - Other -> - ?line test_server:fail(Other) - after 10000 -> - ?line test_server:fail(timeout) - end, + _ = spawn_link(?MODULE, do_command_e_4, [Program]), + receive + {'EXIT', Pid, {einval, _}} when is_pid(Pid) -> + ok; + Other -> + test_server:fail(Other) + after 10000 -> + test_server:fail(timeout) + end, ok. do_command_e_4(Program) -> - ?line P = open_port({spawn, Program}, [{packet, 1}]), - ?line Data = lists:duplicate(257, $a), - ?line erlang:port_command(P, Data), + P = open_port({spawn, Program}, [{packet, 1}]), + Data = lists:duplicate(257, $a), + erlang:port_command(P, Data), exit(survived). %% Tests the port_info/1 BIF port_info1(Config) when is_list(Config) -> - ?line load_control_drv(Config), + load_control_drv(Config), Me=self(), - ?line P = open_port({spawn, control_drv}, []), - ?line A1 = erlang:port_info(P), - ?line false = lists:keysearch(registered_name, 1, A1), - ?line register(myport, P), - ?line A = erlang:port_info(P), - ?line {value,{registered_name,myport}}= - lists:keysearch(registered_name, 1, A), - ?line {value,{name,"control_drv"}}=lists:keysearch(name, 1, A), - ?line {value,{links,[Me]}}=lists:keysearch(links, 1, A), - ?line {value,{id,_IdNum}}=lists:keysearch(id, 1, A), - ?line {value,{connected,_}}=lists:keysearch(connected, 1, A), - ?line {value,{input,0}}=lists:keysearch(input, 1, A), - ?line {value,{output,0}}=lists:keysearch(output, 1, A), - ?line true=erlang:port_close(P), + P = open_port({spawn, control_drv}, []), + A1 = erlang:port_info(P), + false = lists:keysearch(registered_name, 1, A1), + register(myport, P), + A = erlang:port_info(P), + {value,{registered_name,myport}}= lists:keysearch(registered_name, 1, A), + {value,{name,"control_drv"}}=lists:keysearch(name, 1, A), + {value,{links,[Me]}}=lists:keysearch(links, 1, A), + {value,{id,_IdNum}}=lists:keysearch(id, 1, A), + {value,{connected,_}}=lists:keysearch(connected, 1, A), + {value,{input,0}}=lists:keysearch(input, 1, A), + {value,{output,0}}=lists:keysearch(output, 1, A), + {value,{os_pid,undefined}}=lists:keysearch(os_pid, 1, A), % linked-in driver doesn't have a OS pid + true=erlang:port_close(P), ok. %% Tests erlang:port_info/2" port_info2(Config) when is_list(Config) -> - ?line load_control_drv(Config), + load_control_drv(Config), - ?line P = open_port({spawn,control_drv}, [binary]), - ?line [] = erlang:port_info(P, registered_name), - ?line register(myport, P), - ?line {registered_name, myport} = erlang:port_info(P, registered_name), + P = open_port({spawn,control_drv}, [binary]), + [] = erlang:port_info(P, registered_name), + register(myport, P), + {registered_name, myport} = erlang:port_info(P, registered_name), - ?line {name, "control_drv"}=erlang:port_info(P, name), - ?line {id, _IdNum} = erlang:port_info(P, id), + {name, "control_drv"}=erlang:port_info(P, name), + {id, _IdNum} = erlang:port_info(P, id), Me=self(), - ?line {links, [Me]} = erlang:port_info(P, links), - ?line {connected, Me} = erlang:port_info(P, connected), - ?line {input, 0}=erlang:port_info(P, input), - ?line {output,0}=erlang:port_info(P, output), - - ?line erlang:port_control(P, $i, "abc"), - ?line receive - {P,{data,<<"abc">>}} -> ok - end, - ?line {input,3} = erlang:port_info(P, input), - ?line {output,0} = erlang:port_info(P, output), - - ?line Bin = list_to_binary(lists:duplicate(2047, 42)), - ?line output_test(P, Bin, 3, 0), + {links, [Me]} = erlang:port_info(P, links), + {connected, Me} = erlang:port_info(P, connected), + {input, 0}=erlang:port_info(P, input), + {output,0}=erlang:port_info(P, output), + {os_pid, undefined}=erlang:port_info(P, os_pid), % linked-in driver doesn't have a OS pid + + erlang:port_control(P, $i, "abc"), + receive + {P,{data,<<"abc">>}} -> ok + end, + {input,3} = erlang:port_info(P, input), + {output,0} = erlang:port_info(P, output), + + Bin = list_to_binary(lists:duplicate(2047, 42)), + output_test(P, Bin, 3, 0), - ?line true = erlang:port_close(P), + true = erlang:port_close(P), + ok. + +%% Tests the port_info/1,2 os_pid option BIF +port_info_os_pid(Config) when is_list(Config) -> + case os:type() of + {unix,_} -> + do_port_info_os_pid(); + _ -> + {skip,"Only on Unix."} + end. + +do_port_info_os_pid() -> + P = open_port({spawn, "echo $$"}, [eof]), + A = erlang:port_info(P), + {os_pid, InfoOSPid} = erlang:port_info(P, os_pid), + EchoPidStr = receive + {P, {data, EchoPidStr0}} -> EchoPidStr0 + after 10000 -> test_server:fail(timeout) + end, + {ok, [EchoPid], []} = io_lib:fread("~u\n", EchoPidStr), + {value,{os_pid, InfoOSPid}}=lists:keysearch(os_pid, 1, A), + EchoPid = InfoOSPid, + true = erlang:port_close(P), ok. output_test(_, _, Input, Output) when Output > 16#1fffffff -> @@ -237,7 +262,7 @@ output_test(P, Bin, Input0, Output0) -> {P,{data,Bin}} -> ok; Other -> io:format("~p", [Other]), - ?line ?t:fail() + ?t:fail() end, Input = Input0 + size(Bin), Output = Output0 + size(Bin), @@ -254,109 +279,106 @@ output_test(P, Bin, Input0, Output0) -> %% Tests the port_connect/2 BIF. connect(Config) when is_list(Config) -> - ?line load_control_drv(Config), + load_control_drv(Config), - ?line P = open_port({spawn, control_drv}, []), + P = open_port({spawn, control_drv}, []), register(myport, P), - ?line true = erlang:port_connect(myport, self()), + true = erlang:port_connect(myport, self()), %% Connect the port to another process. Data = "hello, world", Parent = self(), - ?line Rec = - fun(Me) -> receive - {P,{data,Data}} -> - Parent ! connect_ok, - Me(Me) - end - end, - ?line RecPid = spawn_link(fun() -> Rec(Rec) end), - ?line true = erlang:port_connect(P, RecPid), - ?line unlink(P), + Rec = fun(Me) -> + receive + {P,{data,Data}} -> + Parent ! connect_ok, + Me(Me) + end + end, + RecPid = spawn_link(fun() -> Rec(Rec) end), + true = erlang:port_connect(P, RecPid), + unlink(P), %% Send a command to the port and make sure that the %% other process receives the echo. - ?line erlang:port_command(P, Data), - ?line receive - connect_ok -> ok - end, + erlang:port_command(P, Data), + receive + connect_ok -> ok + end, %% Tests some errors. - ?line {'EXIT',{badarg, _}}=(catch erlang:port_connect(self(), self())), - ?line {'EXIT',{badarg, _}}=(catch erlang:port_connect(self(), P)), - ?line {'EXIT',{badarg, _}}=(catch erlang:port_connect(P, P)), - ?line {'EXIT',{badarg, _}}=(catch erlang:port_connect(P, xxxx)), - ?line {'EXIT',{badarg, _}}=(catch erlang:port_connect(P, [])), + {'EXIT',{badarg, _}}=(catch erlang:port_connect(self(), self())), + {'EXIT',{badarg, _}}=(catch erlang:port_connect(self(), P)), + {'EXIT',{badarg, _}}=(catch erlang:port_connect(P, P)), + {'EXIT',{badarg, _}}=(catch erlang:port_connect(P, xxxx)), + {'EXIT',{badarg, _}}=(catch erlang:port_connect(P, [])), - ?line process_flag(trap_exit, true), - ?line exit(P, you_should_die), - ?line receive - {'EXIT',RecPid,you_should_die} -> ok; - Other -> ?line ?t:fail({bad_message,Other}) - end, + process_flag(trap_exit, true), + exit(P, you_should_die), + receive + {'EXIT',RecPid,you_should_die} -> ok; + Other -> ?line ?t:fail({bad_message,Other}) + end, %% Done. ok. %% Tests port_control/3 control(Config) when is_list(Config) -> - ?line load_control_drv(Config), - ?line P = open_port({spawn, control_drv}, []), + load_control_drv(Config), + P = open_port({spawn, control_drv}, []), %% Test invalid (out-of-range) arguments. - ?line {'EXIT', {badarg, _}} = (catch erlang:port_control(self(), 1, [])), + {'EXIT', {badarg, _}} = (catch erlang:port_control(self(), 1, [])), - ?line {'EXIT', {badarg, _}} = (catch erlang:port_control(P, -1, [])), - ?line {'EXIT', {badarg, _}} = (catch erlang:port_control(P, -34887348739733833, [])), - ?line {'EXIT', {badarg, _}} = (catch erlang:port_control(P, 16#100000000, [])), - ?line {'EXIT', {badarg, _}} = (catch erlang:port_control(P, a, [])), - ?line {'EXIT', {badarg, _}} = (catch erlang:port_control(P, 'e', dum)), - ?line {'EXIT', {badarg, _}} = (catch erlang:port_control(P, $e, dum)), - ?line {'EXIT', {badarg, _}} = (catch erlang:port_control(P, $e, fun(X) -> X end)), - ?line {'EXIT', {badarg, _}} = (catch erlang:port_control(P, $e, - [fun(X) -> X end])), - ?line {'EXIT', {badarg, _}} = (catch erlang:port_control(P, $e, - [1|fun(X) -> X end])), + {'EXIT', {badarg, _}} = (catch erlang:port_control(P, -1, [])), + {'EXIT', {badarg, _}} = (catch erlang:port_control(P, -34887348739733833, [])), + {'EXIT', {badarg, _}} = (catch erlang:port_control(P, 16#100000000, [])), + {'EXIT', {badarg, _}} = (catch erlang:port_control(P, a, [])), + {'EXIT', {badarg, _}} = (catch erlang:port_control(P, 'e', dum)), + {'EXIT', {badarg, _}} = (catch erlang:port_control(P, $e, dum)), + {'EXIT', {badarg, _}} = (catch erlang:port_control(P, $e, fun(X) -> X end)), + {'EXIT', {badarg, _}} = (catch erlang:port_control(P, $e, [fun(X) -> X end])), + {'EXIT', {badarg, _}} = (catch erlang:port_control(P, $e, [1|fun(X) -> X end])), %% Test errors detected by the driver. - ?line {'EXIT', {badarg, _}} = (catch erlang:port_control(P, 177, [])), - ?line {'EXIT', {badarg, _}} = (catch erlang:port_control(P, 155, - random_packet(1024))), + {'EXIT', {badarg, _}} = (catch erlang:port_control(P, 177, [])), + {'EXIT', {badarg, _}} = (catch erlang:port_control(P, 155, random_packet(1024))), %% Test big op codes. register(myport, P), - ?line test_op(myport, 256), - ?line test_op(P, 256), - ?line test_op(P, 16#0033A837), - ?line test_op(P, 16#0ab37938), - ?line test_op(P, 16#eab37938), - ?line test_op(P, 16#ffffFFFF), + test_op(myport, 256), + test_op(P, 256), + test_op(P, 16#0033A837), + test_op(P, 16#0ab37938), + test_op(P, 16#eab37938), + test_op(P, 16#ffffFFFF), %% Test the echo function of the driver. - ?line echo(P, 0), - ?line echo(P, 1), - ?line echo(P, 10), - ?line echo(P, 13), - ?line echo(P, 63), - ?line echo(P, 64), - ?line echo(P, 65), - ?line echo(P, 127), - ?line echo(P, 1023), - ?line echo(P, 1024), - ?line echo(P, 11243), - ?line echo(P, 70000), + echo(P, 0), + echo(P, 1), + echo(P, 10), + echo(P, 13), + echo(P, 63), + echo(P, 64), + echo(P, 65), + echo(P, 127), + echo(P, 1023), + echo(P, 1024), + echo(P, 11243), + echo(P, 70000), %% Done. - ?line true=erlang:port_close(myport), + true = erlang:port_close(myport), ok. test_op(P, Op) -> @@ -364,23 +386,23 @@ test_op(P, Op) -> <<Op:32>> = list_to_binary(R). echo_to_busy(Config) when is_list(Config) -> - ?line Dog = test_server:timetrap(test_server:seconds(10)), - ?line load_control_drv(Config), - ?line P = open_port({spawn, control_drv}, []), - ?line erlang:port_control(P, $b, [1]), % Set to busy. + Dog = test_server:timetrap(test_server:seconds(10)), + load_control_drv(Config), + P = open_port({spawn, control_drv}, []), + erlang:port_control(P, $b, [1]), % Set to busy. Self = self(), - ?line Echoer = spawn(fun() -> echoer(P, Self) end), - ?line receive after 500 -> ok end, - ?line erlang:port_control(P, $b, [0]), % Set to not busy. - ?line receive - {Echoer, done} -> - ok; - {Echoer, Other} -> - test_server:fail(Other); - Other -> - test_server:fail({unexpected_message, Other}) - end, - ?line test_server:timetrap_cancel(Dog), + Echoer = spawn(fun() -> echoer(P, Self) end), + receive after 500 -> ok end, + erlang:port_control(P, $b, [0]), % Set to not busy. + receive + {Echoer, done} -> + ok; + {Echoer, Other} -> + test_server:fail(Other); + Other -> + test_server:fail({unexpected_message, Other}) + end, + test_server:timetrap_cancel(Dog), ok. echoer(P, ReplyTo) -> @@ -405,9 +427,9 @@ echo(P, Size) -> Packet = erlang:port_control(P, $e, [unaligned_sub_bin(Bin)]). load_control_drv(Config) when is_list(Config) -> - ?line DataDir = ?config(data_dir, Config), - ?line erl_ddll:start(), - ?line ok = load_driver(DataDir, "control_drv"). + DataDir = ?config(data_dir, Config), + erl_ddll:start(), + ok = load_driver(DataDir, "control_drv"). load_driver(Dir, Driver) -> case erl_ddll:load_driver(Dir, Driver) of @@ -459,4 +481,3 @@ sub_bin(Bin) when is_binary(Bin) -> B. id(I) -> I. - |