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]; |
| 59 | var IPA_Emulation_CT vc_IPA[NR_IPA]; |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 60 | var IPA_CCM_Parameters g_ccm_pars[NR_IPA]; |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 61 | } |
| 62 | |
| 63 | friend function f_IPA_send(integer idx, octetstring data) runs on IPA_CT { |
| 64 | var MTP3_Field_sio sio := { ni := '00'B, prio := '00'B, si := '0011'B }; |
| 65 | IPA[idx].send(t_ASP_MTP3_TRANSFERreq(sio, 0, 0, 0, data)); |
| 66 | } |
| 67 | |
| 68 | 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] | 69 | alt { |
| 70 | [] IPA[idx].receive(t_ASP_MTP3_TRANSFERind(?, ?, ?, ?, data)) { |
| 71 | setverdict(pass); |
| 72 | } |
| 73 | [] IPA[idx].receive { |
| 74 | setverdict(fail, "Received unexpected data on IPA port while waiting for ", data); |
| 75 | mtc.stop; |
| 76 | } |
| 77 | } |
| 78 | } |
| 79 | |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 80 | private function f_rnd_ipa_len() runs on IPA_CT return integer { |
| 81 | var integer rnd_len := f_rnd_int(100); |
| 82 | /* We need at least 1 byte of data, othewise osmocom IPA stack will discard and close the socket */ |
| 83 | if (rnd_len == 0) { |
| 84 | rnd_len := 1; |
| 85 | } |
| 86 | return rnd_len; |
| 87 | } |
| 88 | |
| 89 | /* Test if traffic is routed from idx_tx to idx_rx */ |
| 90 | private function f_test_traffic(integer idx_tx, integer idx_rx) |
| 91 | runs on IPA_CT { |
| 92 | var octetstring data := f_rnd_octstring(f_rnd_ipa_len()); |
| 93 | f_IPA_send(idx_tx, data); |
| 94 | f_IPA_exp(idx_rx, data); |
| 95 | } |
| 96 | |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 97 | friend function f_init_ipa() runs on IPA_CT { |
| 98 | var integer i; |
| 99 | |
| 100 | f_init_common(); |
| 101 | |
| 102 | for (i := 0; i < NR_IPA; i:=i+1) { |
| 103 | vc_IPA[i] := IPA_Emulation_CT.create("IPA" & int2str(i)); |
| 104 | map(vc_IPA[i]:IPA_PORT, system:IPA_CODEC_PT); |
| 105 | connect(self:IPA[i], vc_IPA[i]:MTP3_SP_PORT); |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 106 | g_ccm_pars[i] := c_IPA_default_ccm_pars; |
| 107 | g_ccm_pars[i].name := mp_ipa_as_names[i]; |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 108 | } |
| 109 | } |
| 110 | |
Pau Espin Pedrol | 9f51483 | 2019-11-08 15:24:13 +0100 | [diff] [blame] | 111 | friend function f_connect_ipa(integer idx, boolean use_unknown_asp_port := false) runs on IPA_CT { |
| 112 | var integer port_offset := 0; |
| 113 | if (use_unknown_asp_port) { |
| 114 | /* Add 100 to the port since we know that port is not configured in any |
| 115 | ASP only up to NR_IPA are configured. */ |
| 116 | port_offset := 100; |
| 117 | } |
Pau Espin Pedrol | b51c087 | 2020-08-21 13:42:30 +0200 | [diff] [blame] | 118 | 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] | 119 | mp_local_ipa_port + idx + port_offset, g_ccm_pars[idx])); |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 120 | } |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 121 | |
| 122 | |
| 123 | /* "accept-asp-connections pre-configured" and client from unknown source */ |
| 124 | testcase TC_unknown_client_nodynamic() runs on IPA_CT { |
| 125 | f_init_common(); |
| 126 | f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"}, |
| 127 | "accept-asp-connections pre-configured"); |
| 128 | f_init_ipa(); |
Pau Espin Pedrol | 9f51483 | 2019-11-08 15:24:13 +0100 | [diff] [blame] | 129 | f_connect_ipa(0, true); |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 130 | f_sleep(1.0); |
| 131 | if (IPA[0].checkstate("Connected")) { |
| 132 | setverdict(fail, "Expected IPA port to be disconnected"); |
| 133 | } else { |
| 134 | setverdict(pass); |
| 135 | } |
| 136 | /* switch back to default */ |
| 137 | f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"}, |
| 138 | "accept-asp-connections dynamic-permitted"); |
| 139 | } |
| 140 | |
| 141 | /* "accept-asp-connections pre-configured" and client from known source */ |
| 142 | testcase TC_known_client_nodynamic() runs on IPA_CT { |
| 143 | f_init_common(); |
| 144 | f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"}, |
| 145 | "accept-asp-connections pre-configured"); |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 146 | f_init_ipa(); |
Pau Espin Pedrol | 9f51483 | 2019-11-08 15:24:13 +0100 | [diff] [blame] | 147 | f_connect_ipa(0, false); |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 148 | f_sleep(1.0); |
| 149 | if (not IPA[0].checkstate("Connected")) { |
| 150 | setverdict(fail, "Expected IPA port to be connected"); |
| 151 | } else { |
| 152 | setverdict(pass); |
| 153 | } |
| 154 | /* switch back to default */ |
| 155 | f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"}, |
| 156 | "accept-asp-connections dynamic-permitted"); |
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); |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 165 | f_sleep(1.0); |
| 166 | if (not IPA[0].checkstate("Connected")) { |
| 167 | setverdict(fail, "Expected IPA port to be connected"); |
| 168 | } else { |
| 169 | setverdict(pass); |
| 170 | } |
| 171 | } |
| 172 | |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 173 | private function f_tc_tmt_override(boolean unknwon_dynamic_asp) |
| 174 | runs on IPA_CT { |
Pau Espin Pedrol | b72928d | 2019-11-07 17:38:32 +0100 | [diff] [blame] | 175 | f_init_ipa(); |
| 176 | |
| 177 | /* bring up the 'sender' side (single ASP in AS) */ |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 178 | f_connect_ipa(4, unknwon_dynamic_asp); |
Pau Espin Pedrol | b72928d | 2019-11-07 17:38:32 +0100 | [diff] [blame] | 179 | /* activate the first 'receiver' side ASP */ |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 180 | f_connect_ipa(5, unknwon_dynamic_asp); |
Pau Espin Pedrol | b72928d | 2019-11-07 17:38:32 +0100 | [diff] [blame] | 181 | f_sleep(1.0); |
| 182 | |
| 183 | /* verify traffic is routed from sender to [sole] receiver */ |
| 184 | f_test_traffic(4, 5); |
| 185 | |
| 186 | /* activate the second 'receiver' side ASP */ |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 187 | f_connect_ipa(6, unknwon_dynamic_asp); |
Pau Espin Pedrol | b72928d | 2019-11-07 17:38:32 +0100 | [diff] [blame] | 188 | f_sleep(1.0); |
| 189 | |
| 190 | /* verify traffic is routed from sender to new receiver */ |
| 191 | f_test_traffic(4, 6); |
| 192 | } |
| 193 | |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 194 | /* test "traffic-mode override" behavior */ |
| 195 | testcase TC_tmt_override() runs on IPA_CT { |
| 196 | f_tc_tmt_override(false); |
| 197 | } |
| 198 | |
| 199 | /* test "traffic-mode override" behavior, with "accept-asp-connections dynamic-permitted" and clients from unknown ASPs */ |
| 200 | testcase TC_unknown_client_dynamic_tmt_override() runs on IPA_CT { |
| 201 | f_tc_tmt_override(true); |
| 202 | } |
| 203 | |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 204 | private altstep as_count_rx(integer idx, template (present) octetstring exp, inout integer counter) |
| 205 | runs on IPA_CT { |
| 206 | [] IPA[idx].receive(t_ASP_MTP3_TRANSFERind(?, ?, ?, ?, exp)) { |
| 207 | counter := counter + 1; |
| 208 | } |
| 209 | } |
| 210 | |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 211 | private function f_tc_tmt_loadshare(boolean unknwon_dynamic_asp) |
| 212 | runs on IPA_CT { |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 213 | var integer i; |
| 214 | |
| 215 | f_init_ipa(); |
| 216 | |
| 217 | /* bring up the 'sender' side (single ASP in AS) */ |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 218 | f_connect_ipa(0, unknwon_dynamic_asp); |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 219 | /* activate the first 'receiver' side ASP */ |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 220 | f_connect_ipa(1, unknwon_dynamic_asp); |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 221 | f_sleep(1.0); |
| 222 | |
| 223 | /* verify traffic is routed from sender to [sole] receiver */ |
| 224 | for (i := 0; i < 10; i := i+1) { |
| 225 | f_test_traffic(0, 1); |
| 226 | } |
| 227 | |
| 228 | /* activate the second 'receiver' side ASP */ |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 229 | f_connect_ipa(2, unknwon_dynamic_asp); |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 230 | f_sleep(1.0); |
| 231 | |
| 232 | /* verify traffic is routed from sender to new receiver */ |
| 233 | const integer iter_per_asp := 5; |
| 234 | var integer num_rx[3] := { 0, 0, 0 }; |
| 235 | for (i := 0; i < 2*iter_per_asp; i := i+1) { |
| 236 | var octetstring data := f_rnd_octstring(f_rnd_ipa_len()); |
| 237 | f_IPA_send(0, data); |
| 238 | alt { |
Pau Espin Pedrol | 4d91578 | 2020-08-21 12:24:35 +0200 | [diff] [blame] | 239 | [] as_count_rx(1, data, num_rx[1]); |
| 240 | [] as_count_rx(2, data, num_rx[2]); |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 241 | } |
| 242 | } |
| 243 | /* FIXME: check for extraneous messages? */ |
| 244 | for (i := 1; i <= 2; i := i+1) { |
| 245 | if (num_rx[i] != iter_per_asp) { |
| 246 | setverdict(fail, "Received ", num_rx[i], " out of expected ", iter_per_asp, |
| 247 | "DATA messages at IPA port ", i); |
| 248 | } |
| 249 | } |
| 250 | setverdict(pass); |
| 251 | } |
| 252 | |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 253 | /* test "traffic-mode load-share" behavior */ |
| 254 | testcase TC_tmt_loadshare() runs on IPA_CT { |
| 255 | f_tc_tmt_loadshare(false); |
| 256 | } |
| 257 | |
| 258 | /* test "traffic-mode override" behavior, with "accept-asp-connections dynamic-permitted" and clients from unknown ASPs */ |
| 259 | testcase TC_unknown_client_dynamic_tmt_loadshare() runs on IPA_CT { |
| 260 | f_tc_tmt_override(true); |
| 261 | } |
| 262 | |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 263 | control { |
| 264 | execute( TC_unknown_client_nodynamic() ); |
| 265 | execute( TC_known_client_nodynamic() ); |
| 266 | execute( TC_unknown_client_dynamic() ); |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 267 | execute( TC_tmt_override() ); |
| 268 | execute( TC_unknown_client_dynamic_tmt_override() ); |
Pau Espin Pedrol | 01ec0bf | 2019-11-07 14:50:07 +0100 | [diff] [blame] | 269 | execute( TC_tmt_loadshare() ); |
Pau Espin Pedrol | 7021cfd | 2019-11-08 15:25:44 +0100 | [diff] [blame] | 270 | execute( TC_unknown_client_dynamic_tmt_loadshare() ); |
Harald Welte | 0db4413 | 2019-10-17 11:09:05 +0200 | [diff] [blame] | 271 | } |
| 272 | |
| 273 | |
| 274 | } |