Testing 测试容错代码

Testing 测试容错代码,testing,fault-tolerance,Testing,Fault Tolerance,我目前正在开发一个服务器应用程序,我们已经同意尝试并维护一定级别的服务。我们要保证的服务级别是:如果服务器接受了请求,并且服务器向客户端发送了确认信息,那么我们要保证即使服务器崩溃,请求也会发生。由于请求可以长时间运行,而确认时间需要短,因此我们通过持久化请求,然后向客户端发送确认,然后执行各种操作来实现请求。在执行操作时,它们也会被持久化,因此服务器知道启动时请求的状态,并且还有各种与外部系统的协调机制来检查日志的准确性 这一切似乎都运行得相当好,但我们很难确信这一点,因为我们发现测试容错代码

我目前正在开发一个服务器应用程序,我们已经同意尝试并维护一定级别的服务。我们要保证的服务级别是:如果服务器接受了请求,并且服务器向客户端发送了确认信息,那么我们要保证即使服务器崩溃,请求也会发生。由于请求可以长时间运行,而确认时间需要短,因此我们通过持久化请求,然后向客户端发送确认,然后执行各种操作来实现请求。在执行操作时,它们也会被持久化,因此服务器知道启动时请求的状态,并且还有各种与外部系统的协调机制来检查日志的准确性

这一切似乎都运行得相当好,但我们很难确信这一点,因为我们发现测试容错代码非常困难。到目前为止,我们提出了两种策略,但都不完全令人满意:

  • 让一个外部进程监视服务器代码,然后在外部进程认为是测试中合适的时候尝试将其杀死
  • 为应用程序添加代码,使其在某个关键点崩溃

我对第一种策略的问题是,外部进程无法知道应用程序的确切状态,因此我们无法确定我们是否遇到了代码中最有问题的点。第二种策略的问题是,尽管它可以更好地控制错误的发生,但我不喜欢在应用程序中插入错误的代码,即使使用可选编译等,我担心过多地查看错误注入点并将其滑入生产环境太容易了。

我认为有三种方法可以解决这个问题,如果可用,我可以建议对这些不同的代码段进行一组全面的集成测试,在这些集成过程中,使用依赖项注入或工厂对象生成中断操作

其次,使用随机kill-9运行应用程序,禁用网络接口可能是测试这些东西的好方法

我还建议测试文件系统故障。如何实现这一点取决于您的操作系统、Solaris或FreeBSD。我将在文件中创建一个zfs文件系统,然后在应用程序运行时管理该文件

如果您使用的是数据库代码,那么我建议您也测试数据库的故障


依赖注入的另一个替代方案,可能也是我将使用的解决方案,是拦截器,您可以在代码中启用崩溃测试拦截器,这些拦截器将知道应用程序的状态,并在正确的时间引入上面列出的故障,或者您可能想要创建的任何其他故障。它不需要对现有代码进行更改,只需要一些额外的代码来包装它。

第一点的一个可能答案是将实验与外部进程相乘,这样就增加了影响代码中有问题部分的可能性。然后,您可以分析核心转储文件以确定代码实际崩溃的位置

另一种方法是通过存根库或内核调用来增加可观察性和/或可命令性,即不修改应用程序代码


你可以在维基百科的页面上找到一些参考资料,特别是在软件实现的故障注入部分。

我正准备写与Justin相同的内容:)

我建议在测试期间更换的组件可以是日志组件(如果您有,如果没有,我强烈建议实现一个…)。用生成错误的代码替换它相对容易,而且记录器通常会获得足够的信息来了解当前的应用程序状态

此外,确保测试代码不进入生产环境似乎也是可行的。不过我不鼓励条件编译,而是使用一些配置文件来选择日志组件


使用“随机”杀死可能有助于检测错误,但由于其不确定性,不适合进行系统测试。因此,我不会将其用于自动测试。

您对故障注入的关注并不是一个基本问题。您只需要一种万无一失的方法来防止这样的代码在部署中结束。一种方法是将故障注入器设计为调试器。即,故障是由流程外部的流程注入的。这已经提供了一个隔离级别。此外,大多数操作系统提供某种访问控制,除非特别启用,否则会阻止调试。在最原始的形式中,它是通过将其限制为
root
,在其他操作系统上,它需要特定的“调试权限”。当然,在生产中没有人会有这种情况,因此,您的故障注入器甚至不能在生产中运行


实际上,故障注入器可以在特定地址设置断点,即功能或甚至代码行。然后,您可以对此作出反应,例如,在某个断点被命中三次后终止进程。

在哪里可以找到有关.NET平台上“崩溃测试拦截器”的更多信息?尽管我们在单元测试中使用DI,但我认为它在集成测试中不会工作得太好。这有两个原因:首先,我们希望集成测试尽可能接近将在生产环境中运行的代码;其次,要求注入的代码导致故障将对我们如何设计应用程序的各个模块产生重大(和不希望的)影响。嗨,Robert,这里有一些很好的阅读资料,也有一个使用Spring.NET的很好的例子一些可能比Spring更容易的附加选项(除非您已经在使用Spring)是一个很棒的库,NanoContainer提供的拦截器也可能是一个选项,但我不确定.NET版本中AOP支持的状态。让记录器负责