6.2.4.1 Đặc tả giao thức
Hình 6.9: Tương tác giữa hai tác tửKhach hang và Gio hang
Hình vẽ trên mô tả kịch bản đặt hàng của khách hàng trong một hệ thống bán hàng. Có hai tác tử tham gia: Khach hang và Gio hang. Để đặt hàng, đầu tiên khách hàng gửi yêu cầu đặt hàng. Khi nhận được yêu cầu đặt hàng của khách hàng, giỏ hàng có thể chấp nhận yêu cầu, từ chối yêu cầu hoặc đưa ra một lời đề nghị sửa đổi cho
67
khách hàng. Nhận được lời đề nghị từ phía giỏ hàng, khách hàng có thể chấp nhận hoặc hủy bỏ lờ đề nghị. Sau đó, giỏ hàng có thể chấp nhận yêu cầu đặt hàng hoặc đưa
ra thông báo lỗi trả về cho khách hàng.
Giao thức cũng có thểđịnh nghĩa bằng biểu đồ trạng thái UML như sau:
Hình 6.9: Biểu đồ trạng thái biểu diễn giao thức tương tác tác tử
Lập trình viên sẽcài đặt agent Customer đại diện cho khách hàng có hai hành vi chính:
- Gửi thông điệp yêu cầu đặt hàng. - Trả lời đề nghị từ phía giỏ hàng.
AgentShoppingCart đại diện cho agent Gio hang, cũng có hai hành vi chính:
- Trả lời yêu cầu đặt hàng của khách hàng. - Gửi lời đề nghị cho khách hàng.
Mã nguồn cụ thể tôi giới thiệu trong Phụ lục C và D của khóa luận.
6.2.4.2 Kiểm chứng
Mã aspect sinh ra từ công cụPVG:
public aspect ProtocolChecker{
public final static int STATE_START = 0;
public final static int STATE_refuseRequest = STATE_START;
public final static int STATE_agreeRequest = STATE_START;
public final static int STATE_sendSuggest = 2;
public final static int STATE_refuseSuggest = 3;
public final static int STATE_sendRequest = 3;
public final static int STATE_agreeSuggest = 3;
private int state = STATE_START;
public ProtocolChecker(){
68
}
pointcut pc_refuseSuggest(): call (void refuseSuggest()); before(): pc_refuseSuggest() {
if (!(state==STATE_sendSuggest)){ System.out.print("Wrong at:
"+thisJoinPointStaticPart.getSignature()); System.out.print(" In file:
"+thisJoinPointStaticPart.getSourceLocation().getFileName()); System.out.println(" At line:
"+thisJoinPointStaticPart.getSourceLocation().getLine()); }}
after(): pc_refuseSuggest() { state = STATE_refuseSuggest; }
pointcut pc_refuseRequest(): call (void refuseRequest()); before(): pc_refuseRequest() {
if (!(state==STATE_refuseSuggest || state==STATE_sendRequest ||
state==STATE_agreeSuggest)){
System.out.print("Wrong at:
"+thisJoinPointStaticPart.getSignature()); System.out.print(" In file:
"+thisJoinPointStaticPart.getSourceLocation().getFileName()); System.out.println(" At line:
"+thisJoinPointStaticPart.getSourceLocation().getLine()); }}
after(): pc_refuseRequest() { state = STATE_refuseRequest; }
pointcut pc_sendSuggest(): call (void sendSuggest()); before(): pc_sendSuggest() {
if (!(state==STATE_refuseSuggest || state==STATE_sendRequest ||
state==STATE_agreeSuggest)){
System.out.print("Wrong at:
"+thisJoinPointStaticPart.getSignature()); System.out.print(" In file:
"+thisJoinPointStaticPart.getSourceLocation().getFileName()); System.out.println(" At line:
"+thisJoinPointStaticPart.getSourceLocation().getLine()); }}
after(): pc_sendSuggest() { state = STATE_sendSuggest; }
pointcut pc_sendRequest(): call (void sendRequest()); before(): pc_sendRequest() {
if (!(state==STATE_START)){ System.out.print("Wrong at:
"+thisJoinPointStaticPart.getSignature()); System.out.print(" In file:
"+thisJoinPointStaticPart.getSourceLocation().getFileName()); System.out.println(" At line:
"+thisJoinPointStaticPart.getSourceLocation().getLine()); }}
after(): pc_sendRequest() { state = STATE_sendRequest; }
69
pointcut pc_agreeSuggest(): call (void agreeSuggest()); before(): pc_agreeSuggest() {
if (!(state==STATE_sendSuggest)){ System.out.print("Wrong at:
"+thisJoinPointStaticPart.getSignature()); System.out.print(" In file:
"+thisJoinPointStaticPart.getSourceLocation().getFileName()); System.out.println(" At line:
"+thisJoinPointStaticPart.getSourceLocation().getLine()); }}
after(): pc_agreeSuggest() { state = STATE_agreeSuggest; }
pointcut pc_agreeRequest(): call (void agreeRequest()); before(): pc_agreeRequest() {
if (!(state==STATE_refuseSuggest || state==STATE_sendRequest ||
state==STATE_agreeSuggest)){
System.out.print("Wrong at:
"+thisJoinPointStaticPart.getSignature()); System.out.print(" In file:
"+thisJoinPointStaticPart.getSourceLocation().getFileName()); System.out.println(" At line:
"+thisJoinPointStaticPart.getSourceLocation().getLine()); }} after(): pc_agreeRequest() { state = STATE_agreeRequest; } }
Tích hợp mã aspect này vào chương trình chính, tôi thực hiện một số ca kiểm thử và thu được kết quảnhư sau:
- WrongTest1: Agent Customer gửi thông điệp trả lời đề nghị trước khi gửi
thông điệp yêu cầu.
o Kết quả:
Hình 6.10: Agent – wrongTest1
o Nhận xét: Agent ShoppingCart vẫn xử lý yêu cầu từ phía Customer
70
aspect kiểm chứng đã phát hiện ra lỗi sai đặc tả và thông báo cho
người dùng.
- WrongTest2: Agent ShoppingCart gửi cảthông điệp chấp nhận đặt hàng và từ chối đặt hàng khi Customer gửi một yêu cầu đặt hàng.
o Kết quả:
Hình 6.11: Agent – wrongTest2
o Nhận xét: Mã aspect kiểm chứng bắt được lỗi sai đặc tả giao thức trong thời gian chạy.
6.3 Kết luận
Trong chương này, tôi đã trình bày cách cài đ ặt công cụ PVG dựa vào phương
pháp “kiểm chứng đặc tả UML cho tác tử phần mềm”. Mã aspectđược sinh ra từ công cụ PVG sẽđược đan vào mã nguồn của chương trình chính thông qua trình biên dịch AspectJ để kiếm chứng giao thức đặc tả trong thời gian chạy. Bước đầu tiến hành kiểm chứng một số giao thức thực tế, tôi thấy mã aspect do công cụ PVG tạo ra đã đáp ứng
71
Chương 7. Kết luận