0

我正在开发一个 API,当用户上传文件时,它会即时处理该文件以从中提取一些数据。该文件可能非常大(最大 5 GB)并且不会保留在服务器上。

我有一堆使用Flask 提供的通用测试工具的系统测试。我也知道如何让测试上传文件

然而,有一个案例我没有被系统测试覆盖。如果用户开始上传文件,然后在中间断开连接,而服务器正忙于从它已经收到的数据中提取数据怎么办?

curl通过启动一个大文件并在中间终止客户端来玩。API 的行为似乎符合我的预期。但我更喜欢完全自动化的方法。

我怎样才能做到这一点?Flask 或 Werkzeug 中有什么东西可以让我进行这样的测试吗?如果没有,什么是可行的方法?

4

1 回答 1

1

搜索了一会,似乎 Flask 的测试功能和Requests 库都无法帮助我。因此,解决方案是使用Python 的 sockets进行手动 HTTP 请求。

为了节省时间,模拟请求并研究实际发送的内容的最简单方法是使用curl一些附加参数:

  • --trace-ascii -可以显示curl发送和接收的所有内容。非常便利。

  • --limit-rate 3K帮助模拟了一个非常慢的连接,结合gunicorn( gunicorn --timeout 2 ...) 中的超时配置允许重现客户端开始 POST 文件,然后挂起太久的情况。

curl从那里,我只需将它在终端中报告的行为复制到正在使用socket.socket().

然后,测试代码通过一个线程将文件流式传输到服务器,同时定期暂停并向主线程报告其进度。当发送文件的一部分而不是全部时,主线程将突然终止正在流式传输文件的线程。然后它将等待 gunicorn 超时,然后与数据库交互以检查处理是否按预期进行。

我不知道的一件事是 Werkzeug 缓冲了请求,这绝对不直观,因为使用 时,每次遇到换行符时都会调用传递给 Werkzeug 的流werkzeug.formparser.parse_form_data()的方法。write诀窍是它首先被缓冲,并且只有当缓冲区已满时,才会write开始为缓冲区中的数据调用。最初,我只发送包含几千字节的文件,所以看起来 Werkzeug 只是在读取内存中的整个文件,然后才让我处理它。当我开始发送大于其 65,536 字节缓冲区的文件时,我注意到write在缓冲区被填满后,我收到了对 in burst 的调用。

于 2018-08-25T13:20:45.187 回答