Okhttp: MockWebServer throttleBody delay does not work as expected

Created on 16 May 2018  路  2Comments  路  Source: square/okhttp

I'm having trouble figuring out how to use the throttleBody function of the MockWebServer, specifically the delay feature. I'm not sure if im using the function correctly, but everytime i try an run this test, the assertion fails:

    @Test fun validateMockServer() {
        val client = OkHttpClient.Builder().build()
        val server = MockWebServer()
        server.start()
        val baseUrl = server.url("")

        val delayMS = 200L
        val byteSpeed = 1_000_000_000L

        val originalString = "a".repeat(400_000)

        server.enqueue(MockResponse()
                .setHeadersDelay(delayMS, TimeUnit.MILLISECONDS)
                .throttleBody(byteSpeed, delayMS, TimeUnit.MILLISECONDS)
                .setBody(originalString))

        val start = System.currentTimeMillis()
        val call = client.newCall(Request.Builder().get().url(baseUrl).build())
        val body = call.execute().body()!!
        val string = body.string()
        val time = System.currentTimeMillis() - start
        server.shutdown()
        assert(time > delayMS)
    }

am i doing something wrong?
The delayMS should never be larger than the time it took to execute the request

bug tests

Most helpful comment

Good catch - The fact that your request executes faster than setHeadersDelay, looks like a bug in writeHttpResponse, it calls getBodyDelay twice.

The fact that writing the body isn't delayed is because there is no final wait after sending the final batch of body bytes. So it sends the 400k bytes immediately, and doesn't have a loop that would cause it to delay 200ms.

/**

  • Throttles the request reader and response writer to sleep for the given period after each
  • series of {@code bytesPerPeriod} bytes are transferred. Use this to simulate network behavior.
    */
    public MockResponse throttleBody(long bytesPerPeriod, long period, TimeUnit unit) {

All 2 comments

Good catch - The fact that your request executes faster than setHeadersDelay, looks like a bug in writeHttpResponse, it calls getBodyDelay twice.

The fact that writing the body isn't delayed is because there is no final wait after sending the final batch of body bytes. So it sends the 400k bytes immediately, and doesn't have a loop that would cause it to delay 200ms.

/**

  • Throttles the request reader and response writer to sleep for the given period after each
  • series of {@code bytesPerPeriod} bytes are transferred. Use this to simulate network behavior.
    */
    public MockResponse throttleBody(long bytesPerPeriod, long period, TimeUnit unit) {

Fixed!

Was this page helpful?
0 / 5 - 0 ratings