zoukankan      html  css  js  c++  java
  • TTCN中PTC的执行流程

    一些概念

    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()中相关内容。



  • 相关阅读:
    AutoFac
    MEF 基础简介 四
    MEF 基础简介 三
    MEF 基础简介 二
    MEF 基础简介 一
    Ioc原理理解
    .NET里面 abstract class和Interface有什么区别以及用法的展现?
    .NET-ORM框架EF-Code First代码优先
    SQL SERVER PIVOT与用法解释
    SQL Server 中的 NOLOCK 到底是什么意思?
  • 原文地址:https://www.cnblogs.com/lxjshuju/p/6724331.html
Copyright © 2011-2022 走看看