Skip to content

Commit

Permalink
[ct] fix rate limit unit test
Browse files Browse the repository at this point in the history
  • Loading branch information
RoadRunnr committed May 27, 2024
1 parent 2be3d10 commit 682d7b5
Showing 1 changed file with 32 additions and 12 deletions.
44 changes: 32 additions & 12 deletions test/diameter_Gy_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -637,14 +637,25 @@ ccr_retry(Config) ->
ok.

rate_limit(_Config) ->
%% With 4 peers, a rate limit at 10 req/s and 2 retries (= 3 attempts max) we should
%% be able to get 40 requests through,
%% However, the peer selection based on relative load and the actual reduction of the token
%% happens in different places. That means that a select peer can have exceed its token
%% limit when we try to use it. The actual amount successful requests will therefor be
%% lower than the configured rate.

Self = self(),

TriggerFun =
fun(SRefs, Action) ->
lists:foreach(fun({Pid, Ref}) -> Pid ! {Ref, Action} end, SRefs)
end,
CollectFun =
fun CollectFun(_, [], Acc) ->
Acc;
CollectFun(Key, [H|T], Acc) ->
CollectFun(Key, [{_Pid, Ref}|T], Acc) ->
receive
{H, Key, {R, _, _}} ->
{Ref, Key, {R, _, _}} ->
maps:update_with(R, fun(X) -> X + 1 end, 1, CollectFun(Key, T, Acc))
end
end,
Expand All @@ -655,14 +666,21 @@ rate_limit(_Config) ->
ct:pal("Peers-#0: ~p", [ergw_aaa_diameter_srv:get_peers_info()]),
StartT = erlang:monotonic_time(),

%% with 4 peers, a rate limit at 10 req/s and 2 retries (= 3 attempts max) we should
%% be able to get 40 requests through
SRefs = [begin Ref = make_ref(), spawn(?MODULE, async_session, [Self, Ref]), Ref end
|| _ <- lists:seq(1, 60)],
SRefs = [begin
Ref = make_ref(),
Pid = spawn(?MODULE, async_session, [Self, Ref]),
{Pid, Ref}
end || _ <- lists:seq(1, 60)],

TriggerFun(SRefs, start),
CCRi = CollectFun('CCR-Initial', SRefs, #{}),
InitT = erlang:monotonic_time(),
ct:pal("Peers-#1: ~p", [ergw_aaa_diameter_srv:get_peers_info()]),

%% wait long enough to refill all token buckets
ct:sleep(1100),

TriggerFun(SRefs, terminate),
CCRt = CollectFun('CCR-Terminate', SRefs, #{}),
TermT = erlang:monotonic_time(),
ct:pal("Peers-#2: ~p", [ergw_aaa_diameter_srv:get_peers_info()]),
Expand All @@ -683,11 +701,11 @@ rate_limit(_Config) ->
{skip, "Test took too long, runner is too slow"};
true ->
?match(#{ok := OkayI, {error,rate_limit} := LimitI}
when OkayI >= 40 andalso
when OkayI >= 20 andalso
LimitI /= 0 andalso
OkayI + LimitI =:= 60, CCRi),
?match(#{ok := OkayT, {error,rate_limit} := LimitT}
when OkayT >= 40 andalso
when OkayT >= 20 andalso
LimitT /= 0 andalso
OkayT + LimitT =:= 60, CCRt),
ok
Expand Down Expand Up @@ -1136,16 +1154,15 @@ basic_session(CCR_I_T_Delay) ->
set_test_info(ccr_t_rate_limit, {session, SId}, Result).

async_session(Owner, Ref) ->
async_session(Owner, Ref, 1100).

async_session(Owner, Ref, Delay) ->
Session = init_session(#{}, []),
{ok, SId} = ergw_aaa_session_sup:new_session(self(), Session),
GyOpts = #{credits => #{1000 => empty}},

receive {Ref, start} -> ok end,

IResult = ergw_aaa_session:invoke(SId, GyOpts, {gy, 'CCR-Initial'}, []),
Owner ! {Ref, 'CCR-Initial', IResult},

timer:sleep(Delay),
UsedCredits =
[{1000, #{'CC-Input-Octets' => [0],
'CC-Output-Octets' => [0],
Expand All @@ -1157,6 +1174,9 @@ async_session(Owner, Ref, Delay) ->
GyTerm = #{'Termination-Cause' =>
?'DIAMETER_BASE_TERMINATION-CAUSE_LOGOUT',
used_credits => UsedCredits},

receive {Ref, terminate} -> ok end,

TResult = ergw_aaa_session:invoke(SId, GyTerm, {gy, 'CCR-Terminate'}, []),
Owner ! {Ref, 'CCR-Terminate', TResult},

Expand Down

0 comments on commit 682d7b5

Please sign in to comment.