osmo-ttcn3-hacks/remsim/RemsimBankd_Tests.ttcn

442 lines
14 KiB
Plaintext

module RemsimBankd_Tests {
/* Integration Tests for osmo-remsim-bankd
* (C) 2019 by Harald Welte <laforge@gnumonks.org>
* 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
*
* This test suite tests osmo-remsim-bankd by attaching to the external interfaces
* such as RSPRO for simulated clients + server.
*/
import from Osmocom_Types all;
import from IPA_Emulation all;
import from Misc_Helpers all;
import from VPCD_Types all;
import from VPCD_CodecPort all;
import from VPCD_Adapter all;
import from RSPRO all;
import from RSRES all;
import from RSPRO_Types all;
import from RSPRO_Server all;
import from REMSIM_Tests all;
modulepar {
integer mp_bank_id := 1;
integer mp_num_slots := 8;
}
/* We implement a RSPRO server to simulate the remsim-server and a
RSPRO client to simulate a remsim-client connecting to bankd */
type component bankd_test_CT extends rspro_server_CT, rspro_client_CT, VPCD_Adapter_CT {
timer g_T_guard := 60.0;
}
private altstep as_Tguard() runs on bankd_test_CT {
[] g_T_guard.timeout {
setverdict(fail, "Timeout of T_guard");
Misc_Helpers.f_shutdown(__BFILE__, __LINE__);
}
}
private function f_init(boolean start_client := false) runs on bankd_test_CT {
var ComponentIdentity srv_comp_id := valueof(ts_CompId(remsimServer, "ttcn-server"));
/* Start the guard timer */
g_T_guard.start;
activate(as_Tguard());
f_rspro_srv_init(0, mp_server_ip, mp_server_port, srv_comp_id);
if (start_client) {
f_init_client(0);
}
}
private function f_init_client(integer i := 0) runs on rspro_client_CT {
var ComponentIdentity clnt_comp_id := valueof(ts_CompId(remsimClient, "ttcn-client"));
f_rspro_init(rspro[0], mp_bankd_ip, mp_bankd_port, clnt_comp_id, 0);
rspro[0].rspro_client_slot := { clientId := 23+i, slotNr := 0 };
}
/* Test if the bankd disconnects the TCP/IPA session if we don't respond to connectBankReq */
testcase TC_connectBankReq_timeout() runs on bankd_test_CT {
timer T := 20.0;
f_init();
f_rspro_srv_exp(tr_RSPRO_ConnectBankReq(?, ?, ?));
T.start;
alt {
[] RSPRO_SRV[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
setverdict(pass);
}
[] RSPRO_SRV[0].receive { repeat; }
[] T.timeout {
setverdict(fail, "Timeout waiting for disconnect");
}
}
}
/* accept an inbound connection from bankd to simulated server */
testcase TC_connectBankReq() runs on bankd_test_CT {
f_init();
as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}
/* attempt to create a mapping */
testcase TC_createMapping() runs on bankd_test_CT {
f_init();
as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
f_rspro_srv_reset_state(ok);
var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
var ClientSlot cs := { clientId := 23, slotNr := 42 };
f_rspro_srv_create_slotmap(cs, bs);
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}
/* attempt to create a mapping for a slot that already has a mapping */
testcase TC_createMapping_busySlot() runs on bankd_test_CT {
f_init();
as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
f_rspro_srv_reset_state(ok);
var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
var ClientSlot cs := { clientId := 23, slotNr := 42 };
/* create the mapping the first time */
f_rspro_srv_create_slotmap(cs, bs);
/* re-create the mapping a second time */
f_rspro_srv_create_slotmap(cs, bs);
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}
/* attempt to create a mapping for an out-of-range slot number */
testcase TC_createMapping_invalidSlot() runs on bankd_test_CT {
f_init();
as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
f_rspro_srv_reset_state(ok);
var BankSlot bs := { bankId := mp_bank_id, slotNr := 200 };
var ClientSlot cs := { clientId := 23, slotNr := 42 };
f_rspro_srv_create_slotmap(cs, bs, exp_res := illegalSlotId);
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}
/* attempt to create a mapping for an invalid bankID */
testcase TC_createMapping_invalidBank() runs on bankd_test_CT {
f_init();
as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
f_rspro_srv_reset_state(ok);
var BankSlot bs := { bankId := 200, slotNr := 0 };
var ClientSlot cs := { clientId := 23, slotNr := 42 };
f_rspro_srv_create_slotmap(cs, bs, exp_res := illegalBankId);
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}
/* attempt to remove a non-existant mapping */
testcase TC_removeMapping_unknownMap() runs on bankd_test_CT {
f_init();
as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
f_rspro_srv_reset_state(ok);
var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
var ClientSlot cs := { clientId := 23, slotNr := 42 };
f_rspro_srv_remove_slotmap(cs, bs, exp_res := unknownSlotmap);
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}
/* add and then remove a mapping, expect both to be successful */
testcase TC_removeMapping() runs on bankd_test_CT {
f_init();
as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
f_rspro_srv_reset_state(ok);
var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
var ClientSlot cs := { clientId := 23, slotNr := 42 };
f_rspro_srv_create_slotmap(cs, bs);
f_rspro_srv_remove_slotmap(cs, bs);
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}
/* connect from client to bankd without specifying a clientId */
testcase TC_clientConnect_missingSlot() runs on bankd_test_CT {
f_init_client(0);
RSPRO[0].send(ts_RSPRO_ConnectClientReq(rspro[0].rspro_id, omit));
f_rspro_exp(tr_RSPRO_ConnectClientRes(?, ResultCode:illegalClientId), 0);
f_rspro_exp_disconnect(0);
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}
/* connect from client to bankd using a clientId for which bankd has no map */
testcase TC_clientConnect_unknown() runs on bankd_test_CT {
f_init_client(0);
f_rspro_connect_client(0, tr_Status_ok_or_nocard);
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}
/* connect from client to bankd using a clientSlot for which bankd has no map */
/* first connect client, then later add matching mapping from server */
testcase TC_clientConnect_createMapping() runs on bankd_test_CT {
f_init_client(0);
f_rspro_connect_client(0, tr_Status_ok_or_nocard);
f_init();
as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);
f_sleep(10.0);
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}
/* first add mapping, then connect matching client */
testcase TC_createMapping_clientConnect() runs on bankd_test_CT {
/* FIXME: this would only be done in f_init_client(), but we need it before */
rspro[0].rspro_client_slot := { clientId := 23+0, slotNr := 0 };
f_init();
as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
f_rspro_srv_reset_state(ok);
var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);
f_sleep(1.0);
f_init_client(0);
f_rspro_connect_client(0, tr_Status_ok_or_nocard);
/* FIXME: how to determine that bank correctly mapped us */
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}
/* first add mapping, then connect client, then change mapping (expect disconnect) */
testcase TC_createMapping_connectClient_changeMapping() runs on bankd_test_CT {
/* FIXME: this would only be done in f_init_client(), but we need it before */
rspro[0].rspro_client_slot := { clientId := 23+0, slotNr := 0 };
f_init();
as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
f_rspro_srv_reset_state(ok);
/* create slotmap */
var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);
f_sleep(1.0);
/* connect client */
f_init_client(0);
f_rspro_connect_client(0, tr_Status_ok_or_nocard);
/* FIXME: how to determine that bank correctly mapped us */
/* create another mapping for the same bank-slot */
var ClientSlot cs := { clientId := 987, slotNr := 654 };
f_rspro_srv_create_slotmap(cs, bs);
/* expect client to be disconnected */
timer T := 5.0;
T.start;
alt {
[] RSPRO[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
setverdict(pass);
}
[] RSPRO[0].receive {
setverdict(fail, "Unexpected RSPRO on client connection");
}
[] T.timeout {
setverdict(fail, "Timeout waiting for client being disconnected");
}
}
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}
/* first add mapping, then connect client, then re-crete mapping (expect no disconnect) */
testcase TC_createMapping_connectClient_recreateMapping() runs on bankd_test_CT {
/* FIXME: this would only be done in f_init_client(), but we need it before */
rspro[0].rspro_client_slot := { clientId := 23+0, slotNr := 0 };
f_init();
as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
f_rspro_srv_reset_state(ok);
/* create slotmap */
var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);
f_sleep(1.0);
/* connect client */
f_init_client(0);
f_rspro_connect_client(0, tr_Status_ok_or_nocard);
/* FIXME: how to determine that bank correctly mapped us */
/* re-create same mapping for the same bank-slot */
f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);
/* expect client not to be disconnected */
timer T := 5.0;
T.start;
alt {
[] RSPRO[0].receive(tr_ASP_IPA_EV(ASP_IPA_EVENT_DOWN)) {
setverdict(fail, "Unexpected client disconnect");
}
[] RSPRO[0].receive {
repeat;
}
[] T.timeout {
setverdict(pass);
}
}
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}
/* add mapping, connect matching client, disconnect + reconnect */
testcase TC_createMapping_clientReconnect() runs on bankd_test_CT {
/* FIXME: this would only be done in f_init_client(), but we need it before */
rspro[0].rspro_client_slot := { clientId := 23+0, slotNr := 0 };
f_init();
as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
f_rspro_srv_reset_state(ok);
var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);
f_sleep(1.0);
f_init_client(0);
f_rspro_connect_client(0, tr_Status_ok_or_nocard);
/* TODO: works only with empty slot, as setAtrReq isn't handled */
/* FIXME: how to determine that bank correctly mapped us */
f_sleep(5.0);
f_rspro_fini(rspro[0], 0);
f_init_client(0);
f_rspro_connect_client(0, tr_Status_ok_or_nocard);
/* FIXME: how to determine that bank correctly mapped us */
f_sleep(5.0);
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}
/* remove mapping while client is connected */
testcase TC_removeMapping_connected() runs on bankd_test_CT {
f_init_client(0);
f_rspro_connect_client(0, tr_Status_ok_or_nocard);
/* TODO: works only with empty slot, as setAtrReq isn't handled */
f_init();
as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);
/* FIXME: how to determine that bank correctly mapped us */
f_sleep(5.0);
f_rspro_srv_remove_slotmap(rspro[0].rspro_client_slot, bs);
f_rspro_exp_disconnect(0);
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}
private altstep as_vpcd() runs on VPCD_Adapter_CT {
[] VPCD.receive(tr_VPCD_Recv(g_vpcd_conn_id, tr_VPCD_CTRL_ATR)) {
f_vpcd_send(ts_VPCD_DATA('3B9F96801FC78031A073BE21136743200718000001A5'O));
repeat;
}
[] VPCD.receive(tr_VPCD_Recv(g_vpcd_conn_id, tr_VPCD_CTRL_OFF)) {
repeat;
}
[] VPCD.receive(tr_VPCD_Recv(g_vpcd_conn_id, tr_VPCD_CTRL_ON)) {
repeat;
}
}
/* transceive a TPDU from modem to card (and back) */
function f_rspro_xceive_mdm2card_vpcd(integer idx, BankSlot bs, template (value) octetstring data,
template (value) TpduFlags flags, template (value) octetstring res) runs on bankd_test_CT return octetstring {
var RsproPDU rx;
RSPRO[idx].send(ts_RSPRO_TpduModemToCard(rspro[idx].rspro_client_slot, bs, flags, data));
f_vpcd_exp(tr_VPCD_DATA(data));
f_vpcd_send(ts_VPCD_DATA(res));
rx := f_rspro_exp(tr_RSPRO_TpduCardToModem(bs, rspro[idx].rspro_client_slot, ?, ?));
if (rx.msg.tpduCardToModem.data != valueof(res)) {
setverdict(fail, "Expected ", res, " from card, but got ", rx.msg.tpduCardToModem.data);
}
return rx.msg.tpduCardToModem.data;
}
/* first add mapping, then connect matching client and exchange some TPDUs */
testcase TC_createMapping_exchangeTPDU() runs on bankd_test_CT {
/* FIXME: this would only be done in f_init_client(), but we need it before */
rspro[0].rspro_client_slot := { clientId := 23+0, slotNr := 0 };
VPCD_Adapter.f_connect();
activate(as_vpcd());
f_sleep(2.0);
f_init();
as_connectBankReq(bid := mp_bank_id, nslots := mp_num_slots);
f_rspro_srv_reset_state(ok);
var BankSlot bs := { bankId := mp_bank_id, slotNr := 0 };
f_rspro_srv_create_slotmap(rspro[0].rspro_client_slot, bs);
f_sleep(1.0);
f_init_client(0);
f_rspro_connect_client(0, ok);
/* FIXME: how to determine that bank correctly mapped us */
f_rspro_exp(tr_RSPRO_SetAtrReq(rspro[0].rspro_client_slot, ?));
var TpduFlags f := {tpduHeaderPresent:=true, finalPart:=true, procByteContinueTx:=false,
procByteContinueRx:=false};
for (var integer i := 0; i < 10; i:=i+1) {
f_rspro_xceive_mdm2card_vpcd(0, bs, 'A0A40000023F00'O, f, '9000'O);
}
Misc_Helpers.f_shutdown(__BFILE__, __LINE__, pass);
}
control {
execute( TC_connectBankReq_timeout() );
execute( TC_connectBankReq() );
execute( TC_createMapping() );
execute( TC_createMapping_busySlot() );
execute( TC_createMapping_invalidSlot() );
execute( TC_createMapping_invalidBank() );
execute( TC_removeMapping_unknownMap() );
execute( TC_removeMapping() );
execute( TC_clientConnect_missingSlot() );
execute( TC_clientConnect_unknown() );
execute( TC_clientConnect_createMapping() );
execute( TC_createMapping_clientConnect() );
execute( TC_createMapping_clientReconnect() );
execute( TC_removeMapping_connected() );
execute( TC_createMapping_connectClient_changeMapping() );
execute( TC_createMapping_connectClient_recreateMapping() );
execute( TC_createMapping_exchangeTPDU() );
}
}