blob: ef8be2a7f827ae95f08e03b229add9d9a419af9b [file] [log] [blame]
Alexander Couzens20cd41e2021-01-11 02:56:03 +01001module NS_Tests {
2
3/* Osmocom NS test suite for NS over framerelay or udp ip.access style in TTCN-3
4 * (C) 2021 sysmocom s.f.m.c. GmbH <info@sysmocom.de>
5 * Author: Alexander Couzens <lynxis@fe80.eu>
6 * All rights reserved.
7 *
8 * Released under the terms of GNU General Public License, Version 2 or
9 * (at your option) any later version.
10 *
11 * SPDX-License-Identifier: GPL-2.0-or-later
12 */
13
14import from General_Types all;
15import from Osmocom_Types all;
16import from Osmocom_Gb_Types all;
17import from NS_Types all;
18import from BSSGP_Types all;
19import from UD_Types all;
20import from NS_Emulation all;
21import from Native_Functions all;
22import from IPL4asp_Types all;
23import from RAW_NS all;
24import from Osmocom_VTY_Functions all;
25import from TELNETasp_PortType all;
26
27modulepar {
28 OsmoNsDialect mp_dialect := NS2_DIALECT_IPACCESS;
29 NSConfiguration mp_nsconfig := {
30 nsei := 96,
31 role_sgsn := false,
32 handle_sns := false,
33 nsvc := {
34 {
35 provider := {
36 ip := {
37 address_family := AF_INET,
38 local_udp_port := 21000,
39 local_ip := "127.0.0.1",
40 remote_udp_port := 23000,
41 remote_ip := "127.0.0.1"
42 }
43 },
44 nsvci := 97
45 }
46 }
47 };
48}
49
50type component RAW_Test_CT extends RAW_NS_CT {
51 port TELNETasp_PT NSVTY;
52}
53
54private function f_init_vty() runs on RAW_Test_CT {
55 map(self:NSVTY, system:NSVTY);
56 f_vty_set_prompts(NSVTY);
57 f_vty_transceive(NSVTY, "enable");
58 f_vty_transceive(NSVTY, "nsvc nsei " & int2str(mp_nsconfig.nsei) & " force-unconfigured");
59}
60
61/* ensure no matching message is received within 'tout' */
62function f_ensure_no_ns(integer idx := 0, boolean answer_alive := false, float tout := 3.0)
63runs on RAW_Test_CT {
64 var PDU_NS nrf;
65
66 timer T := tout;
67 var default d := activate(ax_rx_fail_on_any_ns(idx));
68 T.start;
69 alt {
70 [answer_alive] as_rx_alive_tx_ack();
71 [] T.timeout {
72 setverdict(pass);
73 }
74 }
75 deactivate(d);
76}
77
78function f_fails_except_reset(integer idx := 0, float tout := 15.0)
79runs on RAW_Test_CT {
80 var PDU_NS nrf;
81 timer T := 15.0;
82 T.start;
83 alt {
84 [] NSCP[idx].receive(tr_NS_RESET(*, *, *)) {
85 repeat;
86 }
87 [] NSCP[idx].receive(PDU_NS: ?) -> value nrf {
88 setverdict(fail, "Received unexpected NS: ", nrf);
89 mtc.stop;
90 }
91 [] T.timeout {
92 setverdict(pass);
93 }
94 }
95}
96
97testcase TC_tx_reset() runs on RAW_Test_CT {
98 f_init_vty();
99 f_init_ns_codec(mp_nsconfig, guard_secs := 10.0);
100
101 /* do a NS Reset procedure */
102 f_outgoing_ns_reset();
103
104 setverdict(pass);
105 f_sleep(1.0);
106}
107
108testcase TC_tx_reset_tx_alive() runs on RAW_Test_CT {
109 f_init_vty();
110 f_init_ns_codec(mp_nsconfig, guard_secs := 10.0);
111
112 /* do a NS Reset procedure */
113 f_outgoing_ns_reset();
114
115 /* check outgoing NS procedure */
116 f_outgoing_ns_alive();
117
118 setverdict(pass);
119 f_sleep(1.0);
120}
121
122testcase TC_tx_reset_rx_alive() runs on RAW_Test_CT {
123 f_init_vty();
124 f_init_ns_codec(mp_nsconfig, guard_secs := 10.0);
125
126 /* do a NS Reset procedure */
127 f_outgoing_ns_reset();
128
129 activate(as_rx_ns_unblock_ack());
130 /* check outgoing NS procedure */
131 as_rx_alive_tx_ack(oneshot := true);
132
133 setverdict(pass);
134 f_sleep(1.0);
135}
136
137/* 48.016 7.2 unblock procedure
138 *
139 * TTCN -> NS: reset
140 * TTCN <- NS: reset ack
141 * TTCN -> NS: unblock
142 * TTCN <- NS: unblock ack
143 */
144testcase TC_tx_unblock() runs on RAW_Test_CT {
145 f_init_vty();
146 f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);
147
148 /* do a NS Reset procedure */
149 f_outgoing_ns_reset();
150 /* send alive acks */
151 activate(as_rx_alive_tx_ack());
152
153 f_outgoing_ns_unblock();
154 setverdict(pass);
155 f_sleep(1.0);
156}
157
158/* 48.016 7.2 tx unblock retries
159 *
160 * TTCN -> NS: reset
161 * TTCN <- NS: reset ack
162 * TTCN -> NS: unblock
163 * TTCN <- NS: unblock ack
164 * TTCN -> NS: unblock
165 * TTCN <- NS: unblock ack
166 * TTCN -> NS: unblock
167 * TTCN <- NS: unblock ack
168 */
169testcase TC_tx_unblock_retries() runs on RAW_Test_CT {
170 f_init_vty();
171 f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);
172
173 /* do a NS Reset procedure */
174 f_outgoing_ns_reset();
175 /* send alive acks */
176 activate(as_rx_alive_tx_ack());
177
178 f_outgoing_ns_unblock();
179 f_outgoing_ns_unblock();
180 f_outgoing_ns_unblock();
181 setverdict(pass);
182 f_sleep(1.0);
183}
184
185/* 48.016 7.2 block procedure
186 *
187 * TTCN -> NS: reset
188 * TTCN <- NS: reset ack
189 * TTCN -> NS: unblock
190 * TTCN <- NS: unblock ack
191 * TTCN -> NS: block
192 * TTCN <- NS: block ack
193 */
194testcase TC_tx_block() runs on RAW_Test_CT {
195 f_init_vty();
196 f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);
197
198 /* do a NS Reset procedure */
199 f_outgoing_ns_reset();
200 activate(as_rx_alive_tx_ack());
201
202 f_outgoing_ns_unblock();
203 f_sleep(1.0);
204
205 f_outgoing_ns_block(NS_CAUSE_EQUIPMENT_FAILURE);
206 setverdict(pass);
207 f_sleep(1.0);
208}
209
210/* 48.016 7.2 block procedure by vty
211 *
212 * TTCN -> NS: reset
213 * TTCN <- NS: reset ack
214 * TTCN -> NS: unblock
215 * TTCN <- NS: unblock ack
216 * vty: block nsvc
217 * TTCN <- NS: block
218 * TTCN -> NS: block ack
219 */
220function tx_block_by_vty(float guard_secs := 30.0) runs on RAW_Test_CT {
221 f_init_vty();
222 f_init_ns_codec(mp_nsconfig, guard_secs := guard_secs);
223
224 /* do a NS Reset procedure */
225 f_outgoing_ns_reset();
226 activate(as_rx_alive_tx_ack());
227
228 f_outgoing_ns_unblock();
229 f_sleep(1.0);
230
231 f_vty_transceive(NSVTY, "nsvc " & int2str(mp_nsconfig.nsvc[0].nsvci) & " block");
232
233 alt {
234 [] as_rx_ns_block_ack(oneshot := true, nsvci := mp_nsconfig.nsvc[0].nsvci);
235 }
236 setverdict(pass);
237}
238
239testcase TC_tx_block_by_vty() runs on RAW_Test_CT {
240 tx_block_by_vty(30.0);
241 f_sleep(1.0);
242}
243
244/* 48.016 7.2 block precedure by vty and reset the NSVC.
245 * The NSVC should be still blocked after the reset.
246 */
247testcase TC_tx_block_by_vty_reset() runs on RAW_Test_CT {
248 timer T := 10.0;
249
250 tx_block_by_vty(60.0);
251 f_outgoing_ns_reset();
252
253 var default d := activate(ax_rx_fail_on_any_ns());
254 T.start;
255 alt {
256 [] as_rx_alive_tx_ack();
257 [] T.timeout { setverdict(pass); }
258 }
259 deactivate(d);
260}
261
262/* 48.016 7.4.1 ignore unexpected NS_ALIVE ACK */
263testcase TC_no_reset_alive_ack() runs on RAW_Test_CT {
264 f_init_vty();
265 f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);
266
267 NSCP[0].send(t_NS_ALIVE_ACK);
268 f_fails_except_reset();
269 setverdict(pass);
270 f_sleep(1.0);
271}
272
273/* 48.016 7.3.1 NS_RESET with wrong nsei */
274testcase TC_reset_wrong_nsei() runs on RAW_Test_CT {
275 f_init_vty();
276 f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);
277
278 NSCP[0].send(ts_NS_RESET(NS_CAUSE_EQUIPMENT_FAILURE, g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei + 20));
279 NSCP[0].receive(tr_NS_RESET_ACK(g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
280 f_fails_except_reset();
281 setverdict(pass);
282 f_sleep(1.0);
283}
284
285/* 48.016 7.3.1 NS_RESET with wrong nsvci */
286testcase TC_reset_wrong_nsvci() runs on RAW_Test_CT {
287 f_init_vty();
288 f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);
289
290 NSCP[0].send(ts_NS_RESET(NS_CAUSE_EQUIPMENT_FAILURE, g_nsconfig.nsvc[0].nsvci + 20, g_nsconfig.nsei));
291 NSCP[0].receive(tr_NS_RESET_ACK(g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
292 f_fails_except_reset();
293 setverdict(pass);
294 f_sleep(1.0);
295}
296
297/* 48.016 7.3.1 NS_RESET with wrong nsvci + nsei */
298testcase TC_reset_wrong_nsei_nsvci() runs on RAW_Test_CT {
299 f_init_vty();
300 f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);
301
302 NSCP[0].send(ts_NS_RESET(NS_CAUSE_EQUIPMENT_FAILURE, g_nsconfig.nsvc[0].nsvci + 20, g_nsconfig.nsei + 20));
303 NSCP[0].receive(tr_NS_RESET_ACK(g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
304 f_fails_except_reset();
305 setverdict(pass);
306 f_sleep(1.0);
307}
308
309/* 48.016 7.3.1 NS_RESET_ACK with wrong nsei */
310testcase TC_reset_ack_wrong_nsei() runs on RAW_Test_CT {
311 f_init_vty();
312 f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);
313
314 NSCP[0].receive(tr_NS_RESET(*, g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
315 NSCP[0].send(ts_NS_RESET_ACK(g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei + 20));
316 f_fails_except_reset();
317 setverdict(pass);
318 f_sleep(1.0);
319}
320
321/* 48.016 7.3.1 NS_RESET_ACK with wrong nsvci */
322testcase TC_reset_ack_wrong_nsvci() runs on RAW_Test_CT {
323 f_init_vty();
324 f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);
325
326 NSCP[0].receive(tr_NS_RESET(*, g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
327 NSCP[0].send(ts_NS_RESET_ACK(g_nsconfig.nsvc[0].nsvci + 20, g_nsconfig.nsei));
328 f_fails_except_reset();
329 setverdict(pass);
330 f_sleep(1.0);
331}
332
333/* 48.016 7.3.1 NS_RESET_ACK with wrong nsvci + nsei */
334testcase TC_reset_ack_wrong_nsei_nsvci() runs on RAW_Test_CT {
335 f_init_vty();
336 f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);
337
338 NSCP[0].receive(tr_NS_RESET(*, g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
339 NSCP[0].send(ts_NS_RESET_ACK(g_nsconfig.nsvc[0].nsvci + 20, g_nsconfig.nsei + 20));
340 f_fails_except_reset();
341 setverdict(pass);
342 f_sleep(1.0);
343}
344
345/* 48.016 7.3.1 ignore unexpected NS_RESET_ACK after NS_RESET+ALIVE */
346testcase TC_ignore_reset_ack() runs on RAW_Test_CT {
347 f_init_vty();
348 f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);
349
350 /* do a NS Reset procedure */
351 f_outgoing_ns_reset();
352
353 /* unblock and alive */
354 alt {
355 [] as_rx_ns_unblock_ack(oneshot := true);
356 [] as_rx_alive_tx_ack();
357 }
358
359 NSCP[0].send(ts_NS_RESET_ACK(g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
360 f_ensure_no_ns(answer_alive := true, tout := 15.0);
361 setverdict(pass);
362 f_sleep(1.0);
363}
364
365/* 48.016 7.3 NS_RESET retries */
366testcase TC_reset_retries() runs on RAW_Test_CT {
367 var integer reset := 0;
368
369 f_init_vty();
370 f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);
371
372 alt {
373 [] NSCP[0].receive(tr_NS_RESET(*, *, *)) {
374 reset := reset + 1;
375 if (reset <= 3) {
376 repeat;
377 } else {
378 setverdict(pass);
379 }
380 }
381 }
382
383 f_sleep(1.0);
384}
385
386/* 48.016 behave RESET_ACK got dropped
387 * TTCN -> NS: reset
388 * TTCN <- NS: reset ack
389 * TTCN <- NS: unblock
390 * TTCN -> NS: reset
391 * TTCN <- NS: reset ack
392 * TTCN <- NS: unblock
393 */
394testcase TC_reset_on_block_reset() runs on RAW_Test_CT {
395 var integer i := 0;
396
397 f_init_vty();
398 f_init_ns_codec(mp_nsconfig, guard_secs := 30.0);
399
400 f_outgoing_ns_reset();
401 activate(as_rx_alive_tx_ack());
402
403 alt {
404 [] NSCP[0].receive(t_NS_UNBLOCK) {
405 NSCP[0].send(ts_NS_RESET(NS_CAUSE_EQUIPMENT_FAILURE, g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
406 i := i + 1;
407 if (i < 3) {
408 repeat;
409 } else {
410 setverdict(pass);
411 }
412 }
413 [] NSCP[0].receive(tr_NS_RESET_ACK(g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei)) { repeat; }
414 }
415
416 f_sleep(1.0);
417}
418
419/* 48.016 7.4 test procedure for frame relay with a single nsvci */
420function f_alive_retries_single(boolean reset := false) runs on RAW_Test_CT {
421 f_init_vty();
422 f_init_ns_codec(mp_nsconfig, guard_secs := 60.0);
423
424 /* do a NS Reset procedure */
425 f_outgoing_ns_reset();
426
427 alt {
428 [] as_rx_ns_unblock_ack(oneshot := true);
429 [] as_rx_alive_tx_ack();
430 }
431
432 /* wait for one alive and answer it */
433 as_rx_alive_tx_ack(oneshot := true);
434 NSCP[0].receive(t_NS_ALIVE);
435 NSCP[0].receive(t_NS_ALIVE);
436 NSCP[0].receive(t_NS_ALIVE);
437 NSCP[0].receive(t_NS_ALIVE);
438 if (reset) {
439 NSCP[0].receive(tr_NS_RESET(*, g_nsconfig.nsvc[0].nsvci, g_nsconfig.nsei));
440 } else {
441 f_ensure_no_ns(tout := 10.0);
442 }
443
444 setverdict(pass);
445 f_sleep(1.0);
446}
447
448testcase TC_alive_retries_single_reset() runs on RAW_Test_CT {
449 f_alive_retries_single(reset := true);
450}
451
452testcase TC_alive_retries_single_no_resp() runs on RAW_Test_CT {
453 f_alive_retries_single(reset := false);
454}
455
456control {
457 execute( TC_tx_reset() );
458
459 /* 48.016 7.2 Block procedure */
460 execute( TC_tx_block() );
461 execute( TC_tx_block_by_vty() );
462 execute( TC_tx_block_by_vty_reset() );
463 // execute( TC_block_other_nsvc() ); // reset, unblock, sleep(1), block over another nsvci
464 /* 48.016 7.2 Unblock procedure */
465 execute( TC_tx_unblock() );
466 execute( TC_tx_unblock_retries() );
467 // execute( TC_rx_unblock_tx_unblock() ); // wait for an rx unblock pdu, send an unblock pdu, expect unblock ack pdu
468 // execute( TC_unblockable() ); // block a NS-VCI via vty, try block procedure
469
470 /* 48.016 7.2.1 Block Abnormal Condition */
471 /* 48.016 7.2.1 Unblock Abnormal Condition */
472
473 /* 48.016 7.3.1 Abnormal Condition */
474 if (mp_dialect == NS2_DIALECT_STATIC_RESETBLOCK) {
475 execute( TC_reset_wrong_nsei() );
476 execute( TC_reset_wrong_nsvci() );
477 execute( TC_reset_wrong_nsei_nsvci() );
478 execute( TC_reset_ack_wrong_nsei() );
479 execute( TC_reset_ack_wrong_nsvci() );
480 execute( TC_reset_ack_wrong_nsei_nsvci() );
481 execute( TC_reset_retries() );
482 execute( TC_reset_on_block_reset() );
483 }
484 execute( TC_ignore_reset_ack() );
485
486 /* 48.016 7.4 Test procedure on frame relay */
487 execute( TC_tx_reset_tx_alive() );
488 execute( TC_tx_reset_rx_alive() );
489
490 /* 48.016 7.4.1 Abnormal Condition */
491 if (mp_dialect == NS2_DIALECT_STATIC_RESETBLOCK) {
492 // execute( TC_alive_retries_multi() ); // check if alive retries works and block over an alive nsvc
493 execute( TC_alive_retries_single_reset() );
494 } else if (mp_dialect == NS2_DIALECT_IPACCESS) {
495 execute( TC_alive_retries_single_no_resp() );
496 }
497 execute( TC_no_reset_alive_ack() );
498}
499
500}