okhttp
116 строк · 3.7 Кб
1/*
2* Copyright (C) 2024 Square, Inc.
3*
4* Licensed under the Apache License, Version 2.0 (the "License");
5* you may not use this file except in compliance with the License.
6* You may obtain a copy of the License at
7*
8* http://www.apache.org/licenses/LICENSE-2.0
9*
10* Unless required by applicable law or agreed to in writing, software
11* distributed under the License is distributed on an "AS IS" BASIS,
12* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13* See the License for the specific language governing permissions and
14* limitations under the License.
15*/
16package okhttp3.containers
17
18import assertk.assertThat
19import assertk.assertions.contains
20import assertk.assertions.isEmpty
21import assertk.assertions.isNotEmpty
22import java.io.ByteArrayOutputStream
23import java.io.PrintStream
24import java.util.concurrent.ExecutorService
25import java.util.concurrent.Executors
26import okhttp3.Dispatcher
27import okhttp3.HttpUrl.Companion.toHttpUrl
28import okhttp3.OkHttpClient
29import okhttp3.Request
30import okhttp3.containers.BasicMockServerTest.Companion.MOCKSERVER_IMAGE
31import okhttp3.containers.BasicMockServerTest.Companion.trustMockServer
32import okhttp3.testing.PlatformRule
33import org.junit.jupiter.api.AfterEach
34import org.junit.jupiter.api.BeforeEach
35import org.junit.jupiter.api.Test
36import org.junit.jupiter.api.extension.RegisterExtension
37import org.junit.jupiter.api.parallel.Isolated
38import org.mockserver.client.MockServerClient
39import org.mockserver.model.HttpRequest.request
40import org.mockserver.model.HttpResponse.response
41import org.testcontainers.containers.MockServerContainer
42import org.testcontainers.junit.jupiter.Container
43import org.testcontainers.junit.jupiter.Testcontainers
44
45@Testcontainers
46@Isolated
47class BasicLoomTest {
48@JvmField
49@RegisterExtension
50val platform = PlatformRule()
51
52// Use mock server so we are strictly testing OkHttp client only in this test.
53// We should test MockWebServer later.
54@Container
55val mockServer: MockServerContainer = MockServerContainer(MOCKSERVER_IMAGE)
56
57val capturedOut = ByteArrayOutputStream()
58
59private lateinit var executor: ExecutorService
60
61private lateinit var client: OkHttpClient
62
63@BeforeEach
64fun setUp() {
65platform.assumeLoom()
66assertThat(System.getProperty("jdk.tracePinnedThreads")).isNotEmpty()
67
68client =
69OkHttpClient.Builder()
70.trustMockServer()
71.dispatcher(Dispatcher(newVirtualThreadPerTaskExecutor()))
72.build()
73
74executor = newVirtualThreadPerTaskExecutor()
75
76// Capture non-deterministic but probable sysout warnings of pinned threads
77// https://docs.oracle.com/en/java/javase/21/core/virtual-threads.html
78System.setOut(PrintStream(capturedOut))
79}
80
81@AfterEach
82fun checkForPinning() {
83assertThat(capturedOut.toString()).isEmpty()
84}
85
86private fun newVirtualThreadPerTaskExecutor(): ExecutorService {
87return Executors::class.java.getMethod("newVirtualThreadPerTaskExecutor").invoke(null) as ExecutorService
88}
89
90@Test
91fun testHttpsRequest() {
92MockServerClient(mockServer.host, mockServer.serverPort).use { mockServerClient ->
93mockServerClient
94.`when`(
95request().withPath("/person")
96.withQueryStringParameter("name", "peter"),
97)
98.respond(response().withBody("Peter the person!"))
99
100val results =
101(1..20).map {
102executor.submit {
103val response =
104client.newCall(Request((mockServer.secureEndpoint + "/person?name=peter").toHttpUrl())).execute()
105
106val body = response.body.string()
107assertThat(body).contains("Peter the person")
108}
109}
110
111results.forEach {
112it.get()
113}
114}
115}
116}
117