Current section
Files
Jump to
Current section
Files
src/regis.erl
-module(regis).
-export([ register/3
, unregister/2
, unregister_all/1
, whereis_job/1
, jobs/1
, num_registered_pids/0
, callback/1
]).
-define(SERVER, regis_pnode_s).
%% Public API
whereis_job(JobMeta) ->
gen_server:call(?SERVER, {whereis_job, JobMeta}).
jobs(JobMeta) ->
gen_server:call(?SERVER, {jobs, JobMeta}).
num_registered_pids() ->
gen_server:call(?SERVER, {num_registered_pids}).
register(JobMeta, VNodeId, Pid) ->
gen_server:cast(?SERVER, {reg, JobMeta, VNodeId, Pid}).
unregister(JobMeta, Pid) ->
gen_server:cast(?SERVER, {unreg, JobMeta, Pid}).
unregister_all(Pid) ->
gen_server:cast(?SERVER, {unreg_all, Pid}).
%% ===================================================================
%% EUnit tests
%% ===================================================================
-include_lib("eunit/include/eunit.hrl").
-define(setup(F), {setup, fun start_t/0, fun stop_t/1, F}).
%% Описание спецификаций
%%%%%%%%%%%%%%%%%%%%%%%%%%
%%% TESTS DESCRIPTIONS %%%
%%%%%%%%%%%%%%%%%%%%%%%%%%
start_stop_test_() ->
{"0. Сервер должен запускаться, останавливаться и иметь зарегистрированное имя", ?setup(fun is_registered/1)}.
register_test_() ->
[
{"1 Register. Должна иметься возможность регистрации Pid и Job из одной функции", ?setup(fun register_t/1)},
{"2 UnRegister. Должна иметься возможность снятия с регистрации Pid и Job из одной функции обладая полями (JobMeta и Pid)", ?setup(fun unregister_t/1)},
{"3 Search. Должна быть возможность определения Pid по имени Job, извлечения всех зарегистрированных джобов и количества зарегистрированных Pid", ?setup(fun search_t/1)},
{"4 Процесс должен автоматически сниматься с регистрации после завершения или при внезапной смерти", ?setup(fun auto_unregister_t/1)}
].
%%%%%%%%%%%%%%%%%%%%%%%
%%% SETUP FUNCTIONS %%%
%%%%%%%%%%%%%%%%%%%%%%%
start_t() ->
{ok, Pid} = ?SERVER:start_link(),
Pid.
stop_t(_) ->
?SERVER:stop([]).
%%%%%%%%%%%%%%%%%%%%
%%% ACTUAL TESTS %%%
%%%%%%%%%%%%%%%%%%%%
is_registered(Pid) ->
[
?_assert(erlang:is_process_alive(Pid)),
?_assertEqual(Pid, whereis(regis_pnode_s))
].
register_t(_State) ->
Self = self(),
JobMeta1 = {pscomp1, sample1, Self},
VnodeItem1 = {111111111112234455666, Self},
JobsId=pscomp_proc_jobs,
PidsId=pscomp_proc_pids,
[
?_assertMatch(ok, register(JobMeta1, VnodeItem1, Self) ),
?_assertEqual(1, num_items(JobsId, JobMeta1) ),
?_assertEqual(1, num_items(PidsId, Self) )
].
unregister_t(_State) ->
Self = self(),
JobMeta1 = {pscomp1, sample1, Self},
VnodeItem1 = {111111111112234455666, Self},
VnodeItem2 = {212313123486898080821, Self},
JobsId=pscomp_proc_jobs,
PidsId=pscomp_proc_pids,
[ register(JobMeta1, VnodeItem, Self) || VnodeItem <- [ VnodeItem1, VnodeItem2 ] ],
[
?_assertEqual(2, num_items(JobsId, JobMeta1) ),
?_assertEqual(1, num_items(PidsId, Self) ),
?_assertMatch(ok, unregister(JobMeta1, Self) ),
?_assertEqual(0, num_items(JobsId, JobMeta1) ),
?_assertEqual(0, num_items(PidsId, Self) )
].
search_t(_State) ->
Self = self(),
JobMeta1 = {pscomp1, sample1, Self},
VnodeItem1 = {111111111112234455666, Self},
VnodeItem2 = {212313123486898080821, Self},
[
?_assertMatch(ok, register(JobMeta1, VnodeItem1, Self) ),
?_assertEqual(true, is_pid( whereis_job(JobMeta1) ) ),
?_assertMatch(ok, register(JobMeta1, VnodeItem2, Self) ),
?_assertEqual(1, num_registered_pids() ),
?_assertEqual(2, lists:sum( lists:map(fun(_X) -> 1 end, jobs(JobMeta1) ) ) )
].
auto_unregister_t(_) ->
JobMeta = {pscomp1, sample1, self()},
Pid = spawn_link(fun() -> callback(JobMeta) end),
timer:sleep(15),
Ref = make_ref(),
WherePid1 = whereis_job(JobMeta),
whereis_job(JobMeta) ! {self(), Ref, hi},
Rec = receive
{Ref, hi} -> true
after 2000 -> false
end,
exit(Pid, kill),
WherePid2 = whereis_job(JobMeta),
[ ?_assert( is_pid(WherePid1) ),
?_assert(Rec),
?_assertEqual(undefined, WherePid2)
].
%%%%%%%%%%%%%%%%%%%%%%%%
%%% HELPER FUNCTIONS %%%
%%%%%%%%%%%%%%%%%%%%%%%%
callback(JobMeta) ->
ok = register(JobMeta, _VnodeItem1 = {111111111112234455666, self()}, self()),
receive
{From, Ref, Msg} -> From ! {Ref, Msg}
end.
num_items(TabId, LookupItem) ->
case ets:lookup(TabId, LookupItem) of
[] ->
0;
[{_Pid, Items}] ->
lists:sum( lists:map(fun(_X) -> 1 end, Items) )
end.