| module STP_Tests_IPA { |
| |
| /* Osmocom STP test suite in in TTCN-3 |
| * (C) 2019 Harald Welte <laforge@gnumonks.org> |
| * All rights reserved. |
| * |
| * Released under the terms of GNU General Public License, Version 2 or |
| * (at your option) any later version. |
| * |
| * SPDX-License-Identifier: GPL-2.0-or-later |
| */ |
| |
| friend module STP_Tests; |
| |
| import from General_Types all; |
| import from Osmocom_Types all; |
| import from IPL4asp_Types all; |
| |
| import from TELNETasp_PortType all; |
| import from Osmocom_VTY_Functions all; |
| |
| import from SCCP_Types all; |
| import from SCCP_Templates all; |
| import from SCCPasp_Types all; |
| import from SCCP_Emulation all; |
| |
| import from IPA_Emulation all; |
| |
| import from M3UA_Emulation all; |
| import from M3UA_CodecPort all; |
| import from MTP3asp_Types all; |
| import from MTP3asp_PortType all; |
| |
| import from STP_Tests_Common all; |
| |
| private const integer NR_IPA := 7; |
| |
| type record of charstring AspNameArray; |
| |
| modulepar { |
| charstring mp_stp_ipa_ip := "127.0.0.1"; |
| charstring mp_local_ipa_ip := "127.0.0.1"; |
| integer mp_stp_ipa_port := 5000; |
| integer mp_local_ipa_port := 20000; |
| AspNameArray mp_ipa_as_names := {"ipa-as-loadshare-sender", |
| "ipa-as-loadshare-receiver", |
| "ipa-as-loadshare-receiver", |
| "ipa-as-dynamic-asp", |
| "ipa-as-override-sender", |
| "ipa-as-override-receiver", |
| "ipa-as-override-receiver" |
| }; |
| } |
| |
| type component IPA_CT extends Test_CT { |
| /* for IPA we use the IPA_Emulation and not directly IPA_CodecPort to avoid |
| * having to re-invent IPA CCM handling here */ |
| port MTP3asp_PT IPA[NR_IPA]; |
| port IPA_SP_PT IPA_CTRL[NR_IPA]; |
| var IPA_Emulation_CT vc_IPA[NR_IPA]; |
| var IPA_CCM_Parameters g_ccm_pars[NR_IPA]; |
| } |
| |
| friend function f_IPA_send(integer idx, octetstring data) runs on IPA_CT { |
| var MTP3_Field_sio sio := { ni := '00'B, prio := '00'B, si := '0011'B }; |
| IPA[idx].send(t_ASP_MTP3_TRANSFERreq(sio, 0, 0, 0, data)); |
| } |
| |
| friend function f_IPA_exp(integer idx, template (present) octetstring data) runs on IPA_CT { |
| alt { |
| [] IPA[idx].receive(t_ASP_MTP3_TRANSFERind(?, ?, ?, ?, data)) { |
| setverdict(pass); |
| } |
| [] IPA[idx].receive { |
| setverdict(fail, "Received unexpected data on IPA port while waiting for ", data); |
| mtc.stop; |
| } |
| } |
| } |
| |
| private function f_rnd_ipa_len() runs on IPA_CT return integer { |
| var integer rnd_len := f_rnd_int(100); |
| /* We need at least 1 byte of data, othewise osmocom IPA stack will discard and close the socket */ |
| if (rnd_len == 0) { |
| rnd_len := 1; |
| } |
| return rnd_len; |
| } |
| |
| /* Test if traffic is routed from idx_tx to idx_rx */ |
| private function f_test_traffic(integer idx_tx, integer idx_rx) |
| runs on IPA_CT { |
| var octetstring data := f_rnd_octstring(f_rnd_ipa_len()); |
| f_IPA_send(idx_tx, data); |
| f_IPA_exp(idx_rx, data); |
| } |
| |
| friend function f_init_ipa() runs on IPA_CT { |
| var integer i; |
| |
| f_init_common(); |
| |
| for (i := 0; i < NR_IPA; i:=i+1) { |
| vc_IPA[i] := IPA_Emulation_CT.create("IPA" & int2str(i)); |
| map(vc_IPA[i]:IPA_PORT, system:IPA_CODEC_PT); |
| connect(self:IPA[i], vc_IPA[i]:MTP3_SP_PORT); |
| connect(self:IPA_CTRL[i], vc_IPA[i]:IPA_SP_PORT); |
| g_ccm_pars[i] := c_IPA_default_ccm_pars; |
| g_ccm_pars[i].name := mp_ipa_as_names[i]; |
| } |
| } |
| |
| friend function f_connect_ipa(integer idx, boolean use_unknown_asp_port := false, boolean exp_act := true) runs on IPA_CT { |
| var integer port_offset := 0; |
| if (use_unknown_asp_port) { |
| /* Add 100 to the port since we know that port is not configured in any |
| ASP only up to NR_IPA are configured. */ |
| port_offset := 100; |
| } |
| vc_IPA[idx].start(IPA_Emulation.main_client(mp_stp_ipa_ip, mp_stp_ipa_port, mp_local_ipa_ip, |
| mp_local_ipa_port + idx + port_offset, g_ccm_pars[idx])); |
| IPA_CTRL[idx].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)); |
| alt { |
| [exp_act] IPA_CTRL[idx].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)); |
| [not exp_act] IPA_CTRL[idx].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)); |
| [] IPA_CTRL[idx].receive(tr_ASP_IPA_EV(?)) { repeat; } |
| } |
| } |
| |
| |
| /* "accept-asp-connections pre-configured" and client from unknown source */ |
| testcase TC_unknown_client_nodynamic() runs on IPA_CT { |
| f_init_common(); |
| f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"}, |
| "accept-asp-connections pre-configured"); |
| f_init_ipa(); |
| f_connect_ipa(0, true, false); |
| |
| /* switch back to default */ |
| f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"}, |
| "accept-asp-connections dynamic-permitted"); |
| setverdict(pass); |
| } |
| |
| /* "accept-asp-connections pre-configured" and client from known source */ |
| testcase TC_known_client_nodynamic() runs on IPA_CT { |
| f_init_common(); |
| f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"}, |
| "accept-asp-connections pre-configured"); |
| f_init_ipa(); |
| f_connect_ipa(0, false); |
| |
| /* switch back to default */ |
| f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"}, |
| "accept-asp-connections dynamic-permitted"); |
| setverdict(pass); |
| } |
| |
| |
| /* "accept-asp-connections dynamic-permitted" and client from unknown source */ |
| testcase TC_unknown_client_dynamic() runs on IPA_CT { |
| f_init_common(); |
| f_init_ipa(); |
| f_connect_ipa(0, true); |
| setverdict(pass); |
| } |
| |
| private function f_tc_tmt_override(boolean unknwon_dynamic_asp) |
| runs on IPA_CT { |
| f_init_ipa(); |
| |
| /* bring up the 'sender' side (single ASP in AS) */ |
| f_connect_ipa(4, unknwon_dynamic_asp); |
| /* activate the first 'receiver' side ASP */ |
| f_connect_ipa(5, unknwon_dynamic_asp); |
| |
| /* verify traffic is routed from sender to [sole] receiver */ |
| f_test_traffic(4, 5); |
| |
| /* activate the second 'receiver' side ASP */ |
| f_connect_ipa(6, unknwon_dynamic_asp); |
| |
| /* verify traffic is routed from sender to new receiver */ |
| f_test_traffic(4, 6); |
| setverdict(pass); |
| } |
| |
| /* test "traffic-mode override" behavior */ |
| testcase TC_tmt_override() runs on IPA_CT { |
| f_tc_tmt_override(false); |
| } |
| |
| /* test "traffic-mode override" behavior, with "accept-asp-connections dynamic-permitted" and clients from unknown ASPs */ |
| testcase TC_unknown_client_dynamic_tmt_override() runs on IPA_CT { |
| f_tc_tmt_override(true); |
| } |
| |
| private altstep as_count_rx(integer idx, template (present) octetstring exp, inout integer counter) |
| runs on IPA_CT { |
| [] IPA[idx].receive(t_ASP_MTP3_TRANSFERind(?, ?, ?, ?, exp)) { |
| counter := counter + 1; |
| } |
| } |
| |
| private function f_tc_tmt_loadshare(boolean unknwon_dynamic_asp) |
| runs on IPA_CT { |
| var integer i; |
| |
| f_init_ipa(); |
| |
| /* bring up the 'sender' side (single ASP in AS) */ |
| f_connect_ipa(0, unknwon_dynamic_asp); |
| /* activate the first 'receiver' side ASP */ |
| f_connect_ipa(1, unknwon_dynamic_asp); |
| |
| /* verify traffic is routed from sender to [sole] receiver */ |
| for (i := 0; i < 10; i := i+1) { |
| f_test_traffic(0, 1); |
| } |
| |
| /* activate the second 'receiver' side ASP */ |
| f_connect_ipa(2, unknwon_dynamic_asp); |
| |
| /* verify traffic is routed from sender to new receiver */ |
| const integer iter_per_asp := 5; |
| var integer num_rx[3] := { 0, 0, 0 }; |
| for (i := 0; i < 2*iter_per_asp; i := i+1) { |
| var octetstring data := f_rnd_octstring(f_rnd_ipa_len()); |
| f_IPA_send(0, data); |
| alt { |
| [] as_count_rx(1, data, num_rx[1]); |
| [] as_count_rx(2, data, num_rx[2]); |
| } |
| } |
| /* FIXME: check for extraneous messages? */ |
| for (i := 1; i <= 2; i := i+1) { |
| if (num_rx[i] != iter_per_asp) { |
| setverdict(fail, "Received ", num_rx[i], " out of expected ", iter_per_asp, |
| "DATA messages at IPA port ", i); |
| } |
| } |
| setverdict(pass); |
| } |
| |
| /* test "traffic-mode load-share" behavior */ |
| testcase TC_tmt_loadshare() runs on IPA_CT { |
| f_tc_tmt_loadshare(false); |
| } |
| |
| /* test "traffic-mode override" behavior, with "accept-asp-connections dynamic-permitted" and clients from unknown ASPs */ |
| testcase TC_unknown_client_dynamic_tmt_loadshare() runs on IPA_CT { |
| f_tc_tmt_override(true); |
| } |
| |
| control { |
| execute( TC_unknown_client_nodynamic() ); |
| execute( TC_known_client_nodynamic() ); |
| execute( TC_unknown_client_dynamic() ); |
| execute( TC_tmt_override() ); |
| execute( TC_unknown_client_dynamic_tmt_override() ); |
| execute( TC_tmt_loadshare() ); |
| execute( TC_unknown_client_dynamic_tmt_loadshare() ); |
| } |
| |
| |
| } |