Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Inconsistent data from request. #5

Closed
jaylyerly opened this issue Aug 29, 2016 · 6 comments
Closed

Inconsistent data from request. #5

jaylyerly opened this issue Aug 29, 2016 · 6 comments

Comments

@jaylyerly
Copy link

I'm using EnvoyAmbassador in unit tests to mock my API server. In order to validate the JSON body that the software under test sends, I'm using DataReader.read(input) like below. This works fine most of the time, but sometimes it fails. When it does fail, it looks like there's no data read by the DataReader(input) method. In the case below, the buffer has length 0.

Give the sporadic nature of the error, it feels like it might be a race condition? Any clues as to why this might fail once in a while?

        if let input = environ["swsgi.input"] as? SWSGIInput {
            let buffer = NSMutableData()
            DataReader.read(input) { data in
                for var d in data {     // data is list of UInt8
                    buffer.appendData(NSData(bytes: &d, length: sizeof(UInt8)))
                }
            }
            swiftyJson = JSON(data: buffer)
            if (buffer.length == 0) {
                XCTFail("Found zero length buffer parsing JSON")
            }
@fangpenlin
Copy link
Contributor

@jaylyerly DataReader.read(input) is an async operation, namely, it's not blocking until it reads data. Instead, it only calls the closure you pass in when data is available.

So, instead of assert the data after DataReader.read(input), I would suggest you just assert inside the read closure like this:

        if let input = environ["swsgi.input"] as? SWSGIInput {
            let buffer = NSMutableData()
            DataReader.read(input) { data in
                for var d in data {     // data is list of UInt8
                    buffer.appendData(NSData(bytes: &d, length: sizeof(UInt8)))
                }
                swiftyJson = JSON(data: buffer)
                if (buffer.length == 0) {
                    XCTFail("Found zero length buffer parsing JSON")
                }
            }

@jaylyerly
Copy link
Author

Ah, I see. Silly mistake on my part. Thanks for the pointer. I've made the change to validate the data inside the read closure and things are working very well.

Thanks again for the great framework!

@jaylyerly
Copy link
Author

Weirdly, I upgraded to Xcode 8 and Swift 2.3 and the instability is back. I'm doing all my data inspection inside the read closure, but sometimes it's still empty. Any clue as to why the Xcode/Swift change might cause the behavior to change?

        if let input = environ["swsgi.input"] as? SWSGIInput {
            DataReader.read(input) { data in
                let buffer = NSMutableData()
                for var d in data {     // data is list of UInt8
                    buffer.appendData(NSData(bytes: &d, length: sizeof(UInt8)))
                }
                if (buffer.length == 0) && (expectEmpty == false) {
                    XCTFail("Found zero length buffer parsing JSON")
                }

                let swiftyJson = JSON(data: buffer)
                if expectEmpty == false {
                    XCTAssertNotEqual(swiftyJson, JSON(data: NSData()))
                }
                completion?(swiftyJson)
            }
        } 

@jaylyerly
Copy link
Author

Oops. Forgot to reopen.

@jaylyerly jaylyerly reopened this Oct 5, 2016
@yichenshen
Copy link

yichenshen commented Apr 16, 2017

Hi, I seem to be getting this problem too. I'm on Swift 3.1 with the same problem.

It does seem to be a race condition. In fact, if I force a wait on line 130 of Transport.swift, like

do {
        sleep(1) // For debugging
        data = try socket.recv(size: Transport.recvChunkSize)
}

All the data, including the body is received, but without the debug code the request body will be missing. So it seems to be some form of race condition within the TCPSocket class.

@tranquvis
Copy link

Hi. I described this issue again and provided a solution. See #18.
(Didn't realized that this is the same problem. Sorry!)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

4 participants