I have some issue with distributed tests under rebar.
Rebar starts node with name nonode@nohost
. After it I call help function make_distrib
which provide normal node name and starts distribution work.
After starting the slave node I couldn't sent to it any lambda. I had error:
=ERROR REPORT==== 27-Jul-2013::22:48:02 === Error in process on node 'test1@just' with exit value: {{badfun,#Fun<msg_proxy_tests.2.117197241>},[{error_handler,undefined_lambda,3,[{file,"error_handler.erl"},{line,64}]}]}
But! If I run it test with simple way - all works good:
$erl 1> c(msg_proxy_tests). {ok,msg_proxy_tests} 2> eunit:test({module, msg_proxy_tests},[verbose]). ======================== EUnit ======================== module 'msg_proxy_tests'msg_proxy_tests: distrib_mode_test_ (distribute mode test for nodes)... msg_proxy_tests.erl:14:<0.48.0>: nodes ( ) = [test1@just] msg_proxy_tests.erl:15:<9999.39.0>: node ( ) = test1@just msg_proxy_tests.erl:17:<0.48.0>: nodes ( ) = [test1@just] [0.238 s] ok
How can I fix this?
-module(msg_proxy_tests). -include_lib("eunit/include/eunit.hrl"). distrib_mode_test_()-> {"distribute mode test for nodes", timeout, 60, fun() -> {ok, Host} = inet:gethostname(), make_distrib("tests@"++Host, shortnames), slave:start(Host, test1), ?debugVal(nodes()), spawn(list_to_atom("test1@"++Host), fun()-> ?debugVal(node()) end), timer:sleep(100), ?debugVal(nodes()), stop_distrib(), ok end}. -spec make_distrib( NodeName::string()|atom(), NodeType::shortnames | longnames) -> {ok, ActualNodeName::atom} | {error, Reason::term()}. make_distrib(NodeName, NodeType) when is_list(NodeName) -> make_distrib(erlang:list_to_atom(NodeName), NodeType); make_distrib(NodeName, NodeType) -> case node() of 'nonode@nohost' -> [] = os:cmd("epmd -daemon"), case net_kernel:start([NodeName, NodeType]) of {ok, _Pid} -> node() end; CurrNode -> CurrNode end. stop_distrib()-> net_kernel:stop().
That is because of module hash on both nodes is different. That happens because eunit compiles code before it run and module contains -ifdef(TEST)
macroses, which will definitely change it's hash.
Thats why anonymous function #Fun<msg_proxy_tests.2.117197241
could not be called and error occurred. (look at function name and you will notice funny numbers, this is module hash, it will be different on both nodes).
If you want to avoid this, you should call funs by it fully qualified name: module:fun_name/arity
.