• 沒有找到結果。

4.   實作與實驗結果

4.1   F RAMEWORK

Figure 4.1 Framework

整個 framework 的工作環境,都是由 BPEL 與 web services 建立而成。而我們的 系統是使用 axis2 這個套件來產生的。我先稍為簡介一下 axis2,apache axis2[25]

是一個 web 服務的核心支援引擎。之前版本是 axis。在 2004 年 8 月的會議討論 之後,正式確定新的架構。新的 axis2 是根據 axis1.x 改寫而來,而且提供 Java 與

C 兩種開發版本,axis2 比起原本的 Axis 更靈活更有效能。因為 axis2 使用更多模 組化的觀念,當你有一些特別的功能或是一些安全性的需求,可以直接以模組 (module)的方式添加進去。另外就是安全性的問題,web service 可靠信息服務由 apache sandesha2 支持 WS-Coordination,而 WS-Atomic Transaction 由 apache

47

kandula2 支持 WS-Security,由 apache rampart 支持 WS-Addressing 已包括作 axis2 在為核心模組。而且 axis2 現在還支持異步 Web 服務和異步 Web 服務調用並使用 非阻塞的客戶端,這對於一些應用相當有幫助。而且 axis2 又可容易可以跟 tomcat 結合,所以是相當多 web service 實作平台的首選。

以下是我實作的幾個部分,一一的跟大家介紹:

Test Script:test script 為一個 XML 檔案,作為其執行的腳本。agent 在執行的時

候就直接讀取 test script 做為 input 的 value。最大的作用就是可以達到自動化驗證 的目的,不用再等使用者輸入。而且當要改變 value 時,只要修改 test script 就可 以了,code 的修改幾乎都不用再變動了,我覺得這是在做 testing 之時一個蠻方便 的設計。以下為一個 test script 的 example。

<?xml version="1.0" encoding="UTF-8"?>

<TestScript>

<Application>

<ParticipantBehavior>

<ProcessName>0</ProcessName>

<Peterson1>

<Participant>

<PrcID>0</PrcID>

<flag0>1</flag0>

48

<flag1>0</flag1>

<turn>1</turn>

</Participant>

</Peterson1>>

<ProcessName>1</ProcessName>

<Peterson2>

<Participant>

<PrcID>1</PrcID>

<flag0>0</flag0>

<flag1>1</flag1>

<turn>1</turn>

</Participant>

</Peterson2>>

</ParticipantBehavior>

<OutputVerificaton>

<REGEX>Case\\s[0-9]*\\sis\\sOk|Case\\s[0-9]*\\sis\\sReject</REGEX>

49

</OutputVerificaton>

</Application>

</TestScript>

Figure 4.2 TestScript

<ParticipantBehavior>這個結構之內,就是那些原本應該是需要人輸入的一些資訊,

因為裡面可能會有不只一組以上的輸入,所以會使用一些 tag 將其做區分。例如:

<Peterson1>,<Peterson2>就是代表兩組不同的 input。而<Participant>之中就是那些 input 的資料,分別會有一些欄位名跟數值。<OutputVerificaton>這個結構之內,

有一個<REGEX>的 tag,這個 tag 就是存放 java regular expression 的 pattern 在裡 面。

Agent:agent 為一個 java 程式,做為一個 client 端的啟動程式。當開始執行時,

會先啟動 inputreader 這個 function,利用 DOM 的技術,讀進 test script 中的資料。

將這些資料送入發送 web services 的 petersonthread 之中,做為 request 的 input 值。

接下來 petersonthread 就是將 request 利用 service 的 operation 將 request 發送到

BPEL process 當中,然後開始執行整個 BPEL process 的運作。當全部的 process 都執行完了以後,BPEL process 就會發送 response 給 agent。當 agent 收到 response 之後,我們會使用 java 的 regular expression 來驗證 response 所回傳的訊息是不是 我們所預期的。

Proxy:proxy 這個 web services,我是採用 apache axis2 結合 eclipse 的 axis2 code

50

generator 來製作的。proxy 在這個 system 當中,扮演非常重要的角色。原本正常 來說,應該是 BPEL process 直接發送 request 到 web services provider 就可以了,

並不需要一個 proxy。但是因為我們要 testing 的關係,所以必須多加一個 proxy 在 web services provider 之前,來運作 reachability testing。不過也因為這樣,原本 的 BPEL process 必須要做修改,將 invoke activity 的 WSDL 做一個修改,讓它發 送到 proxy 去。當 BPEL process 發送 request 到 proxy 之後,這時候因為 proxy 本 身就是一個 web service 的關係,所以當有一個 request 送到 proxy 來了之後。proxy 會另外啟動一個 thread 來處理這個 request,這樣才可以繼續監聽原本的 port,並 不會因為一個 request 就把整個 service 給占住了。所以我們的 proxy 是一個

