-module(pooler_perf_test). -compile([export_all]). -include_lib("eunit/include/eunit.hrl"). -define(gv(X, L), proplists:get_value(X, L)). setup() -> setup(10, 100, 5). setup(InitCount, MaxCount, NumPools) -> MakePool = fun(I) -> N = integer_to_list(I), Name = "p" ++ N, Arg0 = "pool-" ++ Name, [ {name, list_to_atom(Name)}, {max_count, MaxCount}, {init_count, InitCount}, {start_mfa, {pooled_gs, start_link, [{Arg0}]}} ] end, Pools = [MakePool(I) || I <- lists:seq(1, NumPools)], application:set_env(pooler, pools, Pools), application:start(pooler). consumer_cycle(N) -> consumer_cycle(N, 0, 0). consumer_cycle(N, NumOk, NumFail) when N > 0 -> P = pooler:take_member(p1), case P of Pid when is_pid(Pid) -> true = is_process_alive(P), pooler:return_member(p1, P, ok), consumer_cycle(N - 1, NumOk + 1, NumFail); _ -> consumer_cycle(N - 1, NumOk, NumFail + 1) end; consumer_cycle(0, NumOk, NumFail) -> [{ok, NumOk}, {fail, NumFail}]. test1() -> N = 10000, {Time, _} = timer:tc( fun() -> consumer_cycle(N) end, [] ), Time / N. consumer_worker(N, Parent) -> spawn(fun() -> Parent ! {self(), consumer_cycle(N)} end). test3(W, N) -> [consumer_worker(W, self()) || _I <- lists:seq(1, N)]. test2(Iter, Workers) -> Self = self(), {Time, Res} = timer:tc( fun() -> Pids = [ consumer_worker(Iter, Self) || _I <- lists:seq(1, Workers) ], gather_pids(Pids) end, [] ), {NumOk, NumFail} = lists:foldr( fun({_, L}, {O, F}) -> {O + ?gv(ok, L), F + ?gv(fail, L)} end, {0, 0}, Res ), {Time, [{ok, NumOk}, {fail, NumFail}]}. gather_pids(Pids) -> gather_pids(Pids, []). gather_pids([Pid | Rest], Acc) -> receive {Pid, Ans} -> gather_pids(Rest, [{Pid, Ans} | Acc]); stop -> stop end; gather_pids([], Acc) -> Acc. pooler_take_return_test_() -> {foreach, % setup fun() -> InitCount = 100, MaxCount = 100, NumPools = 5, logger:set_handler_config(default, filters, []), setup(InitCount, MaxCount, NumPools) end, fun(_X) -> application:stop(pooler) end, [ {"take return cycle single worker", fun() -> NumCycles = 10000, Ans = consumer_cycle(NumCycles), ?assertEqual(NumCycles, ?gv(ok, Ans)), ?assertEqual(0, ?gv(fail, Ans)) end}, {"take return cycle multiple workers", fun() -> Self = self(), Iter = 100, Workers = 100, Pids = [ consumer_worker(Iter, Self) || _I <- lists:seq(1, Workers) ], Res = gather_pids(Pids), {NumOk, NumFail} = lists:foldr( fun({_, L}, {O, F}) -> {O + ?gv(ok, L), F + ?gv(fail, L)} end, {0, 0}, Res ), %% not sure what to test here now. We expect some %% failures if init count is less than max count %% because of async start. ?assertEqual(0, NumFail), ?assertEqual(100 * 100, NumOk) end} ]}.