1: %% 2: %% %CopyrightBegin% 3: %% 4: %% Copyright Ericsson AB 2005-2012. All Rights Reserved. 5: %% 6: %% The contents of this file are subject to the Erlang Public License, 7: %% Version 1.1, (the "License"); you may not use this file except in 8: %% compliance with the License. You should have received a copy of the 9: %% Erlang Public License along with this software. If not, it can be 10: %% retrieved online at http://www.erlang.org/. 11: %% 12: %% Software distributed under the License is distributed on an "AS IS" 13: %% basis, WITHOUT WARRANTY OF ANY KIND, either express or implied. See 14: %% the License for the specific language governing rights and limitations 15: %% under the License. 16: %% 17: %% %CopyrightEnd% 18: %% 19: 20: -module(run_erl_SUITE). 21: 22: -export([all/0, suite/0,groups/0,init_per_suite/1, end_per_suite/1, 23: init_per_group/2,end_per_group/2, 24: init_per_testcase/2,end_per_testcase/2, 25: basic/1,heavy/1,heavier/1,defunct/1]). 26: -export([ping_me_back/1]). 27: 28: -include_lib("test_server/include/test_server.hrl"). 29: 30: init_per_testcase(_Case, Config) -> 31: Dog = ?t:timetrap(?t:minutes(2)), 32: [{watchdog, Dog}|Config]. 33: 34: end_per_testcase(_Case, Config) -> 35: Dog = ?config(watchdog, Config), 36: ?t:timetrap_cancel(Dog), 37: ok. 38: 39: suite() -> [{ct_hooks,[ts_install_cth]}]. 40: 41: all() -> 42: [basic, heavy, heavier, defunct]. 43: 44: groups() -> 45: []. 46: 47: init_per_suite(Config) -> 48: Config. 49: 50: end_per_suite(_Config) -> 51: ok. 52: 53: init_per_group(_GroupName, Config) -> 54: Config. 55: 56: end_per_group(_GroupName, Config) -> 57: Config. 58: 59: 60: basic(Config) when is_list(Config) -> 61: case os:type() of 62: {unix,_} -> basic_1(Config); 63: _ -> {skip,"Not Unix"} 64: end. 65: 66: basic_1(Config) -> 67: ?line {Node,Pipe} = do_run_erl(Config, "basic"), 68: 69: ?line ToErl = open_port({spawn,"to_erl "++Pipe}, []), 70: ?line erlang:port_command(ToErl, "halt().\r\n"), 71: 72: receive 73: {nodedown,Node} -> 74: ?line io:format("Down: ~p\n", [Node]) 75: after 10000 -> 76: ?line ?t:fail() 77: end, 78: 79: ok. 80: 81: heavy(Config) when is_list(Config) -> 82: case os:type() of 83: {unix,_} -> heavy_1(Config); 84: _ -> {skip,"Not Unix"} 85: end. 86: 87: heavy_1(Config) -> 88: ?line {Node,Pipe} = do_run_erl(Config, "heavy"), 89: 90: ?line ToErl = open_port({spawn,"to_erl "++Pipe}, []), 91: IoFormat = "io:format(\"~s\n\", [lists:duplicate(10000, 10)]).\r\n", 92: ?line erlang:port_command(ToErl, IoFormat), 93: ?line erlang:port_command(ToErl, IoFormat), 94: ?line erlang:port_command(ToErl, IoFormat), 95: ?line erlang:port_command(ToErl, "init:stop().\r\n"), 96: 97: receive 98: {nodedown,Node} -> 99: ?line io:format("Down: ~p\n", [Node]) 100: after 10000 -> 101: ?line ?t:fail() 102: end, 103: 104: ?line case count_new_lines(ToErl, 0) of 105: Nls when Nls > 30000 -> 106: ok; 107: Nls -> 108: ?line io:format("new_lines: ~p\n", [Nls]), 109: ?line ?t:fail() 110: end. 111: 112: 113: ping_me_back([Node]) when is_atom(Node) -> 114: net_adm:ping(Node); 115: ping_me_back([Node]) -> 116: net_adm:ping(list_to_atom(Node)). 117: 118: count_new_lines(P, N) -> 119: receive 120: {P,{data,S}} -> 121: count_new_lines(P, count_new_lines_1(S, N)) 122: after 0 -> 123: N 124: end. 125: 126: count_new_lines_1([$\n|T], N) -> 127: count_new_lines_1(T, N+1); 128: count_new_lines_1([_|T], N) -> 129: count_new_lines_1(T, N); 130: count_new_lines_1([], N) -> N. 131: 132: heavier(Config) when is_list(Config) -> 133: case os:type() of 134: {unix,_} -> heavier_1(Config); 135: _ -> {skip,"Not Unix"} 136: end. 137: 138: heavier_1(Config) -> 139: ?line {Node,Pipe} = do_run_erl(Config, "heavier"), 140: 141: ?line ToErl = open_port({spawn,"to_erl "++Pipe}, []), 142: io:format("ToErl = ~p\n", [ToErl]), 143: X = 1, 144: Y = 555, 145: Z = 42, 146: ?line random:seed(X, Y, Z), 147: SeedCmd = lists:flatten(io_lib:format("random:seed(~p, ~p, ~p). \r\n", 148: [X,Y,Z])), 149: ?line io:format("~p\n", [SeedCmd]), 150: ?line erlang:port_command(ToErl, SeedCmd), 151: 152: Iter = 1000, 153: MaxLen = 2048, 154: 155: Random = "f(F), "++ 156: "F = fun(F,0) -> ok; "++ 157: "(F,N) -> " ++ 158: "io:format(\"\\\"~s\\\"~n\","++ 159: "[[35|[random:uniform(25)+65 || " ++ 160: "_ <- lists:seq(1, "++ 161: "random:uniform("++ 162: integer_to_list(MaxLen)++ 163: "))]]]), "++ 164: "F(F,N-1) "++ 165: "end,"++ 166: "F(F,"++integer_to_list(Iter)++")."++" \r\n", 167: 168: 169: ?line io:format("~p\n", [Random]), 170: ?line erlang:port_command(ToErl, Random), 171: 172: %% Finish. 173: 174: ?line erlang:port_command(ToErl, "init:stop().\r\n"), 175: ?line receive_all(Iter, ToErl, MaxLen), 176: receive 177: {nodedown,Node} -> 178: ?line io:format("Down: ~p\n", [Node]) 179: after 10000 -> 180: ?line c:flush(), 181: ?line ?t:fail() 182: end, 183: 184: ok. 185: 186: receive_all(Iter, ToErl, MaxLen) -> 187: receive_all_1(Iter, [], ToErl, MaxLen). 188: 189: receive_all_1(0, _, _, _) -> ok; 190: receive_all_1(Iter, Line, ToErl, MaxLen) -> 191: NumChars = random:uniform(MaxLen), 192: Pattern = [random:uniform(25)+65 || _ <- lists:seq(1, NumChars)], 193: receive_all_2(Iter, {NumChars,Pattern}, Line, ToErl, MaxLen). 194: 195: 196: receive_all_2(Iter, {NumChars,Pattern}, Line0, ToErl, MaxLen) -> 197: case receive_match(Line0, {NumChars,Pattern}) of 198: {match,Line} -> 199: %%io:format("Match: ~p\n", [Line]), 200: receive_all_1(Iter-1, Line, ToErl, MaxLen); 201: {nomatch,Line} -> 202: %%io:format("NoMatch: ~p\n", [Line]), 203: receive 204: {ToErl,{data,S}} -> 205: %%io:format("Recv: ~p\n", [S]), 206: receive_all_2(Iter, {NumChars,Pattern}, Line++S, ToErl, MaxLen) 207: after 10000 -> 208: io:format("Timeout waiting for\n~p\ngot\n~p\n", 209: [Pattern, Line]), 210: ?line ?t:fail() 211: end 212: end. 213: 214: 215: receive_match("\"#"++T, {NumChars,Pattern}) when length(T) >= NumChars -> 216: Match = lists:sublist(T, NumChars), 217: io:format("match candidate: ~p\n", [Match]), 218: Match = Pattern, 219: {match,lists:nthtail(NumChars, T)}; 220: receive_match("\"#"++T, _) -> 221: {nomatch,"\"#"++T}; 222: receive_match("\""=Line, _) -> 223: {nomatch,Line}; 224: receive_match([_|T], Tpl) -> 225: receive_match(T, Tpl); 226: receive_match(Line, _) -> 227: {nomatch,Line}. 228: 229: 230: defunct(Config) when is_list(Config) -> 231: case os:type() of 232: {unix,_} -> defunct_1(Config); 233: _ -> {skip,"Not Unix"} 234: end. 235: 236: defunct_1(Config) -> 237: case os:find_executable(perl) of 238: false -> 239: {skip,"No perl found"}; 240: Perl -> 241: defunct_2(Config, Perl) 242: end. 243: 244: defunct_2(Config, Perl) -> 245: ?line Data = ?config(data_dir, Config), 246: ?line RunErlTest = filename:join(Data, "run_erl_test.pl"), 247: ?line Defuncter = filename:join(Data, "defuncter.pl"), 248: ?line Priv = ?config(priv_dir, Config), 249: ?line LogDir = filename:join(Priv, "defunct"), 250: ?line ok = file:make_dir(LogDir), 251: ?line Pipe = LogDir ++ "/", 252: ?line RunErl = os:find_executable(run_erl), 253: ?line Cmd = Perl ++ " " ++ RunErlTest ++ " \"" ++ RunErl ++ "\" " ++ 254: Defuncter ++ " " ++ Pipe ++ " " ++ LogDir, 255: ?line io:format("~p", [Cmd]), 256: ?line Res = os:cmd(Cmd), 257: ?line io:format("~p\n", [Res]), 258: "OK"++_ = Res, 259: ok. 260: 261: %%% Utilities. 262: 263: do_run_erl(Config, Case) -> 264: ?line Priv = ?config(priv_dir, Config), 265: ?line LogDir = filename:join(Priv, Case), 266: ?line ok = file:make_dir(LogDir), 267: ?line Pipe = LogDir ++ "/", 268: ?line NodeName = "run_erl_node_" ++ Case, 269: ?line Cmd = "run_erl "++Pipe++" "++LogDir++" \"erl -sname " ++ NodeName ++ 270: " -pa " ++ filename:dirname(code:which(?MODULE)) ++ 271: " -s " ++ ?MODULE_STRING ++ " ping_me_back " ++ 272: atom_to_list(node()) ++ "\"", 273: ?line io:format("~p\n", [Cmd]), 274: 275: ?line net_kernel:monitor_nodes(true), 276: ?line open_port({spawn,Cmd}, []), 277: ?line [_,Host] = string:tokens(atom_to_list(node()), "@"), 278: ?line Node = list_to_atom(NodeName++"@"++Host), 279: 280: receive 281: {nodeup,Node} -> 282: ?line io:format("Up: ~p\n", [Node]); 283: Other -> 284: ?line io:format("Unexpected: ~p\n", [Other]), 285: ?line ?t:fail() 286: after 10000 -> 287: ?line ?t:fail() 288: end, 289: 290: {Node,Pipe}.