我在钢筋下的分布式测试存在一些问题。
Rebar以名称nonode@nohost
启动节点。之后,我调用帮助函数make_distrib
,它提供正常的节点名称并开始分发工作
启动从节点后,我无法向它发送任何lambda。我有错误:
=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}]}]}
但是!如果我用简单的方式运行测试 - 一切正常:
$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
我该如何解决这个问题?
-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().
答案 0 :(得分:1)
那是因为两个节点上的模块散列不同。发生这种情况是因为eunit在运行代码之前编译代码并且模块包含-ifdef(TEST)
个宏,这肯定会改变它的哈希值。
这就是为什么无法调用匿名函数#Fun<msg_proxy_tests.2.117197241
并发生错误的原因。 (查看函数名称,您会注意到有趣的数字,这是模块哈希,它在两个节点上都会有所不同)。
如果你想避免这种情况,你应该用完全限定的名字叫{} module:fun_name/arity
。