2011-10-21 55 views
7

我正在開發一個用於通過HTTP進行通信的Java庫,並且我希望在出現網絡問題(如丟包,高延遲,低帶寬和擁塞)時測試其可靠性和性能。我使用Apache's httpclient library從客戶端進行連接,並使用Java自己的com.sun.net.httpserver.HttpServer來啓動HTTP服務器。創建用於測試分佈式系統的網絡錯誤

有沒有圖書館可以做這種事情,或者我應該推出自己的?我想我可以嘗試將我自己的org.apache.http.conn.scheme.SchemeSocketFactory插入到客戶端,並模擬上面提到的幾個問題,但我更喜歡使用已經工作的東西:-)

這與問題Creating TCP network errors for unit testing類似,但我正在尋找涉及Java on Linux的解決方案。我已經看過點擊,這是針對該問題的建議,但我不確定它可以提供我期待的內容。

回答

3

由於Java API無法訪問低級網絡API,因此模擬它將會很具有挑戰性。

或者Apache HTTP核心組件庫可能會幫助您模擬延遲和數據丟失以及可能的帶寬問題。該庫具有注入您自己的會話輸入和輸出緩衝區的功能。您可以在Advanced Features of HTTP Core

的文檔通過注入自己的緩衝

  • 延遲可能會小延遲注入讀取和寫入
  • 數據丟失是扔掉一些字節。這不是真正意義上的數據包丟失,因爲沒有重複的重新發送。
  • 帶寬可以通過調整讀/寫和刷新操作來限制。
  • 流量很難模擬,除非作爲緩衝區的讀寫緩慢。

您還可以查看Grinder項目中提供的TCPProxy。我沒有詳細看過它。該文檔顯示EchoFilter作爲示例,但我相信應該可以擴展過濾器以延遲流中的字節發送和接收。但使用代理來模擬網絡問題很有意義。這樣,您的客戶端和服務器仍然對正在進行的測試無知。

在這兩種情況下,網絡問題的仿真似乎都是Java中儘可能最大的努力。 或者你可以設置一個本地防火牆,並將其配置爲攔截並播放它接收到的數據包。

希望這是有幫助的。

+0

是的,這**有幫助。謝謝! –

1

而不是試圖實現網絡錯誤(在你的情況下,它可能意味着修改httpclient庫或模擬服務器中的錯誤和延遲),你應該考慮使用WAN模擬器,如WANEM。在我看來,這將是一個更簡單和更可行的解決方案。

+0

感謝您的建議。儘管如此,我寧願在Java源代碼中加入一些東西,因爲我必須在分佈式系統的所有節點上推出它。而且我不想幹擾節點上同時發生的任何其他網絡流量。 –

3

如果您沒有對系統進行集成測試,I.E與外部服務器等運行完整的堆棧,那麼使用模擬工具就是您正在尋找的東西。它們允許您記錄您正在處理的庫的行爲。這樣可以節省運行庫代碼,而不需要驗證。

使用諸如mockito之類的東西,或者如果需要的話PowerMock,您可以告訴庫在調用您調用的方法時拋出異常。

實施例:

import static org.mockito.Mockito.mock 
import static org.mockito.Mockito.when 
... 
@Test(expected=HttpException.class) 
public void invockationThrowsHttpException() { 
    ... 
    HttpClient httpClient = mock(HttpClient.class) 
    when(httpClient).executeMethod(args...).thenThrow(HttpException...) 

    underTest.invokeCodeUnderTest(args...) 
    ... 
} 

上面的例子假設JUnit4。 Mockito網站上有一個相當不錯的教程。如果您需要模擬mockito不會模擬的東西(例如靜態或最終方法),則使用PowerMock。

另一方面,我注意到Apache的HTTP客戶端處於生命週期結束,他們建議改用Apache HTTP組件。如果你的項目還處於早期階段,現在可能值得轉換。

+0

感謝您的輸入。沒有意識到HTTP客戶端已經到了終點;我將不得不尋找替代方案。至於你使用嘲諷的建議:我確實想要運行整個系統。 –