吴惠妍
(北京全路通信信号研究设计院集团有限公司,北京 100070)
随着软件复杂度的增加,传统的软件开发方法已不能满足效率和安全性的需求。为解决这一不足,高安全应用开发环境SCADE应运而生,SCADE已普遍应用于航空航天、国防、轨道交通等对安全性要求极高的领域。SCADE开发的模型在经过模型仿真以及模型测试后可直接生成高安全性的代码。
SCADE模型仿真和测试普遍采用人工编辑输入数据测试的方式,这使得大多数的测试只能手动进行,没有测试辅助工具或者测试脚本支持数据生成。而且人工编辑的数据由于其与真实数据存在差异,测试环境的保真度差,这也会导致不确定或者不正确的测试结果(假阳性和假阴性结果)。此外,在与外部实物环境进行联合测试时,需要编译并装载(load)到目标平台上,如果发现新的缺陷(bug),则需要返回模型再次修改,如图1所示,开发、仿真、测试效率亟待提高。
图1 传统仿真流程Fig.1 Traditional simulation process
如果在模型设计阶段就能将模型与外部实物环境进行互联,测试环境的仿真度得以提高,进而减少模型生成代码编译后装载到平台上产生的错误,这样测试也不会被视作发生在瀑布开发周期后期的一个阶段,而是不断发生在迭代、增量和并发开发周期的持续性活动完成快速迭代。实物接入在线仿真环境如图2所示。关键技术在于模型如何与外部实物通信。
图2 实物在线仿真Fig.2 Online physical simulation
SCADE自带的模型库不包含与外界进行通信的模块,需要进行单独开发。与外界通信有多种方式,如基于以太网的UDP、TCP通信、串行通信等,本文以最常用的通信为例,阐述SCADE与外界通信的实现方式。
UDP发送模块中包含数据拷贝模块,该模块用于将变长的数据格式化为固定长度的数据,UDP发送模块是导入代码模块,是由人工编写代码的方式采用C语言实现的socket通信,实现根据socket句柄、IP地址及端口号完成UDP数据的发送。
该UDP通信模块实现与外部实物互联,其特点在于:1)支持数据录播及回放功能,可以提高回归测试自动化的程度;2)UDP通信IP地址和端口号可配置;3)UDP通信模块支持多路链接,且链路之间相互独立,没有任何依赖及干扰。
UDP通信接收子模块共有3个分支,其中,第1个分支由UDP信息接收(updRecvElt)操作符、数据录入(dataSava)操作符构成,该分支用于实物环境下的仿真,并同时录制数据;第2个分支由数据下载(dataLoad)操作符构成,该分支用于离线环境的实现数据回放;第3个分支由UDP信息接收(updRecvElt)操作符构成,该分支用于仅在实物环境下的仿真,不需要录制数据的场景。
关键部分包含UDP信息接收操作符、数据录入操作符、数据下载操作符,这3个操作符均为导入代码模块(Imported Operator),是由人工编写C代码导入实现的。其中,UDP信息接收操作符用于根据socket句柄及端口号完成UDP数据的接收;数据录入操作符用于完成每个测试用例中测试数据的记录,每一次记录形成一个以"testcase*"命名的文件夹,各端口收集的数据分别存储到不同的命名为"data*.csv"的文件中,如图3所示,数据下载操作符用于完成数据的回放,当选择回放记录条目后,该模块会读取对应的"data*.csv"的数据并载入仿真环境中。
图3 数据记录格式Fig.3 Data record format
接口设计时采用参数配置的方式。配置参数包括端口"port",IP地址"add*",数据长度"dataLen",如图4所示,使用相关模块时,仅需在模块属性对话框中进行参数设置即可。
图4 接口设计Fig.4 Interface design
被测模型可能同时存在多个与外界通信的接口,且各通信之间需要相互独立,不能相互依赖及干扰,因此UDP通信模块将socket句柄交由外部模型来管理。UDP通信模块申请socket句柄之后将套接字句柄(socketHander)交由SCADE的"last"变量保存,如图5所示中的"last’socketHandler"。这样多个UDP连接可以通过同一个UDP信息接收模块分时复用,在不同时刻通过输入不同的套接字句柄来实现,UDP通信由模型的输入参数(socketHanderIn)决定。
图5 socketHandler处理Fig.5 socketHandler processing
SCADE有数据流图和安全状态机两套建模机制,分别适合于连续系统和离散系统建模。本文提供的模型与实物联合仿真测试框架采用状态机来实现,状态机中有4个状态。
1)初始(init)状态包含索引(indexPlus)操作符。在实物环境下仿真测试时会记录多个测试用例(testcase*)。索引操作符用于选定仿真过程从哪个测试用例开始载入数据。
2)数据回放状态(dataReplay)包含无数据(noData)模块和被测模块环境(testEnv)。无数据模块用于判定所选取的数据包(一个测试用例中可能有多个数据包)是否已读完,只在有数据的时候才能激活。而被测模块环境是对被仿真模块搭建的仿真环境,被仿真测试模型SystemUT有6个通信连接,因此为其搭建了对应的仿真测试环境模块。被仿真测试模型环境内嵌到一个初始化操作符中,切换到新的测试用例之前要先初始化被测对象的仿真环境。
3)新用例(newCase)状态用于在本测试用例的数据包数据读完之后切换至下一个测试用例,当测试用例全部读完并仿真后,进入终止(finish)状态。
4)终止(finish)状态,仿真结束。
整个仿真测试流程如图6所示。从第一个测试用例开始测试过程,遍历测试用例中所有数据包中的数据并发送给被测对象,在每个测试用例测试结束后,需要进行测试仿真环境的初始化,以便准备下一个测试用例。这样迭代直至所有测试用例执行完毕,测试结束。
图6 测试框架工作流程Fig.6 Test framework workflow
相比仅在SCADE内部做模型仿真测试,与外部实物环境的联合仿真有更多优势:
1)模型测试能够获得更真实的测试数据输入;
2)省去了繁重的手工编辑测试数据的工作,保证数据的有效性,测试变得更加便捷快速;
3)数据记录和回放功能使得仿真测试可以脱离外部实物环境也能进行同样真实度的仿真测试;
4)在数据记录完之后的回归测试更加方便,可实现自动化。