aboutsummaryrefslogtreecommitdiffstats
path: root/erts/test/run_erl_SUITE.erl
diff options
context:
space:
mode:
Diffstat (limited to 'erts/test/run_erl_SUITE.erl')
-rw-r--r--erts/test/run_erl_SUITE.erl270
1 files changed, 270 insertions, 0 deletions
diff --git a/erts/test/run_erl_SUITE.erl b/erts/test/run_erl_SUITE.erl
new file mode 100644
index 0000000000..afff4120d4
--- /dev/null
+++ b/erts/test/run_erl_SUITE.erl
@@ -0,0 +1,270 @@
+%%
+%% %CopyrightBegin%
+%%
+%% Copyright Ericsson AB 2005-2009. All Rights Reserved.
+%%
+%% The contents of this file are subject to the Erlang Public License,
+%% Version 1.1, (the "License"); you may not use this file except in
+%% compliance with the License. You should have received a copy of the
+%% Erlang Public License along with this software. If not, it can be
+%% retrieved online at http://www.erlang.org/.
+%%
+%% Software distributed under the License is distributed on an "AS IS"
+%% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See
+%% the License for the specific language governing rights and limitations
+%% under the License.
+%%
+%% %CopyrightEnd%
+%%
+
+-module(run_erl_SUITE).
+
+-export([all/1,init_per_testcase/2,fin_per_testcase/2,
+ basic/1,heavy/1,heavier/1,defunct/1]).
+-export([ping_me_back/1]).
+
+-include("test_server.hrl").
+
+init_per_testcase(_Case, Config) ->
+ Dog = ?t:timetrap(?t:minutes(2)),
+ [{watchdog, Dog}|Config].
+
+fin_per_testcase(_Case, Config) ->
+ Dog = ?config(watchdog, Config),
+ ?t:timetrap_cancel(Dog),
+ ok.
+
+all(suite) ->
+ [basic,heavy,heavier,defunct].
+
+basic(Config) when is_list(Config) ->
+ case os:type() of
+ {unix,_} -> basic_1(Config);
+ _ -> {skip,"Not Unix"}
+ end.
+
+basic_1(Config) ->
+ ?line {Node,Pipe} = do_run_erl(Config, "basic"),
+
+ ?line ToErl = open_port({spawn,"to_erl "++Pipe}, []),
+ ?line erlang:port_command(ToErl, "halt().\r\n"),
+
+ receive
+ {nodedown,Node} ->
+ ?line io:format("Down: ~p\n", [Node])
+ after 10000 ->
+ ?line ?t:fail()
+ end,
+
+ ok.
+
+heavy(Config) when is_list(Config) ->
+ case os:type() of
+ {unix,_} -> heavy_1(Config);
+ _ -> {skip,"Not Unix"}
+ end.
+
+heavy_1(Config) ->
+ ?line {Node,Pipe} = do_run_erl(Config, "heavy"),
+
+ ?line ToErl = open_port({spawn,"to_erl "++Pipe}, []),
+ IoFormat = "io:format(\"~s\n\", [lists:duplicate(10000, 10)]).\r\n",
+ ?line erlang:port_command(ToErl, IoFormat),
+ ?line erlang:port_command(ToErl, IoFormat),
+ ?line erlang:port_command(ToErl, IoFormat),
+ ?line erlang:port_command(ToErl, "init:stop().\r\n"),
+
+ receive
+ {nodedown,Node} ->
+ ?line io:format("Down: ~p\n", [Node])
+ after 10000 ->
+ ?line ?t:fail()
+ end,
+
+ ?line case count_new_lines(ToErl, 0) of
+ Nls when Nls > 30000 ->
+ ok;
+ Nls ->
+ ?line io:format("new_lines: ~p\n", [Nls]),
+ ?line ?t:fail()
+ end.
+
+
+ping_me_back([Node]) when is_atom(Node) ->
+ net_adm:ping(Node);
+ping_me_back([Node]) ->
+ net_adm:ping(list_to_atom(Node)).
+
+count_new_lines(P, N) ->
+ receive
+ {P,{data,S}} ->
+ count_new_lines(P, count_new_lines_1(S, N))
+ after 0 ->
+ N
+ end.
+
+count_new_lines_1([$\n|T], N) ->
+ count_new_lines_1(T, N+1);
+count_new_lines_1([_|T], N) ->
+ count_new_lines_1(T, N);
+count_new_lines_1([], N) -> N.
+
+heavier(Config) when is_list(Config) ->
+ case os:type() of
+ {unix,_} -> heavier_1(Config);
+ _ -> {skip,"Not Unix"}
+ end.
+
+heavier_1(Config) ->
+ ?line {Node,Pipe} = do_run_erl(Config, "heavier"),
+
+ ?line ToErl = open_port({spawn,"to_erl "++Pipe}, []),
+ io:format("ToErl = ~p\n", [ToErl]),
+ X = 1,
+ Y = 555,
+ Z = 42,
+ ?line random:seed(X, Y, Z),
+ SeedCmd = lists:flatten(io_lib:format("random:seed(~p, ~p, ~p). \r\n",
+ [X,Y,Z])),
+ ?line io:format("~p\n", [SeedCmd]),
+ ?line erlang:port_command(ToErl, SeedCmd),
+
+ Iter = 1000,
+ MaxLen = 2048,
+
+ Random = "f(F), "++
+ "F = fun(F,0) -> ok; "++
+ "(F,N) -> " ++
+ "io:format(\"\\\"~s\\\"~n\","++
+ "[[35|[random:uniform(25)+65 || " ++
+ "_ <- lists:seq(1, "++
+ "random:uniform("++
+ integer_to_list(MaxLen)++
+ "))]]]), "++
+ "F(F,N-1) "++
+ "end,"++
+ "F(F,"++integer_to_list(Iter)++")."++" \r\n",
+
+
+ ?line io:format("~p\n", [Random]),
+ ?line erlang:port_command(ToErl, Random),
+
+ %% Finish.
+
+ ?line erlang:port_command(ToErl, "init:stop().\r\n"),
+ ?line receive_all(Iter, ToErl, MaxLen),
+ receive
+ {nodedown,Node} ->
+ ?line io:format("Down: ~p\n", [Node])
+ after 10000 ->
+ ?line c:flush(),
+ ?line ?t:fail()
+ end,
+
+ ok.
+
+receive_all(Iter, ToErl, MaxLen) ->
+ receive_all_1(Iter, [], ToErl, MaxLen).
+
+receive_all_1(0, _, _, _) -> ok;
+receive_all_1(Iter, Line, ToErl, MaxLen) ->
+ NumChars = random:uniform(MaxLen),
+ Pattern = [random:uniform(25)+65 || _ <- lists:seq(1, NumChars)],
+ receive_all_2(Iter, {NumChars,Pattern}, Line, ToErl, MaxLen).
+
+
+receive_all_2(Iter, {NumChars,Pattern}, Line0, ToErl, MaxLen) ->
+ case receive_match(Line0, {NumChars,Pattern}) of
+ {match,Line} ->
+ %%io:format("Match: ~p\n", [Line]),
+ receive_all_1(Iter-1, Line, ToErl, MaxLen);
+ {nomatch,Line} ->
+ %%io:format("NoMatch: ~p\n", [Line]),
+ receive
+ {ToErl,{data,S}} ->
+ %%io:format("Recv: ~p\n", [S]),
+ receive_all_2(Iter, {NumChars,Pattern}, Line++S, ToErl, MaxLen)
+ after 10000 ->
+ io:format("Timeout waiting for\n~p\ngot\n~p\n",
+ [Pattern, Line]),
+ ?line ?t:fail()
+ end
+ end.
+
+
+receive_match("\"#"++T, {NumChars,Pattern}) when length(T) >= NumChars ->
+ Match = lists:sublist(T, NumChars),
+ io:format("match candidate: ~p\n", [Match]),
+ Match = Pattern,
+ {match,lists:nthtail(NumChars, T)};
+receive_match("\"#"++T, _) ->
+ {nomatch,"\"#"++T};
+receive_match("\""=Line, _) ->
+ {nomatch,Line};
+receive_match([_|T], Tpl) ->
+ receive_match(T, Tpl);
+receive_match(Line, _) ->
+ {nomatch,Line}.
+
+
+defunct(Config) when is_list(Config) ->
+ case os:type() of
+ {unix,_} -> defunct_1(Config);
+ _ -> {skip,"Not Unix"}
+ end.
+
+defunct_1(Config) ->
+ case os:find_executable(perl) of
+ false ->
+ {skip,"No perl found"};
+ Perl ->
+ defunct_2(Config, Perl)
+ end.
+
+defunct_2(Config, Perl) ->
+ ?line Data = ?config(data_dir, Config),
+ ?line RunErlTest = filename:join(Data, "run_erl_test.pl"),
+ ?line Defuncter = filename:join(Data, "defuncter.pl"),
+ ?line Priv = ?config(priv_dir, Config),
+ ?line LogDir = filename:join(Priv, "defunct"),
+ ?line ok = file:make_dir(LogDir),
+ ?line Pipe = LogDir ++ "/",
+ ?line RunErl = os:find_executable(run_erl),
+ ?line Cmd = Perl ++ " " ++ RunErlTest ++ " " ++ RunErl ++ " " ++
+ Defuncter ++ " " ++ Pipe ++ " " ++ LogDir,
+ ?line io:format("~p", [Cmd]),
+ ?line Res = os:cmd(Cmd),
+ ?line io:format("~p\n", [Res]),
+ "OK"++_ = Res,
+ ok.
+
+%%% Utilities.
+
+do_run_erl(Config, Case) ->
+ ?line Priv = ?config(priv_dir, Config),
+ ?line LogDir = filename:join(Priv, Case),
+ ?line ok = file:make_dir(LogDir),
+ ?line Pipe = LogDir ++ "/",
+ ?line NodeName = "run_erl_node_" ++ Case,
+ ?line Cmd = "run_erl "++Pipe++" "++LogDir++" \"erl -sname " ++ NodeName ++
+ " -pa " ++ filename:dirname(code:which(?MODULE)) ++
+ " -s " ++ ?MODULE_STRING ++ " ping_me_back " ++
+ atom_to_list(node()) ++ "\"",
+ ?line io:format("~p\n", [Cmd]),
+
+ ?line net_kernel:monitor_nodes(true),
+ ?line open_port({spawn,Cmd}, []),
+ ?line [_,Host] = string:tokens(atom_to_list(node()), "@"),
+ ?line Node = list_to_atom(NodeName++"@"++Host),
+
+ receive
+ {nodeup,Node} ->
+ ?line io:format("Up: ~p\n", [Node]);
+ Other ->
+ ?line io:format("Unexpected: ~p\n", [Other]),
+ ?line ?t:fail()
+ after 10000 ->
+ ?line ?t:fail()
+ end,
+
+ {Node,Pipe}.