Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 1 | module STP_Tests_IPA { |
| 2 | |
| 3 | /* Osmocom STP test suite in in TTCN-3 |
| 4 | * (C) 2019 Harald Welte <laforge@gnumonks.org> |
| 5 | * All rights reserved. |
| 6 | * |
| 7 | * Released under the terms of GNU General Public License, Version 2 or |
| 8 | * (at your option) any later version. |
| 9 | * |
| 10 | * SPDX-License-Identifier: GPL-2.0-or-later |
| 11 | */ |
| 12 | |
| 13 | friend module STP_Tests; |
| 14 | |
| 15 | import from General_Types all; |
| 16 | import from Osmocom_Types all; |
| 17 | import from IPL4asp_Types all; |
| 18 | |
| 19 | import from TELNETasp_PortType all; |
| 20 | import from Osmocom_VTY_Functions all; |
| 21 | |
| 22 | import from SCCP_Types all; |
| 23 | import from SCCP_Templates all; |
| 24 | import from SCCPasp_Types all; |
| 25 | import from SCCP_Emulation all; |
| 26 | |
| 27 | import from IPA_Emulation all; |
| 28 | |
| 29 | import from M3UA_Emulation all; |
| 30 | import from M3UA_CodecPort all; |
| 31 | import from MTP3asp_Types all; |
| 32 | import from MTP3asp_PortType all; |
| 33 | |
| 34 | import from STP_Tests_Common all; |
| 35 | |
Pau Espin Pedrol | b72928d | 2019-11-07 17:38:32 +0100 | [diff] [blame] | 36 | private const integer NR_IPA := 7; |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 37 | |
| 38 | type record of charstring AspNameArray; |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 39 | |
| 40 | modulepar { |
Pau Espin Pedrol | b51c087 | 2020-08-21 13:42:30 +0200 | [diff] [blame] | 41 | charstring mp_stp_ipa_ip := "127.0.0.1"; |
| 42 | charstring mp_local_ipa_ip := "127.0.0.1"; |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 43 | integer mp_stp_ipa_port := 5000; |
| 44 | integer mp_local_ipa_port := 20000; |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 45 | AspNameArray mp_ipa_as_names := {"ipa-as-loadshare-sender", |
| 46 | "ipa-as-loadshare-receiver", |
| 47 | "ipa-as-loadshare-receiver", |
Pau Espin Pedrol | b72928d | 2019-11-07 17:38:32 +0100 | [diff] [blame] | 48 | "ipa-as-dynamic-asp", |
| 49 | "ipa-as-override-sender", |
| 50 | "ipa-as-override-receiver", |
| 51 | "ipa-as-override-receiver" |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 52 | }; |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 53 | } |
| 54 | |
| 55 | type component IPA_CT extends Test_CT { |
| 56 | /* for IPA we use the IPA_Emulation and not directly IPA_CodecPort to avoid |
| 57 | * having to re-invent IPA CCM handling here */ |
| 58 | port MTP3asp_PT IPA[NR_IPA]; |
Pau Espin Pedrol | 8c0f2fc | 2020-09-23 18:39:30 +0200 | [diff] [blame] | 59 | port IPA_SP_PT IPA_CTRL[NR_IPA]; |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 60 | var IPA_Emulation_CT vc_IPA[NR_IPA]; |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 61 | var IPA_CCM_Parameters g_ccm_pars[NR_IPA]; |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 62 | } |
| 63 | |
| 64 | friend function f_IPA_send(integer idx, octetstring data) runs on IPA_CT { |
| 65 | var MTP3_Field_sio sio := { ni := '00'B, prio := '00'B, si := '0011'B }; |
| 66 | IPA[idx].send(t_ASP_MTP3_TRANSFERreq(sio, 0, 0, 0, data)); |
| 67 | } |
| 68 | |
| 69 | friend function f_IPA_exp(integer idx, template (present) octetstring data) runs on IPA_CT { |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 70 | alt { |
| 71 | [] IPA[idx].receive(t_ASP_MTP3_TRANSFERind(?, ?, ?, ?, data)) { |
| 72 | setverdict(pass); |
| 73 | } |
| 74 | [] IPA[idx].receive { |
| 75 | setverdict(fail, "Received unexpected data on IPA port while waiting for ", data); |
| 76 | mtc.stop; |
| 77 | } |
| 78 | } |
| 79 | } |
| 80 | |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 81 | private function f_rnd_ipa_len() runs on IPA_CT return integer { |
| 82 | var integer rnd_len := f_rnd_int(100); |
| 83 | /* We need at least 1 byte of data, othewise osmocom IPA stack will discard and close the socket */ |
| 84 | if (rnd_len == 0) { |
| 85 | rnd_len := 1; |
| 86 | } |
| 87 | return rnd_len; |
| 88 | } |
| 89 | |
| 90 | /* Test if traffic is routed from idx_tx to idx_rx */ |
| 91 | private function f_test_traffic(integer idx_tx, integer idx_rx) |
| 92 | runs on IPA_CT { |
| 93 | var octetstring data := f_rnd_octstring(f_rnd_ipa_len()); |
| 94 | f_IPA_send(idx_tx, data); |
| 95 | f_IPA_exp(idx_rx, data); |
| 96 | } |
| 97 | |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 98 | friend function f_init_ipa() runs on IPA_CT { |
| 99 | var integer i; |
| 100 | |
| 101 | f_init_common(); |
| 102 | |
| 103 | for (i := 0; i < NR_IPA; i:=i+1) { |
| 104 | vc_IPA[i] := IPA_Emulation_CT.create("IPA" & int2str(i)); |
| 105 | map(vc_IPA[i]:IPA_PORT, system:IPA_CODEC_PT); |
| 106 | connect(self:IPA[i], vc_IPA[i]:MTP3_SP_PORT); |
Pau Espin Pedrol | 8c0f2fc | 2020-09-23 18:39:30 +0200 | [diff] [blame] | 107 | connect(self:IPA_CTRL[i], vc_IPA[i]:IPA_SP_PORT); |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 108 | g_ccm_pars[i] := c_IPA_default_ccm_pars; |
| 109 | g_ccm_pars[i].name := mp_ipa_as_names[i]; |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 110 | } |
| 111 | } |
| 112 | |
Pau Espin Pedrol | 8c0f2fc | 2020-09-23 18:39:30 +0200 | [diff] [blame] | 113 | friend function f_connect_ipa(integer idx, boolean use_unknown_asp_port := false, boolean exp_act := true) runs on IPA_CT { |
Pau Espin Pedrol | 9f51483 | 2019-11-08 15:24:13 +0100 | [diff] [blame] | 114 | var integer port_offset := 0; |
| 115 | if (use_unknown_asp_port) { |
| 116 | /* Add 100 to the port since we know that port is not configured in any |
| 117 | ASP only up to NR_IPA are configured. */ |
| 118 | port_offset := 100; |
| 119 | } |
Pau Espin Pedrol | b51c087 | 2020-08-21 13:42:30 +0200 | [diff] [blame] | 120 | vc_IPA[idx].start(IPA_Emulation.main_client(mp_stp_ipa_ip, mp_stp_ipa_port, mp_local_ipa_ip, |
Pau Espin Pedrol | 9f51483 | 2019-11-08 15:24:13 +0100 | [diff] [blame] | 121 | mp_local_ipa_port + idx + port_offset, g_ccm_pars[idx])); |
Pau Espin Pedrol | 8c0f2fc | 2020-09-23 18:39:30 +0200 | [diff] [blame] | 122 | IPA_CTRL[idx].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_UP)); |
| 123 | alt { |
| 124 | [exp_act] IPA_CTRL[idx].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_ID_ACK)); |
| 125 | [not exp_act] IPA_CTRL[idx].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)); |
| 126 | [] IPA_CTRL[idx].receive(tr_ASP_IPA_EV(?)) { repeat; } |
| 127 | } |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 128 | } |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 129 | |
| 130 | |
| 131 | /* "accept-asp-connections pre-configured" and client from unknown source */ |
| 132 | testcase TC_unknown_client_nodynamic() runs on IPA_CT { |
| 133 | f_init_common(); |
| 134 | f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"}, |
| 135 | "accept-asp-connections pre-configured"); |
| 136 | f_init_ipa(); |
Pau Espin Pedrol | 8c0f2fc | 2020-09-23 18:39:30 +0200 | [diff] [blame] | 137 | f_connect_ipa(0, true, false); |
| 138 | |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 139 | /* switch back to default */ |
| 140 | f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"}, |
| 141 | "accept-asp-connections dynamic-permitted"); |
Pau Espin Pedrol | 8c0f2fc | 2020-09-23 18:39:30 +0200 | [diff] [blame] | 142 | setverdict(pass); |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 143 | } |
| 144 | |
| 145 | /* "accept-asp-connections pre-configured" and client from known source */ |
| 146 | testcase TC_known_client_nodynamic() runs on IPA_CT { |
| 147 | f_init_common(); |
| 148 | f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"}, |
| 149 | "accept-asp-connections pre-configured"); |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 150 | f_init_ipa(); |
Pau Espin Pedrol | 9f51483 | 2019-11-08 15:24:13 +0100 | [diff] [blame] | 151 | f_connect_ipa(0, false); |
Pau Espin Pedrol | 8c0f2fc | 2020-09-23 18:39:30 +0200 | [diff] [blame] | 152 | |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 153 | /* switch back to default */ |
| 154 | f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"}, |
| 155 | "accept-asp-connections dynamic-permitted"); |
Pau Espin Pedrol | 8c0f2fc | 2020-09-23 18:39:30 +0200 | [diff] [blame] | 156 | setverdict(pass); |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 157 | } |
| 158 | |
| 159 | |
| 160 | /* "accept-asp-connections dynamic-permitted" and client from unknown source */ |
| 161 | testcase TC_unknown_client_dynamic() runs on IPA_CT { |
| 162 | f_init_common(); |
| 163 | f_init_ipa(); |
Pau Espin Pedrol | 9f51483 | 2019-11-08 15:24:13 +0100 | [diff] [blame] | 164 | f_connect_ipa(0, true); |
Pau Espin Pedrol | 8c0f2fc | 2020-09-23 18:39:30 +0200 | [diff] [blame] | 165 | setverdict(pass); |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 166 | } |
| 167 | |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 168 | private function f_tc_tmt_override(boolean unknwon_dynamic_asp) |
| 169 | runs on IPA_CT { |
Pau Espin Pedrol | b72928d | 2019-11-07 17:38:32 +0100 | [diff] [blame] | 170 | f_init_ipa(); |
| 171 | |
| 172 | /* bring up the 'sender' side (single ASP in AS) */ |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 173 | f_connect_ipa(4, unknwon_dynamic_asp); |
Pau Espin Pedrol | b72928d | 2019-11-07 17:38:32 +0100 | [diff] [blame] | 174 | /* activate the first 'receiver' side ASP */ |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 175 | f_connect_ipa(5, unknwon_dynamic_asp); |
Pau Espin Pedrol | b72928d | 2019-11-07 17:38:32 +0100 | [diff] [blame] | 176 | |
| 177 | /* verify traffic is routed from sender to [sole] receiver */ |
| 178 | f_test_traffic(4, 5); |
| 179 | |
| 180 | /* activate the second 'receiver' side ASP */ |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 181 | f_connect_ipa(6, unknwon_dynamic_asp); |
Pau Espin Pedrol | b72928d | 2019-11-07 17:38:32 +0100 | [diff] [blame] | 182 | |
| 183 | /* verify traffic is routed from sender to new receiver */ |
| 184 | f_test_traffic(4, 6); |
Pau Espin Pedrol | 8c0f2fc | 2020-09-23 18:39:30 +0200 | [diff] [blame] | 185 | setverdict(pass); |
Pau Espin Pedrol | b72928d | 2019-11-07 17:38:32 +0100 | [diff] [blame] | 186 | } |
| 187 | |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 188 | /* test "traffic-mode override" behavior */ |
| 189 | testcase TC_tmt_override() runs on IPA_CT { |
| 190 | f_tc_tmt_override(false); |
| 191 | } |
| 192 | |
| 193 | /* test "traffic-mode override" behavior, with "accept-asp-connections dynamic-permitted" and clients from unknown ASPs */ |
| 194 | testcase TC_unknown_client_dynamic_tmt_override() runs on IPA_CT { |
| 195 | f_tc_tmt_override(true); |
| 196 | } |
| 197 | |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 198 | private altstep as_count_rx(integer idx, template (present) octetstring exp, inout integer counter) |
| 199 | runs on IPA_CT { |
| 200 | [] IPA[idx].receive(t_ASP_MTP3_TRANSFERind(?, ?, ?, ?, exp)) { |
| 201 | counter := counter + 1; |
| 202 | } |
| 203 | } |
| 204 | |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 205 | private function f_tc_tmt_loadshare(boolean unknwon_dynamic_asp) |
| 206 | runs on IPA_CT { |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 207 | var integer i; |
| 208 | |
| 209 | f_init_ipa(); |
| 210 | |
| 211 | /* bring up the 'sender' side (single ASP in AS) */ |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 212 | f_connect_ipa(0, unknwon_dynamic_asp); |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 213 | /* activate the first 'receiver' side ASP */ |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 214 | f_connect_ipa(1, unknwon_dynamic_asp); |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 215 | |
| 216 | /* verify traffic is routed from sender to [sole] receiver */ |
| 217 | for (i := 0; i < 10; i := i+1) { |
| 218 | f_test_traffic(0, 1); |
| 219 | } |
| 220 | |
| 221 | /* activate the second 'receiver' side ASP */ |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 222 | f_connect_ipa(2, unknwon_dynamic_asp); |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 223 | |
| 224 | /* verify traffic is routed from sender to new receiver */ |
| 225 | const integer iter_per_asp := 5; |
| 226 | var integer num_rx[3] := { 0, 0, 0 }; |
| 227 | for (i := 0; i < 2*iter_per_asp; i := i+1) { |
| 228 | var octetstring data := f_rnd_octstring(f_rnd_ipa_len()); |
| 229 | f_IPA_send(0, data); |
| 230 | alt { |
Pau Espin Pedrol | 4d91578 | 2020-08-21 12:24:35 +0200 | [diff] [blame] | 231 | [] as_count_rx(1, data, num_rx[1]); |
| 232 | [] as_count_rx(2, data, num_rx[2]); |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 233 | } |
| 234 | } |
| 235 | /* FIXME: check for extraneous messages? */ |
| 236 | for (i := 1; i <= 2; i := i+1) { |
| 237 | if (num_rx[i] != iter_per_asp) { |
| 238 | setverdict(fail, "Received ", num_rx[i], " out of expected ", iter_per_asp, |
| 239 | "DATA messages at IPA port ", i); |
| 240 | } |
| 241 | } |
| 242 | setverdict(pass); |
| 243 | } |
| 244 | |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 245 | /* test "traffic-mode load-share" behavior */ |
| 246 | testcase TC_tmt_loadshare() runs on IPA_CT { |
| 247 | f_tc_tmt_loadshare(false); |
| 248 | } |
| 249 | |
| 250 | /* test "traffic-mode override" behavior, with "accept-asp-connections dynamic-permitted" and clients from unknown ASPs */ |
| 251 | testcase TC_unknown_client_dynamic_tmt_loadshare() runs on IPA_CT { |
| 252 | f_tc_tmt_override(true); |
| 253 | } |
| 254 | |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 255 | control { |
| 256 | execute( TC_unknown_client_nodynamic() ); |
| 257 | execute( TC_known_client_nodynamic() ); |
| 258 | execute( TC_unknown_client_dynamic() ); |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 259 | execute( TC_tmt_override() ); |
| 260 | execute( TC_unknown_client_dynamic_tmt_override() ); |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 261 | execute( TC_tmt_loadshare() ); |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 262 | execute( TC_unknown_client_dynamic_tmt_loadshare() ); |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 263 | } |
| 264 | |
| 265 | |
| 266 | } |