Permalink
Browse files

Update process_relation_test, and make it and ets_r_t run without eunit.

  • Loading branch information...
1 parent 10df17f commit 645cd2cd3015b5fd029b3e029e3a56e0711d07d0 @esstrifork esstrifork committed Feb 5, 2014
@@ -0,0 +1,41 @@
+-module(ets_race_tests).
+
+-compile(export_all).
+
+-include("triq.hrl").
+-include("unit.hrl").
+
+% ../../../../../jerl -sname erj -pz ../../../../../triq/ebin
+% c(ets_race_tests, [{i, "../../../../../triq/include"}]).
+% ets_race_tests:test().
+
+%%%========== Entry point: ====================
+test() ->
+ eunit_test(?MODULE).
+
+give_away_die_race_test() ->
+ N = 10000,
+ expect_to_leave_N_tables(0,
+ fun() ->
+ [give_away_die_race()
+ || _ <- lists:seq(1,N)]
+ end).
+
+give_away_die_race() ->
+ Pid = spawn(fun() -> ok end),
+ %Tab = ets:new(foo, [{heir, Pid, here_you_are}]),
+ Tab = ets:new(foo, []),
+ try ets:give_away(Tab, Pid, here_you_are)
+ catch _:badarg -> ets:delete(Tab)
+ end.
+
+
+
+
+expect_to_leave_N_tables(N, Action) when is_integer(N),
+ is_function(Action,0) ->
+ Before = ets:all(),
+ Action(),
+ timer:sleep(500),
+ After = ets:all(),
+ ?assertEqual(N, length(After -- Before)).
@@ -2,13 +2,20 @@
-compile(export_all).
--include_lib("eunit/include/eunit.hrl").
-include("triq.hrl").
+-include("unit.hrl").
% ../../../../../jerl -sname erj -pz ../../../../../triq/ebin
% c(process_relation_tests, [{i, "../../../../../triq/include"}]).
% process_relation_tests:test().
+
+%%%========== Entry point: ====================
+test() ->
+ eunit_test(?MODULE).
+
+%%%========== Tests: ==============================
+
child_survives_tail_spawn_nonlink_test() ->
N = 1000,
expect_to_leave_N_processes(N,
@@ -58,8 +65,56 @@ nontail_spawn_link_child_with_siblings_exits_abnormally_test() ->
fun() ->
[nontail_spawn_link_child_with_siblings_exits_abnormally()
|| _ <- lists:seq(1,N)]
+ end,
+ 2000).
+
+%%%----------
+%%% Link storm: Many simultaneous linkings against the same process
+link_storm_normal_exit_test() ->
+ N=100, M=100,
+ expect_to_leave_N_processes(N*M,
+ fun() ->
+ [link_storm_normal_exit(M)
+ || _ <- lists:seq(1,N)]
+ end).
+link_storm_normal_exit(M) ->
+ Linkee = spawn(fun() -> receive wait_then_exit ->
+ timer:sleep(500),
+ exit(normal)
+ end
+ end),
+ _Spawned =
+ lists:map(fun(_) ->
+ spawn(fun() -> link(Linkee),
+ receive never -> ok after 3000->done end
+ end)
+ end,
+ lists:seq(1,M)),
+ Linkee ! wait_then_exit.
+
+%%%----------
+%%% Link storm: Many simultaneous linkings against the same process
+link_storm_abnormal_exit_test() ->
+ N = 1000, M=100,
+ expect_to_leave_N_processes(0,
+ fun() ->
+ [link_storm_abnormal_exit(M)
+ || _ <- lists:seq(1,N)]
end).
+link_storm_abnormal_exit(M) ->
+ Linkee = spawn(fun() -> receive never -> ok end end),
+ _Spawned =
+ lists:map(fun(_) ->
+ spawn(fun() -> link(Linkee),
+ receive never -> ok after 5->done end
+ end)
+ end,
+ lists:seq(1,M)),
+ spawn(fun() -> timer:sleep(500),
+ exit(Linkee,crash)
+ end).
+%%%----------
%%% Tests propagation + possibility of having been sent exit when trying to link
link_kill_race_test() ->
@@ -122,27 +177,32 @@ nontail_spawn_link_child_with_siblings_exits_abnormally() ->
spawn(fun() ->
%% Earlier sibling 1:
spawn_link(fun() ->
- receive never -> ok end
+ receive never -> ok
+ after 2000 -> io:format("S1") end
end),
timer:sleep(1),
%% Earlier sibling 2:
spawn_link(fun() ->
- receive never -> ok end
+ receive never -> ok
+ after 2000 -> io:format("S2") end
end),
%% Abnormally exiting:
spawn_link(fun() ->
exit(ab),
- receive never -> ok end
+ io:format("S3")
end),
%% Subsequent sibling 1:
spawn_link(fun() ->
- receive never -> ok end
+ receive never -> ok
+ after 2000 -> io:format("S4") end
end),
timer:sleep(1),
%% Subsequent sibling 2:
spawn_link(fun() ->
- receive never -> ok end
- end)
+ receive never -> ok
+ after 2000 -> io:format("S5") end
+ end),
+ timer:sleep(500)
end).
link_kill_race() ->
@@ -156,14 +216,16 @@ link_kill_race() ->
end),
exit(Pid,go_away).
-expect_to_leave_N_processes(N, Action) when is_integer(N),
- is_function(Action,0) ->
+%%%========== Utilities: ====================
+expect_to_leave_N_processes(N, Action) ->
+ expect_to_leave_N_processes(N, Action,1000).
+
+expect_to_leave_N_processes(N, Action, Timeout)
+ when is_integer(N),
+ is_function(Action,0),
+ is_integer(Timeout) ->
Before = processes(),
Action(),
- timer:sleep(1000),
+ timer:sleep(Timeout),
After = processes(),
?assertEqual(N, length(After -- Before)).
-
-
-test() ->
- eunit:test(?MODULE).
@@ -0,0 +1,44 @@
+-ifndef(_unit_hrl_included_).
+-define(_unit_hrl_included_,yes).
+
+eunit_test(Module) ->
+ TestFunctions = [F || {F,0} <- Module:module_info(exports),
+ lists:suffix("_test", atom_to_list(F))],
+ io:format("========== Running test suite ~s ==========\n", [Module]),
+ Results =
+ lists:map(fun(F) ->
+ io:format("---------- Running test ~s ----------\n", [F]),
+ Res = try Module:F(),
+ true
+ catch _:Err ->
+ io:format("*** Exception: ~p\n", [Err]),
+ false
+ end,
+ io:format(" ----- Test ~s ~s -----\n",
+ [F, case Res of
+ true -> "SUCCEEDED";
+ false -> "FAILED"
+ end]),
+ {F,Res}
+ end,
+ TestFunctions),
+ FailedTests = [F || {F,Res} <- Results, not Res],
+ io:format(" ===== Test suite ~s: Tests: ~p Failed: ~p =====\n",
+ [Module, length(TestFunctions), length(FailedTests)]),
+ case FailedTests of
+ [] ->
+ ok;
+ _ ->
+ error({test_suite_failed, Module, FailedTests})
+ end.
+
+-define(assertEqual(Expected,Actual),
+ (fun(X,X) -> ok;
+ (Exp,Act) -> error({assertion_failed,
+ {line,?LINE},
+ {expr, ??Actual},
+ {expected_value, Exp},
+ {actual_value, Act}})
+ end)(Expected,Actual)).
+
+-endif.

0 comments on commit 645cd2c

Please sign in to comment.