multithread 的環境,所以我們在 proxy 之中就要利用 entry protocol 與 exit protocol 來記錄每個 request 存取 share object 的狀況。我們在 entry protocol 裡面使用了 semaphore 來保護同一個時間,只有一個 thread 可以進入 critical section 存取到 share object data。而我們的 entry protocol 與 exit protocol,會將存取的 share object 的資料 log 起來。內容包括 prcid、valuename、versionnumber、value、locctr,我 們將這些資料收集起來之後稱做 event history。當 BPEL process 都執行完畢之後,

我們會將每一個 proxy 的 event history 都收集起來,然後開始進行 race variants 的 分析。然後再根據推出來的 race variants 在執行一次 BPEL process,這樣的動作 會一直執行下去,這個動作稱為 prefixbased replay,直到 race variants 都執行到沒 有為止。當所以動作都完成了,代表這個 testing 的動作也完全執行完畢了,這時

51

就會 BPEL process 就會回應 agent 一個 response 結束這個程式。

BPEL:我們的 application 都是使用 BEPL 來建構,而我們採用的 BPEL engine

是 activeBPEL[26]。由於他目前是 open source 加上 activeBPEL 幾乎就是 BPEL

engine 的代表,許多目前一些開發的 BPEL 產品的基型,幾乎都是參考 activeBPEL,

於是我們也採用這一款代表性相當高的引擎。因為其有 GUI 介面的 editor,所以 建立起來並不困難,只要將原先建立好的 wsdl 根據需求,將他用適當的 activity 給 import 進去。再慢慢建立好整個 BPEL process,這樣 BPEL 文件也建立完成。

當文件建立好了之後,就要建立一個 pdd 來 deploy,由 pdd 加上 BPEL 的文件就 可以運作到 tomcat 之上。activeBPEL engine 本身並沒有辦法執行 asynchronous 的 message 的 transition。所以必須依賴 correlation set 來做一個 mapping 的動作。

correlation set 可以指定某幾個 wsdl 裡面的參數,互相 mapping 只有在參數相同的 時候才會讓另一個 receive activity 執行下去。可以參照下圖這個例子。當 invoke 的 message1 的 prcid 為 1,而如果送到 receive 的 message2 如果 prcid 為 2 的時候,

這時候 process 的執行就會 waiting 在 receive 那邊,直到 receive 收到 prcid 為 1 的 message,才會繼續執行下去。

52

Figure 4.3 Correlation set

Dynamic effective testing:由於我們將測試時所需的數據收集完成之後,還是必

須依賴 Dynamic effective testing 來做 race variant 的分析。當整個 SOA applications 全部執行完一次之後,我們寫了一個 Testmain 的 method 來執行 Dynamic effective

testing。一開始先進行 state analyzer,把之前收集來的 syn-squence,進行 function 的轉換,避免有重複的 state 也放進去進行 race analyzer。

PSEGJointNodes tmpJntPnts = new PSEGJointNodes();

tmpJntPnts.get(ExecLogRG);

Figure 4.4 state analyzer

接下來就進行 race analyzer,當進行 state analyzer 之後,如果產生的數量為零的 話就不用進行 race analyzer。反之,就進行 race analyzer 來推導出 race variant。產 生 race variant 之後,將 race variant 放入 RVQueue 當中。

53 if(tmpJntPnts.size()==0)

System.out.println("A3TestMain: Error! No Group-Joint

node produced.");

else {

RaceGraphSet TransformedSYNSequences1 =

StateAnalyzer.exec(ExecLogRG);

genRVNum =

RaceVariant.MultiGen(TransformedSYNSequences1, RVQueue);

}

Figure 4.5 race analyzer

接下來就是每次取出一個 race variant 來進行 prefix based replay,再將每一次產生 的 syn-sequence 記錄下來,再次進行 race analyzer 來推導 race variant。這樣反覆 的執行,直到將 RVQueue 當中的 race variant 全部消除完畢,就算是完整的執行 dynamic effective testing。

while(RVQueue.size()!=0) {

for(RaceGraph tmpRV : RVQueue) {

RVQueue.remove(tmpRV);

RaceGraph tmpExecLogRG =

54 PrefixBasedReplay.perform(tmpRV);

if(PetersonThread.gotInfiniteLoop) {

NumOf_gotInftLoop = NumOf_gotInftLoop+1;

}

NumOfTest = NumOfTest + 1;

ExecLogSet.add(tmpExecLogRG);

PSEGJointNodes tmpJntPnts2 = new PSEGJointNodes();

tmpJntPnts2.get(tmpExecLogRG);

if(tmpJntPnts2.size()==0) {

genRVNum = 0;

System.out.println("Error! No Group-Joint node

produced.");

} else {

RaceGraphSet TransformedSYNSequences2 =

StateAnalyzer.exec(tmpExecLogRG);

genRVNum =

RaceVariant.MultiGen(TransformedSYNSequences2, RVQueue);

}

55

System.out.println("Test #" + NumOfTest +

": Generate " + genRVNum + " RVs, accumulate

" +

RVQueue.size() + " RVs, " +

NumOf_gotInftLoop + " tests got stuck in infinite loops.");

break;

}

}

Figure 4.6 test main

相關文件