Kiểm chứng giao thức biểu diễn giao thức ghi nợ ở một máy ATM

Một phần của tài liệu KIỂM CHỨNG ĐẶT TẢ UML CHO TÁC TỬ PHẦN MỀM (Trang 68 - 74)

ATM

6.2.2.1 Đặc tả giao thức

61

Giao thức mô tả tương tác giữa hai lớp AccountDBManager. Khi một đối

tượng Account gọi phương thức debit() một dãy các hàm được gọi phải tuân theo giao thức được định nghĩa để hoàn thành giao dịch:

Account.debit() -> Account.getBalance() -> DBManager.queryB() -> Account.setBalance() -> DBManager.updateB(). 6.2.2.2 Kiểm chứng aspect: import java.io.File; import java.util.*; import org.aspectj.lang.JoinPoint; import readXMI_SequenceDiagram.*;

public aspect ProtocolChecker {

int NUMBER_OF_CLASSES = 2;

SharedStateManager sm = new SharedStateManager(NUMBER_OF_CLASSES);

static HashMap<String, Set<String>> fsm = null;

static HashSet<String> entrySigs, exitSigs; ProtocolChecker(){

if (fsm == null) loadProtocol(); }

pointcut pc_Account_debit(): call (void Account.debit()) ;

before(): pc_Account_debit() {

Object o = thisJoinPoint.getTarget();

if (!sm.isBinded(o))

sm.newSharedState(o); }

after(): pc_Account_debit() {

String s = thisJoinPoint.getSignature().toString(); Object o = thisJoinPoint.getTarget();

log("change state: " + sm.getSharedState(o).getState() + " ---> " + s);

sm.setSharedState(o, s);

}

pointcut pc_DBManager_updateB_String(String str): args(str) && call

(void DBManager.updateB(String));

before(String str): pc_DBManager_updateB_String(str) {

Object o = thisJoinPoint.getTarget();

if (!sm.isBinded(o)) sm.bind(o);

String s = thisJoinPoint.getSignature().toString();

if (! isValidState(o, s)) {

log("Invalid change: " + sm.getSharedState(o).getState() + " ---> " + s);

log(thisJoinPoint); (adsbygoogle = window.adsbygoogle || []).push({});

} }

after(String str): pc_DBManager_updateB_String(str){

String s = thisJoinPoint.getSignature().toString(); Object o = thisJoinPoint.getTarget();

log("change state: " + sm.getSharedState(o).getState() + " ---> " + s);

if (exitSigs.contains(s)) sm.reset(o);

62

pointcut pc_DBManager_queryB_String(String str): args(str) && call

(int DBManager.queryB(String));

before (String str): pc_DBManager_queryB_String(str) {

Object o = thisJoinPoint.getTarget();

if (!sm.isBinded(o)) sm.bind(o);

String s = thisJoinPoint.getSignature().toString();

if (! isValidState(o, s)) {

log("Invalid change: " + sm.getSharedState(o).getState() + " ---> " + s);

log(thisJoinPoint);

} }

after(String str): pc_DBManager_queryB_String(str) {

String s = thisJoinPoint.getSignature().toString(); Object o = thisJoinPoint.getTarget();

log("change state: " + sm.getSharedState(o).getState() + " ---> " + s);

sm.setSharedState(o, s); }

pointcut pc_Account_getBalance(): call (int Account.getBalance());

before (): pc_Account_getBalance() {

Object o = thisJoinPoint.getTarget();

if (!sm.isBinded(o)) sm.bind(o);

String s = thisJoinPoint.getSignature().toString();

if (! isValidState(o, s)) {

log("Invalid change: " + sm.getSharedState(o).getState() + " ---> " + s);

log(thisJoinPoint);

} }

after(): pc_Account_getBalance() { (adsbygoogle = window.adsbygoogle || []).push({});

String s = thisJoinPoint.getSignature().toString(); Object o = thisJoinPoint.getTarget();

log("change state: " + sm.getSharedState(o).getState() + " ---> " + s);

sm.setSharedState(o, s); }

pointcut pc_Account_setBalance_int(int ba): args(ba) && call (void

Account.setBalance(int));

before (int ba): pc_Account_setBalance_int(ba) {

Object o = thisJoinPoint.getTarget();

if (!sm.isBinded(o)) sm.bind(o);

String s = thisJoinPoint.getSignature().toString();

if (! isValidState(o, s)) {

log("Invalid change: " + sm.getSharedState(o).getState() + " ---> " + s);

log(thisJoinPoint);

} }

after(int ba): pc_Account_setBalance_int(ba) {

String s = thisJoinPoint.getSignature().toString(); Object o = thisJoinPoint.getTarget();

log("change state: " + sm.getSharedState(o).getState() + " ---> " + s);

sm.setSharedState(o, s); }

63 String s = "WRONG: " + jp.getSourceLocation() + ":" + jp.getSignature(); System.out.println(s); } void log(String s) { System.out.println("INF: "+ s); }

boolean isValidState(Object o, String st){

boolean b = fsm.containsKey(st);

SharedState state = sm.getSharedState(o); String objState = state.getState();

if (b)

b = fsm.get(st).contains(objState);

return b;

}

public void loadProtocol(){

try{

File xmlFile = new File ("./src/model/sequence.xml"); SequenceDiagramFSM colfsm = new

SequenceDiagramFSM(xmlFile); fsm = colfsm.fsm; entrySigs = colfsm.entrySigs; exitSigs = colfsm.exitSigs; } catch (Exception e) { e.printStackTrace(); } } }

