blob: beb2aa997aa4a377f96750255ded407b697e295b [file] [log] [blame]
Harald Welte0db44132019-10-17 11:09:05 +02001module 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
13friend module STP_Tests;
14
15import from General_Types all;
16import from Osmocom_Types all;
17import from IPL4asp_Types all;
18
19import from TELNETasp_PortType all;
20import from Osmocom_VTY_Functions all;
21
22import from SCCP_Types all;
23import from SCCP_Templates all;
24import from SCCPasp_Types all;
25import from SCCP_Emulation all;
26
27import from IPA_Emulation all;
28
29import from M3UA_Emulation all;
30import from M3UA_CodecPort all;
31import from MTP3asp_Types all;
32import from MTP3asp_PortType all;
33
34import from STP_Tests_Common all;
35
Pau Espin Pedrolb72928d2019-11-07 17:38:32 +010036private const integer NR_IPA := 7;
Pau Espin Pedrol01ec0bf2019-11-07 14:50:07 +010037
38type record of charstring AspNameArray;
Harald Welte0db44132019-10-17 11:09:05 +020039
40modulepar {
41 integer mp_stp_ipa_port := 5000;
42 integer mp_local_ipa_port := 20000;
Pau Espin Pedrol01ec0bf2019-11-07 14:50:07 +010043 AspNameArray mp_ipa_as_names := {"ipa-as-loadshare-sender",
44 "ipa-as-loadshare-receiver",
45 "ipa-as-loadshare-receiver",
Pau Espin Pedrolb72928d2019-11-07 17:38:32 +010046 "ipa-as-dynamic-asp",
47 "ipa-as-override-sender",
48 "ipa-as-override-receiver",
49 "ipa-as-override-receiver"
Pau Espin Pedrol01ec0bf2019-11-07 14:50:07 +010050 };
Harald Welte0db44132019-10-17 11:09:05 +020051}
52
53type component IPA_CT extends Test_CT {
54 /* for IPA we use the IPA_Emulation and not directly IPA_CodecPort to avoid
55 * having to re-invent IPA CCM handling here */
56 port MTP3asp_PT IPA[NR_IPA];
57 var IPA_Emulation_CT vc_IPA[NR_IPA];
Pau Espin Pedrol01ec0bf2019-11-07 14:50:07 +010058 var IPA_CCM_Parameters g_ccm_pars[NR_IPA];
Harald Welte0db44132019-10-17 11:09:05 +020059}
60
61friend function f_IPA_send(integer idx, octetstring data) runs on IPA_CT {
62 var MTP3_Field_sio sio := { ni := '00'B, prio := '00'B, si := '0011'B };
63 IPA[idx].send(t_ASP_MTP3_TRANSFERreq(sio, 0, 0, 0, data));
64}
65
66friend function f_IPA_exp(integer idx, template (present) octetstring data) runs on IPA_CT {
Harald Welte0db44132019-10-17 11:09:05 +020067 alt {
68 [] IPA[idx].receive(t_ASP_MTP3_TRANSFERind(?, ?, ?, ?, data)) {
69 setverdict(pass);
70 }
71 [] IPA[idx].receive {
72 setverdict(fail, "Received unexpected data on IPA port while waiting for ", data);
73 mtc.stop;
74 }
75 }
76}
77
Pau Espin Pedrol01ec0bf2019-11-07 14:50:07 +010078private function f_rnd_ipa_len() runs on IPA_CT return integer {
79 var integer rnd_len := f_rnd_int(100);
80 /* We need at least 1 byte of data, othewise osmocom IPA stack will discard and close the socket */
81 if (rnd_len == 0) {
82 rnd_len := 1;
83 }
84 return rnd_len;
85}
86
87/* Test if traffic is routed from idx_tx to idx_rx */
88private function f_test_traffic(integer idx_tx, integer idx_rx)
89runs on IPA_CT {
90 var octetstring data := f_rnd_octstring(f_rnd_ipa_len());
91 f_IPA_send(idx_tx, data);
92 f_IPA_exp(idx_rx, data);
93}
94
Harald Welte0db44132019-10-17 11:09:05 +020095friend function f_init_ipa() runs on IPA_CT {
96 var integer i;
97
98 f_init_common();
99
100 for (i := 0; i < NR_IPA; i:=i+1) {
101 vc_IPA[i] := IPA_Emulation_CT.create("IPA" & int2str(i));
102 map(vc_IPA[i]:IPA_PORT, system:IPA_CODEC_PT);
103 connect(self:IPA[i], vc_IPA[i]:MTP3_SP_PORT);
Pau Espin Pedrol01ec0bf2019-11-07 14:50:07 +0100104 g_ccm_pars[i] := c_IPA_default_ccm_pars;
105 g_ccm_pars[i].name := mp_ipa_as_names[i];
Harald Welte0db44132019-10-17 11:09:05 +0200106 }
107}
108
Pau Espin Pedrol9f514832019-11-08 15:24:13 +0100109friend function f_connect_ipa(integer idx, boolean use_unknown_asp_port := false) runs on IPA_CT {
110 var integer port_offset := 0;
111 if (use_unknown_asp_port) {
112 /* Add 100 to the port since we know that port is not configured in any
113 ASP only up to NR_IPA are configured. */
114 port_offset := 100;
115 }
Pau Espin Pedrol01ec0bf2019-11-07 14:50:07 +0100116 vc_IPA[idx].start(IPA_Emulation.main_client(mp_stp_ip, mp_stp_ipa_port, mp_local_ip,
Pau Espin Pedrol9f514832019-11-08 15:24:13 +0100117 mp_local_ipa_port + idx + port_offset, g_ccm_pars[idx]));
Pau Espin Pedrol01ec0bf2019-11-07 14:50:07 +0100118}
Harald Welte0db44132019-10-17 11:09:05 +0200119
120
121/* "accept-asp-connections pre-configured" and client from unknown source */
122testcase TC_unknown_client_nodynamic() runs on IPA_CT {
123 f_init_common();
124 f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"},
125 "accept-asp-connections pre-configured");
126 f_init_ipa();
Pau Espin Pedrol9f514832019-11-08 15:24:13 +0100127 f_connect_ipa(0, true);
Harald Welte0db44132019-10-17 11:09:05 +0200128 f_sleep(1.0);
129 if (IPA[0].checkstate("Connected")) {
130 setverdict(fail, "Expected IPA port to be disconnected");
131 } else {
132 setverdict(pass);
133 }
134 /* switch back to default */
135 f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"},
136 "accept-asp-connections dynamic-permitted");
137}
138
139/* "accept-asp-connections pre-configured" and client from known source */
140testcase TC_known_client_nodynamic() runs on IPA_CT {
141 f_init_common();
142 f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"},
143 "accept-asp-connections pre-configured");
Harald Welte0db44132019-10-17 11:09:05 +0200144 f_init_ipa();
Pau Espin Pedrol9f514832019-11-08 15:24:13 +0100145 f_connect_ipa(0, false);
Harald Welte0db44132019-10-17 11:09:05 +0200146 f_sleep(1.0);
147 if (not IPA[0].checkstate("Connected")) {
148 setverdict(fail, "Expected IPA port to be connected");
149 } else {
150 setverdict(pass);
151 }
152 /* switch back to default */
153 f_vty_config2(VTY, {"cs7 instance 0", "listen ipa 5000"},
154 "accept-asp-connections dynamic-permitted");
Harald Welte0db44132019-10-17 11:09:05 +0200155}
156
157
158/* "accept-asp-connections dynamic-permitted" and client from unknown source */
159testcase TC_unknown_client_dynamic() runs on IPA_CT {
160 f_init_common();
161 f_init_ipa();
Pau Espin Pedrol9f514832019-11-08 15:24:13 +0100162 f_connect_ipa(0, true);
Harald Welte0db44132019-10-17 11:09:05 +0200163 f_sleep(1.0);
164 if (not IPA[0].checkstate("Connected")) {
165 setverdict(fail, "Expected IPA port to be connected");
166 } else {
167 setverdict(pass);
168 }
169}
170
Pau Espin Pedrolb72928d2019-11-07 17:38:32 +0100171/* test "traffic-mode override" behavior */
172testcase TC_tmt_override() runs on IPA_CT {
173 f_init_ipa();
174
175 /* bring up the 'sender' side (single ASP in AS) */
176 f_connect_ipa(4);
177 /* activate the first 'receiver' side ASP */
178 f_connect_ipa(5);
179 f_sleep(1.0);
180
181 /* verify traffic is routed from sender to [sole] receiver */
182 f_test_traffic(4, 5);
183
184 /* activate the second 'receiver' side ASP */
185 f_connect_ipa(6);
186 f_sleep(1.0);
187
188 /* verify traffic is routed from sender to new receiver */
189 f_test_traffic(4, 6);
190}
191
Pau Espin Pedrol01ec0bf2019-11-07 14:50:07 +0100192private altstep as_count_rx(integer idx, template (present) octetstring exp, inout integer counter)
193runs on IPA_CT {
194 [] IPA[idx].receive(t_ASP_MTP3_TRANSFERind(?, ?, ?, ?, exp)) {
195 counter := counter + 1;
196 }
197}
198
199/* test "traffic-mode load-share" behavior */
200testcase TC_tmt_loadshare() runs on IPA_CT {
201 var integer i;
202
203 f_init_ipa();
204
205 /* bring up the 'sender' side (single ASP in AS) */
206 f_connect_ipa(0);
207 /* activate the first 'receiver' side ASP */
208 f_connect_ipa(1);
209 f_sleep(1.0);
210
211 /* verify traffic is routed from sender to [sole] receiver */
212 for (i := 0; i < 10; i := i+1) {
213 f_test_traffic(0, 1);
214 }
215
216 /* activate the second 'receiver' side ASP */
217 f_connect_ipa(2);
218 f_sleep(1.0);
219
220 /* verify traffic is routed from sender to new receiver */
221 const integer iter_per_asp := 5;
222 var integer num_rx[3] := { 0, 0, 0 };
223 for (i := 0; i < 2*iter_per_asp; i := i+1) {
224 var octetstring data := f_rnd_octstring(f_rnd_ipa_len());
225 f_IPA_send(0, data);
226 alt {
227 [] as_count_rx(1, data, num_rx[1])
228 [] as_count_rx(2, data, num_rx[2])
229 }
230 }
231 /* FIXME: check for extraneous messages? */
232 for (i := 1; i <= 2; i := i+1) {
233 if (num_rx[i] != iter_per_asp) {
234 setverdict(fail, "Received ", num_rx[i], " out of expected ", iter_per_asp,
235 "DATA messages at IPA port ", i);
236 }
237 }
238 setverdict(pass);
239}
240
Harald Welte0db44132019-10-17 11:09:05 +0200241control {
242 execute( TC_unknown_client_nodynamic() );
243 execute( TC_known_client_nodynamic() );
244 execute( TC_unknown_client_dynamic() );
Pau Espin Pedrolb72928d2019-11-07 17:38:32 +0100245 execute (TC_tmt_override() );
Pau Espin Pedrol01ec0bf2019-11-07 14:50:07 +0100246 execute( TC_tmt_loadshare() );
Harald Welte0db44132019-10-17 11:09:05 +0200247}
248
249
250}