一些概念

Component(測试组件或者測试成分),TTCN接触下来最频繁的就是MTC(Main Test Component,主測试组件),在执行測试用例前,须要首先创建一个MTC。在testcase执行过程中。仅仅能有唯一的MTC。

假设没有指明testcase须要runs on在某个Component。系统默认的component就是MTC。在testcase代码中。不能控制MTC的建立与停止。

非主測试组件的測试组件叫PTC(ParallelTest Component, 并行測试组件), PTC是由testcase控制的,最后由系统销毁。testcase能够运行create。start,stop等操作 。

简单说,一个PTC就能够理解为TTCN模拟出来的一台远程主机的进程。通过它。模拟出其它主机实现并行測试。

而測试组件之间,通过通信port实现通信。

一个简单的样例

这个testcase中,简单运行:

telnet_IPworks();
//check if every port configuration is right
startClient(tsp_ptcClientName0); //在这里启动名为tsp_ptcClientName0的PTC
startClient(tsp_ptcClientName1);
startClient(tsp_ptcClientName2);
startClient(tsp_ptcClientName3);
startClient(tsp_ptcClientName4); startClient(tsp_ptcClientName11);

sendCommand_byPTC("date ",tsp_ptcClientName11,2.2);

PCT和startClient的实现(common/CLI/CLI_Function.ttcn.linux):

//定义了接下来须要使用的PTC,相似C中的结构体概念
type component PTC_CT
{
port TELNETasp_PT telnet_client_port; //与ipwork測试系统接口通信的端口
port ProcePort managePort; //与mtc通讯的端口 var BatchCommand tcv_batchCommand; //if tcv_bcheckBatchResp== true ,check BatchCommad's Response from SUT ,or not
var boolean tcv_bcheckBatchResp := true;
} function startClient(charstring p_ClientName) runs on MTC_CT
{
//initial PTC
//假设没有初始化PTC的列表,则依据ipwork.cfg中定义的tsp_ptcClientName*名。初始化若干PTC备用 if(tcv_isPTCInitial == false)
{
// PTC_CT.create(tsp_ptcClientName0)建立一个名为tsp_ptcClientName0的PTC。但不启动
ptcClientName[0]:= PTC_CT.create(tsp_ptcClientName0);
ptcClientName[1]:= PTC_CT.create(tsp_ptcClientName1);
ptcClientName[2]:= PTC_CT.create(tsp_ptcClientName2);
ptcClientName[3]:= PTC_CT.create(tsp_ptcClientName3);
ptcClientName[4]:= PTC_CT.create(tsp_ptcClientName4);
ptcClientName[5]:= PTC_CT.create(tsp_ptcClientName5);
ptcClientName[6]:= PTC_CT.create(tsp_ptcClientName6);
ptcClientName[7]:= PTC_CT.create(tsp_ptcClientName7);
ptcClientName[8]:= PTC_CT.create(tsp_ptcClientName8);
ptcClientName[9]:= PTC_CT.create(tsp_ptcClientName9);
ptcClientName[10]:= PTC_CT.create(tsp_ptcClientName10);
ptcClientName[11]:= PTC_CT.create(tsp_ptcClientName11);
tcv_isPTCInitial := true; //have been intialed
} //获取名为p_ClientName的PTC引用p_ptcClient
var PTC_CT p_ptcClient := getCurrentPTC(p_ClientName);
log(getCurrentPTC(p_ClientName)); //假设p_ptcClient已经停止执行
if(false == p_ptcClient.running)
{
//利用map,将測试组件p_ptcClient映射到ipwork測试系统接口上,system是測试系统的组件引用
map(p_ptcClient:telnet_client_port,system:telnet_client_port);
//connect直接把p_ptcClient的端口managePort连接到mtc的managePort端口,
//这样建立一条双工的通信关系
connect(p_ptcClient:managePort,mtc:managePort);
//启动PTC引用p_ptcClient。启动后执行CliSimulator()
p_ptcClient.start(CliSimulator());
pause(1.0);
}
//sendCommand_byPTC("ipwcli",p_ClientName,0.2);
//sendCommand_byPTC(tsp_user_admin,p_ClientName,0.2);
//sendCommand_byPTC(tsp_adminpassword,p_ClientName,1.2);
}

startClient首先检查PCT的存储容器ptcClientName是否被初始化。假设没有,则依据配置文件ipwork.cfg中设定的名字,create(两个概念,这里仅仅是create,而不start)若干PCT引用填入ptcClientName备用。

然后,依据參数p_ClientName获取对应的PCT引用。

随后。调用p_ptcClient.running检測,p_ptcClient是否在执行(running执行在一个測试部件上检查还有一个測试部件是否执行,这里实在mtc上检查p_ptcClient)。

