groovygrailsspock

HTTP Connection Error in cleanupSpec() Function in Spock: "SSL is disabled"


I'm encountering an issue when making an HTTP request in the cleanupSpec() function of a Spock test. The same HTTP GET request works perfectly in both the test case and the cleanup() function, but when it's called from cleanupSpec(), I get the following error:

Connect Error: Cannot send HTTPS request. SSL is disabled
io.micronaut.http.client.exceptions.HttpClientException: Connect Error: Cannot send HTTPS request. SSL is disabled

It seems like the connection is closed before cleanupSpec() is executed. Below is the relevant code and error log:

@MicronautTest
class TestGetSpec extends Specification {

    @Shared
    @Inject
    HttpClient httpClient

    def cleanup() {
        println("TestGETSpec:: Calling cleanup() function")

        def response = httpClient.toBlocking().exchange(
                HttpRequest.GET("https://jsonplaceholder.typicode.com/posts/1").accept(MediaType.APPLICATION_JSON),
                Object
        )
    }

    def cleanupSpec() {
        println("TestGETSpec:: Calling cleanupSpec() function")

        def response = httpClient.toBlocking().exchange(
                HttpRequest.GET("https://jsonplaceholder.typicode.com/posts/1").accept(MediaType.APPLICATION_JSON),
                Object
        )
    }

    def "test HTTP request with ReactorHttpClient"() {
        when:
        def response = httpClient.toBlocking().exchange(
                HttpRequest.GET("https://jsonplaceholder.typicode.com/posts/1").accept(MediaType.APPLICATION_JSON),
                Object
        )

        then:
        response.status.code == 200
    }
}

Error Message:

Connect Error: Cannot send HTTPS request. SSL is disabled
io.micronaut.http.client.exceptions.HttpClientException: Connect Error: Cannot send HTTPS request. SSL is disabled
    at app//io.micronaut.http.client.netty.ConnectionManager$Pool.onNewConnectionFailure(ConnectionManager.java:986)
    at app//io.micronaut.http.client.netty.PoolResizer.doSomeWork(PoolResizer.java:157)
    at app//io.micronaut.http.client.netty.PoolResizer.dirty(PoolResizer.java:77)
    at app//io.micronaut.http.client.netty.PoolResizer.addPendingRequest(PoolResizer.java:233)
    at app//io.micronaut.http.client.netty.ConnectionManager$Pool.acquire(ConnectionManager.java:965)
    at app//io.micronaut.http.client.netty.ConnectionManager.connect(ConnectionManager.java:430)
    at app//io.micronaut.http.client.netty.DefaultHttpClient.exchangeImpl(DefaultHttpClient.java:1113)
    at app//io.micronaut.http.client.netty.DefaultHttpClient.lambda$exchange$8(DefaultHttpClient.java:811)
    at app//reactor.core.publisher.FluxFlatMap.trySubscribeScalarMap(FluxFlatMap.java:152)
    at app//reactor.core.publisher.FluxSwitchMapNoPrefetch.subscribeOrReturn(FluxSwitchMapNoPrefetch.java:61)
    at app//reactor.core.publisher.Flux.subscribe(Flux.java:8759)
    at app//reactor.core.publisher.Flux.blockFirst(Flux.java:2703)
    at app//io.micronaut.http.client.netty.DefaultHttpClient$1.exchange(DefaultHttpClient.java:547)
    at app//io.micronaut.http.client.BlockingHttpClient.exchange(BlockingHttpClient.java:77)
    at app//io.micronaut.http.client.BlockingHttpClient.exchange(BlockingHttpClient.java:106)
    at app//com.example.TestGetSpec.cleanupSpec(TestGETSpec.groovy:34)

I also checked the Micronaut and Spock documentation but couldn't find a clear explanation for this behavior. My expectation was that the HTTP client would remain active until cleanupSpec() is executed.

Any suggestions or hints on how to resolve this issue would be greatly appreciated. Thank you so much for your help!


Solution

  • This is either a shortcoming or a bug in micronaut-test.

    If you look at https://github.com/micronaut-projects/micronaut-test/blob/4.5.x/test-spock/src/main/java/io/micronaut/test/extensions/spock/MicronautSpockExtension.java#L117-L123 you see that the Micronaut extension adds a cleanup spec interceptor and in that first does its afterTestClass and afterClass actions before it calls invocation.proceed(). This last call is, what hands over to the next interceptor or ulimately to the cleanupSpec() execution.

    So either micronaut-test has a reason to tear down stuff before cleanupSpec() methods are called, or they just call the proceed() method too late and should do it before their cleanup code.

    But looking at the history of that block previously the proceed() call was not there at all and people complained that setupSpec() is not executed. So I think they just call it in the wrong order. You should open a bug against micronaut-test.