Skip to content

Commit 52a1131

Browse files
committed
Merge branch 'eunit/fix-node-instantiator' into maint
* eunit/fix-node-instantiator: Fix runtime dependencies eunit: Pass node name to {node, ...} instantiator
2 parents bccd0c4 + a1208ab commit 52a1131

3 files changed

Lines changed: 112 additions & 45 deletions

File tree

lib/eunit/src/eunit.app.src

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -25,4 +25,4 @@
2525
{registered,[]},
2626
{applications, [kernel,stdlib]},
2727
{env, []},
28-
{runtime_dependencies, ["stdlib-6.0","kernel-5.3","erts-9.0"]}]}.
28+
{runtime_dependencies, ["stdlib-6.0","kernel-8.3","erts-9.0"]}]}.

lib/eunit/src/eunit_data.erl

Lines changed: 50 additions & 41 deletions
Original file line numberDiff line numberDiff line change
@@ -375,49 +375,58 @@ parse({node, N, T}, Options) when is_atom(N) ->
375375
parse({node, N, "", T}, Options);
376376
parse({node, N, A, T1}=T, Options) when is_atom(N) ->
377377
case eunit_lib:is_string(A) of
378-
true ->
379-
%% TODO: better stack traces for internal funs like these
380-
parse({setup,
381-
fun () ->
382-
%% TODO: auto-start net_kernel if needed
383-
StartedNet = false,
384-
%% The following is commented out because of problems when running
385-
%% eunit as part of the init sequence (from the command line):
386-
%% StartedNet =
387-
%% case whereis(net_kernel) of
388-
%% undefined ->
389-
%% M = list_to_atom(atom_to_list(N)
390-
%% ++ "_master"),
391-
%% case net_kernel:start([M]) of
392-
%% {ok, _} ->
393-
%% true;
394-
%% {error, E} ->
395-
%% throw({net_kernel_start, E})
396-
%% end;
397-
%% _ -> false
398-
%% end,
399-
%% ?debugVal({started, StartedNet}),
400-
{Name, Host} = eunit_lib:split_node(N),
401-
{ok, Node} = case peer:start_link(#{
378+
true ->
379+
%% TODO: better stack traces for internal funs like these
380+
%% Wrap T1 so the instantiator receives the node name
381+
T2 = case T1 of
382+
F when is_function(F, 1) ->
383+
fun({_Peer, NodeName, _}) -> F(NodeName) end;
384+
{with, As} when is_list(As) ->
385+
fun({_Peer, NodeName, _}) ->
386+
{with, NodeName, As}
387+
end;
388+
_ ->
389+
T1
390+
end,
391+
parse({setup,
392+
fun () ->
393+
{Name, Host} = eunit_lib:split_node(N),
394+
StartedNet =
395+
case node() of
396+
'nonode@nohost' ->
397+
M = list_to_atom(atom_to_list(Name)
398+
++ "_master"),
399+
case net_kernel:start(M, #{name_domain => shortnames}) of
400+
{ok, _} ->
401+
true;
402+
{error, E} ->
403+
throw({net_kernel_start, E})
404+
end;
405+
_ -> false
406+
end,
407+
PathArgs = lists:flatmap(
408+
fun(P) -> ["-pa", P] end,
409+
code:get_path()),
410+
{ok, Peer, NodeName} = case peer:start_link(#{
402411
host => atom_to_list(Host),
403-
name => Name, args => parse_peer_args(A)}) of
404-
{ok, Pid} -> {ok, Pid};
405-
{ok, Pid, _Node} -> {ok, Pid};
412+
name => Name,
413+
args => PathArgs ++ parse_peer_args(A)}) of
414+
{ok, Pid, Node0} -> {ok, Pid, Node0};
406415
{error, Rsn} -> throw({peer_start, Rsn})
407416
end,
408-
{Node, StartedNet}
409-
end,
410-
fun ({Node, StopNet}) ->
411-
%% ?debugVal({stop, StopNet}),
412-
peer:stop(Node),
413-
case StopNet of
414-
true -> net_kernel:stop();
415-
false -> ok
416-
end
417-
end,
418-
T1}, Options);
419-
false ->
420-
bad_test(T)
417+
{Peer, NodeName, StartedNet}
418+
end,
419+
fun ({Peer, _NodeName, StopNet}) ->
420+
%% ?debugVal({stop, StopNet}),
421+
peer:stop(Peer),
422+
case StopNet of
423+
true -> net_kernel:stop();
424+
false -> ok
425+
end
426+
end,
427+
T2}, Options);
428+
false ->
429+
bad_test(T)
421430
end;
422431
parse({module, M}, Options) when is_atom(M) ->
423432
{data, {"module '" ++ atom_to_list(M) ++ "'", get_module_tests(M, Options)}};
@@ -833,7 +842,7 @@ data_test_() ->
833842
?_assertMatch(ok, eunit:test({spawn, Tests})),
834843
?_assertMatch(ok, eunit:test({setup, Setup, Cleanup,
835844
fun (P) -> ?_test(ok = ping(P)) end})),
836-
%%?_assertMatch(ok, eunit:test({node, test@localhost, Tests})),
845+
?_assertMatch(ok, eunit:test({node, test@localhost, Tests})),
837846
?_assertMatch(ok, eunit:test({module, eunit_lib})),
838847
?_assertMatch(ok, eunit:test(eunit_lib)),
839848
?_assertMatch(ok, eunit:test("examples/tests.txt"))

