Ambassador icon indicating copy to clipboard operation
Ambassador copied to clipboard

Inconsistent data from request.

Open jaylyerly opened this issue 9 years ago • 6 comments

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")
            }

jaylyerly avatar Aug 29 '16 15:08 jaylyerly

@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")
                }
            }

fangpenlin avatar Sep 08 '16 21:09 fangpenlin

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 avatar Sep 11 '16 22:09 jaylyerly

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 avatar Sep 28 '16 20:09 jaylyerly

Oops. Forgot to reopen.

jaylyerly avatar Oct 05 '16 13:10 jaylyerly

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.

yichenshen avatar Apr 16 '17 03:04 yichenshen

Hi. I described this issue again and provided a solution. See https://github.com/envoy/Ambassador/issues/18. (Didn't realized that this is the same problem. Sorry!)

tranquvis avatar Jul 07 '17 11:07 tranquvis