Tương tự như với giao thức applet. Lập trình viên sẽ xây dựng hai lớp là Account (adsbygoogle = window.adsbygoogle || []).push({});

DBManagernhư đã đặc tả. Mã aspectđược sinh ra từ công cụPVG sẽđược kết hợp với mã nguồn của chương trình. Sau đây là một sốtrường hợp kiểm chứng:

- CorrecTest1: o Lời gọi hàm: Account.debit(); ccount.getBalance(); DBManager.queryB("str"); Account.setBalance(1); DBManager.updateB("str"); o Kết quả: called debit() called getBalance() called queryB() called setBalance() called updateB()

o Nhận xét: chuỗi gọi hàm đúng với đặc tả giao thức, trong khi chạy không phát sinh lỗi.

- WrongTest1:

64 Account.debit(); DBManager.queryB("str"); Account.getBalance(); DBManager.queryB("str"); Account.setBalance(1); DBManager.updateB("str"); o Kết quả: Hình 6.8: Debit – wrongTest1

Nhật xét: Chuỗi gọi hàm sai đặc tả tại hai phương thức

DBManager.queryB("str"); Account.getBalance();vì vậy khi chạy, chương trình thông báo lỗi tại vị trí gọi hai phương thức này.

6.2.3 Kim chng giao thc [A*B] n

Giả sử ta cần kiểm chứng giao thức được mô tả bằng biểu thức chính quy như

sau:

[void open() * void close()]3

aspect sinh ra từ công cụPVG:

import org.aspectj.lang.JoinPoint;

public aspect ABnChecker{

int num = 0;

int count = 0;

int number = 3;

pointcut pc_open(): call (void open()); before(): pc_open() { if (num != 0){ log(thisJoinPoint); }} after(): pc_open() { count++;

65

num++;

if(count > number) log(thisJoinPoint);

}

pointcut pc_close(): call (void close()); after(): pc_close() {

num--;

if(num != 0 || count > number){ log(thisJoinPoint); }} void log(JoinPoint jp){ String s = "WRONG: " + jp.getSourceLocation() + ":" + jp.getSignature();

System.out.println(s); }

pointcut checkn() : call (void checkprotocolAnBn()); after(): checkn() {

if(count != number){

System.out.println("protocol is false"); }

} (adsbygoogle = window.adsbygoogle || []).push({});

/* copy this method to source code public static void checkprotocolAnBn(){ }

*/ }

Dưới đây là kết quả của một số ca kiểm thửđược thực hiện sau khi tích hợp mã

aspectvào chương trình chính: - WrongTest1:

o Chuỗi gọi hàm:

connectDB db = new connectDB(); db.open(); db.close(); db.open(); db.close(); o Kết quả: called open() called close() called open() called close() protocol is false - WrongTest2: o Chuỗi gọi hàm:

connectDB db = new connectDB();

db.open(); db.open(); db.close();

66 db.close(); db.open(); db.close(); o Kết quả: called open()

WRONG: CheckAxBn.java:40:void connectDB.open()

called open() called close()

WRONG: CheckAxBn.java:41:void connectDB.close()

called close() called open() called close()

- Nhận xét: Cả hai ca kiểm thử, chuỗi gọi hàm đều sai với đặc tả và trong khi chạy, chương trình đều báo lỗi.

Một phần của tài liệu KIỂM CHỨNG ĐẶT TẢ UML CHO TÁC TỬ PHẦN MỀM (Trang 68 - 74)