From 8dd59fba5ea57c1533014e143ba8a3c65997eb34 Mon Sep 17 00:00:00 2001 From: Pau Espin Pedrol Date: Wed, 29 Apr 2020 15:08:16 +0200 Subject: pcu: Rename PCU*RAW* content to PCU Basically what's done here: * mv PCU_Tests_RAW${suffix}.ttcn -> PCU_Tests${suffix}.ttcn * mv PCUIF_RAW_Components.ttcn -> PCUIF_Components.ttcn * Change module names according to file names and fix all references in code and configuration. Change-Id: Iacaddb56e41012ba58ef6d1b9e79d2c012259bed --- pcu/PCU_Tests_SNS.ttcn | 405 +++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 405 insertions(+) create mode 100644 pcu/PCU_Tests_SNS.ttcn (limited to 'pcu/PCU_Tests_SNS.ttcn') diff --git a/pcu/PCU_Tests_SNS.ttcn b/pcu/PCU_Tests_SNS.ttcn new file mode 100644 index 00000000..fc98979d --- /dev/null +++ b/pcu/PCU_Tests_SNS.ttcn @@ -0,0 +1,405 @@ +module PCU_Tests_SNS { + +/* Osmocom PCU test suite for IP Sub-Network-Service (SNS) in TTCN-3 + * (C) 2018-2019 Harald Welte + * 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 + */ + +import from Osmocom_Types all; +import from PCU_Tests_NS all; +import from SGSN_Components all; +import from Osmocom_Gb_Types all; +import from NS_CodecPort all; +import from NS_Types all; + +/********************************************************************************** + * Modern Gb/IP bring-up test cases using IP Sub-Network Service (SNS) + **********************************************************************************/ + +/* perform inbound SNS-SIZE procedure */ +function f_incoming_sns_size(template (omit) NsCause cause := omit, integer idx := 0) +runs on RAW_NS_CT { + log("f_incoming_sns_size(idx=", idx, ")"); + var PDU_NS rx; + /* expect one single SNS-SIZE with RESET flag; one remote v4 EP; no v6 EP */ + rx := f_ns_exp(tr_SNS_SIZE(g_nsconfig[idx].nsei, rst_flag := true, max_nsvcs := 8, + num_v4 := 4, num_v6 := omit), idx); + NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_SIZE_ACK(g_nsconfig[idx].nsei, cause))); +} + +/* perform outbound SNS-SIZE procedure */ +function f_outgoing_sns_size(template (omit) NsCause cause := omit, integer idx:= 0) +runs on RAW_NS_CT { + log("f_outgoing_sns_size(idx=", idx, ")"); + var PDU_NS rx; + NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_SIZE(g_nsconfig[idx].nsei, rst_flag := true, max_nsvcs := 1, + num_v4 := 1, num_v6 := omit) + )); + /* expect one single SNS-SIZE with RESET flag; one remote v4 EP; no v6 EP */ + rx := f_ns_exp(tr_SNS_SIZE_ACK(g_nsconfig[idx].nsei, cause), idx); +} + +/* perform inbound SNS-CONFIG procedure */ +function f_incoming_sns_config(template (omit) NsCause cause := omit, integer idx := 0) +runs on RAW_NS_CT { + log("f_incoming_sns_config(idx=", idx, ")"); + var PDU_NS rx; + var template IP4_Elements v4_elem := { tr_SNS_IPv4(mp_nsconfig.remote_ip, + mp_nsconfig.remote_udp_port) }; + rx := f_ns_exp(tr_SNS_CONFIG(g_nsconfig[idx].nsei, end_flag := true, v4 := v4_elem), idx); + NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG_ACK(g_nsconfig[idx].nsei, cause))); +} + +/* perform outbound SNS-CONFIG procedure */ +function f_outgoing_sns_config(template (omit) NsCause cause := omit, integer idx := 0) +runs on RAW_NS_CT { + log("f_outgoing_sns_config(idx=", idx, ")"); + var PDU_NS rx; + var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx].local_ip, + g_nsconfig[idx].local_udp_port) } + NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG(g_nsconfig[idx].nsei, true, v4))); + rx := f_ns_exp(tr_SNS_CONFIG_ACK(g_nsconfig[idx].nsei, cause), idx); +} + +/* perform outbound SNS-CONFIG procedure (separate endpoints: 1 for control, 1 for user */ +function f_outgoing_sns_config_1c1u(template (omit) NsCause cause := omit, integer idx := 0) +runs on RAW_NS_CT { + log("f_outgoing_sns_config_1c1u(idx=", idx, ")"); + var PDU_NS rx; + var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[0].local_ip, + g_nsconfig[0].local_udp_port, 1, 0), + ts_SNS_IPv4(g_nsconfig[1].local_ip, + g_nsconfig[1].local_udp_port, 0, 1) }; + NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG(g_nsconfig[idx].nsei, true, v4))); + rx := f_ns_exp(tr_SNS_CONFIG_ACK(g_nsconfig[idx].nsei, cause), idx); +} + +/* perform outbound SNS-CONFIG procedure (separate endpoints: 1 for control, 1 for user */ +function f_outgoing_sns_config_1c1u_separate(template (omit) NsCause cause := omit, integer idx := 0) +runs on RAW_NS_CT { + log("f_outgoing_sns_config_1c1u_separate(idx=", idx, ")"); + var PDU_NS rx; + var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[1].local_ip, + g_nsconfig[1].local_udp_port, 1, 0), + ts_SNS_IPv4(g_nsconfig[2].local_ip, + g_nsconfig[2].local_udp_port, 0, 1) }; + NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CONFIG(g_nsconfig[idx].nsei, true, v4))); + rx := f_ns_exp(tr_SNS_CONFIG_ACK(g_nsconfig[idx].nsei, cause), idx); +} + +function f_outgoing_sns_add(integer idx_add, uint8_t w_sig := 1, uint8_t w_user := 1, integer idx := 0) +runs on RAW_NS_CT { + log("f_outgoing_sns_add(idx_add=", idx_add, ")"); + var PDU_NS rx; + var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx_add].local_ip, + g_nsconfig[idx_add].local_udp_port, + w_sig, w_user) }; + NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_ADD(g_nsconfig[idx].nsei, 23, v4))); + rx := f_ns_exp(tr_SNS_ACK(g_nsconfig[idx].nsei, 23, omit, v4)); +} + +function f_outgoing_sns_del(integer idx_del, uint8_t w_sig := 1, uint8_t w_user := 1, integer idx := 0) +runs on RAW_NS_CT { + log("f_outgoing_sns_del(idx_del=", idx_del, ")"); + var PDU_NS rx; + var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx_del].local_ip, + g_nsconfig[idx_del].local_udp_port, + w_sig, w_user) }; + NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_DEL(g_nsconfig[idx].nsei, 24, omit, v4))); + rx := f_ns_exp(tr_SNS_ACK(g_nsconfig[idx].nsei, 24, omit, v4)); +} + +function f_outgoing_sns_chg_weight(integer idx_chg, uint8_t w_sig, uint8_t w_user, integer idx := 0) +runs on RAW_NS_CT { + log("f_outgoing_sns_chg_weight(idx_chg=", idx_chg, ")"); + var PDU_NS rx; + var template (omit) IP4_Elements v4 := { ts_SNS_IPv4(g_nsconfig[idx_chg].local_ip, + g_nsconfig[idx_chg].local_udp_port, + w_sig, w_user) }; + NSCP[idx].send(t_NS_Send(g_ns_conn_id[idx], ts_SNS_CHG_WEIGHT(g_nsconfig[idx].nsei, 25, v4))); + rx := f_ns_exp(tr_SNS_ACK(g_nsconfig[idx].nsei, 25, omit, v4)); +} + + + + + +/* PCU-originated SNS-SIZE: successful case */ +testcase TC_sns_po_size_success() runs on RAW_Test_CT { + f_init_ns_codec(); + f_init_pcuif(); + f_incoming_sns_size(); + f_sleep(1.0); + setverdict(pass); +} + +/* PCU-originated SNS-SIZE: NACK from our side */ +testcase TC_sns_po_size_nack() runs on RAW_Test_CT { + f_init_ns_codec(); + f_init_pcuif(); + f_incoming_sns_size(NS_CAUSE_PROTOCOL_ERROR_UNSPEIFIED); + /* FIXME: ensure we don't get a SNS-CONFIG */ + /* FIXME: ensure we get re-transmitted SNS-SIZE attempts */ + f_sleep(10.0); + setverdict(pass); +} + +/* PCU-originated SNS-CONFIG: successful case */ +testcase TC_sns_po_config_success() runs on RAW_Test_CT { + f_init_ns_codec(); + f_init_pcuif(); + f_incoming_sns_size(); + f_incoming_sns_config(); + f_sleep(1.0); + setverdict(pass); +} + +/* PCU-originated SNS-CONFIG: successful case */ +testcase TC_sns_po_config_nack() runs on RAW_Test_CT { + f_init_ns_codec(); + f_init_pcuif(); + f_incoming_sns_size(); + f_incoming_sns_config(NS_CAUSE_PROTOCOL_ERROR_UNSPEIFIED); + /* FIXME: ensure we get re-transmitted SNS-CONFIG attempts */ + f_sleep(10.0); + setverdict(pass); +} + + +/* SGSN-originated SNS-SIZE: successful case */ +testcase TC_sns_so_config_success() runs on RAW_Test_CT { + f_init_ns_codec(); + f_init_pcuif(); + f_incoming_sns_size(); + f_incoming_sns_config(); + f_outgoing_sns_config(); + + /* wait for one ALIVE cycle, then ACK any further ALIVE in the background */ + as_rx_alive_tx_ack(oneshot := true); + activate(as_rx_alive_tx_ack()); + + f_outgoing_ns_alive(); + + /* Expect BVC-RESET for signaling (0) and ptp BVCI */ + as_rx_bvc_reset_tx_ack(0, oneshot := true); + as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvci, oneshot := true); + as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvci, oneshot := true); + + /* wait for one FLOW-CONTROL BVC and then ACK any further in the future */ + as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci, oneshot := true); + activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci)); + setverdict(pass); +} + +private function f_sns_bringup_1c1u(boolean sgsn_originated_reset := false) runs on RAW_Test_CT { + /* Activate two NS codec ports */ + f_init_ns_codec(); + f_init_ns_codec(1); + f_init_pcuif(); + /* Perform Size + BSS-originated config */ + f_incoming_sns_size(); + f_incoming_sns_config(); + /* perform SGSN-originated config using idx==0 for signalling and idx==1 for user traffic */ + f_outgoing_sns_config_1c1u(); + + /* wait for one ALIVE cycle, then ACK any further ALIVE in the background + * for both NS-VCs */ + as_rx_alive_tx_ack(oneshot := true, idx := 0); + activate(as_rx_alive_tx_ack(idx := 0)); + as_rx_alive_tx_ack(oneshot := true, idx := 1); + activate(as_rx_alive_tx_ack(idx := 1)); + + /* perform outgoing ALIVE procedure for both NS-VCs */ + f_outgoing_ns_alive(0); + f_outgoing_ns_alive(1); + + if (sgsn_originated_reset) { + f_tx_bvc_reset_rx_ack(0); + f_tx_bvc_reset_rx_ack(mp_gb_cfg.bvci); + } else { + /* Expect BVC-RESET for signaling (0) and ptp BVCI */ + as_rx_bvc_reset_tx_ack(0, oneshot := true); + as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvci, oneshot := true); + } + /* Expect UNBLOCK for ptp BVCI on signaling NS-VC (idx==0) */ + as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvci, oneshot := true); + + /* wait for one FLOW-CONTROL BVC and then ACK any further in the future. Flow + * control happens on the p-t-p BVCI and hence on index 1 */ + as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci, oneshot := true, idx := 1); + activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci, idx := 1)); +} + +/* Test full IP-SNS bring-up with two NS-VCs, one sig-only and one user-only */ +testcase TC_sns_1c1u() runs on RAW_Test_CT { + f_sns_bringup_1c1u(); + setverdict(pass); +} + +private function f_sns_bringup_1c1u_separate(boolean sgsn_originated_reset := false) runs on RAW_Test_CT { + /* Activate two NS codec ports */ + f_init_ns_codec(); + f_init_ns_codec(1); + f_init_ns_codec(2); + f_init_pcuif(); + /* Perform Size + BSS-originated config */ + f_incoming_sns_size(); + f_incoming_sns_config(); + /* perform SGSN-originated config using idx==0 for signalling and idx==1 for user traffic */ + f_outgoing_sns_config_1c1u_separate(); + + /* wait for one ALIVE cycle, then ACK any further ALIVE in the background + * for both NS-VCs */ + as_rx_alive_tx_ack(oneshot := true, idx := 1); + activate(as_rx_alive_tx_ack(idx := 1)); + as_rx_alive_tx_ack(oneshot := true, idx := 2); + activate(as_rx_alive_tx_ack(idx := 2)); + /* ensure there's no NS-ALIVE received on idx==0 */ + f_ensure_no_ns(t_NS_ALIVE, idx := 0); + + /* perform outgoing ALIVE procedure for both NS-VCs */ + f_outgoing_ns_alive(1); + f_outgoing_ns_alive(2); + /* ensure there's no response to NS-ALIVE sent on idx==0 */ + f_outgoing_ns_alive_no_ack(idx := 0); + + if (sgsn_originated_reset) { + f_tx_bvc_reset_rx_ack(0, idx := 1); + f_tx_bvc_reset_rx_ack(mp_gb_cfg.bvci, idx := 1); + } else { + /* Expect BVC-RESET for signaling BVCI=0 and ptp BVCI */ + as_rx_bvc_reset_tx_ack(0, oneshot := true, idx := 1); + as_rx_bvc_reset_tx_ack(mp_gb_cfg.bvci, oneshot := true, idx := 1); + } + /* Expect UNBLOCK for ptp BVCI on signaling NS-VC (idx==1) */ + as_rx_bvc_unblock_tx_ack(mp_gb_cfg.bvci, oneshot := true, idx := 1); + + /* wait for one FLOW-CONTROL BVC and then ACK any further in the future. Flow + * control happens on the p-t-p BVCI and hence on index 1 */ + as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci, oneshot := true, idx := 2); + activate(as_rx_bvc_fc_tx_ack(mp_gb_cfg.bvci, idx := 2)); +} + +/* Test full IP-SNS bring-up with two NS-VCs, one sig-only and one user-only - and where + * the initial IP/port for the SNS procedure is *not* part of the NS-VCs later */ +testcase TC_sns_1c1u_separate() runs on RAW_Test_CT { + f_sns_bringup_1c1u_separate(); + setverdict(pass); +} + +/* Test full IP-SNS bring-up with two NS-VCs, one sig-only and one user-only and use + * SGSN-originated BVC-RESET rather than BSS-originated */ +testcase TC_sns_1c1u_so_bvc_reset() runs on RAW_Test_CT { + f_sns_bringup_1c1u_separate(sgsn_originated_reset := true); + setverdict(pass); +} + +/* Transmit BVC-RESET before NS-ALIVE of PCU was ACKed: expect no response */ +testcase TC_sns_1c1u_so_bvc_reset_too_early() runs on RAW_Test_CT { + /* Activate two NS codec ports */ + f_init_ns_codec(); + f_init_ns_codec(1); + f_init_ns_codec(2); + f_init_pcuif(); + /* Perform Size + BSS-originated config */ + f_incoming_sns_size(); + f_incoming_sns_config(); + /* perform SGSN-originated config using idx==0 for signalling and idx==1 for user traffic */ + f_outgoing_sns_config_1c1u_separate(); + + /* DON'T ACK ANY INBOUND NS-ALIVE HERE! */ + + /* perform outgoing ALIVE procedure for both NS-VCs */ + f_outgoing_ns_alive(1); + f_outgoing_ns_alive(2); + /* ensure there's no response to NS-ALIVE sent on idx==0 */ + f_outgoing_ns_alive_no_ack(idx := 0); + + /* Transmit BVC-RESET and expect no ACK*/ + f_tx_bvc_reset_rx_ack(0, idx := 1, exp_ack := false); + f_tx_bvc_reset_rx_ack(mp_gb_cfg.bvci, idx := 1, exp_ack := false); +} + +/* Test adding new IP endpoints at runtime */ +testcase TC_sns_add() runs on RAW_Test_CT { + f_sns_bringup_1c1u(); + + /* crate another NS codec port on the tester side */ + f_init_ns_codec(2); + + f_outgoing_sns_add(idx_add := 2, w_sig := 0, w_user := 1, idx := 0); + + /* wait for one ALIVE cycle, then ACK any further ALIVE in the background */ + as_rx_alive_tx_ack(oneshot := true, idx := 2); + activate(as_rx_alive_tx_ack(idx := 2)); + + f_outgoing_ns_alive(2); + /* TODO: Should we expect FLOW-CONTROL BVC here too? */ + setverdict(pass); +} + +/* Test deleting IP endpoints at runtime */ +testcase TC_sns_del() runs on RAW_Test_CT { + f_sns_bringup_1c1u(); + + f_outgoing_sns_del(idx_del := 1, w_sig := 0, w_user := 1, idx := 0); + /* FIXME: ensure we don't receive anything on just-deleted NS-VC anymore */ + setverdict(pass); +} + +/* Test changing weights at runtime */ +testcase TC_sns_chg_weight() runs on RAW_Test_CT { + f_sns_bringup_1c1u(); + + /* change w_user from 1 to 200 */ + f_outgoing_sns_chg_weight(idx_chg := 1, w_sig := 0, w_user := 200, idx := 0); + setverdict(pass); +} + +import from PCUIF_Types all; +import from PCUIF_CodecPort all; + +altstep as_pcu_activate() runs on RAW_PCU_CT { + var PCUIF_send_data sd; + [] PCU.receive(t_SD_PCUIF(g_pcu_conn_id, tr_PCUIF_ACT_REQ(?, ?, ?))) -> value sd { repeat; } + +} + +testcase TC_pcuif_rach() runs on RAW_Test_CT { + f_sns_bringup_1c1u(); + activate(as_pcu_activate()); + + f_pcuif_tx(ts_PCUIF_RACH_IND(bts_nr:=0, trx_nr:=0, ts_nr:=0, ra:=23, + is_11bit:=0, burst_type:=BURST_TYPE_0, + fn:=42, arfcn:=871, qta:=0)); + PCU.receive(t_SD_PCUIF(g_pcu_conn_id, + tr_PCUIF_DATA_REQ(bts_nr:=0, trx_nr:=0, ts_nr:=0, block_nr:=?, fn:=?, + sapi:=PCU_IF_SAPI_AGCH, data:=?))); + setverdict(pass); +} + + + +control { + execute( TC_sns_po_size_success() ); + execute( TC_sns_po_size_nack() ); + execute( TC_sns_po_config_success() ); + execute( TC_sns_po_config_nack() ); + execute( TC_sns_so_config_success() ); + execute( TC_sns_1c1u() ); + execute( TC_sns_1c1u_separate() ); + execute( TC_sns_1c1u_so_bvc_reset() ); + execute( TC_sns_1c1u_so_bvc_reset_too_early() ); + execute( TC_sns_add() ); + execute( TC_sns_del() ); + execute( TC_sns_chg_weight() ); + + execute( TC_pcuif_rach() ); +} + +} -- cgit v1.2.3