Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -77,7 +77,6 @@
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.graphql.execution.DataFetcherExceptionResolverAdapter;
import org.springframework.kafka.core.KafkaTemplate;
import org.springframework.scheduling.quartz.SchedulerFactoryBean;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.web.client.RestClient;
Expand Down Expand Up @@ -250,7 +249,11 @@ static class SentryCacheConfiguration {
}

@Configuration(proxyBeanMethods = false)
@ConditionalOnClass(KafkaTemplate.class)
@ConditionalOnClass(
name = {
"org.springframework.kafka.core.KafkaTemplate",
"io.sentry.kafka.SentryKafkaProducerInterceptor"
})
@ConditionalOnProperty(name = "sentry.enable-queue-tracing", havingValue = "true")
@ConditionalOnMissingClass("io.sentry.opentelemetry.SentryAutoConfigurationCustomizerProvider")
@Open
Expand Down
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
package io.sentry.spring.boot.jakarta

import io.sentry.kafka.SentryKafkaProducerInterceptor
import io.sentry.opentelemetry.SentryAutoConfigurationCustomizerProvider
import io.sentry.spring.jakarta.kafka.SentryKafkaConsumerBeanPostProcessor
import io.sentry.spring.jakarta.kafka.SentryKafkaProducerBeanPostProcessor
Expand Down Expand Up @@ -30,6 +31,9 @@ class SentryKafkaAutoConfigurationTest {
private val noOtelClassLoader =
FilteredClassLoader(SentryAutoConfigurationCustomizerProvider::class.java)

private val noSentryKafkaClassLoader =
FilteredClassLoader(SentryKafkaProducerInterceptor::class.java)

@Test
fun `registers Kafka BPPs when queue tracing is enabled`() {
contextRunner
Expand All @@ -49,6 +53,17 @@ class SentryKafkaAutoConfigurationTest {
}
}

@Test
fun `does not register Kafka BPPs when sentry-kafka is not present`() {
contextRunner
.withClassLoader(noSentryKafkaClassLoader)
.withPropertyValues("sentry.enable-queue-tracing=true")
.run { context ->
assertThat(context).doesNotHaveBean(SentryKafkaProducerBeanPostProcessor::class.java)
assertThat(context).doesNotHaveBean(SentryKafkaConsumerBeanPostProcessor::class.java)
}
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Test passes for wrong reason, not testing sentry-kafka absence

Medium Severity

The new regression test does not register Kafka BPPs when sentry-kafka is not present uses noSentryKafkaClassLoader which only filters SentryKafkaProducerInterceptor. However, since the OTel class SentryAutoConfigurationCustomizerProvider remains on the test classpath (it's a testImplementation dependency and is not filtered here), the @ConditionalOnMissingClass annotation on SentryKafkaQueueConfiguration already prevents the beans from loading. The test passes because OTel is present, not because sentry-kafka is absent, making it an ineffective regression test. The noSentryKafkaClassLoader needs to also filter the OTel class to isolate the condition being tested.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit bd9d3b5. Configure here.


@Test
fun `does not register Kafka BPPs when queue tracing is explicitly false`() {
contextRunner
Expand Down
18 changes: 17 additions & 1 deletion test/system-test-runner.py
Original file line number Diff line number Diff line change
Expand Up @@ -68,6 +68,13 @@

KAFKA_CONTAINER_NAME = "sentry-java-system-test-kafka"
KAFKA_BOOTSTRAP_SERVERS = "localhost:9092"
KAFKA_BROKER_REQUIRED_MODULES = {
"sentry-samples-console",
"sentry-samples-spring-boot-jakarta",
}
KAFKA_PROFILE_REQUIRED_MODULES = {
"sentry-samples-spring-boot-jakarta",
}

class ServerType(Enum):
TOMCAT = 0
Expand Down Expand Up @@ -202,7 +209,10 @@ def kill_process(self, pid: int, name: str) -> None:
print(f"Process {pid} was already dead")

def module_requires_kafka(self, sample_module: str) -> bool:
return sample_module == "sentry-samples-console"
return sample_module in KAFKA_BROKER_REQUIRED_MODULES

def module_requires_kafka_profile(self, sample_module: str) -> bool:
return sample_module in KAFKA_PROFILE_REQUIRED_MODULES

def wait_for_port(self, host: str, port: int, max_attempts: int = 20) -> bool:
for _ in range(max_attempts):
Expand Down Expand Up @@ -423,6 +433,12 @@ def start_spring_server(self, sample_module: str, java_agent: str, java_agent_au
env.update(SENTRY_ENVIRONMENT_VARIABLES)
env["SENTRY_AUTO_INIT"] = java_agent_auto_init

if self.module_requires_kafka_profile(sample_module):
env["SPRING_PROFILES_ACTIVE"] = "kafka"
print("Enabling Spring profile: kafka")
else:
env.pop("SPRING_PROFILES_ACTIVE", None)

# Build command
jar_path = f"sentry-samples/{sample_module}/build/libs/{sample_module}-0.0.1-SNAPSHOT.jar"
cmd = ["java"]
Expand Down
Loading