创建网络错误以测试分布式系统

时间:2011-10-21 11:26:20

标签: java http distributed

我正在开发一个用于通过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类似,但我正在寻找在Linux上涉及Java的解决方案。我查看了针对该问题的建议点击,但我不确定它是否能提供我正在寻找的内容。

3 个答案:

答案 0 :(得分: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 Components。如果您的项目仍处于早期阶段,那么现在可能值得切换。

答案 1 :(得分:3)

由于Java API无法访问低级网络API,因此模拟它将具有挑战性。

或者,Apache HTTP Core组件库可能有助于您模拟延迟和数据丢失以及可能的带宽问题。该库具有注入您自己的会话输入和输出缓冲区的功能。您可以在Advanced Features of HTTP Core

找到该文档

注入自己的缓冲区

  • 延迟可以是注入读写的小延迟
  • 数据丢失是丢弃的一些字节。它不是真正意义上的数据包丢失,因为没有重复重发。
  • 可以通过调整读/写和刷新操作来限制带宽。
  • 流量很难模拟,除非读缓慢写入缓冲区。

您还可以查看Grinder项目中提供的TCPProxy。我没详细看过它。文档显示EchoFilter作为示例,但我相信应该可以扩展过滤器以延迟流中字节的发送和接收。但是使用代理来模拟网络问题是有意义的。这样,您的客户端和服务器仍然对正在进行的测试一无所知。

在这两种情况下,网络问题的模拟似乎是Java中可能的最佳努力。 否则,您可以设置本地防火墙,并将其配置为拦截并播放它收到的数据包。

希望这有用。

答案 2 :(得分:1)

您可以考虑使用像WANEM这样的WAN仿真器,而不是尝试实现网络错误(在您的情况下,它可能意味着修改httpclient库或模拟服务器中的错误和延迟)。在我看来,这将是一个更简单,更可行的解决方案。