假设没有执行,则依次执行map和connect。map为p_ptcClient与ipwork之间建立映射 ,connect为mtc和p_ptcClient建立一个双工的通信关系,即mtc的输出口指向p_ptcClient的输入口。p_ptcClient的输出口指向mtc的输入口。然后,执行p_ptcClient.start启动PTC,PTC启动后执行的就是start的參数CliSimulator()。如同pthread_create或者exec执行线程或进程函数一样。

我们已经启动了新的PTC,那么看看p_ptcClient的CliSimulator()里面到底运行了那些东西:

function CliSimulator() runs on PTC_CT
{
var charstring command := "";
var charstring result := "";
var charstring keyWords := "";
timer t := 5.0;
alt
{
//依据模板signature sig_Command(inout charstring p_Command),等待还有一个測试组
//件的调用请求。远程调用时传入的參数p_Command将被赋予command。这里的managePort就是
//之前mtc与p_ptcClient建立关联的端口。那么这里就是等待mtc的调用
[]managePort.getcall(sig_Command:{?}) -> param(command)
{
//依据mtc的command,telnet_client_port 即之前map建立的p_ptcClient与
//ipwork建立的关联, telnet_client_port.send(command)将把mtc传来的command转发//给ipwork
telnet_client_port.send(command);
repeat;
} //Batch command operation
[]managePort.getcall(sig_BatchCommand:{?,?,?}) -param(tcv_batchCommand,keyWords,tcv_bcheckBatchResp)
{
var integer number := sizeof(tcv_batchCommand);
for(var integer i:=0;i<number;i:=i+1)
{
telnet_client_port.send(tcv_batchCommand[i]);
if(tcv_bcheckBatchResp == true)
{
t.start; //启动计时器
alt
{
//接收到回复
[]telnet_client_port.receive(charstring:?) -> value result; { //返回值与keyword比較
result := regexp(result,"*("&keyWords&")*",0); t.stop; //关闭计时器
//错误结果
if(result == "")
{
log(tcv_batchCommand[i]," fail");
setverdict(fail); //设置測试失败
stop; //停止当前component
}
else if(result == keyWords)
{
log("Execute command:",tcv_batchCommand[i]," success");
} }
[]t.timeout //超时
{
log("Time out ,don't receive Response from SUT.fail");
setverdict(fail);
stop;
}
} telnet_client_port.clear; }
}
//调用sig_sendBatchcommandFinished。不等待。直接运行下一步 managePort.call(sig_sendBatchcommandFinished:{},nowait);
repeat; }
[]telnet_client_port.receive(charstring:? ) -> value result
{
managePort.call(sig_Command:{result},nowait);
repeat;
}
[]telnet_client_port.receive
{
repeat;
} }
}

这里的alt是可选步,如同一个switch的消息循环,每一个case选项或是等待远程过程调用请求,或是等待接受数据。假设有请求或者传输数据,程序就会跳进相应的case,,这里主要关心[]managePort.getcall(sig_Command:{?}) ->param(command)

getcall等待远程的call。managePort就是之前mtc与p_ptcClient建立关联的端口,那么这里就是等待mtc的call调用,依据module CLI_Signature中定义的函数原型signature sig_Command(inout charstring p_Command),mtc远程call时传入的參数p_Command将被赋予command。telnet_client_port
即之前map建立的p_ptcClient与ipwork建立的关联, telnet_client_port.send(command)将把mtc传来的command转发给ipwork。

