Skip to content

Flaky test 'HTTPClientTests.testFileDownload' #347

Open
@Lukasa

Description

@Lukasa

Hit on #346. Output:

Test Case 'HTTPClientTests.testFileDownload' started at 2021-03-16 07:45:24.473
/code/Tests/AsyncHTTPClientTests/HTTPClientTests.swift:505: error: HTTPClientTests.testFileDownload : XCTAssertEqual failed: ("Optional(50)") is not equal to ("Optional(45)") - 
Test Case 'HTTPClientTests.testFileDownload' failed (0.779 seconds)

This test as crafted is inherently racy. The code in question is here:

let delegate = try FileDownloadDelegate(path: path)
let progress = try self.defaultClient.execute(
request: request,
delegate: delegate
)
.wait()
try XCTAssertEqual(50, TemporaryFileHelpers.fileSize(path: path))
return progress

This code assumes that once the task future completes the data will all be written to disk. However, FileDownloadDelegate does not guarantee this, and the delegate protocol we have provided makes it impossible to guarantee it. While the delegate protocol will exert backpressure on the response, it cannot prevent multiple events occurring at the same time. This means it is possible to see a situation where the same call to Channel.read triggers both .body and .end. If that happens, the task promise will complete but we may not have performed the final write and file close yet.

This is revealed in this test by the fact that the checking of the file on disk revealed fewer than 50 bytes written, but the progress structure accounts for all 50. They'll get there eventually, but we can't guarantee they're there right away.

The solution to this issue likely involves adding a promise to FileDownloadDelegate that will be fulfilled when the FD is closed, such that we know no further I/O to the file is forthcoming.

Metadata

Metadata

Assignees

No one assigned

    Labels

    area/testingImprovements to tests.kind/bugFeature doesn't work as expected.

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions