123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140 |
- -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}
- ]}.
|