Repository: square/okhttp
File: okhttp/src/test/java/okhttp3/ServerTruncatesRequestTest.kt (Kotlin)

Code before:
        .post(SlowRequestBody)
        .build())

    call.execute().use { response ->
      assertThat(response.body!!.string()).isEqualTo("abc")
    }

    val expectedEvents = mutableListOf<String>()
    expectedEvents += "CallStart"
    expectedEvents += "ProxySelectStart"
    expectedEvents += "ProxySelectEnd"
    expectedEvents += "DnsStart"
    expectedEvents += "DnsEnd"
    expectedEvents += "ConnectStart"
    if (https) {
      expectedEvents += "SecureConnectStart"
      expectedEvents += "SecureConnectEnd"
    }
    expectedEvents += "ConnectEnd"
    expectedEvents += "ConnectionAcquired"
    expectedEvents += "RequestHeadersStart"
    expectedEvents += "RequestHeadersEnd"
    expectedEvents += "RequestBodyStart"
    expectedEvents += "RequestFailed"
    expectedEvents += "ResponseHeadersStart"
    expectedEvents += "ResponseHeadersEnd"
    expectedEvents += "ResponseBodyStart"
    expectedEvents += "ResponseBodyEnd"
    expectedEvents += "ConnectionReleased"
    expectedEvents += "CallEnd"
    assertThat(listener.recordedEventTypes()).isEqualTo(expectedEvents)

    // Confirm that the connection pool was not corrupted by making another call.
    makeSimpleCall()
  }

  /**
   * If the server returns a full response, it doesn't really matter if the HTTP/2 stream is reset.
   * Attempts to write the request body fails fast.
   */
  @Test fun serverTruncatesRequestHttp2OnDuplexRequest() {
    enableProtocol(Protocol.HTTP_2)

    server.enqueue(MockResponse()
        .setSocketPolicy(SocketPolicy.DO_NOT_READ_REQUEST_BODY)
        .setBody("abc")
        .apply { this.http2ErrorCode = ErrorCode.NO_ERROR.httpCode })

    val requestBody = AsyncRequestBody()

    val call = client.newCall(Request.Builder()

Review comment (suggestion):
maybe a trailing comment here highlighting that the important part is we read the response headers and body even on error.

Code after:
        .post(SlowRequestBody)
        .build())

    call.execute().use { response ->
      assertThat(response.body!!.string()).isEqualTo("abc")
    }

    val expectedEvents = mutableListOf<String>()
    // Start out with standard events...
    expectedEvents += "CallStart"
    expectedEvents += "ProxySelectStart"
    expectedEvents += "ProxySelectEnd"
    expectedEvents += "DnsStart"
    expectedEvents += "DnsEnd"
    expectedEvents += "ConnectStart"
    if (https) {
      expectedEvents += "SecureConnectStart"
      expectedEvents += "SecureConnectEnd"
    }
    expectedEvents += "ConnectEnd"
    expectedEvents += "ConnectionAcquired"
    expectedEvents += "RequestHeadersStart"
    expectedEvents += "RequestHeadersEnd"
    expectedEvents += "RequestBodyStart"
    // ... but we can read the response even after writing the request fails.
    expectedEvents += "RequestFailed"
    expectedEvents += "ResponseHeadersStart"
    expectedEvents += "ResponseHeadersEnd"
    expectedEvents += "ResponseBodyStart"
    expectedEvents += "ResponseBodyEnd"
    expectedEvents += "ConnectionReleased"
    expectedEvents += "CallEnd"
    assertThat(listener.recordedEventTypes()).isEqualTo(expectedEvents)

    // Confirm that the connection pool was not corrupted by making another call.
    makeSimpleCall()
  }

  /**
   * If the server returns a full response, it doesn't really matter if the HTTP/2 stream is reset.
   * Attempts to write the request body fails fast.
   */
  @Test fun serverTruncatesRequestHttp2OnDuplexRequest() {
    enableProtocol(Protocol.HTTP_2)

    server.enqueue(MockResponse()
        .setSocketPolicy(SocketPolicy.DO_NOT_READ_REQUEST_BODY)
        .setBody("abc")
        .apply { this.http2ErrorCode = ErrorCode.NO_ERROR.httpCode })

    val requestBody = AsyncRequestBody()