Skip to content

Commit

Permalink
Test UPF connection reject / down state
Browse files Browse the repository at this point in the history
  • Loading branch information
RoadRunnr committed Dec 13, 2019
1 parent 19d8f10 commit 7c52673
Show file tree
Hide file tree
Showing 4 changed files with 107 additions and 13 deletions.
20 changes: 14 additions & 6 deletions src/ergw_sx_node.erl
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,19 @@
tdf,
notify_up = [] :: [{pid(), reference()}]}).

-ifdef(TEST).
-define(AssocReqTimeout, 2).
-define(AssocReqRetries, 5).
-define(AssocTimeout, 5).
-define(AssocRetries, 10).
-define(MaxRetriesScale, 5).
-else.
-define(AssocReqTimeout, 200).
-define(AssocReqRetries, 5).
-define(AssocTimeout, 500).
-define(AssocRetries, 10).
-define(MaxRetriesScale, 5).
-endif.

-define(TestCmdTag, '$TestCmd').

Expand Down Expand Up @@ -253,11 +261,11 @@ handle_event(enter, _OldState, _State, _Data) ->
handle_event({call, From}, {?TestCmdTag, pfcp_ctx}, _, #data{pfcp_ctx = PCtx}) ->
{keep_state_and_data, [{reply, From, PCtx}]};
handle_event({call, From}, {?TestCmdTag, reconnect}, dead, Data) ->
{next_state, connecting, Data, [{reply, From, ok}]};
{next_state, connecting, Data#data{retries = 0}, [{reply, From, ok}]};
handle_event({call, From}, {?TestCmdTag, reconnect}, connecting, _) ->
{keep_state_and_data, [{reply, From, ok}]};
handle_event({call, From}, {?TestCmdTag, reconnect}, {connected, _}, Data) ->
{next_state, dead, handle_nodedown(Data), [{reply, From, ok}]};
handle_event({call, From}, {?TestCmdTag, reconnect}, {connected, _} = State, Data) ->
{next_state, dead, handle_nodedown(Data#data{retries = 0}), [{reply, From, ok}]};
handle_event({call, From}, {?TestCmdTag, wait4nodeup}, {connected, _}, _) ->
{keep_state_and_data, [{reply, From, ok}]};
handle_event({call, _From}, {?TestCmdTag, wait4nodeup}, _, _) ->
Expand Down Expand Up @@ -608,10 +616,10 @@ connect_sx_candidates(List, NextPrio, Available) ->
connect_sx_candidates(Next, NextPrio, Available)
end.

notify_up(Server, NotifyUp) when length(NotifyUp) /= 0 ->
notify_up(Server, [{Pid, Ref}|_] = NotifyUp) when is_pid(Pid), is_reference(Ref) ->
gen_statem:cast(Server, {notify_up, NotifyUp});
notify_up(_, _) ->
ok.
notify_up(Server, {Pid, Ref} = NotifyUp) when is_pid(Pid), is_reference(Ref) ->
gen_statem:cast(Server, {notify_up, [NotifyUp]}).

lb(first, [H|T]) -> {H, T};
lb(random, [H]) -> {H, []};
Expand Down
14 changes: 11 additions & 3 deletions test/ergw_test_lib.erl
Original file line number Diff line number Diff line change
Expand Up @@ -76,9 +76,17 @@ lib_init_per_suite(Config0) ->
meck_init(Config),
load_config(AppCfg),
{ok, _} = application:ensure_all_started(ergw),
{ok, _} = ergw_test_sx_up:start('pgw-u', proplists:get_value(pgw_u_sx, Config)),
{ok, _} = ergw_test_sx_up:start('sgw-u', proplists:get_value(sgw_u_sx, Config)),
{ok, _} = ergw_test_sx_up:start('tdf-u', proplists:get_value(tdf_u_sx, Config)),

case proplists:get_value(upf, Config, true) of
true ->
{ok, _} = ergw_test_sx_up:start('pgw-u', proplists:get_value(pgw_u_sx, Config)),
{ok, _} = ergw_test_sx_up:start('sgw-u', proplists:get_value(sgw_u_sx, Config)),
{ok, _} = ergw_test_sx_up:start('tdf-u', proplists:get_value(tdf_u_sx, Config));
_ ->
ok = ergw_test_sx_up:stop('pgw-u'),
ok = ergw_test_sx_up:stop('sgw-u'),
ok = ergw_test_sx_up:stop('tdf-u')
end,
{ok, AppsCfg} = application:get_env(ergw_aaa, apps),
[{aaa_cfg, AppsCfg} |Config].

Expand Down
7 changes: 6 additions & 1 deletion test/ergw_test_sx_up.erl
Original file line number Diff line number Diff line change
Expand Up @@ -38,7 +38,12 @@ start(Role, IP) ->
gen_server:start({local, server_name(Role)}, ?MODULE, [IP], []).

stop(Role) ->
gen_server:call(server_name(Role), stop).
try
gen_server:call(server_name(Role), stop)
catch
exit:{noproc,_} ->
ok
end.

restart(Role) ->
gen_server:call(server_name(Role), restart).
Expand Down
79 changes: 76 additions & 3 deletions test/pgw_SUITE.erl
Original file line number Diff line number Diff line change
Expand Up @@ -465,6 +465,8 @@ init_per_suite(Config0) ->
end_per_suite(_Config) ->
ok.

init_per_group(sx_fail, Config) ->
[{upf, false} | Config];
init_per_group(ipv6, Config0) ->
case ergw_test_lib:has_ipv6_test_config() of
true ->
Expand All @@ -479,7 +481,9 @@ init_per_group(ipv4, Config0) ->

end_per_group(Group, Config)
when Group == ipv4; Group == ipv6 ->
ok = lib_end_per_suite(Config).
ok = lib_end_per_suite(Config);
end_per_group(sx_fail, _Config) ->
ok.

common() ->
[invalid_gtp_pdu,
Expand Down Expand Up @@ -553,13 +557,21 @@ common() ->
gx_rar_gy_interaction,
tdf_app_id].

sx_fail() ->
[sx_connect_fail].

groups() ->
[{ipv4, [], common()},
{ipv6, [], common()}].
{ipv6, [], common()},
{sx_fail, [{ipv4, [], sx_fail()},
{ipv6, [], sx_fail()}]
}
].

all() ->
[{group, ipv4},
{group, ipv6}].
{group, ipv6},
{group, sx_fail}].

%%%===================================================================
%%% Tests
Expand Down Expand Up @@ -677,6 +689,10 @@ init_per_testcase(create_session_overload, Config) ->
init_per_testcase(sx_cp_to_up_forward, Config) ->
setup_per_testcase(Config, false),
Config;
init_per_testcase(sx_connect_fail, Config) ->
meck_reset(Config),
start_gtpc_server(Config),
Config;
init_per_testcase(gy_validity_timer, Config) ->
setup_per_testcase(Config),
set_online_charging(true),
Expand Down Expand Up @@ -2256,6 +2272,63 @@ sx_timeout(Config) ->
ok = meck:delete(ergw_gsn_lib, create_sgi_session, 4),
ok.

%%--------------------------------------------------------------------
sx_connect_fail() ->
[{doc, "Check that a unreachable UPF leads to a proper error response"}].
sx_connect_fail(Config) ->
ok = meck:new(ergw_sx_node, [passthrough]),
ok = meck:expect(ergw_sx_node,select_sx_node,
fun(Candidates, Context) ->
try
meck:passthrough([Candidates, Context])
catch
throw:#ctx_err{} = CtxErr ->
meck:exception(throw, CtxErr)
end
end),

%% reduce Sx timeout to speed up test
ok = meck:expect(ergw_sx_socket, call,
fun(Peer, _T1, _N1, Msg, CbInfo) ->
meck:passthrough([Peer, 100, 2, Msg, CbInfo])
end),
ok = meck:expect(ergw_gsn_lib, create_sgi_session,
fun(PCtx, NodeCaps, SessionOpts, Ctx) ->
try
meck:passthrough([PCtx, NodeCaps, SessionOpts, Ctx])
catch
throw:#ctx_err{} = CtxErr ->
meck:exception(throw, CtxErr)
end
end),

Self = self(),
SxNodes = supervisor:which_children(ergw_sx_node_sup),
?match([_], SxNodes),
ct:pal("SxNodes: ~p", [SxNodes]),
Expect =
[begin
Ref = make_ref(),
ergw_sx_node:notify_up(Pid, {Self, Ref}),
ergw_sx_node:test_cmd(Pid, reconnect),
Ref
end || {_, Pid, _, _} <- SxNodes, is_pid(Pid)],
Result =
[receive {Ref, Notify} -> Notify; Other -> Other after 2000 -> timeout end ||
Ref <- Expect],
[?equal(dead, R) || R <- Result],

create_session(system_failure, Config),

?equal([], outstanding_requests()),
ok = meck:wait(?HUT, terminate, '_', ?TIMEOUT),
meck_validate(Config),
true = meck:validate(ergw_sx_node),

ok = meck:delete(ergw_sx_socket, call, 5),
ok = meck:delete(ergw_gsn_lib, create_sgi_session, 4),
ok.

%%--------------------------------------------------------------------
sx_ondemand() ->
[{doc, "Connect to Sx Node on demand"}].
Expand Down

0 comments on commit 7c52673

Please sign in to comment.