diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index efd54795895..fde4afead10 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -31,7 +31,7 @@ retrofit = "2.9.0" slf4j = "1.7.30" springboot2 = "2.7.18" springboot3 = "3.5.0" -springboot4 = "4.0.0-M3" +springboot4 = "4.0.0-RC1" # Android targetSdk = "34" compileSdk = "34" @@ -166,6 +166,7 @@ springboot3-starter-security = { module = "org.springframework.boot:spring-boot- springboot3-starter-jdbc = { module = "org.springframework.boot:spring-boot-starter-jdbc", version.ref = "springboot3" } springboot3-starter-actuator = { module = "org.springframework.boot:spring-boot-starter-actuator", version.ref = "springboot3" } springboot4-otel = { module = "io.opentelemetry.instrumentation:opentelemetry-spring-boot-starter", version.ref = "otelInstrumentation" } +springboot4-resttestclient = { module = "org.springframework.boot:spring-boot-resttestclient", version.ref = "springboot4" } springboot4-starter = { module = "org.springframework.boot:spring-boot-starter", version.ref = "springboot4" } springboot4-starter-graphql = { module = "org.springframework.boot:spring-boot-starter-graphql", version.ref = "springboot4" } springboot4-starter-quartz = { module = "org.springframework.boot:spring-boot-starter-quartz", version.ref = "springboot4" } diff --git a/sentry-spring-7/build.gradle.kts b/sentry-spring-7/build.gradle.kts index a8071860ad0..8102909afb0 100644 --- a/sentry-spring-7/build.gradle.kts +++ b/sentry-spring-7/build.gradle.kts @@ -75,6 +75,7 @@ dependencies { testImplementation(libs.springboot4.starter.webflux) testImplementation(libs.springboot4.starter.restclient) testImplementation(libs.springboot4.starter.webclient) + testImplementation(libs.springboot4.resttestclient) testImplementation(projects.sentryReactor) } diff --git a/sentry-spring-7/src/test/kotlin/io/sentry/spring7/graphql/SentrySpringSubscriptionHandlerTest.kt b/sentry-spring-7/src/test/kotlin/io/sentry/spring7/graphql/SentrySpringSubscriptionHandlerTest.kt index c216b4595d2..1ed217037a2 100644 --- a/sentry-spring-7/src/test/kotlin/io/sentry/spring7/graphql/SentrySpringSubscriptionHandlerTest.kt +++ b/sentry-spring-7/src/test/kotlin/io/sentry/spring7/graphql/SentrySpringSubscriptionHandlerTest.kt @@ -40,8 +40,8 @@ class SentrySpringSubscriptionHandlerTest { whenever(parameters.environment).thenReturn(dataFetchingEnvironment) val resultObject = SentrySpringSubscriptionHandler() - .onSubscriptionResult(Flux.error(exception), scopes, exceptionReporter, parameters) - assertThrows { (resultObject as Flux).blockFirst() } + .onSubscriptionResult(Flux.error(exception), scopes, exceptionReporter, parameters) + assertThrows { (resultObject as Flux).blockFirst() } verify(exceptionReporter) .captureThrowable( @@ -77,12 +77,12 @@ class SentrySpringSubscriptionHandlerTest { val resultObject = SentrySpringSubscriptionHandler() .onSubscriptionResult( - Flux.error(wrappedException), + Flux.error(wrappedException), scopes, exceptionReporter, parameters, ) - assertThrows { (resultObject as Flux).blockFirst() } + assertThrows { (resultObject as Flux).blockFirst() } verify(exceptionReporter) .captureThrowable( diff --git a/sentry-spring-7/src/test/kotlin/io/sentry/spring7/mvc/SentrySpringIntegrationTest.kt b/sentry-spring-7/src/test/kotlin/io/sentry/spring7/mvc/SentrySpringIntegrationTest.kt index 1127456cc6c..4b7e806730f 100644 --- a/sentry-spring-7/src/test/kotlin/io/sentry/spring7/mvc/SentrySpringIntegrationTest.kt +++ b/sentry-spring-7/src/test/kotlin/io/sentry/spring7/mvc/SentrySpringIntegrationTest.kt @@ -42,9 +42,9 @@ import org.mockito.kotlin.verify import org.mockito.kotlin.whenever import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.resttestclient.TestRestTemplate import org.springframework.boot.test.context.SpringBootTest -import org.springframework.boot.web.server.test.LocalServerPort -import org.springframework.boot.web.server.test.client.TestRestTemplate +import org.springframework.boot.test.web.server.LocalServerPort import org.springframework.boot.web.servlet.FilterRegistrationBean import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration @@ -80,13 +80,15 @@ import org.springframework.web.reactive.function.client.WebClient class SentrySpringIntegrationTest { companion object { + @JvmStatic @BeforeClass - fun `configure awaitlity`() { + fun `configure awaitlity`(): Unit { Awaitility.setDefaultTimeout(500, TimeUnit.MILLISECONDS) } + @JvmStatic @AfterClass - fun `reset awaitility`() { + fun `reset awaitility`(): Unit { Awaitility.reset() } } @@ -115,17 +117,19 @@ class SentrySpringIntegrationTest { restTemplate.exchange("http://localhost:$port/hello", HttpMethod.GET, entity, Void::class.java) - verify(transport) - .send( - checkEvent { event -> - assertThat(event.request).isNotNull() - assertThat(event.request!!.url).isEqualTo("http://localhost:$port/hello") - assertThat(event.user).isNotNull() - assertThat(event.user!!.username).isEqualTo("user") - assertThat(event.user!!.ipAddress).isEqualTo("169.128.0.1") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> + assertThat(event.request).isNotNull() + assertThat(event.request!!.url).isEqualTo("http://localhost:$port/hello") + assertThat(event.user).isNotNull() + assertThat(event.user!!.username).isEqualTo("user") + assertThat(event.user!!.ipAddress).isEqualTo("169.128.0.1") + }, + anyOrNull(), + ) + } } @Test @@ -140,14 +144,16 @@ class SentrySpringIntegrationTest { Void::class.java, ) - verify(transport) - .send( - checkEvent { event -> - assertThat(event.request).isNotNull() - assertThat(event.request!!.data).isEqualTo("""{"body":"content"}""") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> + assertThat(event.request).isNotNull() + assertThat(event.request!!.data).isEqualTo("""{"body":"content"}""") + }, + anyOrNull(), + ) + } } @Test @@ -162,14 +168,16 @@ class SentrySpringIntegrationTest { Void::class.java, ) - verify(transport) - .send( - checkEvent { event -> - assertThat(event.request).isNotNull() - assertThat(event.request!!.data).isEqualTo("""{"body":"content"}""") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> + assertThat(event.request).isNotNull() + assertThat(event.request!!.data).isEqualTo("""{"body":"content"}""") + }, + anyOrNull(), + ) + } } @Test @@ -181,14 +189,16 @@ class SentrySpringIntegrationTest { restTemplate.exchange("http://localhost:$port/hello", HttpMethod.GET, entity, Void::class.java) - verify(transport) - .send( - checkEvent { event -> - assertThat(event.user).isNotNull() - assertThat(event.user!!.ipAddress).isEqualTo("169.128.0.1") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> + assertThat(event.user).isNotNull() + assertThat(event.user!!.ipAddress).isEqualTo("169.128.0.1") + }, + anyOrNull(), + ) + } } @Test @@ -197,18 +207,20 @@ class SentrySpringIntegrationTest { restTemplate.getForEntity("http://localhost:$port/throws", String::class.java) - verify(transport) - .send( - checkEvent { event -> - assertThat(event.exceptions).isNotNull().isNotEmpty - val ex = event.exceptions!!.first() - assertThat(ex.value).isEqualTo("something went wrong") - assertThat(ex.mechanism).isNotNull() - assertThat(ex.mechanism!!.isHandled).isFalse() - assertThat(ex.mechanism!!.type).isEqualTo(SentryExceptionResolver.MECHANISM_TYPE) - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> + assertThat(event.exceptions).isNotNull().isNotEmpty + val ex = event.exceptions!!.first() + assertThat(ex.value).isEqualTo("something went wrong") + assertThat(ex.mechanism).isNotNull() + assertThat(ex.mechanism!!.isHandled).isFalse() + assertThat(ex.mechanism!!.type).isEqualTo(SentryExceptionResolver.MECHANISM_TYPE) + }, + anyOrNull(), + ) + } } @Test @@ -217,11 +229,13 @@ class SentrySpringIntegrationTest { restTemplate.getForEntity("http://localhost:$port/throws", String::class.java) - verify(transport) - .send( - checkEvent { event -> assertThat(event.transaction).isEqualTo("GET /throws") }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> assertThat(event.transaction).isEqualTo("GET /throws") }, + anyOrNull(), + ) + } } @Test @@ -230,7 +244,7 @@ class SentrySpringIntegrationTest { restTemplate.getForEntity("http://localhost:$port/throws-handled", String::class.java) - await.during(Duration.ofSeconds(2)).untilAsserted { + await.atMost(3, TimeUnit.SECONDS).during(Duration.ofSeconds(2)).untilAsserted { verify(transport, never()) .send(checkEvent { event -> assertThat(event).isNotNull() }, anyOrNull()) } @@ -240,29 +254,35 @@ class SentrySpringIntegrationTest { fun `calling a method annotated with @SentryCaptureException captures exception`() { val exception = java.lang.RuntimeException("test exception") anotherService.aMethodThatTakesAnException(exception) - verify(transport) - .send( - checkEvent { assertThat(it.exceptions!!.first().value).isEqualTo(exception.message) }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { assertThat(it.exceptions!!.first().value).isEqualTo(exception.message) }, + anyOrNull(), + ) + } } @Test fun `calling a method annotated with @SentryCaptureException captures exception in later param`() { val exception = java.lang.RuntimeException("test exception") anotherService.aMethodThatTakesAnExceptionAsLaterParam("a", "b", exception) - verify(transport) - .send( - checkEvent { assertThat(it.exceptions!!.first().value).isEqualTo(exception.message) }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { assertThat(it.exceptions!!.first().value).isEqualTo(exception.message) }, + anyOrNull(), + ) + } } @Test fun `calling a method annotated with @SentryTransaction creates transaction`() { someService.aMethod() - verify(transport) - .send(checkTransaction { assertThat(it.status).isEqualTo(SpanStatus.OK) }, anyOrNull()) + await.untilAsserted { + verify(transport) + .send(checkTransaction { assertThat(it.status).isEqualTo(SpanStatus.OK) }, anyOrNull()) + } } @Test @@ -272,14 +292,16 @@ class SentrySpringIntegrationTest { } catch (e: Exception) { scopes.captureException(e) } - verify(transport) - .send( - checkEvent { - assertThat(it.contexts.trace).isNotNull - assertThat(it.contexts.trace!!.operation).isEqualTo("bean") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { + assertThat(it.contexts.trace).isNotNull + assertThat(it.contexts.trace!!.operation).isEqualTo("bean") + }, + anyOrNull(), + ) + } } @Test @@ -289,14 +311,16 @@ class SentrySpringIntegrationTest { } catch (e: Exception) { scopes.captureException(e) } - verify(transport) - .send( - checkEvent { - assertThat(it.contexts.trace).isNotNull - assertThat(it.contexts.trace!!.operation).isEqualTo("child-op") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { + assertThat(it.contexts.trace).isNotNull + assertThat(it.contexts.trace!!.operation).isEqualTo("child-op") + }, + anyOrNull(), + ) + } } @Test diff --git a/sentry-spring-7/src/test/kotlin/io/sentry/spring7/webflux/SentryWebfluxIntegrationTest.kt b/sentry-spring-7/src/test/kotlin/io/sentry/spring7/webflux/SentryWebfluxIntegrationTest.kt index 2d44b40c27d..a91023b4ba0 100644 --- a/sentry-spring-7/src/test/kotlin/io/sentry/spring7/webflux/SentryWebfluxIntegrationTest.kt +++ b/sentry-spring-7/src/test/kotlin/io/sentry/spring7/webflux/SentryWebfluxIntegrationTest.kt @@ -27,10 +27,10 @@ import org.mockito.kotlin.whenever import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.ApplicationRunner import org.springframework.boot.autoconfigure.SpringBootApplication -import org.springframework.boot.security.autoconfigure.reactive.ReactiveSecurityAutoConfiguration -import org.springframework.boot.security.autoconfigure.servlet.SecurityAutoConfiguration +import org.springframework.boot.security.autoconfigure.SecurityAutoConfiguration +import org.springframework.boot.security.autoconfigure.web.reactive.ReactiveWebSecurityAutoConfiguration import org.springframework.boot.test.context.SpringBootTest -import org.springframework.boot.web.server.test.LocalServerPort +import org.springframework.boot.test.web.server.LocalServerPort import org.springframework.context.annotation.Bean import org.springframework.http.ResponseEntity import org.springframework.test.context.junit4.SpringRunner @@ -136,7 +136,7 @@ class SentryWebfluxIntegrationTest { } @SpringBootApplication( - exclude = [ReactiveSecurityAutoConfiguration::class, SecurityAutoConfiguration::class] + exclude = [ReactiveWebSecurityAutoConfiguration::class, SecurityAutoConfiguration::class] ) open class App { private val transport = mock().also { whenever(it.isHealthy).thenReturn(true) } diff --git a/sentry-spring-boot-4/build.gradle.kts b/sentry-spring-boot-4/build.gradle.kts index 897d59c3c20..96f2f39adab 100644 --- a/sentry-spring-boot-4/build.gradle.kts +++ b/sentry-spring-boot-4/build.gradle.kts @@ -102,6 +102,7 @@ dependencies { testImplementation(libs.springboot4.starter.webflux) testImplementation(libs.springboot4.starter.restclient) testImplementation(libs.springboot4.starter.webclient) + testImplementation(libs.springboot4.resttestclient) } configure { test { java.srcDir("src/test/java") } } diff --git a/sentry-spring-boot-4/src/test/kotlin/io/sentry/spring/boot4/it/SentrySpringIntegrationTest.kt b/sentry-spring-boot-4/src/test/kotlin/io/sentry/spring/boot4/it/SentrySpringIntegrationTest.kt index 998dfaaf867..473b60def12 100644 --- a/sentry-spring-boot-4/src/test/kotlin/io/sentry/spring/boot4/it/SentrySpringIntegrationTest.kt +++ b/sentry-spring-boot-4/src/test/kotlin/io/sentry/spring/boot4/it/SentrySpringIntegrationTest.kt @@ -24,9 +24,9 @@ import org.mockito.kotlin.whenever import org.slf4j.LoggerFactory import org.springframework.beans.factory.annotation.Autowired import org.springframework.boot.autoconfigure.SpringBootApplication +import org.springframework.boot.resttestclient.TestRestTemplate import org.springframework.boot.test.context.SpringBootTest -import org.springframework.boot.web.server.test.LocalServerPort -import org.springframework.boot.web.server.test.client.TestRestTemplate +import org.springframework.boot.test.web.server.LocalServerPort import org.springframework.context.annotation.Bean import org.springframework.context.annotation.Configuration import org.springframework.http.HttpEntity diff --git a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/mvc/SentrySpringIntegrationTest.kt b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/mvc/SentrySpringIntegrationTest.kt index 6e2ea53fdfd..6d399323f5f 100644 --- a/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/mvc/SentrySpringIntegrationTest.kt +++ b/sentry-spring-jakarta/src/test/kotlin/io/sentry/spring/jakarta/mvc/SentrySpringIntegrationTest.kt @@ -115,17 +115,19 @@ class SentrySpringIntegrationTest { restTemplate.exchange("http://localhost:$port/hello", HttpMethod.GET, entity, Void::class.java) - verify(transport) - .send( - checkEvent { event -> - assertThat(event.request).isNotNull() - assertThat(event.request!!.url).isEqualTo("http://localhost:$port/hello") - assertThat(event.user).isNotNull() - assertThat(event.user!!.username).isEqualTo("user") - assertThat(event.user!!.ipAddress).isEqualTo("169.128.0.1") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> + assertThat(event.request).isNotNull() + assertThat(event.request!!.url).isEqualTo("http://localhost:$port/hello") + assertThat(event.user).isNotNull() + assertThat(event.user!!.username).isEqualTo("user") + assertThat(event.user!!.ipAddress).isEqualTo("169.128.0.1") + }, + anyOrNull(), + ) + } } @Test @@ -140,14 +142,16 @@ class SentrySpringIntegrationTest { Void::class.java, ) - verify(transport) - .send( - checkEvent { event -> - assertThat(event.request).isNotNull() - assertThat(event.request!!.data).isEqualTo("""{"body":"content"}""") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> + assertThat(event.request).isNotNull() + assertThat(event.request!!.data).isEqualTo("""{"body":"content"}""") + }, + anyOrNull(), + ) + } } @Test @@ -162,14 +166,16 @@ class SentrySpringIntegrationTest { Void::class.java, ) - verify(transport) - .send( - checkEvent { event -> - assertThat(event.request).isNotNull() - assertThat(event.request!!.data).isEqualTo("""{"body":"content"}""") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> + assertThat(event.request).isNotNull() + assertThat(event.request!!.data).isEqualTo("""{"body":"content"}""") + }, + anyOrNull(), + ) + } } @Test @@ -181,14 +187,16 @@ class SentrySpringIntegrationTest { restTemplate.exchange("http://localhost:$port/hello", HttpMethod.GET, entity, Void::class.java) - verify(transport) - .send( - checkEvent { event -> - assertThat(event.user).isNotNull() - assertThat(event.user!!.ipAddress).isEqualTo("169.128.0.1") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> + assertThat(event.user).isNotNull() + assertThat(event.user!!.ipAddress).isEqualTo("169.128.0.1") + }, + anyOrNull(), + ) + } } @Test @@ -197,18 +205,20 @@ class SentrySpringIntegrationTest { restTemplate.getForEntity("http://localhost:$port/throws", String::class.java) - verify(transport) - .send( - checkEvent { event -> - assertThat(event.exceptions).isNotNull().isNotEmpty - val ex = event.exceptions!!.first() - assertThat(ex.value).isEqualTo("something went wrong") - assertThat(ex.mechanism).isNotNull() - assertThat(ex.mechanism!!.isHandled).isFalse() - assertThat(ex.mechanism!!.type).isEqualTo(SentryExceptionResolver.MECHANISM_TYPE) - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> + assertThat(event.exceptions).isNotNull().isNotEmpty + val ex = event.exceptions!!.first() + assertThat(ex.value).isEqualTo("something went wrong") + assertThat(ex.mechanism).isNotNull() + assertThat(ex.mechanism!!.isHandled).isFalse() + assertThat(ex.mechanism!!.type).isEqualTo(SentryExceptionResolver.MECHANISM_TYPE) + }, + anyOrNull(), + ) + } } @Test @@ -217,11 +227,13 @@ class SentrySpringIntegrationTest { restTemplate.getForEntity("http://localhost:$port/throws", String::class.java) - verify(transport) - .send( - checkEvent { event -> assertThat(event.transaction).isEqualTo("GET /throws") }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> assertThat(event.transaction).isEqualTo("GET /throws") }, + anyOrNull(), + ) + } } @Test @@ -230,7 +242,7 @@ class SentrySpringIntegrationTest { restTemplate.getForEntity("http://localhost:$port/throws-handled", String::class.java) - await.during(Duration.ofSeconds(2)).untilAsserted { + await.atMost(3, TimeUnit.SECONDS).during(Duration.ofSeconds(2)).untilAsserted { verify(transport, never()) .send(checkEvent { event -> assertThat(event).isNotNull() }, anyOrNull()) } @@ -240,29 +252,35 @@ class SentrySpringIntegrationTest { fun `calling a method annotated with @SentryCaptureException captures exception`() { val exception = java.lang.RuntimeException("test exception") anotherService.aMethodThatTakesAnException(exception) - verify(transport) - .send( - checkEvent { assertThat(it.exceptions!!.first().value).isEqualTo(exception.message) }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { assertThat(it.exceptions!!.first().value).isEqualTo(exception.message) }, + anyOrNull(), + ) + } } @Test fun `calling a method annotated with @SentryCaptureException captures exception in later param`() { val exception = java.lang.RuntimeException("test exception") anotherService.aMethodThatTakesAnExceptionAsLaterParam("a", "b", exception) - verify(transport) - .send( - checkEvent { assertThat(it.exceptions!!.first().value).isEqualTo(exception.message) }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { assertThat(it.exceptions!!.first().value).isEqualTo(exception.message) }, + anyOrNull(), + ) + } } @Test fun `calling a method annotated with @SentryTransaction creates transaction`() { someService.aMethod() - verify(transport) - .send(checkTransaction { assertThat(it.status).isEqualTo(SpanStatus.OK) }, anyOrNull()) + await.untilAsserted { + verify(transport) + .send(checkTransaction { assertThat(it.status).isEqualTo(SpanStatus.OK) }, anyOrNull()) + } } @Test @@ -272,14 +290,16 @@ class SentrySpringIntegrationTest { } catch (e: Exception) { scopes.captureException(e) } - verify(transport) - .send( - checkEvent { - assertThat(it.contexts.trace).isNotNull - assertThat(it.contexts.trace!!.operation).isEqualTo("bean") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { + assertThat(it.contexts.trace).isNotNull + assertThat(it.contexts.trace!!.operation).isEqualTo("bean") + }, + anyOrNull(), + ) + } } @Test @@ -289,14 +309,16 @@ class SentrySpringIntegrationTest { } catch (e: Exception) { scopes.captureException(e) } - verify(transport) - .send( - checkEvent { - assertThat(it.contexts.trace).isNotNull - assertThat(it.contexts.trace!!.operation).isEqualTo("child-op") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { + assertThat(it.contexts.trace).isNotNull + assertThat(it.contexts.trace!!.operation).isEqualTo("child-op") + }, + anyOrNull(), + ) + } } @Test diff --git a/sentry-spring/src/test/kotlin/io/sentry/spring/mvc/SentrySpringIntegrationTest.kt b/sentry-spring/src/test/kotlin/io/sentry/spring/mvc/SentrySpringIntegrationTest.kt index d6c5fd2aa79..26afd5811bf 100644 --- a/sentry-spring/src/test/kotlin/io/sentry/spring/mvc/SentrySpringIntegrationTest.kt +++ b/sentry-spring/src/test/kotlin/io/sentry/spring/mvc/SentrySpringIntegrationTest.kt @@ -116,17 +116,19 @@ class SentrySpringIntegrationTest { restTemplate.exchange("http://localhost:$port/hello", HttpMethod.GET, entity, Void::class.java) - verify(transport) - .send( - checkEvent { event -> - assertThat(event.request).isNotNull() - assertThat(event.request!!.url).isEqualTo("http://localhost:$port/hello") - assertThat(event.user).isNotNull() - assertThat(event.user!!.username).isEqualTo("user") - assertThat(event.user!!.ipAddress).isEqualTo("169.128.0.1") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> + assertThat(event.request).isNotNull() + assertThat(event.request!!.url).isEqualTo("http://localhost:$port/hello") + assertThat(event.user).isNotNull() + assertThat(event.user!!.username).isEqualTo("user") + assertThat(event.user!!.ipAddress).isEqualTo("169.128.0.1") + }, + anyOrNull(), + ) + } } @Test @@ -141,14 +143,16 @@ class SentrySpringIntegrationTest { Void::class.java, ) - verify(transport) - .send( - checkEvent { event -> - assertThat(event.request).isNotNull() - assertThat(event.request!!.data).isEqualTo("""{"body":"content"}""") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> + assertThat(event.request).isNotNull() + assertThat(event.request!!.data).isEqualTo("""{"body":"content"}""") + }, + anyOrNull(), + ) + } } @Test @@ -163,14 +167,16 @@ class SentrySpringIntegrationTest { Void::class.java, ) - verify(transport) - .send( - checkEvent { event -> - assertThat(event.request).isNotNull() - assertThat(event.request!!.data).isEqualTo("""{"body":"content"}""") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> + assertThat(event.request).isNotNull() + assertThat(event.request!!.data).isEqualTo("""{"body":"content"}""") + }, + anyOrNull(), + ) + } } @Test @@ -182,14 +188,16 @@ class SentrySpringIntegrationTest { restTemplate.exchange("http://localhost:$port/hello", HttpMethod.GET, entity, Void::class.java) - verify(transport) - .send( - checkEvent { event -> - assertThat(event.user).isNotNull() - assertThat(event.user!!.ipAddress).isEqualTo("169.128.0.1") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> + assertThat(event.user).isNotNull() + assertThat(event.user!!.ipAddress).isEqualTo("169.128.0.1") + }, + anyOrNull(), + ) + } } @Test @@ -198,18 +206,20 @@ class SentrySpringIntegrationTest { restTemplate.getForEntity("http://localhost:$port/throws", String::class.java) - verify(transport) - .send( - checkEvent { event -> - assertThat(event.exceptions).isNotNull().isNotEmpty - val ex = event.exceptions!!.first() - assertThat(ex.value).isEqualTo("something went wrong") - assertThat(ex.mechanism).isNotNull() - assertThat(ex.mechanism!!.isHandled).isFalse() - assertThat(ex.mechanism!!.type).isEqualTo(SentryExceptionResolver.MECHANISM_TYPE) - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> + assertThat(event.exceptions).isNotNull().isNotEmpty + val ex = event.exceptions!!.first() + assertThat(ex.value).isEqualTo("something went wrong") + assertThat(ex.mechanism).isNotNull() + assertThat(ex.mechanism!!.isHandled).isFalse() + assertThat(ex.mechanism!!.type).isEqualTo(SentryExceptionResolver.MECHANISM_TYPE) + }, + anyOrNull(), + ) + } } @Test @@ -218,11 +228,13 @@ class SentrySpringIntegrationTest { restTemplate.getForEntity("http://localhost:$port/throws", String::class.java) - verify(transport) - .send( - checkEvent { event -> assertThat(event.transaction).isEqualTo("GET /throws") }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { event -> assertThat(event.transaction).isEqualTo("GET /throws") }, + anyOrNull(), + ) + } } @Test @@ -231,7 +243,7 @@ class SentrySpringIntegrationTest { restTemplate.getForEntity("http://localhost:$port/throws-handled", String::class.java) - await.during(Duration.ofSeconds(2)).untilAsserted { + await.atMost(3, TimeUnit.SECONDS).during(Duration.ofSeconds(2)).untilAsserted { verify(transport, never()) .send(checkEvent { event -> assertThat(event).isNotNull() }, anyOrNull()) } @@ -241,29 +253,35 @@ class SentrySpringIntegrationTest { fun `calling a method annotated with @SentryCaptureException captures exception`() { val exception = java.lang.RuntimeException("test exception") anotherService.aMethodThatTakesAnException(exception) - verify(transport) - .send( - checkEvent { assertThat(it.exceptions!!.first().value).isEqualTo(exception.message) }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { assertThat(it.exceptions!!.first().value).isEqualTo(exception.message) }, + anyOrNull(), + ) + } } @Test fun `calling a method annotated with @SentryCaptureException captures exception in later param`() { val exception = java.lang.RuntimeException("test exception") anotherService.aMethodThatTakesAnExceptionAsLaterParam("a", "b", exception) - verify(transport) - .send( - checkEvent { assertThat(it.exceptions!!.first().value).isEqualTo(exception.message) }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { assertThat(it.exceptions!!.first().value).isEqualTo(exception.message) }, + anyOrNull(), + ) + } } @Test fun `calling a method annotated with @SentryTransaction creates transaction`() { someService.aMethod() - verify(transport) - .send(checkTransaction { assertThat(it.status).isEqualTo(SpanStatus.OK) }, anyOrNull()) + await.untilAsserted { + verify(transport) + .send(checkTransaction { assertThat(it.status).isEqualTo(SpanStatus.OK) }, anyOrNull()) + } } @Test @@ -273,14 +291,16 @@ class SentrySpringIntegrationTest { } catch (e: Exception) { scopes.captureException(e) } - verify(transport) - .send( - checkEvent { - assertThat(it.contexts.trace).isNotNull - assertThat(it.contexts.trace!!.operation).isEqualTo("bean") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { + assertThat(it.contexts.trace).isNotNull + assertThat(it.contexts.trace!!.operation).isEqualTo("bean") + }, + anyOrNull(), + ) + } } @Test @@ -290,14 +310,16 @@ class SentrySpringIntegrationTest { } catch (e: Exception) { scopes.captureException(e) } - verify(transport) - .send( - checkEvent { - assertThat(it.contexts.trace).isNotNull - assertThat(it.contexts.trace!!.operation).isEqualTo("child-op") - }, - anyOrNull(), - ) + await.untilAsserted { + verify(transport) + .send( + checkEvent { + assertThat(it.contexts.trace).isNotNull + assertThat(it.contexts.trace!!.operation).isEqualTo("child-op") + }, + anyOrNull(), + ) + } } @Test