使用autobahn-testsuite测试websocket兼容性
背景
这段时间在线上环境的日志中出现了如下错误日志:
。
关于这个异常的分析和解决参考netty websocket extension negotiated
为了复现线上的问题,本地启动了对应的服务,然后使用 golang 编写了一个简单的客户端,示例如下:
1 | package main |
测试发现没有异常出现。然后又在 ws 建立链接之前增加了以下配置,来测试是否对服务端有影响,结果还是没有问题。
1 | // 如果设置为true,则开启内容压缩传输,这里设置为true 测试是否能影响server |
经过 ws 客户端配置的变更测试,均没有发现异常,所以肯定是 client 还有什么配置可能影响服务端的处理,但是对 ws 协议内容本身又没有非常了解的情况下,难以修改 client 的链接配置来做各种测试。
于是接下来对关键词 RSV != 0 and no extension negotiated
进行了搜索,但是结果都不尽人意,还是没有弄清楚在什么情况下会触发此异常。无意中(过程比较冗长)发现了一个叫做 autobahn-testsuite 的组件,可以用来测试对ws的支持情况。
autobahn-testsuite
简介
该测试套件可以对WebSocket基本功能、扩展协议、性能等进行测试。详细说明参见 https://github.com/crossbario/autobahn-testsuite#test-suite-coverage 。
说明
简介中已经简要描述了 testsuite 的功能,但是在本文中只是介绍 testsuite 作为 client 对 server 的测试使用,并不涉及 testsuite 的其他功能。
安装、运行
testsuite 提供了多种使用方式,但是最简单的就是使用配置好的 Docker 镜像的方式,除此之外,还可以使用原生的 python 执行方式,但是鉴于 python 需要环境配置,这里就以 docker 运行方式说明一下使用说明,其他运行方式可以参考本示例。
github 上有个说明,就是直接执行以下命令运行:
1 | docker run -it --rm \ |
说明:
-v ${PWD}/config:/config
将当前目录下的 config
目录映射到容器的 /config
目录-v "${PWD}/reports:/reports"
将当前目录下的 reports
目录映射到容器的 /reports
目录
需要注意的是,这个命令本身没有问题,但是是运行的 server 模式,就是启动了 server,而不是作为 client 测试 server ,所以需要修改为如下配置:
1 | docker run -it --rm \ |
以上命令中增加了 wstest -m fuzzingclient -s config/fuzzingclient.json
命令:
- wstest 就是测试组件的命令
- -m 运行模式,因为我们要运行client模式,所以指定为 fuzzingclient
- -s 指定配置文件
其中配置文件内容格式如下,
1 | { |
配置说明:
主要修改的就是 servers.url 部分,这个地方修改为要测试的 ws server地址,注意 如果要测试是本机,则需要填写本机ip地址,不能是 localhost
或者 127.0.0.1
,否则在容器内无法进行测试到本机上的server。
将其放到写入 当前目录下的 config/fuzzingclient.json,然后执行上面的命令,就可以看到输出(部分省略):
1 | Using explicit spec file 'config/fuzzingclient.json' |
由于测试case比较多(默认是所有),所以耗时及较长,这个时候你可以喝杯茶或者干点其他事情后回来再看看。测试运行结束后程序会自动退出,没有其他输出信息。打开 reports/clients
目录,会发现里面生成了一些文件,将 index.html
用浏览器打开就可以观察测试报告了,大概长得下面这个模样:
说明:
- 结果标签说明(建议自己看英文说明理解)
- Pass 测试执行并且通过
- Non-Strict 测试执行,但是并非完全符合规范
- Fail 测试执行但是失败
- Info (不知如何理解)
- Missing 测试 case 缺失
- 可以点击查看测试case详情
- 可以点击查看测试case和结果详情
结语
本文只是对 autobahn-testsuite websocket 测试套件进行了简要说明,更多功能暂时需要自行去了解(后面如果有深入研究我会再进行补充)。
同时需要注意的是,该套件只是对 server 端进行一个测试,失败并不是代表 server 端有问题,比如 server 端 业务逻辑要求如此,或者 server 本身就是要求支持某个版本而已。