1: %%
    2: %% %CopyrightBegin%
    3: %%
    4: %% Copyright Ericsson AB 2004-2013. 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: -module(jinterface_SUITE).
   20: 
   21: -export([all/0, suite/0,groups/0,init_per_group/2,end_per_group/2, 
   22: 	 init_per_suite/1, end_per_suite/1,
   23: 	 init_per_testcase/2, end_per_testcase/2]).
   24: 
   25: -export([nodename/1, register_and_whereis/1, get_names/1, boolean_atom/1,
   26: 	 node_ping/1, mbox_ping/1,
   27: 	 java_erlang_send_receive/1,
   28: 	 java_internal_send_receive_same_node/1,
   29: 	 java_internal_send_receive_different_nodes/1,
   30: 	 java_internal_send_receive_self/1,
   31: 	 java_link_and_exit/1, erl_link_and_exit/1,
   32: 	 erl_link_java_exit/1, java_link_erl_exit/1,
   33: 	 internal_link_linking_exits/1, internal_link_linked_exits/1,
   34: 	 internal_unlink_linking_exits/1, internal_unlink_linked_exits/1,
   35: 	 normal_exit/1, kill_mbox/1,kill_erl_proc_from_java/1,
   36: 	 kill_mbox_from_erlang/1,
   37: 	 erl_exit_with_reason_any_term/1,
   38: 	 java_exit_with_reason_any_term/1,
   39: 	 status_handler_localStatus/1, status_handler_remoteStatus/1,
   40: 	 status_handler_connAttempt/1]).
   41: 
   42: -include_lib("common_test/include/ct.hrl").
   43: -include("test_server_line.hrl").
   44: 
   45: -define(debug,true).
   46: -ifdef(debug).
   47: -define(dbg(Str,Args), io:format(Str,Args)).
   48: -else.
   49: -define(dbg(Str,Args), ok).
   50: -endif.
   51: 
   52: -define(link_test_reason,link_test_reason).
   53: 
   54: %% Test cases in MboxSendReceive.java
   55: -define(java_erlang_send_receive,1).
   56: -define(java_internal_send_receive_same_node,2).
   57: -define(java_internal_send_receive_different_nodes,3).
   58: -define(java_internal_send_receive_self,4).
   59: 
   60: %% Test cases in MboxLinkUnlink.java
   61: -define(java_link_and_exit, 1).
   62: -define(erl_link_and_exit, 2).
   63: -define(erl_link_java_exit, 3).
   64: -define(java_link_erl_exit, 4).
   65: -define(internal_link_linking_exits, 5).
   66: -define(internal_link_linked_exits, 6).
   67: -define(internal_unlink_linking_exits,7).
   68: -define(internal_unlink_linked_exits,8).
   69: -define(normal_exit,9).
   70: -define(kill_mbox,10).
   71: -define(kill_erl_proc_from_java,11).
   72: -define(kill_mbox_from_erlang,12).
   73: -define(erl_exit_with_reason_any_term,13).
   74: -define(java_exit_with_reason_any_term,14).
   75: 
   76: 
   77: %% Test cases in NodeStatusHandler.java
   78: -define(status_handler_localStatus,1).
   79: -define(status_handler_remoteStatus,2).
   80: -define(status_handler_connAttempt,3).
   81: 
   82: %%%-----------------------------------------------------------------
   83: %%% INIT/END
   84: %%%-----------------------------------------------------------------
   85: suite() -> [{ct_hooks,[ts_install_cth]}].
   86: 
   87: all() -> 
   88:     lists:append([fundamental(), ping(), send_receive(),
   89: 		  link_unlink(), status_handler()]).
   90: 
   91: groups() -> 
   92:     [].
   93: 
   94: init_per_group(_GroupName, Config) ->
   95:     Config.
   96: 
   97: end_per_group(_GroupName, Config) ->
   98:     Config.
   99: 
  100: 
  101: fundamental() ->
  102:     [
  103:      nodename,             % Nodename.java
  104:      register_and_whereis, % RegisterAndWhereis.java
  105:      get_names,            % GetNames.java
  106:      boolean_atom          % BooleanAtom.java
  107:     ].
  108: 
  109: ping() ->
  110:     [
  111:      %% Implemented in NodePing.java
  112:      node_ping,
  113: 
  114:      %% Implemented in MboxPing.java
  115:      mbox_ping
  116:      ].
  117: 
  118: 
  119: send_receive() ->
  120:     [
  121:      %% Implemented in MboxSendReceive.java
  122:      java_erlang_send_receive,
  123:      java_internal_send_receive_same_node,
  124:      java_internal_send_receive_different_nodes,
  125:      java_internal_send_receive_self
  126:     ].
  127: 
  128: %% Note:
  129: %%
  130: %% The test cases in MboxLinkUnlink.java and in
  131: %% NodePing.java, all uses default cookie, and if there
  132: %% is a problem with having the same default cookie in
  133: %% erlang vs jinterface, e.g because the home directory
  134: %% does not get the same in some cases on Windows
  135: %% - they will all fail.
  136: 
  137: link_unlink() ->
  138:     [
  139:      %% Implemented in MboxLinkUnlink.java
  140:      java_link_and_exit,
  141:      erl_link_and_exit,
  142:      erl_link_java_exit,
  143:      java_link_erl_exit,
  144:      internal_link_linking_exits,
  145:      internal_link_linked_exits,
  146:      internal_unlink_linking_exits,
  147:      internal_unlink_linked_exits,
  148:      normal_exit,
  149:      kill_mbox,
  150:      kill_erl_proc_from_java,
  151:      kill_mbox_from_erlang,
  152:      erl_exit_with_reason_any_term,
  153:      java_exit_with_reason_any_term
  154:     ].
  155: 
  156: status_handler() ->
  157:     [
  158:      %% Implemented in NodeStatusHandler.java
  159:      status_handler_localStatus,
  160:      status_handler_remoteStatus,
  161:      status_handler_connAttempt
  162:     ].
  163: 
  164: 
  165: init_per_suite(Config) when is_list(Config) ->
  166:     case case code:priv_dir(jinterface) of
  167: 	     {error,bad_name} -> false;
  168: 	     P -> filelib:is_dir(P) end of
  169: 	true ->
  170: 	    jitu:init_all(Config);
  171: 	false ->
  172: 	    {skip,"No jinterface application"}
  173:     end.
  174: 
  175: end_per_suite(Config) when is_list(Config) ->
  176:     jitu:finish_all(Config).
  177: 
  178: init_per_testcase(Case, _Config) 
  179:   when Case =:= kill_mbox;
  180:        Case =:= kill_mbox_from_erlang ->
  181:     {skip, "Not yet implemented"};
  182: init_per_testcase(_Case,Config) ->
  183:     Dog = ?t:timetrap({seconds,30}),
  184:     [{watch_dog,Dog}|Config].
  185: 
  186: end_per_testcase(_Case,Config) ->
  187:     case whereis(erl_link_server) of
  188: 	undefined -> ok;
  189: 	Pid -> exit(Pid,kill)
  190:     end,
  191:     jitu:kill_all_jnodes(),
  192:     ?t:timetrap_cancel(?config(watch_dog,Config)),
  193:     ok.
  194: 
  195: 
  196: %%%-----------------------------------------------------------------
  197: %%% TEST CASES
  198: %%%-----------------------------------------------------------------
  199: nodename(doc) ->
  200:     ["Nodename.java: "
  201:      "Test OtpNode.node(), OtpNode.alive() and OtpNode.host()"];
  202: nodename(suite) ->
  203:     [];
  204: nodename(Config) when is_list(Config) ->
  205:     [_,Host] = string:tokens(atom_to_list(node()),"@"),
  206:     ok = jitu:java(?config(java, Config),
  207: 		   ?config(data_dir, Config),
  208: 		   "Nodename",
  209: 		   [list_to_atom(Host)]).
  210: 
  211: %%%-----------------------------------------------------------------
  212: register_and_whereis(doc) ->
  213:     ["RegisterAndWhereis.java: "
  214:      "Test OtpNode.registerName(...), OtpMbox.registerName(...) and "
  215:      "OtpNode.whereis(...)"];
  216: register_and_whereis(suite) ->
  217:     [];
  218: register_and_whereis(Config) when is_list(Config) ->
  219:     ok = jitu:java(?config(java, Config),
  220: 		   ?config(data_dir, Config),
  221: 		   "RegisterAndWhereis",
  222: 		   []).
  223: 
  224: %%%-----------------------------------------------------------------
  225: get_names(doc) ->
  226:     ["GetNames.java: "
  227:      "Test OtpNode.getNames()"];
  228: get_names(suite) ->
  229:     [];
  230: get_names(Config) when is_list(Config) ->
  231:     ok = jitu:java(?config(java, Config),
  232: 		   ?config(data_dir, Config),
  233: 		   "GetNames",
  234: 		   []).
  235: 
  236: %%%-----------------------------------------------------------------
  237: boolean_atom(doc) ->
  238:     ["BooleanAtom.java: "
  239:      "Test OtpErlangAtom.booleanValue()"];
  240: boolean_atom(suite) ->
  241:     [];
  242: boolean_atom(Config) when is_list(Config) ->
  243:     ok = jitu:java(?config(java, Config),
  244: 		   ?config(data_dir, Config),
  245: 		   "BooleanAtom",
  246: 		   []).
  247: 
  248: %%%-----------------------------------------------------------------
  249: node_ping(doc) ->
  250:     ["NodePing.java: "
  251:      "Test OtpNode.ping(java.lang.String node, long timeout)"];
  252: node_ping(suite) ->
  253:     [];
  254: node_ping(Config) when is_list(Config) ->
  255:     ok = jitu:java(?config(java, Config),
  256: 		   ?config(data_dir, Config),
  257: 		   "NodePing",
  258: 		   [erlang:get_cookie(),node()]).
  259: 
  260: %%%-----------------------------------------------------------------
  261: mbox_ping(doc) ->
  262:     ["MboxPing.java: "
  263:      "Test OtpNode.createMbox(...) and OtpMbox.ping(...)"];
  264: mbox_ping(suite) ->
  265:     [];
  266: mbox_ping(Config) when is_list(Config) ->
  267:     ok = jitu:java(?config(java, Config),
  268: 		   ?config(data_dir, Config),
  269: 		   "MboxPing",
  270: 		   [erlang:get_cookie(),node()]).
  271: 
  272: %%%-----------------------------------------------------------------
  273: java_erlang_send_receive(doc) ->
  274:     ["Test sending/receiving of erlang messages between erlang and java"];
  275: java_erlang_send_receive(suite) ->
  276:     [];
  277: java_erlang_send_receive(Config) when is_list(Config) ->
  278:     send_receive(?java_erlang_send_receive, fun echo_loop/0, Config).
  279: 
  280: echo_loop() ->
  281:     receive
  282: 	{From,Msg} ->
  283: 	    ?dbg("erl_send_receive_server received ~p",[{From,Msg}]),
  284: 	    ?dbg("erl_send_receive_server sending ~p",[Msg]),
  285: 	    From ! Msg,
  286: 	    echo_loop();
  287: 	done ->
  288: 	    ok
  289:     end.
  290: 
  291: 
  292: %%%-----------------------------------------------------------------
  293: java_internal_send_receive_same_node(doc) ->
  294:     ["MboxSendReceive.java: "
  295:      "Test sending/receiving of erlang messages between mboxes "
  296:      "on the same java node."];
  297: java_internal_send_receive_same_node(suite) ->
  298:     [];
  299: java_internal_send_receive_same_node(Config) when is_list(Config) ->
  300:     send_receive(?java_internal_send_receive_same_node,
  301: 		 fun() -> receive done -> ok end end,
  302: 		 Config).
  303: 
  304: %%%-----------------------------------------------------------------
  305: java_internal_send_receive_different_nodes(doc) ->
  306:     ["MboxSendReceive.java: "
  307:      "Test sending/receiving of erlang messages between mboxes "
  308:      "on different java nodes."];
  309: java_internal_send_receive_different_nodes(suite) ->
  310:     [];
  311: java_internal_send_receive_different_nodes(Config) when is_list(Config) ->
  312:     send_receive(?java_internal_send_receive_different_nodes,
  313: 		 fun() -> receive done -> ok end end,
  314: 		 Config).
  315: 
  316: %%%-----------------------------------------------------------------
  317: java_internal_send_receive_self(doc) ->
  318:     ["MboxSendReceive.java: "
  319:      "Test sending/receiving of erlang messages from an mbox to itself"];
  320: java_internal_send_receive_self(suite) ->
  321:     [];
  322: java_internal_send_receive_self(Config) when is_list(Config) ->
  323:     send_receive(?java_internal_send_receive_self,
  324: 		 fun() -> receive done -> ok end end,
  325: 		 Config).
  326: 
  327: %%%-----------------------------------------------------------------
  328: java_link_and_exit(doc) ->
  329:     ["MboxLinkUnlink.java: "
  330:      "Test link between erlang process and java mailbox."
  331:      "Java mailbox links and exits"];
  332: java_link_and_exit(suite) ->
  333:     [];
  334: java_link_and_exit(Config) when is_list(Config) ->
  335:     LinkFun =
  336: 	fun(Mbox) ->
  337: 		Mbox ! {?java_link_and_exit,self(),?link_test_reason},
  338: 		receive after infinity -> ok end
  339: 	end,
  340:     erl_java_link(LinkFun,java_link_and_exit,Config).
  341: 
  342: 
  343: %%%-----------------------------------------------------------------
  344: erl_link_and_exit(doc) ->
  345:     ["MboxLinkUnlink.java: "
  346:      "Test link between erlang process and java mailbox."
  347:      "Erlang process links and exits"];
  348: erl_link_and_exit(suite) ->
  349:     [];
  350: erl_link_and_exit(Config) when is_list(Config) ->
  351:     LinkFun = fun(Mbox) ->
  352: 		      link(Mbox),
  353: 		      Mbox ! {?erl_link_and_exit,self(),?link_test_reason},
  354: 		      receive ok -> ok end,
  355: 		      exit(?link_test_reason)
  356: 	      end,
  357:     erl_java_link(LinkFun,erl_link_and_exit,Config).
  358: 
  359: %%%-----------------------------------------------------------------
  360: erl_link_java_exit(doc) ->
  361:     ["MboxLinkUnlink.java: "
  362:      "Test link between erlang process and java mailbox."
  363:      "Erlang process links and java mailbox exits"];
  364: erl_link_java_exit(suite) ->
  365:     [];
  366: erl_link_java_exit(Config) when is_list(Config) ->
  367:     LinkFun = fun(Mbox) ->
  368: 		      link(Mbox),
  369: 		      Mbox ! {?erl_link_java_exit,self(),?link_test_reason},
  370: 		      receive after infinity -> ok end
  371: 	      end,
  372:     erl_java_link(LinkFun,erl_link_java_exit,Config).
  373: 
  374: 
  375: %%%-----------------------------------------------------------------
  376: java_link_erl_exit(doc) ->
  377:     ["MboxLinkUnlink.java: "
  378:      "Test link between erlang process and java mailbox."
  379:      "Java mailbox links and erlang process exits"];
  380: java_link_erl_exit(suite) ->
  381:     [];
  382: java_link_erl_exit(Config) when is_list(Config) ->
  383:     LinkFun =
  384: 	fun(Mbox) ->
  385: 		Mbox ! {?java_link_erl_exit,self(),?link_test_reason},
  386: 		receive ok -> ok end,
  387: 		exit(?link_test_reason)
  388: 	end,
  389:     erl_java_link(LinkFun,java_link_erl_exit,Config).
  390: 
  391: %%%-----------------------------------------------------------------
  392: internal_link_linking_exits(doc) ->
  393:     ["MboxLinkUnlink.java: "
  394:      "Test link between two java mailboxes."
  395:      "The mailbox which creates the link is the one exiting"];
  396: internal_link_linking_exits(suite) ->
  397:     [];
  398: internal_link_linking_exits(Config) when is_list(Config) ->
  399:      internal_link_unlink(?internal_link_linking_exits,
  400: 			  internal_link_linking_exits,
  401: 			  Config).
  402: 
  403: %%%-----------------------------------------------------------------
  404: internal_link_linked_exits(doc) ->
  405:     ["MboxLinkUnlink.java: "
  406:      "Test link between two java mailboxes."
  407:      "The mailbox which dies not create the link is the one exiting"];
  408: internal_link_linked_exits(suite) ->
  409:     [];
  410: internal_link_linked_exits(Config) when is_list(Config) ->
  411:     internal_link_unlink(?internal_link_linked_exits,
  412: 			 internal_link_linked_exits,
  413: 			 Config).
  414: 
  415: %%%-----------------------------------------------------------------
  416: internal_unlink_linking_exits(doc) ->
  417:     ["MboxLinkUnlink.java: "
  418:      "Test link and unlink between two java mailboxes. "
  419:      "Mailbox1 creates a link to mailbox2 and removes it. "
  420:      "Then it creates another link and mailbox2 removes is. "
  421:      "Finally mailbox1 exits - mailbox2 must survive"];
  422: internal_unlink_linking_exits(suite) ->
  423:     [];
  424: internal_unlink_linking_exits(Config) when is_list(Config) ->
  425:      internal_link_unlink(?internal_unlink_linking_exits,
  426: 			  internal_unlink_linking_exits,
  427: 			  Config).
  428: 
  429: %%%-----------------------------------------------------------------
  430: internal_unlink_linked_exits(doc) ->
  431:     ["MboxLinkUnlink.java: "
  432:      "Test link and unlink between two java mailboxes. "
  433:      "Mailbox1 creates a link to mailbox2 and removes it. "
  434:      "Then it creates another link and mailbox2 removes is. "
  435:      "Finally mailbox2 exits - mailbox1 must survive"];
  436: internal_unlink_linked_exits(suite) ->
  437:     [];
  438: internal_unlink_linked_exits(Config) when is_list(Config) ->
  439:     internal_link_unlink(?internal_unlink_linked_exits,
  440: 			 internal_unlink_linked_exits,
  441: 			 Config).
  442: 
  443: %%%-----------------------------------------------------------------
  444: normal_exit(doc) ->
  445:     ["MboxLinkUnlink.java: "
  446:      "Test that mbox.close() uses exit reason 'normal', i.e. "
  447:      "that linked processes are not terminated."];
  448: normal_exit(suite) ->
  449:     [];
  450: normal_exit(Config) when is_list(Config) ->
  451:     Fun =
  452: 	fun() ->
  453: 		register(erl_link_server,self()),
  454: 		process_flag(trap_exit,true),
  455: 		receive
  456: 		    {Main,Mbox} when is_pid(Main), is_pid(Mbox) ->
  457: 			?dbg("Erlang sending \"~p\"",[normal_exit]),
  458: 			link(Mbox),
  459: 			Pid = spawn_link(fun() ->
  460: 						 link(Mbox),
  461: 						 Mbox ! {?normal_exit},
  462: 						 receive after infinity -> ok end
  463: 					 end),
  464: 			receive
  465: 			    {'EXIT',Mbox,normal} ->
  466: 				%% Make sure that we don't get the
  467: 				%% exit signal from Pid, and Pid
  468: 				%% should still be alive.
  469: 				receive
  470: 				    {'EXIT',Pid,Reason} ->
  471: 					?dbg("Got unexpected exit signal: ~p",
  472: 					     [{'EXIT',Pid,Reason}]),
  473: 					exit({unexpected,{'EXIT',Pid,Reason}})
  474: 				after 500 ->
  475: 					true = erlang:is_process_alive(Pid),
  476: 					exit(Pid,kill)
  477: 				end,
  478: 				receive done -> Main ! done end
  479: 			after 1000 ->
  480: 				receive
  481: 				    Other ->
  482: 					?dbg("Got garbage when waiting for exit:"
  483: 					     " ~p", [Other]),
  484: 					Main ! done,
  485: 					exit({got_unexpected,Other})
  486: 				after 0 ->
  487: 					ok
  488: 				end
  489: 			end;
  490: 		    Other ->
  491: 			?dbg("Got garbage: ~p",[Other]),
  492: 			exit(Other)
  493: 		end
  494: 	end,
  495: 
  496:     spawn_link(Fun),
  497:     ok = jitu:java(?config(java, Config),
  498: 		   ?config(data_dir, Config),
  499: 		   "MboxLinkUnlink",
  500: 		   [erlang:get_cookie(),node()]).
  501: 
  502: 
  503: %%%-----------------------------------------------------------------
  504: kill_mbox(doc) ->
  505:     ["MboxLinkUnlink.java: "
  506:      "Test that mbox.exit(new OtpErlangAtom(\"kill\") causes linked "
  507:      "processes to exit with reason 'killed', which can be trapped."];
  508: kill_mbox(suite) ->
  509:     {skip, "Not yet implemented"};
  510: kill_mbox(Config) when is_list(Config) ->
  511:     Fun =
  512: 	fun() ->
  513: 		register(erl_link_server,self()),
  514: 		process_flag(trap_exit,true),
  515: 		receive
  516: 		    {Main,Mbox} when is_pid(Main), is_pid(Mbox) ->
  517: 			?dbg("Erlang sending \"~p\"",[kill_mbox]),
  518: 			Pid = spawn_link(fun() ->
  519: 						 process_flag(trap_exit,true),
  520: 						 link(Mbox),
  521: 						 Mbox ! {?kill_mbox},
  522: 						 receive
  523: 						     {'EXIT',Mbox,killed} ->
  524: 							 exit(correct_reason);
  525: 						     {'EXIT',Mbox,R} ->
  526: 							 exit({faulty_reason,R})
  527: 						 end
  528: 					 end),
  529: 			receive
  530: 			    {'EXIT',Pid,{faulty_reason,Reason}} ->
  531: 				receive done -> Main ! done end,
  532: 				exit({faulty_reason,Reason});
  533: 			    {'EXIT',Pid,im_killed} ->
  534: 				receive done -> Main ! done end
  535: 			after 1000 ->
  536: 				receive
  537: 				    Other ->
  538: 					?dbg("Got garbage when waiting for exit:"
  539: 					     " ~p", [Other]),
  540: 					Main ! done,
  541: 					exit({got_unexpected,Other})
  542: 				after 0 ->
  543: 					ok
  544: 				end
  545: 			end;
  546: 		    Other ->
  547: 			?dbg("Got garbage: ~p",[Other]),
  548: 			exit(Other)
  549: 		end
  550: 	end,
  551: 
  552:     spawn_link(Fun),
  553:     ok = jitu:java(?config(java, Config),
  554: 		   ?config(data_dir, Config),
  555: 		   "MboxLinkUnlink",
  556: 		   [erlang:get_cookie(),node()]).
  557: 
  558: %%%-----------------------------------------------------------------
  559: kill_erl_proc_from_java(doc) ->
  560:     ["MboxLinkUnlink.java: "
  561:      "Test that mbox.exit(pid, new OtpErlangAtom(\"kill\") causes erlang "
  562:      "processes <pid> to be killed, even if trapping exits"];
  563: kill_erl_proc_from_java(suite) ->
  564:     [];
  565: kill_erl_proc_from_java(Config) when is_list(Config) ->
  566:     LinkFun = fun(Mbox) ->
  567: 		      process_flag(trap_exit,true),
  568: 		      link(Mbox),
  569: 		      Mbox ! {?kill_erl_proc_from_java, self()},
  570: 		      receive after infinity -> ok end
  571: 	      end,
  572:     erl_java_link(LinkFun,kill_erl_proc_from_java,killed,Config).
  573: 
  574: %%%-----------------------------------------------------------------
  575: kill_mbox_from_erlang(doc) ->
  576:     ["MboxLinkUnlink.java: "
  577:      "Test that exit(Mbox,kill) causes linked the Mbox to be killed, and"
  578:      "linked processes to exit with reason 'killed', even if trapping exits"];
  579: kill_mbox_from_erlang(suite) ->
  580:     {skip, "Not yet implemented"};
  581: kill_mbox_from_erlang(Config) when is_list(Config) ->
  582:     LinkFun = fun(Mbox) ->
  583: 		      link(Mbox),
  584: 		      Mbox ! {?kill_mbox_from_erlang},
  585: 		      exit(Mbox,kill),
  586: 		      receive after infinity -> ok end
  587: 	      end,
  588:     erl_java_link(LinkFun,kill_mbox_from_erlang,killed,Config).
  589: 
  590: %%%-----------------------------------------------------------------
  591: erl_exit_with_reason_any_term(doc) ->
  592:     ["MboxLinkUnlink.java: "
  593:      "Test that any erlang term can be used as exit reason when erlang "
  594:      "process exits and is linked to an mbox."];
  595: erl_exit_with_reason_any_term(suite) ->
  596:     [];
  597: erl_exit_with_reason_any_term(Config) when is_list(Config) ->
  598:     Reason = [hei,self(),{this,is,"a",[different,"reason"]}],
  599:     LinkFun = fun(Mbox) ->
  600: 		      link(Mbox),
  601: 		      Mbox ! {?erl_exit_with_reason_any_term,self(),Reason},
  602: 		      receive ok -> ok end,
  603: 		      exit(Reason)
  604: 	      end,
  605:     erl_java_link(LinkFun,erl_exit_with_reason_any_term,Reason,Config).
  606: 
  607: %%%-----------------------------------------------------------------
  608: java_exit_with_reason_any_term(doc) ->
  609:     ["MboxLinkUnlink.java: "
  610:      "Test that any erlang term can be used as exit reason when mbox "
  611:      "exits and is linked to an erlang process."];
  612: java_exit_with_reason_any_term(suite) ->
  613:     [];
  614: java_exit_with_reason_any_term(Config) when is_list(Config) ->
  615:     Reason = [hei,self(),{this,is,"a",[different,"reason"]}],
  616:     LinkFun =
  617: 	fun(Mbox) ->
  618: 		Mbox ! {?java_exit_with_reason_any_term,self(),Reason},
  619: 		receive after infinity -> ok end
  620: 	end,
  621:     erl_java_link(LinkFun,java_exit_with_reason_any_term,Reason,Config).
  622: 
  623: 
  624: %%%-----------------------------------------------------------------
  625: status_handler_localStatus(doc) ->
  626:     ["NodeStatusHandler.java: "
  627:      "Test OtpNode.registerStatusHandler(...) and the callback "
  628:      "OtpNodeStatus.localStatus(...)"];
  629: status_handler_localStatus(suite) ->
  630:     [];
  631: status_handler_localStatus(Config) when is_list(Config) ->
  632:     spawn_link(fun() ->
  633: 		       erl_status_server([{opt,{localStatus,"javanode1",true}},
  634: 					  {localStatus,"javanode1",false}])
  635: 	       end),
  636:     ok = jitu:java(?config(java, Config),
  637: 		   ?config(data_dir, Config),
  638: 		   "NodeStatusHandler",
  639: 		   [erlang:get_cookie(),node(),?status_handler_localStatus]).
  640: 
  641: %%%-----------------------------------------------------------------
  642: status_handler_remoteStatus(doc) ->
  643:     ["NodeStatusHandler.java: "
  644:      "Test OtpNode.registerStatusHandler(...) and the callback "
  645:      "OtpNodeStatus.remoteStatus(...)"];
  646: status_handler_remoteStatus(suite) ->
  647:     [];
  648: status_handler_remoteStatus(Config) when is_list(Config) ->
  649:     spawn_link(fun() ->
  650: 		       erl_status_server([{opt,{localStatus,"javanode1",true}},
  651: 					  {remoteStatus,"javanode2",true},
  652: 					  {remoteStatus,"javanode2",false}])
  653: 	       end),
  654:     ok = jitu:java(?config(java, Config),
  655: 		   ?config(data_dir, Config),
  656: 		   "NodeStatusHandler",
  657: 		   [erlang:get_cookie(),node(),?status_handler_remoteStatus]).
  658: 
  659: 
  660: %%%-----------------------------------------------------------------
  661: status_handler_connAttempt(doc) ->
  662:     ["NodeStatusHandler.java: "
  663:      "Test OtpNode.registerStatusHandler(...) and the callback "
  664:      "OtpNodeStatus.connAttempt(...)"];
  665: status_handler_connAttempt(suite) ->
  666:     [];
  667: status_handler_connAttempt(Config) when is_list(Config) ->
  668:     spawn_link(fun() ->
  669: 		       erl_status_server([{opt,{localStatus,"javanode1",true}},
  670: 					  {connAttempt,"unknown",true},
  671: 					  {connAttempt,"javanode3",false}])
  672: 	       end),
  673:     ok = jitu:java(?config(java, Config),
  674: 		   ?config(data_dir, Config),
  675: 		   "NodeStatusHandler",
  676: 		   [erlang:get_cookie(),node(),?status_handler_connAttempt]).
  677: 
  678: 
  679: %%%-----------------------------------------------------------------
  680: %%% INTERNAL FUNCTIONS
  681: %%%-----------------------------------------------------------------
  682: send_receive(TestCaseTag,Fun,Config) ->
  683:     spawn(fun() ->
  684: 		  register(erl_send_receive_server,self()),
  685: 		  receive
  686: 		      From when is_pid(From) ->
  687: 			  JavaNode = node(From),
  688: 			  [JavaNode] = nodes(hidden),
  689: 			  From ! {TestCaseTag,self()},
  690: 			  Fun(),
  691: 			  unregister(erl_send_receive_server)
  692: 		  end
  693: 	  end),
  694:     ok = jitu:java(?config(java, Config),
  695: 		   ?config(data_dir, Config),
  696: 		   "MboxSendReceive",
  697: 		   [erlang:get_cookie(),node()]).
  698: 
  699: 
  700: internal_link_unlink(Tag,Msg,Config) ->
  701:     Fun =
  702: 	fun() ->
  703: 		register(erl_link_server,self()),
  704: 		process_flag(trap_exit,true),
  705: 		receive
  706: 		    {Main,Mbox} when is_pid(Main), is_pid(Mbox) ->
  707: 			?dbg("Erlang sending \"~p\"",[Msg]),
  708: 			Mbox ! {Tag,self(),?link_test_reason},
  709: 			receive done -> Main ! done end;
  710: 		    Other ->
  711: 			?dbg("Got garbage: ~p",[Other]),
  712: 			exit(Other)
  713: 		end
  714: 	end,
  715: 
  716:     spawn_link(Fun),
  717:     ok = jitu:java(?config(java, Config),
  718: 		   ?config(data_dir, Config),
  719: 		   "MboxLinkUnlink",
  720: 		   [erlang:get_cookie(),node()]).
  721: 
  722: 
  723: erl_java_link(LinkFun,Msg,Config) ->
  724:     erl_java_link(LinkFun,Msg,?link_test_reason,Config).
  725: 
  726: erl_java_link(LinkFun,Msg,Reason,Config) ->
  727:     Fun =
  728: 	fun() ->
  729: 		register(erl_link_server,self()),
  730: 		process_flag(trap_exit,true),
  731: 		receive
  732: 		    {Main,Mbox} when is_pid(Mbox), is_pid(Mbox) ->
  733: 			?dbg("Erlang sending \"~p\"",[Msg]),
  734: 			Pid = spawn_link(fun() -> LinkFun(Mbox) end),
  735: 			receive
  736: 			    {'EXIT',Pid,Reason} ->
  737: 				receive done -> Main ! done end
  738: 			after 1000 ->
  739: 				receive
  740: 				    Other ->
  741: 					?dbg("Got garbage when waiting for exit:"
  742: 					     " ~p", [Other]),
  743: 					Main ! done,
  744: 					exit({got_unexpected,Other})
  745: 				after 0 ->
  746: 					ok
  747: 				end
  748: 			end;
  749: 		    Other ->
  750: 			?dbg("Got garbage: ~p",[Other]),
  751: 			exit(Other)
  752: 		end
  753: 	end,
  754: 
  755:     spawn_link(Fun),
  756:     ok = jitu:java(?config(java, Config),
  757: 		   ?config(data_dir, Config),
  758: 		   "MboxLinkUnlink",
  759: 		   [erlang:get_cookie(),node()]).
  760: 
  761: erl_status_server(List) ->
  762:     register(erl_status_server,self()),
  763:     erl_status_server(List,undefined).
  764: erl_status_server([{opt,{Tag,NodeName,Up}},{Tag2,NodeName2,Up2}|Rest],_) ->
  765:     receive
  766: 	{Tag,Node,Up,From} = M ->
  767: 	    ?dbg("erl_status_server got: ~p",[M]),
  768: 	    true = lists:prefix(NodeName,Node),
  769: 	    erl_status_server([{Tag2,NodeName2,Up2}|Rest],From);
  770: 	{Tag2,Node2,Up2,From2} = M2 ->
  771: 	    ?dbg("erl_status_server got: ~p",[M2]),
  772: 	    true = lists:prefix(NodeName2,Node2),
  773: 	    erl_status_server(Rest,From2)
  774:     end;
  775: erl_status_server([{Tag,NodeName,Up}|Rest],_) ->
  776:     receive
  777: 	{Tag,Node,Up,From} = M ->
  778: 	    ?dbg("erl_status_server got: ~p",[M]),
  779: 	    true = lists:prefix(NodeName,Node),
  780: 	    erl_status_server(Rest,From);
  781: 	Other ->
  782: 	    ?dbg("erl_status_server got garbage: ~p",[Other]),
  783: 	    exit(Other)
  784:     end;
  785: erl_status_server([],From) ->
  786:     From ! done.