lib/eunit/test/eunit_SUITE.erl

Lines changed: 61 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,7 @@
2424
-export([all/0, suite/0, groups/0, init_per_suite/1, end_per_suite/1,
2525
init_per_group/2, end_per_group/2,
2626
app_test/1, appup_test/1, eunit_test/1, eunit_exact_test/1,
27-
fixture_test/1, primitive_test/1, surefire_utf8_test/1,
27+
fixture_test/1, node_test/1, primitive_test/1, surefire_utf8_test/1,
2828
surefire_latin_test/1, surefire_c0_test/1, surefire_ensure_dir_test/1,
2929
stacktrace_at_timeout_test/1, scale_timeouts_test/1,
3030
report_failed_setup_inparallel_test/1, parse_commandline_test/1]).
@@ -42,8 +42,8 @@ suite() -> [{ct_hooks,[ts_install_cth]}].
4242

4343
all() ->
4444
[app_test, appup_test, eunit_test, eunit_exact_test, primitive_test,
45-
fixture_test, surefire_utf8_test, surefire_latin_test, surefire_c0_test,
46-
surefire_ensure_dir_test, stacktrace_at_timeout_test,
45+
fixture_test, node_test, surefire_utf8_test, surefire_latin_test,
46+
surefire_c0_test, surefire_ensure_dir_test, stacktrace_at_timeout_test,
4747
scale_timeouts_test, report_failed_setup_inparallel_test,
4848
parse_commandline_test].
4949

@@ -155,6 +155,64 @@ fixture_test(Config) when is_list(Config) ->
155155
[{1, fun(_A, _B) -> fun() -> a_test end end}]}),
156156
ok.
157157

158+
node_test(Config) when is_list(Config) ->
159+
T = fun() -> ok end,
160+
%% Plain tests
161+
ok = eunit:test({node, eunit_node_plain, [T, T, T]}),
162+
%% Instantiator receives node name as atom
163+
ok = eunit:test(
164+
{node, eunit_node_inst, fun(Node) ->
165+
true = is_atom(Node),
166+
{spawn, Node, [
167+
fun() -> Node = node() end
168+
]}
169+
end}),
170+
%% With extra args
171+
ok = eunit:test(
172+
{node, eunit_node_args, "+S 1", fun(Node) ->
173+
true = is_atom(Node),
174+
{spawn, Node, [T]}
175+
end}),
176+
%% Test {node, ...} during system initialization (non-distributed).
177+
%% Verifies that auto-starting net_kernel is safe with -eval, -s,
178+
%% -run, and -S flags as described in init(3).
179+
PrivDir = proplists:get_value(priv_dir, Config, "."),
180+
HelperMod = eunit_node_init_test,
181+
HelperSrc = filename:join(PrivDir, atom_to_list(HelperMod) ++ ".erl"),
182+
ok = file:write_file(HelperSrc,
183+
"-module(" ++ atom_to_list(HelperMod) ++ ").\n"
184+
"-export([start/0, start/1]).\n"
185+
"start() -> start([]).\n"
186+
"start(_) ->\n"
187+
" ok = eunit:test({node, init_test, fun() -> ok end}),\n"
188+
" halt(0).\n"),
189+
{ok, HelperMod} = compile:file(HelperSrc, [{outdir, PrivDir}]),
190+
[Exec | ExecArgs] = string:split(ct:get_progname(), " ", all),
191+
Erl = os:find_executable(Exec),
192+
BaseArgs = ExecArgs ++ ["-noshell"],
193+
%% -eval
194+
0 = run_erl_cmd(Erl, BaseArgs ++ ["-eval",
195+
"ok = eunit:test({node, init_eval, fun() -> ok end}), halt(0)."]),
196+
%% -s
197+
0 = run_erl_cmd(Erl, BaseArgs ++ ["-pa", PrivDir,
198+
"-s", atom_to_list(HelperMod), "start"]),
199+
%% -run
200+
0 = run_erl_cmd(Erl, BaseArgs ++ ["-pa", PrivDir,
201+
"-run", atom_to_list(HelperMod), "start"]),
202+
%% -S
203+
0 = run_erl_cmd(Erl, BaseArgs ++ ["-pa", PrivDir,
204+
"-S", atom_to_list(HelperMod), "start"]),
205+
ok.
206+
207+
run_erl_cmd(Erl, Args) ->
208+
Port = open_port({spawn_executable, Erl},
209+
[{args, Args}, stderr_to_stdout, exit_status, hide]),
210+
receive
211+
{Port, {exit_status, Status}} -> Status
212+
after 30_000 ->
213+
ct:fail({erl_timeout, Args})
214+
end.
215+
158216
check_test_results(Primitive, Expected) ->
159217
receive
160218
{test_report, TestReport} ->

0 commit comments

Comments
 (0)