1. 背景

有一回一个Windows软件部署到草原,通过WIFI网络访问几公里之外的视频源,由于网络不好,图像严重卡顿、引发崩溃。当时公司环境无法模拟,也不能远程调试软件,阻碍交付和回款。这也是许多ToB行业常见现象,开发环境一切很好,生产环境各有差异,结果千奇百态。由于除了插拔网线之外难以模拟网络QoS变化,继而忽视此类测试,自然而然留下了可靠性问题,很难快速解决。

其实软件行业发展数十年,你遇到的大多数基础问题早就被解决过不止一次,Google找到How can I simulate a bad internet connection for testing purposes?,MAC/Linux/Windows主流操作系统都有方案,Windows上用Clumsy轻松模拟出网络QoS变化后每次都能复现崩溃,后面顺理成章地解决了问题。

即便如此,事后解决再多bug也不算光荣,因为已经消耗了各个角色的时间和人心成本,修修补补可以提高下限,要突破软件价值的上限天花板,节省成本、把资源投入到追寻更高价值的活动上来,应在计划之初重视软件使用和依赖环境,从软件六性出发完善测试用例,虽有困难、也一定做不到全面,但从一开始就帮助各个角色对软件使用和依赖环境有一个框架性认知对齐,每个人做眼下的具体工作时仍然知道有一个最后的目标和约束,从而保障每一项工作更贴合长远方向、更仔细,避免走偏、低质,这就是品质之道。

下面简单介绍下Clumsy。

2. Clumsy

2.1. 运行

下载后手动点击软件,默认过滤条件是Presets右侧的localhost ipv4 all,作为过滤器显示到Filtering输入框,你可以参考其语法自行编辑。

clumsy

点击Start开始干扰,点击Stop(和Start同一个)按钮关闭干扰。

或者通过命令行启动软件,干扰来自8555的TCP数据包:

clumsy.exe --filter "tcp and (tcp.SrcPort == 8555)" --lag on --lag-inbound on --lag-outbound on --lag-delay 90 --drop on --drop-inbound on --drop-outbound on --drop-chance 90.0 --throttle on --throttle-timeframe 30 --throttle-inbound on --throttle-outbound on --throttle-chance 90.0 --duplicate on --duplicate-count 2 --duplicate-inbound on --duplicate-outbound on --duplicate-chance 90.0 --ood on --ood-inbound on --ood-outbound on --ood-chance 90.0 --tamper on --tamper-inbound on --tamper-outbound on --tamper-chance 90.0

clumsy_cmd

干扰方式如Functions下方参数,后面会介绍。有了命令行支持,可以轻松使用Python之类脚本制作定时、按需干扰,通过定义不同干扰参数组合的测试用例,完善网络QoS变化的可靠性测试。

2.2. Filtering-过滤器

命令行中通过--filter指定参数来标识干扰符合条件的网络包,比如指定源IP、TCP/UDP,以及端号等多种过滤条件的组合。和编辑点击GUI中Filtering效果一致。由于拦截数据包的核心功能依赖WinDivert,所以过滤器语法也须参考WinDivert。

2.3. Functions-干扰途径

  • lag,减慢数据包速度。
  • drop,丢包。
  • throttle,阻塞包再批量发送。
  • duplicate,重复包。
  • out of order,乱序包。
  • tamper,篡改包。

下面截图是RTSP视频被丢包、乱序后花屏,过滤器中开启Drop和Out of order,Chance填为50.0

RTSP视频被丢包、乱序后花屏

3. WinDivert

WinDivert通过一个内核态驱动Windivert.sys去HOOK数据包返给用户态WinDivert.dll,从而实现数据包的捕获、修改和丢弃。说到这,是不是想象空间很大!而抓包神器Wireshark依赖的Winpcap,不能修改数据包,他们过滤数据包的语法也不同。

4. 参考

  1. packet-data-intercept-and-modification
  2. how-can-i-simulate-a-bad-internet-connection-for-testing-purposes