这样就完毕了,从mtc传送命令交由模拟的PTC转发给ipwork測试系统接口的过程。以下的[]managePort.getcall(sig_BatchCommand也大体类似。仅仅是将一串命令打包运行。

最后看下mtc中怎样调用p_ptcClient的方法 ,使用sendCommand_byPTC("date ",tsp_ptcClientName11,2.2),它的作用就是通过名为tsp_ptcClientName11的PTC发送date给ipwork:

function sendCommand_byPTC(charstring p_Command,charstring p_ClientName,float p_pause) runs on MTC_CT
{
var PTC_CT p_ptcClient;
p_ptcClient := getCurrentPTC(p_ClientName); //获取名为p_ClientName的PTC引用
//调用managePort通信的远程方法。方法模板sig_Command。传入參数p_Command
managePort.call(sig_Command:{p_Command},nowait) to p_ptcClient;
pause(p_pause);
}

这里首先获取了获取名为p_ClientName的PTC引用,然后利用managePort调用远程方法(也就是mtc与p_ptcClient关联的port),这里的远程方法会到p_ptcClient中去找模板为sig_Command的方法,也就是之前提到的CliSimulator()中相关内容。

TTCN中PTC的执行流程的更多相关文章

  1. shell中命令的执行流程

    在shell中,一个命令有3中写法: 1 可以直接写(Normal Command) 2 可以放在双引号中("Command") 3 可以放在单引号中('Comand') 这3中写 ...

  2. Springmvc中的HandlerAdaptor执行流程

    今天讲解一下在Springmvc中的HandlerAdaptor执行流程,明白这个过程,你就能画出下面的图: 接下来我们就来看看具体的实现过程吧. 1.0在DispatcherServlet中找到ge ...

  3. Django 中 admin 的执行流程

    Django 中 admin 的执行流程 1 循环加载执行所有已经注册的 app 中的 admin.py 文件 def autodiscover(): autodiscover_modules('ad ...

  4. 深入理解java中HelloWorld的执行流程

    HelloWorld.java是我们学习java的第一个程序,简单的再也不能简单了,可是里面的原理以及执行流程大家都知道吗?最近在复习java知识,特地钻研了一番分享给大家! 贴出HelloWorld ...

  5. Linux中Shell的执行流程

    Shell执行流程 1.Printthe info of reminding 打印提示信息 2.Waitinguser for input(wait) 等待用户输入 3.Acceptthe comma ...

  6. 【u-boot】u-boot中initf_dm()函数执行流程(转)

    前部分设备模型初始化 为了便于阅读,删掉部分代码,只留关键的过程: static int initf_dm(void){    int ret;    ret = dm_init_and_scan(t ...

  7. Servlet中过滤器的执行流程

  8. 死磕 java线程系列之线程池深入解析——普通任务执行流程

    (手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:线程池源码部分如无特殊说明均指ThreadPoolExecutor类. 简介 前面我们一起学习了Java中 ...

  9. 死磕 java线程系列之线程池深入解析——未来任务执行流程

    (手机横屏看源码更方便) 注:java源码分析部分如无特殊说明均基于 java8 版本. 注:线程池源码部分如无特殊说明均指ThreadPoolExecutor类. 简介 前面我们一起学习了线程池中普 ...

随机推荐

  1. 【HBase】Rowkey设计【转】

    本章将深入介绍由HBase的存储架构在设计上带来的影响.如何设计表.row key.column等等,尽可能地使用到HBase存储上的优势. Key设计 HBase有两个基础的主键结构:row key ...

  2. tortisegit 创建分支和合并分支

    第一步:创建本地分支 点击右键选择TortoiseGit,选择Create Branch…,在Branch框中填写新分支的名称(若选中”switch to new branch”则直接转到新分支上,省 ...

  3. VC++编程之道读书笔记(2)

    第三篇 技术细节 第七章:细说开发人员必知必会的39个开发细节 细节36:单例模式的应用 在开发程序时,往往需要在整个工程中只需要一个类的实例.而这个实例一旦被创建就不能被其他的实例再创建了,通常我们 ...

  4. VC++编程之道读书笔记

    第二篇 缪误21:位图数据是按照红绿蓝顺序存储的 大家都知道位图的颜色是由红.绿.蓝三个分量构成的,但是位图颜色数据存储的方式则不是按照这个顺序存储的,而是按照蓝.绿.红的顺序存储的.并且对于真彩色位 ...

  5. (function($){...})(jQuery)是什么意思?

    本文转自:http://blog.csdn.net/rambo_china/article/details/7742321 最近在工作中看到这调用定义方法,并且同时调用的方式,觉得很疑惑,看到这篇博客 ...

  6. 按关键字搜索自己的CSDN博客

    CSDN居然没有搜索自己博客的功能!如果博客写多了后将很难查找. 搜到的办法居然要靠谷歌... 在谷歌输入关键词,格式如下: <要检索的关键词> site:blog.csdn.net/&l ...

  7. C语言 · 素数求和

    算法提高 素数求和   时间限制:1.0s   内存限制:256.0MB      问题描述 输入一个自然数n,求小于等于n的素数之和 样例输入 2 样例输出 2 数据规模和约定 测试样例保证 2 & ...

  8. java-JSP脚本的9个内置对象

    http://blog.csdn.net/titilover/article/details/6800782 http://www.importnew.com/19128.html http://ww ...

  9. VMware 14 Pro 安装 CentOS 7

    今年准备好好学习一下.NET CORE了,那也是得学习Linux.然后又得学习更多,咬着牙干吧... 1.Vmware虚拟机安装 在windows平台,首先咱们得先安装Vmware虚拟机,步骤省略,一 ...

  10. 数据库 Oracle数据库性能优化

    --在Oacle数据库涉及到全表扫描的SQL查询(top,count)中, --现场用户删除表中大部分数据,只保留1W条数据,但是查询仍然很慢,检查磁盘IO,发现磁盘IO不是很高 --经过分析Oacl ...