Skip to content

test(spring): [Sample Tests 29] Move the Spring WAR sample's tests into the module - #6321

Merged
runningcode merged 2 commits into
no/spring-7-integration-testfrom
no/spring-integration-test
Oct 27, 2026
Merged

runningcode merged 2 commits into
no/spring-7-integration-testfrom
no/spring-integration-test

Conversation

@runningcode

@runningcode runningcode commented Oct 20, 2026 •

Copy link
Copy Markdown
Contributor

PR Stack (Sample Tests)


📜 Description

Adds #6319's embedded-Tomcat integrationTest suite to sentry-spring, with io.sentry.spring's packages and javax.servlet. sentry-samples-spring's tests match the jakarta WAR sample's except for the URL, so the suite does too:

  • Person:
    • the failed request's error with its flag and request, the http.server transaction and the logs;
    • creating a person, with its profile.
  • Metrics: the servlet suites' test.

Spring Boot 2's BOM picks Spring 5.3 and Tomcat 9. As in #6319, Spring Boot itself stays off the suite's classpath, so Sentry's servlet container initializer takes its WAR path and adds SentrySpringFilter.

With no system tests left, the sample comes off the runner, the backend workflow and the Spring Boot 2 matrix. That was the matrix's last runner step, so the matrix also drops:

  • the Python setup;
  • SENTRY_URL;
  • the runner's log uploads;
  • the excludeGraphql/excludeKafka exports, which only the sample builds and the runner read.

All three Spring Boot matrices now run only Gradle suites, and the WAR flavor is done.

💡 Motivation and Context

Plain Spring 5, without Boot, now runs end to end in the module. The suite runs 5 tests in a few seconds.

💚 How did you test it?

  • All 5 tests pass on Spring Boot 2.7.18's BOM (Spring 5.3.31, Tomcat 9.0).
  • They also pass with the catalog set to 2.4.13.
  • The suite's runtime classpath has no Spring Boot jar.
  • Without Sentry's initializer, the error has no request.
  • :sentry-spring:check passes, including animal sniffer, and the sample's WAR still builds.

📝 Checklist

  • I added GH Issue ID & Linear ID
  • I added tests to verify the changes.
  • No new PII added or SDK only sends newly added PII if sendDefaultPII is enabled.
  • I updated the docs if needed.
  • I updated the wizard if needed.
  • Review from the native team if needed.
  • No breaking change or entry added to the changelog.
  • No breaking change for hybrid SDKs or communicated to hybrid SDKs.
  • Public API changes reviewed by another Mobile SDK team member or implemented according to the develop docs spec.

🔮 Next steps

The console samples: log4j2 and JUL into their modules, then the plain console sample.

#skip-changelog

🤖 Generated with Claude Code

This was referenced Oct 20, 2026
@sentry

sentry Bot commented Oct 20, 2026 •

Copy link
Copy Markdown

📲 Install Builds

Android

🔗 App Name App ID Version Configuration
SDK Size io.sentry.tests.size 8.61.1 (1) release

⚙️ sentry-android Build Distribution Settings

@runningcode
runningcode force-pushed the no/spring-7-integration-test branch 2 times, most recently from 84b5a63 to 15246a5 Compare October 23, 2026 11:51
@runningcode
runningcode force-pushed the no/spring-integration-test branch 2 times, most recently from 162bf35 to c51a4e8 Compare October 23, 2026 12:48
@runningcode
runningcode force-pushed the no/spring-7-integration-test branch from 15246a5 to 82f9173 Compare October 23, 2026 12:48
@runningcode
runningcode force-pushed the no/spring-integration-test branch from c51a4e8 to 892c858 Compare October 23, 2026 13:02
@runningcode
runningcode force-pushed the no/spring-7-integration-test branch from 82f9173 to 840a54e Compare October 23, 2026 13:02
@runningcode
runningcode force-pushed the no/spring-integration-test branch from 892c858 to ec269f4 Compare October 23, 2026 13:53
Adds sentry-spring-jakarta's embedded-Tomcat integrationTest suite to
sentry-spring, with the module's packages and javax.servlet. The
sample's tests were the jakarta WAR sample's, so the suite is too.
Spring Boot 2's BOM picks Spring 5.3 and Tomcat 9.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 2 matrix. That was the
matrix's last runner step, so it drops the Python setup, the runner's
logs and the exclude properties only the samples and the runner read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@runningcode
runningcode force-pushed the no/spring-7-integration-test branch from 1acad11 to f9b8fdc Compare October 23, 2026 15:10
@runningcode
runningcode force-pushed the no/spring-integration-test branch from ec269f4 to d859296 Compare October 23, 2026 15:10
- name: Install Python dependencies
run: |
python3 -m pip install --upgrade pip
python3 -m pip install -r requirements.txt

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

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

🔥 python for spring boot 2 is 🔥

…into sentry-log4j2 (#6322)

* test(log4j2): Move the log4j2 sample's system test into sentry-log4j2

Adds SentryAppenderIntegrationTest, which configures the Sentry appender
from XML in a logger context of its own and checks what reaches
MockSentryServer: the warning event with its context tag and flag, the
error with its exception and breadcrumbs, and the logs with their
attributes. Logs are enabled through external configuration, as the
sample's sentry.properties does, because the appender has no attribute
for them.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(jul): [Sample Tests 31] Move the JUL sample's system test into sentry-jul (#6323)

* test(jul): Move the JUL sample's system test into sentry-jul

Adds SentryHandlerIntegrationTest, which configures the Sentry handler
through a logging properties file read by LogManager, as the sample
does, and checks what reaches MockSentryServer: the warning with its
flag, the error with its exception and breadcrumbs, and the logs with
their attributes. Its logger is outside io.sentry, whose loggers the
handler drops, and the test restores the LogManager configuration the
other tests read.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 32] Add end-to-end tests of the core APIs and a profiled transaction (#6324)

* test(core): Add an end-to-end test of the core APIs over the HTTP transport

SentryEndToEndTest reports through the APIs an app uses without
integrations and checks what reaches MockSentryServer: messages at the
scope's and an explicit level, an exception with its feature flag, an
event with a fingerprint, breadcrumbs from an event processor and a
beforeBreadcrumb callback, ten events in a row, a transaction with a
child span, and metrics with the scope's attributes.

It ports the core part of the console sample's system test, which ran
the sample's JAR against the Python mock server. The sample's profiling
and Kafka parts follow in their own modules.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type end to end

The console sample's test checked that the captured exception arrives
with its type, RuntimeException, not just its value.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(core): Check that the shutdown hook delivers what an app reported before exiting

The console samples' system tests ran each sample in its own JVM,
asserted that it exited with 0 within 30 seconds, and relied on the
shutdown hook to send everything, because the samples never flush or
close Sentry. The in-process end-to-end tests flush explicitly, so
neither the clean exit nor the hook's flush was tested any more.

Run a small app in a child JVM that returns from main without flushing,
and check that it exits with 0 and that its event, log and metric
arrive.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): [Sample Tests 34] Add an end-to-end test of the raw Kafka client's tracing (#6326)

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): Add an end-to-end test of the raw Kafka client's tracing

SentryKafkaEndToEndTest publishes a message through a wrapped
KafkaProducer to an in-JVM KRaft broker, consumes it with
SentryKafkaConsumerTracing, and checks what reaches MockSentryServer:
the queue.publish span in the producing transaction, and a queue.process
transaction with the consumer origin and the Kafka system that continues
the producer's trace. It ports the Kafka part of the console sample's
system test, which needed a Redpanda container.

The broker comes from spring-kafka-test 3, which needs Java 17, so the
test classpaths resolve Java 17 variants. The tests run on it anyway.

With its core, profiling and Kafka parts ported, the console sample has
no system test left, so it comes off the system-test runner and the
backend workflow, whose base row moves to the console OTLP sample.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 35] Add an end-to-end test of the agentless OpenTelemetry setup (#6327)

* test(opentelemetry): Add an end-to-end test of the agentless OpenTelemetry setup

AgentlessEndToEndTest builds the OpenTelemetry SDK through its
autoconfiguration, which loads Sentry's customizer, and checks what
reaches MockSentryServer: events, a transaction traced through
OpenTelemetry with its child span and profile, and metrics. It ports
sentry-samples-console-opentelemetry-noagent's system test, which no CI
job ran.

The customizer only initializes Sentry when the environment asks it to,
so the test task sets SENTRY_AUTO_INIT. These are the module's first
tests, so it applies the Kotlin plugin and gets an API dump.

The sample has no system test left, so it comes off the system-test
runner and drops the Kotlin plugin it only needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type in agentless mode

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 36] Add an end-to-end test of the OTLP event linking (#6328)

* test(opentelemetry): Add an end-to-end test of the OTLP event linking

OtlpEndToEndTest captures a message, a log and a metric inside an
OpenTelemetry span with OpenTelemetryOtlpEventProcessor installed, and
checks what reaches MockSentryServer: the event carries the span's trace
and span IDs, and the log and the metric arrive. It ports the
OTLP-specific part of the console OTLP sample's system test, which never
checked the link. The sample's other assertions are the console
sample's, which SentryEndToEndTest covers.

The sample has no system test left, so it comes off the system-test
runner and the backend workflow, whose base row moves to the Spring
Boot 4 OTLP sample, and drops the Kotlin plugin it only needed for the
test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring-boot): [Sample Tests 37] Move the Boot 4 OTLP sample's tests into the module (#6329)

* test(spring-boot): Move the Boot 4 OTLP sample's tests into the module

Adds an integrationTestOtlp suite to sentry-spring-boot-4: the servlet
app with the OpenTelemetry Spring Boot starter, set up by
sentry-opentelemetry-otlp-spring, and OpenTelemetryOtlpEventProcessor.
It ports the sample's tests, which were the servlet suite's without
OkHttp, and keeps the log and metric attribute checks the sample had
dropped.

The sample's transactions came from Sentry's own tracing, which CI
enabled with SENTRY_TRACES_SAMPLE_RATE, so the suite sets the sample
rate the same way. A new test checks what OTLP mode is for: an error in
a request carries the request's OpenTelemetry trace. Events point at
that trace rather than at Sentry's transaction, so the GraphQL errors
are checked next to their transactions instead of by trace ID, as the
sample did.

The sample has no system tests left, so it comes off the system-test
runner. It was the backend workflow's last sample, so the workflow goes
too. The Spring Boot 4 matrix runs the new suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and port them to the Boot 4 OTLP suite

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 38] Remove the system-test runner and its Python mock server (#6330)

* test: Remove the system-test runner and its Python mock server

Every sample's system test now lives in the module it tests, so the
Python runner, its mock Sentry server, requirements.txt and the Makefile
targets that ran them have nothing left to run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 39] Remove the io.sentry.systemtest plugin and sentry-system-test-support (#6331)

* test: Remove the io.sentry.systemtest plugin and sentry-system-test-support

With the runner gone, nothing applies the io.sentry.systemtest
convention plugin or depends on sentry-system-test-support, which held
the HTTP and GraphQL clients and the TestHelper the system tests used.
The envelope matchers it delegated to stay in sentry-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs: [Sample Tests 40] Describe the in-module end-to-end tests instead of the system tests (#6332)

* docs: Describe the in-module end-to-end tests instead of the system tests

The e2e_tests rule now covers MockSentryServer, where each kind of
end-to-end test lives, the Spring suites per flavor, the OpenTelemetry
agent fixture, how to run them and the gotchas the migration found. The
test skill runs integration suites by their source set instead of the
Python runner, the new_module rule no longer asks for sample tests, and
AGENTS.md drops sentry-system-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and document the test client and log4j2 suite

The context's TestRestTemplate adds trace headers of its own whenever
Sentry customizes the RestTemplateBuilder, not only in OpenTelemetry
mode, and the Spring Boot modules have an integrationTestLog4j2 suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
@runningcode
runningcode merged commit e506d5d into no/spring-7-integration-test Oct 27, 2026
38 checks passed
@runningcode
runningcode deleted the no/spring-integration-test branch October 27, 2026 08:13
runningcode added a commit that referenced this pull request Oct 27, 2026
…into the module (#6320)

* test(spring): Move the Spring 7 WAR sample's tests into the module

Adds sentry-spring-jakarta's embedded-Tomcat integrationTest suite to
sentry-spring-7, with the module's packages. The sample's tests were
the jakarta WAR sample's, so the suite is too. Spring Boot 4's BOM picks
Spring 7 and Tomcat 11.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 4 matrix. That was the
matrix's last runner step, so it drops the Python setup and the runner's
logs too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring): [Sample Tests 29] Move the Spring WAR sample's tests into the module (#6321)

* test(spring): Move the Spring WAR sample's tests into the module

Adds sentry-spring-jakarta's embedded-Tomcat integrationTest suite to
sentry-spring, with the module's packages and javax.servlet. The
sample's tests were the jakarta WAR sample's, so the suite is too.
Spring Boot 2's BOM picks Spring 5.3 and Tomcat 9.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 2 matrix. That was the
matrix's last runner step, so it drops the Python setup, the runner's
logs and the exclude properties only the samples and the runner read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(log4j2): [Sample Tests 30] Move the log4j2 sample's system test into sentry-log4j2 (#6322)

* test(log4j2): Move the log4j2 sample's system test into sentry-log4j2

Adds SentryAppenderIntegrationTest, which configures the Sentry appender
from XML in a logger context of its own and checks what reaches
MockSentryServer: the warning event with its context tag and flag, the
error with its exception and breadcrumbs, and the logs with their
attributes. Logs are enabled through external configuration, as the
sample's sentry.properties does, because the appender has no attribute
for them.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(jul): [Sample Tests 31] Move the JUL sample's system test into sentry-jul (#6323)

* test(jul): Move the JUL sample's system test into sentry-jul

Adds SentryHandlerIntegrationTest, which configures the Sentry handler
through a logging properties file read by LogManager, as the sample
does, and checks what reaches MockSentryServer: the warning with its
flag, the error with its exception and breadcrumbs, and the logs with
their attributes. Its logger is outside io.sentry, whose loggers the
handler drops, and the test restores the LogManager configuration the
other tests read.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 32] Add end-to-end tests of the core APIs and a profiled transaction (#6324)

* test(core): Add an end-to-end test of the core APIs over the HTTP transport

SentryEndToEndTest reports through the APIs an app uses without
integrations and checks what reaches MockSentryServer: messages at the
scope's and an explicit level, an exception with its feature flag, an
event with a fingerprint, breadcrumbs from an event processor and a
beforeBreadcrumb callback, ten events in a row, a transaction with a
child span, and metrics with the scope's attributes.

It ports the core part of the console sample's system test, which ran
the sample's JAR against the Python mock server. The sample's profiling
and Kafka parts follow in their own modules.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type end to end

The console sample's test checked that the captured exception arrives
with its type, RuntimeException, not just its value.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(core): Check that the shutdown hook delivers what an app reported before exiting

The console samples' system tests ran each sample in its own JVM,
asserted that it exited with 0 within 30 seconds, and relied on the
shutdown hook to send everything, because the samples never flush or
close Sentry. The in-process end-to-end tests flush explicitly, so
neither the clean exit nor the hook's flush was tested any more.

Run a small app in a child JVM that returns from main without flushing,
and check that it exits with 0 and that its event, log and metric
arrive.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): [Sample Tests 34] Add an end-to-end test of the raw Kafka client's tracing (#6326)

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): Add an end-to-end test of the raw Kafka client's tracing

SentryKafkaEndToEndTest publishes a message through a wrapped
KafkaProducer to an in-JVM KRaft broker, consumes it with
SentryKafkaConsumerTracing, and checks what reaches MockSentryServer:
the queue.publish span in the producing transaction, and a queue.process
transaction with the consumer origin and the Kafka system that continues
the producer's trace. It ports the Kafka part of the console sample's
system test, which needed a Redpanda container.

The broker comes from spring-kafka-test 3, which needs Java 17, so the
test classpaths resolve Java 17 variants. The tests run on it anyway.

With its core, profiling and Kafka parts ported, the console sample has
no system test left, so it comes off the system-test runner and the
backend workflow, whose base row moves to the console OTLP sample.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 35] Add an end-to-end test of the agentless OpenTelemetry setup (#6327)

* test(opentelemetry): Add an end-to-end test of the agentless OpenTelemetry setup

AgentlessEndToEndTest builds the OpenTelemetry SDK through its
autoconfiguration, which loads Sentry's customizer, and checks what
reaches MockSentryServer: events, a transaction traced through
OpenTelemetry with its child span and profile, and metrics. It ports
sentry-samples-console-opentelemetry-noagent's system test, which no CI
job ran.

The customizer only initializes Sentry when the environment asks it to,
so the test task sets SENTRY_AUTO_INIT. These are the module's first
tests, so it applies the Kotlin plugin and gets an API dump.

The sample has no system test left, so it comes off the system-test
runner and drops the Kotlin plugin it only needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type in agentless mode

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 36] Add an end-to-end test of the OTLP event linking (#6328)

* test(opentelemetry): Add an end-to-end test of the OTLP event linking

OtlpEndToEndTest captures a message, a log and a metric inside an
OpenTelemetry span with OpenTelemetryOtlpEventProcessor installed, and
checks what reaches MockSentryServer: the event carries the span's trace
and span IDs, and the log and the metric arrive. It ports the
OTLP-specific part of the console OTLP sample's system test, which never
checked the link. The sample's other assertions are the console
sample's, which SentryEndToEndTest covers.

The sample has no system test left, so it comes off the system-test
runner and the backend workflow, whose base row moves to the Spring
Boot 4 OTLP sample, and drops the Kotlin plugin it only needed for the
test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring-boot): [Sample Tests 37] Move the Boot 4 OTLP sample's tests into the module (#6329)

* test(spring-boot): Move the Boot 4 OTLP sample's tests into the module

Adds an integrationTestOtlp suite to sentry-spring-boot-4: the servlet
app with the OpenTelemetry Spring Boot starter, set up by
sentry-opentelemetry-otlp-spring, and OpenTelemetryOtlpEventProcessor.
It ports the sample's tests, which were the servlet suite's without
OkHttp, and keeps the log and metric attribute checks the sample had
dropped.

The sample's transactions came from Sentry's own tracing, which CI
enabled with SENTRY_TRACES_SAMPLE_RATE, so the suite sets the sample
rate the same way. A new test checks what OTLP mode is for: an error in
a request carries the request's OpenTelemetry trace. Events point at
that trace rather than at Sentry's transaction, so the GraphQL errors
are checked next to their transactions instead of by trace ID, as the
sample did.

The sample has no system tests left, so it comes off the system-test
runner. It was the backend workflow's last sample, so the workflow goes
too. The Spring Boot 4 matrix runs the new suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and port them to the Boot 4 OTLP suite

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 38] Remove the system-test runner and its Python mock server (#6330)

* test: Remove the system-test runner and its Python mock server

Every sample's system test now lives in the module it tests, so the
Python runner, its mock Sentry server, requirements.txt and the Makefile
targets that ran them have nothing left to run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 39] Remove the io.sentry.systemtest plugin and sentry-system-test-support (#6331)

* test: Remove the io.sentry.systemtest plugin and sentry-system-test-support

With the runner gone, nothing applies the io.sentry.systemtest
convention plugin or depends on sentry-system-test-support, which held
the HTTP and GraphQL clients and the TestHelper the system tests used.
The envelope matchers it delegated to stay in sentry-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs: [Sample Tests 40] Describe the in-module end-to-end tests instead of the system tests (#6332)

* docs: Describe the in-module end-to-end tests instead of the system tests

The e2e_tests rule now covers MockSentryServer, where each kind of
end-to-end test lives, the Spring suites per flavor, the OpenTelemetry
agent fixture, how to run them and the gotchas the migration found. The
test skill runs integration suites by their source set instead of the
Python runner, the new_module rule no longer asks for sample tests, and
AGENTS.md drops sentry-system-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and document the test client and log4j2 suite

The context's TestRestTemplate adds trace headers of its own whenever
Sentry customizes the RestTemplateBuilder, not only in OpenTelemetry
mode, and the Spring Boot modules have an integrationTestLog4j2 suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring): [Sample Tests 29] Move the Spring WAR sample's tests into the module (#6321)

* test(spring): Move the Spring WAR sample's tests into the module

Adds sentry-spring-jakarta's embedded-Tomcat integrationTest suite to
sentry-spring, with the module's packages and javax.servlet. The
sample's tests were the jakarta WAR sample's, so the suite is too.
Spring Boot 2's BOM picks Spring 5.3 and Tomcat 9.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 2 matrix. That was the
matrix's last runner step, so it drops the Python setup, the runner's
logs and the exclude properties only the samples and the runner read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(log4j2): [Sample Tests 30] Move the log4j2 sample's system test into sentry-log4j2 (#6322)

* test(log4j2): Move the log4j2 sample's system test into sentry-log4j2

Adds SentryAppenderIntegrationTest, which configures the Sentry appender
from XML in a logger context of its own and checks what reaches
MockSentryServer: the warning event with its context tag and flag, the
error with its exception and breadcrumbs, and the logs with their
attributes. Logs are enabled through external configuration, as the
sample's sentry.properties does, because the appender has no attribute
for them.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(jul): [Sample Tests 31] Move the JUL sample's system test into sentry-jul (#6323)

* test(jul): Move the JUL sample's system test into sentry-jul

Adds SentryHandlerIntegrationTest, which configures the Sentry handler
through a logging properties file read by LogManager, as the sample
does, and checks what reaches MockSentryServer: the warning with its
flag, the error with its exception and breadcrumbs, and the logs with
their attributes. Its logger is outside io.sentry, whose loggers the
handler drops, and the test restores the LogManager configuration the
other tests read.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 32] Add end-to-end tests of the core APIs and a profiled transaction (#6324)

* test(core): Add an end-to-end test of the core APIs over the HTTP transport

SentryEndToEndTest reports through the APIs an app uses without
integrations and checks what reaches MockSentryServer: messages at the
scope's and an explicit level, an exception with its feature flag, an
event with a fingerprint, breadcrumbs from an event processor and a
beforeBreadcrumb callback, ten events in a row, a transaction with a
child span, and metrics with the scope's attributes.

It ports the core part of the console sample's system test, which ran
the sample's JAR against the Python mock server. The sample's profiling
and Kafka parts follow in their own modules.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type end to end

The console sample's test checked that the captured exception arrives
with its type, RuntimeException, not just its value.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(core): Check that the shutdown hook delivers what an app reported before exiting

The console samples' system tests ran each sample in its own JVM,
asserted that it exited with 0 within 30 seconds, and relied on the
shutdown hook to send everything, because the samples never flush or
close Sentry. The in-process end-to-end tests flush explicitly, so
neither the clean exit nor the hook's flush was tested any more.

Run a small app in a child JVM that returns from main without flushing,
and check that it exits with 0 and that its event, log and metric
arrive.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): [Sample Tests 34] Add an end-to-end test of the raw Kafka client's tracing (#6326)

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): Add an end-to-end test of the raw Kafka client's tracing

SentryKafkaEndToEndTest publishes a message through a wrapped
KafkaProducer to an in-JVM KRaft broker, consumes it with
SentryKafkaConsumerTracing, and checks what reaches MockSentryServer:
the queue.publish span in the producing transaction, and a queue.process
transaction with the consumer origin and the Kafka system that continues
the producer's trace. It ports the Kafka part of the console sample's
system test, which needed a Redpanda container.

The broker comes from spring-kafka-test 3, which needs Java 17, so the
test classpaths resolve Java 17 variants. The tests run on it anyway.

With its core, profiling and Kafka parts ported, the console sample has
no system test left, so it comes off the system-test runner and the
backend workflow, whose base row moves to the console OTLP sample.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 35] Add an end-to-end test of the agentless OpenTelemetry setup (#6327)

* test(opentelemetry): Add an end-to-end test of the agentless OpenTelemetry setup

AgentlessEndToEndTest builds the OpenTelemetry SDK through its
autoconfiguration, which loads Sentry's customizer, and checks what
reaches MockSentryServer: events, a transaction traced through
OpenTelemetry with its child span and profile, and metrics. It ports
sentry-samples-console-opentelemetry-noagent's system test, which no CI
job ran.

The customizer only initializes Sentry when the environment asks it to,
so the test task sets SENTRY_AUTO_INIT. These are the module's first
tests, so it applies the Kotlin plugin and gets an API dump.

The sample has no system test left, so it comes off the system-test
runner and drops the Kotlin plugin it only needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type in agentless mode

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 36] Add an end-to-end test of the OTLP event linking (#6328)

* test(opentelemetry): Add an end-to-end test of the OTLP event linking

OtlpEndToEndTest captures a message, a log and a metric inside an
OpenTelemetry span with OpenTelemetryOtlpEventProcessor installed, and
checks what reaches MockSentryServer: the event carries the span's trace
and span IDs, and the log and the metric arrive. It ports the
OTLP-specific part of the console OTLP sample's system test, which never
checked the link. The sample's other assertions are the console
sample's, which SentryEndToEndTest covers.

The sample has no system test left, so it comes off the system-test
runner and the backend workflow, whose base row moves to the Spring
Boot 4 OTLP sample, and drops the Kotlin plugin it only needed for the
test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring-boot): [Sample Tests 37] Move the Boot 4 OTLP sample's tests into the module (#6329)

* test(spring-boot): Move the Boot 4 OTLP sample's tests into the module

Adds an integrationTestOtlp suite to sentry-spring-boot-4: the servlet
app with the OpenTelemetry Spring Boot starter, set up by
sentry-opentelemetry-otlp-spring, and OpenTelemetryOtlpEventProcessor.
It ports the sample's tests, which were the servlet suite's without
OkHttp, and keeps the log and metric attribute checks the sample had
dropped.

The sample's transactions came from Sentry's own tracing, which CI
enabled with SENTRY_TRACES_SAMPLE_RATE, so the suite sets the sample
rate the same way. A new test checks what OTLP mode is for: an error in
a request carries the request's OpenTelemetry trace. Events point at
that trace rather than at Sentry's transaction, so the GraphQL errors
are checked next to their transactions instead of by trace ID, as the
sample did.

The sample has no system tests left, so it comes off the system-test
runner. It was the backend workflow's last sample, so the workflow goes
too. The Spring Boot 4 matrix runs the new suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and port them to the Boot 4 OTLP suite

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 38] Remove the system-test runner and its Python mock server (#6330)

* test: Remove the system-test runner and its Python mock server

Every sample's system test now lives in the module it tests, so the
Python runner, its mock Sentry server, requirements.txt and the Makefile
targets that ran them have nothing left to run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 39] Remove the io.sentry.systemtest plugin and sentry-system-test-support (#6331)

* test: Remove the io.sentry.systemtest plugin and sentry-system-test-support

With the runner gone, nothing applies the io.sentry.systemtest
convention plugin or depends on sentry-system-test-support, which held
the HTTP and GraphQL clients and the TestHelper the system tests used.
The envelope matchers it delegated to stay in sentry-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs: [Sample Tests 40] Describe the in-module end-to-end tests instead of the system tests (#6332)

* docs: Describe the in-module end-to-end tests instead of the system tests

The e2e_tests rule now covers MockSentryServer, where each kind of
end-to-end test lives, the Spring suites per flavor, the OpenTelemetry
agent fixture, how to run them and the gotchas the migration found. The
test skill runs integration suites by their source set instead of the
Python runner, the new_module rule no longer asks for sample tests, and
AGENTS.md drops sentry-system-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and document the test client and log4j2 suite

The context's TestRestTemplate adds trace headers of its own whenever
Sentry customizes the RestTemplateBuilder, not only in OpenTelemetry
mode, and the Spring Boot modules have an integrationTestLog4j2 suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
runningcode added a commit that referenced this pull request Oct 27, 2026
…tests into the module (#6319)

* test(spring): Move the Spring jakarta WAR sample's tests into the module

Adds an integrationTest suite to sentry-spring-jakarta that runs a plain
Spring MVC app, set up by an AbstractAnnotationConfigDispatcherServletInitializer
as in a WAR, in an embedded Tomcat against MockSentryServer. Tomcat runs
every servlet container initializer the classpath registers, as it does
for a WAR, and Spring Boot stays off the classpath, so Sentry's
initializer adds SentrySpringFilter the way it does in a real
deployment. The suite ports the sample's Person and Metrics tests and
also checks that the error carries its request.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the suite puts it in the temp dir.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 3 matrix. That was the
matrix's last runner step, so it drops the Python setup and the runner's
logs too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring): [Sample Tests 28] Move the Spring 7 WAR sample's tests into the module (#6320)

* test(spring): Move the Spring 7 WAR sample's tests into the module

Adds sentry-spring-jakarta's embedded-Tomcat integrationTest suite to
sentry-spring-7, with the module's packages. The sample's tests were
the jakarta WAR sample's, so the suite is too. Spring Boot 4's BOM picks
Spring 7 and Tomcat 11.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 4 matrix. That was the
matrix's last runner step, so it drops the Python setup and the runner's
logs too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring): [Sample Tests 29] Move the Spring WAR sample's tests into the module (#6321)

* test(spring): Move the Spring WAR sample's tests into the module

Adds sentry-spring-jakarta's embedded-Tomcat integrationTest suite to
sentry-spring, with the module's packages and javax.servlet. The
sample's tests were the jakarta WAR sample's, so the suite is too.
Spring Boot 2's BOM picks Spring 5.3 and Tomcat 9.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 2 matrix. That was the
matrix's last runner step, so it drops the Python setup, the runner's
logs and the exclude properties only the samples and the runner read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(log4j2): [Sample Tests 30] Move the log4j2 sample's system test into sentry-log4j2 (#6322)

* test(log4j2): Move the log4j2 sample's system test into sentry-log4j2

Adds SentryAppenderIntegrationTest, which configures the Sentry appender
from XML in a logger context of its own and checks what reaches
MockSentryServer: the warning event with its context tag and flag, the
error with its exception and breadcrumbs, and the logs with their
attributes. Logs are enabled through external configuration, as the
sample's sentry.properties does, because the appender has no attribute
for them.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(jul): [Sample Tests 31] Move the JUL sample's system test into sentry-jul (#6323)

* test(jul): Move the JUL sample's system test into sentry-jul

Adds SentryHandlerIntegrationTest, which configures the Sentry handler
through a logging properties file read by LogManager, as the sample
does, and checks what reaches MockSentryServer: the warning with its
flag, the error with its exception and breadcrumbs, and the logs with
their attributes. Its logger is outside io.sentry, whose loggers the
handler drops, and the test restores the LogManager configuration the
other tests read.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 32] Add end-to-end tests of the core APIs and a profiled transaction (#6324)

* test(core): Add an end-to-end test of the core APIs over the HTTP transport

SentryEndToEndTest reports through the APIs an app uses without
integrations and checks what reaches MockSentryServer: messages at the
scope's and an explicit level, an exception with its feature flag, an
event with a fingerprint, breadcrumbs from an event processor and a
beforeBreadcrumb callback, ten events in a row, a transaction with a
child span, and metrics with the scope's attributes.

It ports the core part of the console sample's system test, which ran
the sample's JAR against the Python mock server. The sample's profiling
and Kafka parts follow in their own modules.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type end to end

The console sample's test checked that the captured exception arrives
with its type, RuntimeException, not just its value.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(core): Check that the shutdown hook delivers what an app reported before exiting

The console samples' system tests ran each sample in its own JVM,
asserted that it exited with 0 within 30 seconds, and relied on the
shutdown hook to send everything, because the samples never flush or
close Sentry. The in-process end-to-end tests flush explicitly, so
neither the clean exit nor the hook's flush was tested any more.

Run a small app in a child JVM that returns from main without flushing,
and check that it exits with 0 and that its event, log and metric
arrive.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): [Sample Tests 34] Add an end-to-end test of the raw Kafka client's tracing (#6326)

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): Add an end-to-end test of the raw Kafka client's tracing

SentryKafkaEndToEndTest publishes a message through a wrapped
KafkaProducer to an in-JVM KRaft broker, consumes it with
SentryKafkaConsumerTracing, and checks what reaches MockSentryServer:
the queue.publish span in the producing transaction, and a queue.process
transaction with the consumer origin and the Kafka system that continues
the producer's trace. It ports the Kafka part of the console sample's
system test, which needed a Redpanda container.

The broker comes from spring-kafka-test 3, which needs Java 17, so the
test classpaths resolve Java 17 variants. The tests run on it anyway.

With its core, profiling and Kafka parts ported, the console sample has
no system test left, so it comes off the system-test runner and the
backend workflow, whose base row moves to the console OTLP sample.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 35] Add an end-to-end test of the agentless OpenTelemetry setup (#6327)

* test(opentelemetry): Add an end-to-end test of the agentless OpenTelemetry setup

AgentlessEndToEndTest builds the OpenTelemetry SDK through its
autoconfiguration, which loads Sentry's customizer, and checks what
reaches MockSentryServer: events, a transaction traced through
OpenTelemetry with its child span and profile, and metrics. It ports
sentry-samples-console-opentelemetry-noagent's system test, which no CI
job ran.

The customizer only initializes Sentry when the environment asks it to,
so the test task sets SENTRY_AUTO_INIT. These are the module's first
tests, so it applies the Kotlin plugin and gets an API dump.

The sample has no system test left, so it comes off the system-test
runner and drops the Kotlin plugin it only needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type in agentless mode

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 36] Add an end-to-end test of the OTLP event linking (#6328)

* test(opentelemetry): Add an end-to-end test of the OTLP event linking

OtlpEndToEndTest captures a message, a log and a metric inside an
OpenTelemetry span with OpenTelemetryOtlpEventProcessor installed, and
checks what reaches MockSentryServer: the event carries the span's trace
and span IDs, and the log and the metric arrive. It ports the
OTLP-specific part of the console OTLP sample's system test, which never
checked the link. The sample's other assertions are the console
sample's, which SentryEndToEndTest covers.

The sample has no system test left, so it comes off the system-test
runner and the backend workflow, whose base row moves to the Spring
Boot 4 OTLP sample, and drops the Kotlin plugin it only needed for the
test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring-boot): [Sample Tests 37] Move the Boot 4 OTLP sample's tests into the module (#6329)

* test(spring-boot): Move the Boot 4 OTLP sample's tests into the module

Adds an integrationTestOtlp suite to sentry-spring-boot-4: the servlet
app with the OpenTelemetry Spring Boot starter, set up by
sentry-opentelemetry-otlp-spring, and OpenTelemetryOtlpEventProcessor.
It ports the sample's tests, which were the servlet suite's without
OkHttp, and keeps the log and metric attribute checks the sample had
dropped.

The sample's transactions came from Sentry's own tracing, which CI
enabled with SENTRY_TRACES_SAMPLE_RATE, so the suite sets the sample
rate the same way. A new test checks what OTLP mode is for: an error in
a request carries the request's OpenTelemetry trace. Events point at
that trace rather than at Sentry's transaction, so the GraphQL errors
are checked next to their transactions instead of by trace ID, as the
sample did.

The sample has no system tests left, so it comes off the system-test
runner. It was the backend workflow's last sample, so the workflow goes
too. The Spring Boot 4 matrix runs the new suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and port them to the Boot 4 OTLP suite

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 38] Remove the system-test runner and its Python mock server (#6330)

* test: Remove the system-test runner and its Python mock server

Every sample's system test now lives in the module it tests, so the
Python runner, its mock Sentry server, requirements.txt and the Makefile
targets that ran them have nothing left to run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 39] Remove the io.sentry.systemtest plugin and sentry-system-test-support (#6331)

* test: Remove the io.sentry.systemtest plugin and sentry-system-test-support

With the runner gone, nothing applies the io.sentry.systemtest
convention plugin or depends on sentry-system-test-support, which held
the HTTP and GraphQL clients and the TestHelper the system tests used.
The envelope matchers it delegated to stay in sentry-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs: [Sample Tests 40] Describe the in-module end-to-end tests instead of the system tests (#6332)

* docs: Describe the in-module end-to-end tests instead of the system tests

The e2e_tests rule now covers MockSentryServer, where each kind of
end-to-end test lives, the Spring suites per flavor, the OpenTelemetry
agent fixture, how to run them and the gotchas the migration found. The
test skill runs integration suites by their source set instead of the
Python runner, the new_module rule no longer asks for sample tests, and
AGENTS.md drops sentry-system-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and document the test client and log4j2 suite

The context's TestRestTemplate adds trace headers of its own whenever
Sentry customizes the RestTemplateBuilder, not only in OpenTelemetry
mode, and the Spring Boot modules have an integrationTestLog4j2 suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring): [Sample Tests 29] Move the Spring WAR sample's tests into the module (#6321)

* test(spring): Move the Spring WAR sample's tests into the module

Adds sentry-spring-jakarta's embedded-Tomcat integrationTest suite to
sentry-spring, with the module's packages and javax.servlet. The
sample's tests were the jakarta WAR sample's, so the suite is too.
Spring Boot 2's BOM picks Spring 5.3 and Tomcat 9.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 2 matrix. That was the
matrix's last runner step, so it drops the Python setup, the runner's
logs and the exclude properties only the samples and the runner read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(log4j2): [Sample Tests 30] Move the log4j2 sample's system test into sentry-log4j2 (#6322)

* test(log4j2): Move the log4j2 sample's system test into sentry-log4j2

Adds SentryAppenderIntegrationTest, which configures the Sentry appender
from XML in a logger context of its own and checks what reaches
MockSentryServer: the warning event with its context tag and flag, the
error with its exception and breadcrumbs, and the logs with their
attributes. Logs are enabled through external configuration, as the
sample's sentry.properties does, because the appender has no attribute
for them.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(jul): [Sample Tests 31] Move the JUL sample's system test into sentry-jul (#6323)

* test(jul): Move the JUL sample's system test into sentry-jul

Adds SentryHandlerIntegrationTest, which configures the Sentry handler
through a logging properties file read by LogManager, as the sample
does, and checks what reaches MockSentryServer: the warning with its
flag, the error with its exception and breadcrumbs, and the logs with
their attributes. Its logger is outside io.sentry, whose loggers the
handler drops, and the test restores the LogManager configuration the
other tests read.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 32] Add end-to-end tests of the core APIs and a profiled transaction (#6324)

* test(core): Add an end-to-end test of the core APIs over the HTTP transport

SentryEndToEndTest reports through the APIs an app uses without
integrations and checks what reaches MockSentryServer: messages at the
scope's and an explicit level, an exception with its feature flag, an
event with a fingerprint, breadcrumbs from an event processor and a
beforeBreadcrumb callback, ten events in a row, a transaction with a
child span, and metrics with the scope's attributes.

It ports the core part of the console sample's system test, which ran
the sample's JAR against the Python mock server. The sample's profiling
and Kafka parts follow in their own modules.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type end to end

The console sample's test checked that the captured exception arrives
with its type, RuntimeException, not just its value.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(core): Check that the shutdown hook delivers what an app reported before exiting

The console samples' system tests ran each sample in its own JVM,
asserted that it exited with 0 within 30 seconds, and relied on the
shutdown hook to send everything, because the samples never flush or
close Sentry. The in-process end-to-end tests flush explicitly, so
neither the clean exit nor the hook's flush was tested any more.

Run a small app in a child JVM that returns from main without flushing,
and check that it exits with 0 and that its event, log and metric
arrive.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): [Sample Tests 34] Add an end-to-end test of the raw Kafka client's tracing (#6326)

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): Add an end-to-end test of the raw Kafka client's tracing

SentryKafkaEndToEndTest publishes a message through a wrapped
KafkaProducer to an in-JVM KRaft broker, consumes it with
SentryKafkaConsumerTracing, and checks what reaches MockSentryServer:
the queue.publish span in the producing transaction, and a queue.process
transaction with the consumer origin and the Kafka system that continues
the producer's trace. It ports the Kafka part of the console sample's
system test, which needed a Redpanda container.

The broker comes from spring-kafka-test 3, which needs Java 17, so the
test classpaths resolve Java 17 variants. The tests run on it anyway.

With its core, profiling and Kafka parts ported, the console sample has
no system test left, so it comes off the system-test runner and the
backend workflow, whose base row moves to the console OTLP sample.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 35] Add an end-to-end test of the agentless OpenTelemetry setup (#6327)

* test(opentelemetry): Add an end-to-end test of the agentless OpenTelemetry setup

AgentlessEndToEndTest builds the OpenTelemetry SDK through its
autoconfiguration, which loads Sentry's customizer, and checks what
reaches MockSentryServer: events, a transaction traced through
OpenTelemetry with its child span and profile, and metrics. It ports
sentry-samples-console-opentelemetry-noagent's system test, which no CI
job ran.

The customizer only initializes Sentry when the environment asks it to,
so the test task sets SENTRY_AUTO_INIT. These are the module's first
tests, so it applies the Kotlin plugin and gets an API dump.

The sample has no system test left, so it comes off the system-test
runner and drops the Kotlin plugin it only needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type in agentless mode

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 36] Add an end-to-end test of the OTLP event linking (#6328)

* test(opentelemetry): Add an end-to-end test of the OTLP event linking

OtlpEndToEndTest captures a message, a log and a metric inside an
OpenTelemetry span with OpenTelemetryOtlpEventProcessor installed, and
checks what reaches MockSentryServer: the event carries the span's trace
and span IDs, and the log and the metric arrive. It ports the
OTLP-specific part of the console OTLP sample's system test, which never
checked the link. The sample's other assertions are the console
sample's, which SentryEndToEndTest covers.

The sample has no system test left, so it comes off the system-test
runner and the backend workflow, whose base row moves to the Spring
Boot 4 OTLP sample, and drops the Kotlin plugin it only needed for the
test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring-boot): [Sample Tests 37] Move the Boot 4 OTLP sample's tests into the module (#6329)

* test(spring-boot): Move the Boot 4 OTLP sample's tests into the module

Adds an integrationTestOtlp suite to sentry-spring-boot-4: the servlet
app with the OpenTelemetry Spring Boot starter, set up by
sentry-opentelemetry-otlp-spring, and OpenTelemetryOtlpEventProcessor.
It ports the sample's tests, which were the servlet suite's without
OkHttp, and keeps the log and metric attribute checks the sample had
dropped.

The sample's transactions came from Sentry's own tracing, which CI
enabled with SENTRY_TRACES_SAMPLE_RATE, so the suite sets the sample
rate the same way. A new test checks what OTLP mode is for: an error in
a request carries the request's OpenTelemetry trace. Events point at
that trace rather than at Sentry's transaction, so the GraphQL errors
are checked next to their transactions instead of by trace ID, as the
sample did.

The sample has no system tests left, so it comes off the system-test
runner. It was the backend workflow's last sample, so the workflow goes
too. The Spring Boot 4 matrix runs the new suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and port them to the Boot 4 OTLP suite

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 38] Remove the system-test runner and its Python mock server (#6330)

* test: Remove the system-test runner and its Python mock server

Every sample's system test now lives in the module it tests, so the
Python runner, its mock Sentry server, requirements.txt and the Makefile
targets that ran them have nothing left to run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 39] Remove the io.sentry.systemtest plugin and sentry-system-test-support (#6331)

* test: Remove the io.sentry.systemtest plugin and sentry-system-test-support

With the runner gone, nothing applies the io.sentry.systemtest
convention plugin or depends on sentry-system-test-support, which held
the HTTP and GraphQL clients and the TestHelper the system tests used.
The envelope matchers it delegated to stay in sentry-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs: [Sample Tests 40] Describe the in-module end-to-end tests instead of the system tests (#6332)

* docs: Describe the in-module end-to-end tests instead of the system tests

The e2e_tests rule now covers MockSentryServer, where each kind of
end-to-end test lives, the Spring suites per flavor, the OpenTelemetry
agent fixture, how to run them and the gotchas the migration found. The
test skill runs integration suites by their source set instead of the
Python runner, the new_module rule no longer asks for sample tests, and
AGENTS.md drops sentry-system-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and document the test client and log4j2 suite

The context's TestRestTemplate adds trace headers of its own whenever
Sentry customizes the RestTemplateBuilder, not only in OpenTelemetry
mode, and the Spring Boot modules have an integrationTestLog4j2 suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
runningcode added a commit that referenced this pull request Oct 27, 2026
…e's tests (#6318)

* test(spring-boot): Move the Boot 2 OTel agent sample's tests into the module

Adds the agent setup to sentry-spring-boot, as in the Boot 3 and 4
modules. The sample's tests were the Boot 3 agent sample's minus Cache
and RestClient, which Boot 2 doesn't have. GraphQL and Kafka are gated
on Boot 2.7, as in the other Boot 2 suites.

The shared app has to start on Boot versions without Kafka support, so
the Kafka test starts an app of its own with the kafka profile and an
in-JVM broker. AgentApp becomes a class for that, with the shared
instance in its companion.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 2 matrix, which now
runs both agent tasks and no longer builds the agent separately.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and port them to the Boot 2 agent

Ports the tracing and GraphQL checks to the Boot 2 agent suite, and
gives the app three minutes to start, as for Boot 3 and 4.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring-boot): Stop the Boot 2 agent app when it fails to start

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(spring): [Sample Tests 27] Move the Spring jakarta WAR sample's tests into the module (#6319)

* test(spring): Move the Spring jakarta WAR sample's tests into the module

Adds an integrationTest suite to sentry-spring-jakarta that runs a plain
Spring MVC app, set up by an AbstractAnnotationConfigDispatcherServletInitializer
as in a WAR, in an embedded Tomcat against MockSentryServer. Tomcat runs
every servlet container initializer the classpath registers, as it does
for a WAR, and Spring Boot stays off the classpath, so Sentry's
initializer adds SentrySpringFilter the way it does in a real
deployment. The suite ports the sample's Person and Metrics tests and
also checks that the error carries its request.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the suite puts it in the temp dir.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 3 matrix. That was the
matrix's last runner step, so it drops the Python setup and the runner's
logs too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring): [Sample Tests 28] Move the Spring 7 WAR sample's tests into the module (#6320)

* test(spring): Move the Spring 7 WAR sample's tests into the module

Adds sentry-spring-jakarta's embedded-Tomcat integrationTest suite to
sentry-spring-7, with the module's packages. The sample's tests were
the jakarta WAR sample's, so the suite is too. Spring Boot 4's BOM picks
Spring 7 and Tomcat 11.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 4 matrix. That was the
matrix's last runner step, so it drops the Python setup and the runner's
logs too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring): [Sample Tests 29] Move the Spring WAR sample's tests into the module (#6321)

* test(spring): Move the Spring WAR sample's tests into the module

Adds sentry-spring-jakarta's embedded-Tomcat integrationTest suite to
sentry-spring, with the module's packages and javax.servlet. The
sample's tests were the jakarta WAR sample's, so the suite is too.
Spring Boot 2's BOM picks Spring 5.3 and Tomcat 9.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 2 matrix. That was the
matrix's last runner step, so it drops the Python setup, the runner's
logs and the exclude properties only the samples and the runner read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(log4j2): [Sample Tests 30] Move the log4j2 sample's system test into sentry-log4j2 (#6322)

* test(log4j2): Move the log4j2 sample's system test into sentry-log4j2

Adds SentryAppenderIntegrationTest, which configures the Sentry appender
from XML in a logger context of its own and checks what reaches
MockSentryServer: the warning event with its context tag and flag, the
error with its exception and breadcrumbs, and the logs with their
attributes. Logs are enabled through external configuration, as the
sample's sentry.properties does, because the appender has no attribute
for them.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(jul): [Sample Tests 31] Move the JUL sample's system test into sentry-jul (#6323)

* test(jul): Move the JUL sample's system test into sentry-jul

Adds SentryHandlerIntegrationTest, which configures the Sentry handler
through a logging properties file read by LogManager, as the sample
does, and checks what reaches MockSentryServer: the warning with its
flag, the error with its exception and breadcrumbs, and the logs with
their attributes. Its logger is outside io.sentry, whose loggers the
handler drops, and the test restores the LogManager configuration the
other tests read.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 32] Add end-to-end tests of the core APIs and a profiled transaction (#6324)

* test(core): Add an end-to-end test of the core APIs over the HTTP transport

SentryEndToEndTest reports through the APIs an app uses without
integrations and checks what reaches MockSentryServer: messages at the
scope's and an explicit level, an exception with its feature flag, an
event with a fingerprint, breadcrumbs from an event processor and a
beforeBreadcrumb callback, ten events in a row, a transaction with a
child span, and metrics with the scope's attributes.

It ports the core part of the console sample's system test, which ran
the sample's JAR against the Python mock server. The sample's profiling
and Kafka parts follow in their own modules.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type end to end

The console sample's test checked that the captured exception arrives
with its type, RuntimeException, not just its value.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(core): Check that the shutdown hook delivers what an app reported before exiting

The console samples' system tests ran each sample in its own JVM,
asserted that it exited with 0 within 30 seconds, and relied on the
shutdown hook to send everything, because the samples never flush or
close Sentry. The in-process end-to-end tests flush explicitly, so
neither the clean exit nor the hook's flush was tested any more.

Run a small app in a child JVM that returns from main without flushing,
and check that it exits with 0 and that its event, log and metric
arrive.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): [Sample Tests 34] Add an end-to-end test of the raw Kafka client's tracing (#6326)

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): Add an end-to-end test of the raw Kafka client's tracing

SentryKafkaEndToEndTest publishes a message through a wrapped
KafkaProducer to an in-JVM KRaft broker, consumes it with
SentryKafkaConsumerTracing, and checks what reaches MockSentryServer:
the queue.publish span in the producing transaction, and a queue.process
transaction with the consumer origin and the Kafka system that continues
the producer's trace. It ports the Kafka part of the console sample's
system test, which needed a Redpanda container.

The broker comes from spring-kafka-test 3, which needs Java 17, so the
test classpaths resolve Java 17 variants. The tests run on it anyway.

With its core, profiling and Kafka parts ported, the console sample has
no system test left, so it comes off the system-test runner and the
backend workflow, whose base row moves to the console OTLP sample.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 35] Add an end-to-end test of the agentless OpenTelemetry setup (#6327)

* test(opentelemetry): Add an end-to-end test of the agentless OpenTelemetry setup

AgentlessEndToEndTest builds the OpenTelemetry SDK through its
autoconfiguration, which loads Sentry's customizer, and checks what
reaches MockSentryServer: events, a transaction traced through
OpenTelemetry with its child span and profile, and metrics. It ports
sentry-samples-console-opentelemetry-noagent's system test, which no CI
job ran.

The customizer only initializes Sentry when the environment asks it to,
so the test task sets SENTRY_AUTO_INIT. These are the module's first
tests, so it applies the Kotlin plugin and gets an API dump.

The sample has no system test left, so it comes off the system-test
runner and drops the Kotlin plugin it only needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type in agentless mode

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 36] Add an end-to-end test of the OTLP event linking (#6328)

* test(opentelemetry): Add an end-to-end test of the OTLP event linking

OtlpEndToEndTest captures a message, a log and a metric inside an
OpenTelemetry span with OpenTelemetryOtlpEventProcessor installed, and
checks what reaches MockSentryServer: the event carries the span's trace
and span IDs, and the log and the metric arrive. It ports the
OTLP-specific part of the console OTLP sample's system test, which never
checked the link. The sample's other assertions are the console
sample's, which SentryEndToEndTest covers.

The sample has no system test left, so it comes off the system-test
runner and the backend workflow, whose base row moves to the Spring
Boot 4 OTLP sample, and drops the Kotlin plugin it only needed for the
test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring-boot): [Sample Tests 37] Move the Boot 4 OTLP sample's tests into the module (#6329)

* test(spring-boot): Move the Boot 4 OTLP sample's tests into the module

Adds an integrationTestOtlp suite to sentry-spring-boot-4: the servlet
app with the OpenTelemetry Spring Boot starter, set up by
sentry-opentelemetry-otlp-spring, and OpenTelemetryOtlpEventProcessor.
It ports the sample's tests, which were the servlet suite's without
OkHttp, and keeps the log and metric attribute checks the sample had
dropped.

The sample's transactions came from Sentry's own tracing, which CI
enabled with SENTRY_TRACES_SAMPLE_RATE, so the suite sets the sample
rate the same way. A new test checks what OTLP mode is for: an error in
a request carries the request's OpenTelemetry trace. Events point at
that trace rather than at Sentry's transaction, so the GraphQL errors
are checked next to their transactions instead of by trace ID, as the
sample did.

The sample has no system tests left, so it comes off the system-test
runner. It was the backend workflow's last sample, so the workflow goes
too. The Spring Boot 4 matrix runs the new suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and port them to the Boot 4 OTLP suite

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 38] Remove the system-test runner and its Python mock server (#6330)

* test: Remove the system-test runner and its Python mock server

Every sample's system test now lives in the module it tests, so the
Python runner, its mock Sentry server, requirements.txt and the Makefile
targets that ran them have nothing left to run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 39] Remove the io.sentry.systemtest plugin and sentry-system-test-support (#6331)

* test: Remove the io.sentry.systemtest plugin and sentry-system-test-support

With the runner gone, nothing applies the io.sentry.systemtest
convention plugin or depends on sentry-system-test-support, which held
the HTTP and GraphQL clients and the TestHelper the system tests used.
The envelope matchers it delegated to stay in sentry-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs: [Sample Tests 40] Describe the in-module end-to-end tests instead of the system tests (#6332)

* docs: Describe the in-module end-to-end tests instead of the system tests

The e2e_tests rule now covers MockSentryServer, where each kind of
end-to-end test lives, the Spring suites per flavor, the OpenTelemetry
agent fixture, how to run them and the gotchas the migration found. The
test skill runs integration suites by their source set instead of the
Python runner, the new_module rule no longer asks for sample tests, and
AGENTS.md drops sentry-system-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and document the test client and log4j2 suite

The context's TestRestTemplate adds trace headers of its own whenever
Sentry customizes the RestTemplateBuilder, not only in OpenTelemetry
mode, and the Spring Boot modules have an integrationTestLog4j2 suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring): [Sample Tests 29] Move the Spring WAR sample's tests into the module (#6321)

* test(spring): Move the Spring WAR sample's tests into the module

Adds sentry-spring-jakarta's embedded-Tomcat integrationTest suite to
sentry-spring, with the module's packages and javax.servlet. The
sample's tests were the jakarta WAR sample's, so the suite is too.
Spring Boot 2's BOM picks Spring 5.3 and Tomcat 9.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 2 matrix. That was the
matrix's last runner step, so it drops the Python setup, the runner's
logs and the exclude properties only the samples and the runner read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(log4j2): [Sample Tests 30] Move the log4j2 sample's system test into sentry-log4j2 (#6322)

* test(log4j2): Move the log4j2 sample's system test into sentry-log4j2

Adds SentryAppenderIntegrationTest, which configures the Sentry appender
from XML in a logger context of its own and checks what reaches
MockSentryServer: the warning event with its context tag and flag, the
error with its exception and breadcrumbs, and the logs with their
attributes. Logs are enabled through external configuration, as the
sample's sentry.properties does, because the appender has no attribute
for them.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(jul): [Sample Tests 31] Move the JUL sample's system test into sentry-jul (#6323)

* test(jul): Move the JUL sample's system test into sentry-jul

Adds SentryHandlerIntegrationTest, which configures the Sentry handler
through a logging properties file read by LogManager, as the sample
does, and checks what reaches MockSentryServer: the warning with its
flag, the error with its exception and breadcrumbs, and the logs with
their attributes. Its logger is outside io.sentry, whose loggers the
handler drops, and the test restores the LogManager configuration the
other tests read.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 32] Add end-to-end tests of the core APIs and a profiled transaction (#6324)

* test(core): Add an end-to-end test of the core APIs over the HTTP transport

SentryEndToEndTest reports through the APIs an app uses without
integrations and checks what reaches MockSentryServer: messages at the
scope's and an explicit level, an exception with its feature flag, an
event with a fingerprint, breadcrumbs from an event processor and a
beforeBreadcrumb callback, ten events in a row, a transaction with a
child span, and metrics with the scope's attributes.

It ports the core part of the console sample's system test, which ran
the sample's JAR against the Python mock server. The sample's profiling
and Kafka parts follow in their own modules.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type end to end

The console sample's test checked that the captured exception arrives
with its type, RuntimeException, not just its value.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(core): Check that the shutdown hook delivers what an app reported before exiting

The console samples' system tests ran each sample in its own JVM,
asserted that it exited with 0 within 30 seconds, and relied on the
shutdown hook to send everything, because the samples never flush or
close Sentry. The in-process end-to-end tests flush explicitly, so
neither the clean exit nor the hook's flush was tested any more.

Run a small app in a child JVM that returns from main without flushing,
and check that it exits with 0 and that its event, log and metric
arrive.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): [Sample Tests 34] Add an end-to-end test of the raw Kafka client's tracing (#6326)

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): Add an end-to-end test of the raw Kafka client's tracing

SentryKafkaEndToEndTest publishes a message through a wrapped
KafkaProducer to an in-JVM KRaft broker, consumes it with
SentryKafkaConsumerTracing, and checks what reaches MockSentryServer:
the queue.publish span in the producing transaction, and a queue.process
transaction with the consumer origin and the Kafka system that continues
the producer's trace. It ports the Kafka part of the console sample's
system test, which needed a Redpanda container.

The broker comes from spring-kafka-test 3, which needs Java 17, so the
test classpaths resolve Java 17 variants. The tests run on it anyway.

With its core, profiling and Kafka parts ported, the console sample has
no system test left, so it comes off the system-test runner and the
backend workflow, whose base row moves to the console OTLP sample.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 35] Add an end-to-end test of the agentless OpenTelemetry setup (#6327)

* test(opentelemetry): Add an end-to-end test of the agentless OpenTelemetry setup

AgentlessEndToEndTest builds the OpenTelemetry SDK through its
autoconfiguration, which loads Sentry's customizer, and checks what
reaches MockSentryServer: events, a transaction traced through
OpenTelemetry with its child span and profile, and metrics. It ports
sentry-samples-console-opentelemetry-noagent's system test, which no CI
job ran.

The customizer only initializes Sentry when the environment asks it to,
so the test task sets SENTRY_AUTO_INIT. These are the module's first
tests, so it applies the Kotlin plugin and gets an API dump.

The sample has no system test left, so it comes off the system-test
runner and drops the Kotlin plugin it only needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type in agentless mode

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 36] Add an end-to-end test of the OTLP event linking (#6328)

* test(opentelemetry): Add an end-to-end test of the OTLP event linking

OtlpEndToEndTest captures a message, a log and a metric inside an
OpenTelemetry span with OpenTelemetryOtlpEventProcessor installed, and
checks what reaches MockSentryServer: the event carries the span's trace
and span IDs, and the log and the metric arrive. It ports the
OTLP-specific part of the console OTLP sample's system test, which never
checked the link. The sample's other assertions are the console
sample's, which SentryEndToEndTest covers.

The sample has no system test left, so it comes off the system-test
runner and the backend workflow, whose base row moves to the Spring
Boot 4 OTLP sample, and drops the Kotlin plugin it only needed for the
test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring-boot): [Sample Tests 37] Move the Boot 4 OTLP sample's tests into the module (#6329)

* test(spring-boot): Move the Boot 4 OTLP sample's tests into the module

Adds an integrationTestOtlp suite to sentry-spring-boot-4: the servlet
app with the OpenTelemetry Spring Boot starter, set up by
sentry-opentelemetry-otlp-spring, and OpenTelemetryOtlpEventProcessor.
It ports the sample's tests, which were the servlet suite's without
OkHttp, and keeps the log and metric attribute checks the sample had
dropped.

The sample's transactions came from Sentry's own tracing, which CI
enabled with SENTRY_TRACES_SAMPLE_RATE, so the suite sets the sample
rate the same way. A new test checks what OTLP mode is for: an error in
a request carries the request's OpenTelemetry trace. Events point at
that trace rather than at Sentry's transaction, so the GraphQL errors
are checked next to their transactions instead of by trace ID, as the
sample did.

The sample has no system tests left, so it comes off the system-test
runner. It was the backend workflow's last sample, so the workflow goes
too. The Spring Boot 4 matrix runs the new suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and port them to the Boot 4 OTLP suite

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 38] Remove the system-test runner and its Python mock server (#6330)

* test: Remove the system-test runner and its Python mock server

Every sample's system test now lives in the module it tests, so the
Python runner, its mock Sentry server, requirements.txt and the Makefile
targets that ran them have nothing left to run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 39] Remove the io.sentry.systemtest plugin and sentry-system-test-support (#6331)

* test: Remove the io.sentry.systemtest plugin and sentry-system-test-support

With the runner gone, nothing applies the io.sentry.systemtest
convention plugin or depends on sentry-system-test-support, which held
the HTTP and GraphQL clients and the TestHelper the system tests used.
The envelope matchers it delegated to stay in sentry-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs: [Sample Tests 40] Describe the in-module end-to-end tests instead of the system tests (#6332)

* docs: Describe the in-module end-to-end tests instead of the system tests

The e2e_tests rule now covers MockSentryServer, where each kind of
end-to-end test lives, the Spring suites per flavor, the OpenTelemetry
agent fixture, how to run them and the gotchas the migration found. The
test skill runs integration suites by their source set instead of the
Python runner, the new_module rule no longer asks for sample tests, and
AGENTS.md drops sentry-system-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and document the test client and log4j2 suite

The context's TestRestTemplate adds trace headers of its own whenever
Sentry customizes the RestTemplateBuilder, not only in OpenTelemetry
mode, and the Spring Boot modules have an integrationTestLog4j2 suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
runningcode added a commit that referenced this pull request Oct 27, 2026
…e's tests (#6318)

* test(spring-boot): Move the Boot 2 OTel agent sample's tests into the module

Adds the agent setup to sentry-spring-boot, as in the Boot 3 and 4
modules. The sample's tests were the Boot 3 agent sample's minus Cache
and RestClient, which Boot 2 doesn't have. GraphQL and Kafka are gated
on Boot 2.7, as in the other Boot 2 suites.

The shared app has to start on Boot versions without Kafka support, so
the Kafka test starts an app of its own with the kafka profile and an
in-JVM broker. AgentApp becomes a class for that, with the shared
instance in its companion.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 2 matrix, which now
runs both agent tasks and no longer builds the agent separately.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and port them to the Boot 2 agent

Ports the tracing and GraphQL checks to the Boot 2 agent suite, and
gives the app three minutes to start, as for Boot 3 and 4.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring-boot): Stop the Boot 2 agent app when it fails to start

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(spring): [Sample Tests 27] Move the Spring jakarta WAR sample's tests into the module (#6319)

* test(spring): Move the Spring jakarta WAR sample's tests into the module

Adds an integrationTest suite to sentry-spring-jakarta that runs a plain
Spring MVC app, set up by an AbstractAnnotationConfigDispatcherServletInitializer
as in a WAR, in an embedded Tomcat against MockSentryServer. Tomcat runs
every servlet container initializer the classpath registers, as it does
for a WAR, and Spring Boot stays off the classpath, so Sentry's
initializer adds SentrySpringFilter the way it does in a real
deployment. The suite ports the sample's Person and Metrics tests and
also checks that the error carries its request.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the suite puts it in the temp dir.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 3 matrix. That was the
matrix's last runner step, so it drops the Python setup and the runner's
logs too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring): [Sample Tests 28] Move the Spring 7 WAR sample's tests into the module (#6320)

* test(spring): Move the Spring 7 WAR sample's tests into the module

Adds sentry-spring-jakarta's embedded-Tomcat integrationTest suite to
sentry-spring-7, with the module's packages. The sample's tests were
the jakarta WAR sample's, so the suite is too. Spring Boot 4's BOM picks
Spring 7 and Tomcat 11.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 4 matrix. That was the
matrix's last runner step, so it drops the Python setup and the runner's
logs too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring): [Sample Tests 29] Move the Spring WAR sample's tests into the module (#6321)

* test(spring): Move the Spring WAR sample's tests into the module

Adds sentry-spring-jakarta's embedded-Tomcat integrationTest suite to
sentry-spring, with the module's packages and javax.servlet. The
sample's tests were the jakarta WAR sample's, so the suite is too.
Spring Boot 2's BOM picks Spring 5.3 and Tomcat 9.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 2 matrix. That was the
matrix's last runner step, so it drops the Python setup, the runner's
logs and the exclude properties only the samples and the runner read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(log4j2): [Sample Tests 30] Move the log4j2 sample's system test into sentry-log4j2 (#6322)

* test(log4j2): Move the log4j2 sample's system test into sentry-log4j2

Adds SentryAppenderIntegrationTest, which configures the Sentry appender
from XML in a logger context of its own and checks what reaches
MockSentryServer: the warning event with its context tag and flag, the
error with its exception and breadcrumbs, and the logs with their
attributes. Logs are enabled through external configuration, as the
sample's sentry.properties does, because the appender has no attribute
for them.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(jul): [Sample Tests 31] Move the JUL sample's system test into sentry-jul (#6323)

* test(jul): Move the JUL sample's system test into sentry-jul

Adds SentryHandlerIntegrationTest, which configures the Sentry handler
through a logging properties file read by LogManager, as the sample
does, and checks what reaches MockSentryServer: the warning with its
flag, the error with its exception and breadcrumbs, and the logs with
their attributes. Its logger is outside io.sentry, whose loggers the
handler drops, and the test restores the LogManager configuration the
other tests read.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 32] Add end-to-end tests of the core APIs and a profiled transaction (#6324)

* test(core): Add an end-to-end test of the core APIs over the HTTP transport

SentryEndToEndTest reports through the APIs an app uses without
integrations and checks what reaches MockSentryServer: messages at the
scope's and an explicit level, an exception with its feature flag, an
event with a fingerprint, breadcrumbs from an event processor and a
beforeBreadcrumb callback, ten events in a row, a transaction with a
child span, and metrics with the scope's attributes.

It ports the core part of the console sample's system test, which ran
the sample's JAR against the Python mock server. The sample's profiling
and Kafka parts follow in their own modules.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type end to end

The console sample's test checked that the captured exception arrives
with its type, RuntimeException, not just its value.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(core): Check that the shutdown hook delivers what an app reported before exiting

The console samples' system tests ran each sample in its own JVM,
asserted that it exited with 0 within 30 seconds, and relied on the
shutdown hook to send everything, because the samples never flush or
close Sentry. The in-process end-to-end tests flush explicitly, so
neither the clean exit nor the hook's flush was tested any more.

Run a small app in a child JVM that returns from main without flushing,
and check that it exits with 0 and that its event, log and metric
arrive.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): [Sample Tests 34] Add an end-to-end test of the raw Kafka client's tracing (#6326)

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): Add an end-to-end test of the raw Kafka client's tracing

SentryKafkaEndToEndTest publishes a message through a wrapped
KafkaProducer to an in-JVM KRaft broker, consumes it with
SentryKafkaConsumerTracing, and checks what reaches MockSentryServer:
the queue.publish span in the producing transaction, and a queue.process
transaction with the consumer origin and the Kafka system that continues
the producer's trace. It ports the Kafka part of the console sample's
system test, which needed a Redpanda container.

The broker comes from spring-kafka-test 3, which needs Java 17, so the
test classpaths resolve Java 17 variants. The tests run on it anyway.

With its core, profiling and Kafka parts ported, the console sample has
no system test left, so it comes off the system-test runner and the
backend workflow, whose base row moves to the console OTLP sample.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 35] Add an end-to-end test of the agentless OpenTelemetry setup (#6327)

* test(opentelemetry): Add an end-to-end test of the agentless OpenTelemetry setup

AgentlessEndToEndTest builds the OpenTelemetry SDK through its
autoconfiguration, which loads Sentry's customizer, and checks what
reaches MockSentryServer: events, a transaction traced through
OpenTelemetry with its child span and profile, and metrics. It ports
sentry-samples-console-opentelemetry-noagent's system test, which no CI
job ran.

The customizer only initializes Sentry when the environment asks it to,
so the test task sets SENTRY_AUTO_INIT. These are the module's first
tests, so it applies the Kotlin plugin and gets an API dump.

The sample has no system test left, so it comes off the system-test
runner and drops the Kotlin plugin it only needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type in agentless mode

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 36] Add an end-to-end test of the OTLP event linking (#6328)

* test(opentelemetry): Add an end-to-end test of the OTLP event linking

OtlpEndToEndTest captures a message, a log and a metric inside an
OpenTelemetry span with OpenTelemetryOtlpEventProcessor installed, and
checks what reaches MockSentryServer: the event carries the span's trace
and span IDs, and the log and the metric arrive. It ports the
OTLP-specific part of the console OTLP sample's system test, which never
checked the link. The sample's other assertions are the console
sample's, which SentryEndToEndTest covers.

The sample has no system test left, so it comes off the system-test
runner and the backend workflow, whose base row moves to the Spring
Boot 4 OTLP sample, and drops the Kotlin plugin it only needed for the
test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring-boot): [Sample Tests 37] Move the Boot 4 OTLP sample's tests into the module (#6329)

* test(spring-boot): Move the Boot 4 OTLP sample's tests into the module

Adds an integrationTestOtlp suite to sentry-spring-boot-4: the servlet
app with the OpenTelemetry Spring Boot starter, set up by
sentry-opentelemetry-otlp-spring, and OpenTelemetryOtlpEventProcessor.
It ports the sample's tests, which were the servlet suite's without
OkHttp, and keeps the log and metric attribute checks the sample had
dropped.

The sample's transactions came from Sentry's own tracing, which CI
enabled with SENTRY_TRACES_SAMPLE_RATE, so the suite sets the sample
rate the same way. A new test checks what OTLP mode is for: an error in
a request carries the request's OpenTelemetry trace. Events point at
that trace rather than at Sentry's transaction, so the GraphQL errors
are checked next to their transactions instead of by trace ID, as the
sample did.

The sample has no system tests left, so it comes off the system-test
runner. It was the backend workflow's last sample, so the workflow goes
too. The Spring Boot 4 matrix runs the new suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and port them to the Boot 4 OTLP suite

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 38] Remove the system-test runner and its Python mock server (#6330)

* test: Remove the system-test runner and its Python mock server

Every sample's system test now lives in the module it tests, so the
Python runner, its mock Sentry server, requirements.txt and the Makefile
targets that ran them have nothing left to run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 39] Remove the io.sentry.systemtest plugin and sentry-system-test-support (#6331)

* test: Remove the io.sentry.systemtest plugin and sentry-system-test-support

With the runner gone, nothing applies the io.sentry.systemtest
convention plugin or depends on sentry-system-test-support, which held
the HTTP and GraphQL clients and the TestHelper the system tests used.
The envelope matchers it delegated to stay in sentry-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs: [Sample Tests 40] Describe the in-module end-to-end tests instead of the system tests (#6332)

* docs: Describe the in-module end-to-end tests instead of the system tests

The e2e_tests rule now covers MockSentryServer, where each kind of
end-to-end test lives, the Spring suites per flavor, the OpenTelemetry
agent fixture, how to run them and the gotchas the migration found. The
test skill runs integration suites by their source set instead of the
Python runner, the new_module rule no longer asks for sample tests, and
AGENTS.md drops sentry-system-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and document the test client and log4j2 suite

The context's TestRestTemplate adds trace headers of its own whenever
Sentry customizes the RestTemplateBuilder, not only in OpenTelemetry
mode, and the Spring Boot modules have an integrationTestLog4j2 suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring): [Sample Tests 29] Move the Spring WAR sample's tests into the module (#6321)

* test(spring): Move the Spring WAR sample's tests into the module

Adds sentry-spring-jakarta's embedded-Tomcat integrationTest suite to
sentry-spring, with the module's packages and javax.servlet. The
sample's tests were the jakarta WAR sample's, so the suite is too.
Spring Boot 2's BOM picks Spring 5.3 and Tomcat 9.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 2 matrix. That was the
matrix's last runner step, so it drops the Python setup, the runner's
logs and the exclude properties only the samples and the runner read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(log4j2): [Sample Tests 30] Move the log4j2 sample's system test into sentry-log4j2 (#6322)

* test(log4j2): Move the log4j2 sample's system test into sentry-log4j2

Adds SentryAppenderIntegrationTest, which configures the Sentry appender
from XML in a logger context of its own and checks what reaches
MockSentryServer: the warning event with its context tag and flag, the
error with its exception and breadcrumbs, and the logs with their
attributes. Logs are enabled through external configuration, as the
sample's sentry.properties does, because the appender has no attribute
for them.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(jul): [Sample Tests 31] Move the JUL sample's system test into sentry-jul (#6323)

* test(jul): Move the JUL sample's system test into sentry-jul

Adds SentryHandlerIntegrationTest, which configures the Sentry handler
through a logging properties file read by LogManager, as the sample
does, and checks what reaches MockSentryServer: the warning with its
flag, the error with its exception and breadcrumbs, and the logs with
their attributes. Its logger is outside io.sentry, whose loggers the
handler drops, and the test restores the LogManager configuration the
other tests read.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 32] Add end-to-end tests of the core APIs and a profiled transaction (#6324)

* test(core): Add an end-to-end test of the core APIs over the HTTP transport

SentryEndToEndTest reports through the APIs an app uses without
integrations and checks what reaches MockSentryServer: messages at the
scope's and an explicit level, an exception with its feature flag, an
event with a fingerprint, breadcrumbs from an event processor and a
beforeBreadcrumb callback, ten events in a row, a transaction with a
child span, and metrics with the scope's attributes.

It ports the core part of the console sample's system test, which ran
the sample's JAR against the Python mock server. The sample's profiling
and Kafka parts follow in their own modules.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type end to end

The console sample's test checked that the captured exception arrives
with its type, RuntimeException, not just its value.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(core): Check that the shutdown hook delivers what an app reported before exiting

The console samples' system tests ran each sample in its own JVM,
asserted that it exited with 0 within 30 seconds, and relied on the
shutdown hook to send everything, because the samples never flush or
close Sentry. The in-process end-to-end tests flush explicitly, so
neither the clean exit nor the hook's flush was tested any more.

Run a small app in a child JVM that returns from main without flushing,
and check that it exits with 0 and that its event, log and metric
arrive.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): [Sample Tests 34] Add an end-to-end test of the raw Kafka client's tracing (#6326)

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): Add an end-to-end test of the raw Kafka client's tracing

SentryKafkaEndToEndTest publishes a message through a wrapped
KafkaProducer to an in-JVM KRaft broker, consumes it with
SentryKafkaConsumerTracing, and checks what reaches MockSentryServer:
the queue.publish span in the producing transaction, and a queue.process
transaction with the consumer origin and the Kafka system that continues
the producer's trace. It ports the Kafka part of the console sample's
system test, which needed a Redpanda container.

The broker comes from spring-kafka-test 3, which needs Java 17, so the
test classpaths resolve Java 17 variants. The tests run on it anyway.

With its core, profiling and Kafka parts ported, the console sample has
no system test left, so it comes off the system-test runner and the
backend workflow, whose base row moves to the console OTLP sample.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 35] Add an end-to-end test of the agentless OpenTelemetry setup (#6327)

* test(opentelemetry): Add an end-to-end test of the agentless OpenTelemetry setup

AgentlessEndToEndTest builds the OpenTelemetry SDK through its
autoconfiguration, which loads Sentry's customizer, and checks what
reaches MockSentryServer: events, a transaction traced through
OpenTelemetry with its child span and profile, and metrics. It ports
sentry-samples-console-opentelemetry-noagent's system test, which no CI
job ran.

The customizer only initializes Sentry when the environment asks it to,
so the test task sets SENTRY_AUTO_INIT. These are the module's first
tests, so it applies the Kotlin plugin and gets an API dump.

The sample has no system test left, so it comes off the system-test
runner and drops the Kotlin plugin it only needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type in agentless mode

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 36] Add an end-to-end test of the OTLP event linking (#6328)

* test(opentelemetry): Add an end-to-end test of the OTLP event linking

OtlpEndToEndTest captures a message, a log and a metric inside an
OpenTelemetry span with OpenTelemetryOtlpEventProcessor installed, and
checks what reaches MockSentryServer: the event carries the span's trace
and span IDs, and the log and the metric arrive. It ports the
OTLP-specific part of the console OTLP sample's system test, which never
checked the link. The sample's other assertions are the console
sample's, which SentryEndToEndTest covers.

The sample has no system test left, so it comes off the system-test
runner and the backend workflow, whose base row moves to the Spring
Boot 4 OTLP sample, and drops the Kotlin plugin it only needed for the
test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring-boot): [Sample Tests 37] Move the Boot 4 OTLP sample's tests into the module (#6329)

* test(spring-boot): Move the Boot 4 OTLP sample's tests into the module

Adds an integrationTestOtlp suite to sentry-spring-boot-4: the servlet
app with the OpenTelemetry Spring Boot starter, set up by
sentry-opentelemetry-otlp-spring, and OpenTelemetryOtlpEventProcessor.
It ports the sample's tests, which were the servlet suite's without
OkHttp, and keeps the log and metric attribute checks the sample had
dropped.

The sample's transactions came from Sentry's own tracing, which CI
enabled with SENTRY_TRACES_SAMPLE_RATE, so the suite sets the sample
rate the same way. A new test checks what OTLP mode is for: an error in
a request carries the request's OpenTelemetry trace. Events point at
that trace rather than at Sentry's transaction, so the GraphQL errors
are checked next to their transactions instead of by trace ID, as the
sample did.

The sample has no system tests left, so it comes off the system-test
runner. It was the backend workflow's last sample, so the workflow goes
too. The Spring Boot 4 matrix runs the new suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and port them to the Boot 4 OTLP suite

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 38] Remove the system-test runner and its Python mock server (#6330)

* test: Remove the system-test runner and its Python mock server

Every sample's system test now lives in the module it tests, so the
Python runner, its mock Sentry server, requirements.txt and the Makefile
targets that ran them have nothing left to run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 39] Remove the io.sentry.systemtest plugin and sentry-system-test-support (#6331)

* test: Remove the io.sentry.systemtest plugin and sentry-system-test-support

With the runner gone, nothing applies the io.sentry.systemtest
convention plugin or depends on sentry-system-test-support, which held
the HTTP and GraphQL clients and the TestHelper the system tests used.
The envelope matchers it delegated to stay in sentry-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs: [Sample Tests 40] Describe the in-module end-to-end tests instead of the system tests (#6332)

* docs: Describe the in-module end-to-end tests instead of the system tests

The e2e_tests rule now covers MockSentryServer, where each kind of
end-to-end test lives, the Spring suites per flavor, the OpenTelemetry
agent fixture, how to run them and the gotchas the migration found. The
test skill runs integration suites by their source set instead of the
Python runner, the new_module rule no longer asks for sample tests, and
AGENTS.md drops sentry-system-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and document the test client and log4j2 suite

The context's TestRestTemplate adds trace headers of its own whenever
Sentry customizes the RestTemplateBuilder, not only in OpenTelemetry
mode, and the Spring Boot modules have an integrationTestLog4j2 suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
runningcode added a commit that referenced this pull request Oct 27, 2026
…e's tests (#6317)

* test(spring-boot): Move the Boot 4 OTel agent sample's tests into the module

Adds the agent setup to sentry-spring-boot-4: an agentFixture app that
runs in a child JVM with the built agent attached, and the
integrationTestOtelAgent suite with its integrationTestOtelAgentWithoutAutoInit
task. The sample's tests were the same as the Boot 3 agent sample's, so
the fixture and tests are the Boot 3 ones with Boot 4's packages and
starters.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 4 matrix, which now
runs both agent tasks and no longer builds the agent separately.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: Port the audit fixes to the Boot 4 agent

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring-boot): [Sample Tests 26] Move the Boot 2 OTel agent sample's tests (#6318)

* test(spring-boot): Move the Boot 2 OTel agent sample's tests into the module

Adds the agent setup to sentry-spring-boot, as in the Boot 3 and 4
modules. The sample's tests were the Boot 3 agent sample's minus Cache
and RestClient, which Boot 2 doesn't have. GraphQL and Kafka are gated
on Boot 2.7, as in the other Boot 2 suites.

The shared app has to start on Boot versions without Kafka support, so
the Kafka test starts an app of its own with the kafka profile and an
in-JVM broker. AgentApp becomes a class for that, with the shared
instance in its companion.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 2 matrix, which now
runs both agent tasks and no longer builds the agent separately.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and port them to the Boot 2 agent

Ports the tracing and GraphQL checks to the Boot 2 agent suite, and
gives the app three minutes to start, as for Boot 3 and 4.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring-boot): Stop the Boot 2 agent app when it fails to start

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* test(spring): [Sample Tests 27] Move the Spring jakarta WAR sample's tests into the module (#6319)

* test(spring): Move the Spring jakarta WAR sample's tests into the module

Adds an integrationTest suite to sentry-spring-jakarta that runs a plain
Spring MVC app, set up by an AbstractAnnotationConfigDispatcherServletInitializer
as in a WAR, in an embedded Tomcat against MockSentryServer. Tomcat runs
every servlet container initializer the classpath registers, as it does
for a WAR, and Spring Boot stays off the classpath, so Sentry's
initializer adds SentrySpringFilter the way it does in a real
deployment. The suite ports the sample's Person and Metrics tests and
also checks that the error carries its request.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the suite puts it in the temp dir.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 3 matrix. That was the
matrix's last runner step, so it drops the Python setup and the runner's
logs too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring): [Sample Tests 28] Move the Spring 7 WAR sample's tests into the module (#6320)

* test(spring): Move the Spring 7 WAR sample's tests into the module

Adds sentry-spring-jakarta's embedded-Tomcat integrationTest suite to
sentry-spring-7, with the module's packages. The sample's tests were
the jakarta WAR sample's, so the suite is too. Spring Boot 4's BOM picks
Spring 7 and Tomcat 11.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 4 matrix. That was the
matrix's last runner step, so it drops the Python setup and the runner's
logs too.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring): [Sample Tests 29] Move the Spring WAR sample's tests into the module (#6321)

* test(spring): Move the Spring WAR sample's tests into the module

Adds sentry-spring-jakarta's embedded-Tomcat integrationTest suite to
sentry-spring, with the module's packages and javax.servlet. The
sample's tests were the jakarta WAR sample's, so the suite is too.
Spring Boot 2's BOM picks Spring 5.3 and Tomcat 9.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 2 matrix. That was the
matrix's last runner step, so it drops the Python setup, the runner's
logs and the exclude properties only the samples and the runner read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(log4j2): [Sample Tests 30] Move the log4j2 sample's system test into sentry-log4j2 (#6322)

* test(log4j2): Move the log4j2 sample's system test into sentry-log4j2

Adds SentryAppenderIntegrationTest, which configures the Sentry appender
from XML in a logger context of its own and checks what reaches
MockSentryServer: the warning event with its context tag and flag, the
error with its exception and breadcrumbs, and the logs with their
attributes. Logs are enabled through external configuration, as the
sample's sentry.properties does, because the appender has no attribute
for them.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(jul): [Sample Tests 31] Move the JUL sample's system test into sentry-jul (#6323)

* test(jul): Move the JUL sample's system test into sentry-jul

Adds SentryHandlerIntegrationTest, which configures the Sentry handler
through a logging properties file read by LogManager, as the sample
does, and checks what reaches MockSentryServer: the warning with its
flag, the error with its exception and breadcrumbs, and the logs with
their attributes. Its logger is outside io.sentry, whose loggers the
handler drops, and the test restores the LogManager configuration the
other tests read.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 32] Add end-to-end tests of the core APIs and a profiled transaction (#6324)

* test(core): Add an end-to-end test of the core APIs over the HTTP transport

SentryEndToEndTest reports through the APIs an app uses without
integrations and checks what reaches MockSentryServer: messages at the
scope's and an explicit level, an exception with its feature flag, an
event with a fingerprint, breadcrumbs from an event processor and a
beforeBreadcrumb callback, ten events in a row, a transaction with a
child span, and metrics with the scope's attributes.

It ports the core part of the console sample's system test, which ran
the sample's JAR against the Python mock server. The sample's profiling
and Kafka parts follow in their own modules.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type end to end

The console sample's test checked that the captured exception arrives
with its type, RuntimeException, not just its value.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(core): Check that the shutdown hook delivers what an app reported before exiting

The console samples' system tests ran each sample in its own JVM,
asserted that it exited with 0 within 30 seconds, and relied on the
shutdown hook to send everything, because the samples never flush or
close Sentry. The in-process end-to-end tests flush explicitly, so
neither the clean exit nor the hook's flush was tested any more.

Run a small app in a child JVM that returns from main without flushing,
and check that it exits with 0 and that its event, log and metric
arrive.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): [Sample Tests 34] Add an end-to-end test of the raw Kafka client's tracing (#6326)

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): Add an end-to-end test of the raw Kafka client's tracing

SentryKafkaEndToEndTest publishes a message through a wrapped
KafkaProducer to an in-JVM KRaft broker, consumes it with
SentryKafkaConsumerTracing, and checks what reaches MockSentryServer:
the queue.publish span in the producing transaction, and a queue.process
transaction with the consumer origin and the Kafka system that continues
the producer's trace. It ports the Kafka part of the console sample's
system test, which needed a Redpanda container.

The broker comes from spring-kafka-test 3, which needs Java 17, so the
test classpaths resolve Java 17 variants. The tests run on it anyway.

With its core, profiling and Kafka parts ported, the console sample has
no system test left, so it comes off the system-test runner and the
backend workflow, whose base row moves to the console OTLP sample.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 35] Add an end-to-end test of the agentless OpenTelemetry setup (#6327)

* test(opentelemetry): Add an end-to-end test of the agentless OpenTelemetry setup

AgentlessEndToEndTest builds the OpenTelemetry SDK through its
autoconfiguration, which loads Sentry's customizer, and checks what
reaches MockSentryServer: events, a transaction traced through
OpenTelemetry with its child span and profile, and metrics. It ports
sentry-samples-console-opentelemetry-noagent's system test, which no CI
job ran.

The customizer only initializes Sentry when the environment asks it to,
so the test task sets SENTRY_AUTO_INIT. These are the module's first
tests, so it applies the Kotlin plugin and gets an API dump.

The sample has no system test left, so it comes off the system-test
runner and drops the Kotlin plugin it only needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type in agentless mode

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 36] Add an end-to-end test of the OTLP event linking (#6328)

* test(opentelemetry): Add an end-to-end test of the OTLP event linking

OtlpEndToEndTest captures a message, a log and a metric inside an
OpenTelemetry span with OpenTelemetryOtlpEventProcessor installed, and
checks what reaches MockSentryServer: the event carries the span's trace
and span IDs, and the log and the metric arrive. It ports the
OTLP-specific part of the console OTLP sample's system test, which never
checked the link. The sample's other assertions are the console
sample's, which SentryEndToEndTest covers.

The sample has no system test left, so it comes off the system-test
runner and the backend workflow, whose base row moves to the Spring
Boot 4 OTLP sample, and drops the Kotlin plugin it only needed for the
test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring-boot): [Sample Tests 37] Move the Boot 4 OTLP sample's tests into the module (#6329)

* test(spring-boot): Move the Boot 4 OTLP sample's tests into the module

Adds an integrationTestOtlp suite to sentry-spring-boot-4: the servlet
app with the OpenTelemetry Spring Boot starter, set up by
sentry-opentelemetry-otlp-spring, and OpenTelemetryOtlpEventProcessor.
It ports the sample's tests, which were the servlet suite's without
OkHttp, and keeps the log and metric attribute checks the sample had
dropped.

The sample's transactions came from Sentry's own tracing, which CI
enabled with SENTRY_TRACES_SAMPLE_RATE, so the suite sets the sample
rate the same way. A new test checks what OTLP mode is for: an error in
a request carries the request's OpenTelemetry trace. Events point at
that trace rather than at Sentry's transaction, so the GraphQL errors
are checked next to their transactions instead of by trace ID, as the
sample did.

The sample has no system tests left, so it comes off the system-test
runner. It was the backend workflow's last sample, so the workflow goes
too. The Spring Boot 4 matrix runs the new suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and port them to the Boot 4 OTLP suite

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 38] Remove the system-test runner and its Python mock server (#6330)

* test: Remove the system-test runner and its Python mock server

Every sample's system test now lives in the module it tests, so the
Python runner, its mock Sentry server, requirements.txt and the Makefile
targets that ran them have nothing left to run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 39] Remove the io.sentry.systemtest plugin and sentry-system-test-support (#6331)

* test: Remove the io.sentry.systemtest plugin and sentry-system-test-support

With the runner gone, nothing applies the io.sentry.systemtest
convention plugin or depends on sentry-system-test-support, which held
the HTTP and GraphQL clients and the TestHelper the system tests used.
The envelope matchers it delegated to stay in sentry-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs: [Sample Tests 40] Describe the in-module end-to-end tests instead of the system tests (#6332)

* docs: Describe the in-module end-to-end tests instead of the system tests

The e2e_tests rule now covers MockSentryServer, where each kind of
end-to-end test lives, the Spring suites per flavor, the OpenTelemetry
agent fixture, how to run them and the gotchas the migration found. The
test skill runs integration suites by their source set instead of the
Python runner, the new_module rule no longer asks for sample tests, and
AGENTS.md drops sentry-system-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and document the test client and log4j2 suite

The context's TestRestTemplate adds trace headers of its own whenever
Sentry customizes the RestTemplateBuilder, not only in OpenTelemetry
mode, and the Spring Boot modules have an integrationTestLog4j2 suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring): [Sample Tests 29] Move the Spring WAR sample's tests into the module (#6321)

* test(spring): Move the Spring WAR sample's tests into the module

Adds sentry-spring-jakarta's embedded-Tomcat integrationTest suite to
sentry-spring, with the module's packages and javax.servlet. The
sample's tests were the jakarta WAR sample's, so the suite is too.
Spring Boot 2's BOM picks Spring 5.3 and Tomcat 9.

The sample has no system tests left, so it comes off the system-test
runner, the backend workflow and the Spring Boot 2 matrix. That was the
matrix's last runner step, so it drops the Python setup, the runner's
logs and the exclude properties only the samples and the runner read.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(log4j2): [Sample Tests 30] Move the log4j2 sample's system test into sentry-log4j2 (#6322)

* test(log4j2): Move the log4j2 sample's system test into sentry-log4j2

Adds SentryAppenderIntegrationTest, which configures the Sentry appender
from XML in a logger context of its own and checks what reaches
MockSentryServer: the warning event with its context tag and flag, the
error with its exception and breadcrumbs, and the logs with their
attributes. Logs are enabled through external configuration, as the
sample's sentry.properties does, because the appender has no attribute
for them.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(jul): [Sample Tests 31] Move the JUL sample's system test into sentry-jul (#6323)

* test(jul): Move the JUL sample's system test into sentry-jul

Adds SentryHandlerIntegrationTest, which configures the Sentry handler
through a logging properties file read by LogManager, as the sample
does, and checks what reaches MockSentryServer: the warning with its
flag, the error with its exception and breadcrumbs, and the logs with
their attributes. Its logger is outside io.sentry, whose loggers the
handler drops, and the test restores the LogManager configuration the
other tests read.

The sample has no system tests left, so it comes off the system-test
runner and the backend workflow, and drops the Kotlin plugin it only
needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 32] Add end-to-end tests of the core APIs and a profiled transaction (#6324)

* test(core): Add an end-to-end test of the core APIs over the HTTP transport

SentryEndToEndTest reports through the APIs an app uses without
integrations and checks what reaches MockSentryServer: messages at the
scope's and an explicit level, an exception with its feature flag, an
event with a fingerprint, breadcrumbs from an event processor and a
beforeBreadcrumb callback, ten events in a row, a transaction with a
child span, and metrics with the scope's attributes.

It ports the core part of the console sample's system test, which ran
the sample's JAR against the Python mock server. The sample's profiling
and Kafka parts follow in their own modules.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type end to end

The console sample's test checked that the captured exception arrives
with its type, RuntimeException, not just its value.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(core): Check that the shutdown hook delivers what an app reported before exiting

The console samples' system tests ran each sample in its own JVM,
asserted that it exited with 0 within 30 seconds, and relied on the
shutdown hook to send everything, because the samples never flush or
close Sentry. The in-process end-to-end tests flush explicitly, so
neither the clean exit nor the hook's flush was tested any more.

Run a small app in a child JVM that returns from main without flushing,
and check that it exits with 0 and that its event, log and metric
arrive.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): [Sample Tests 34] Add an end-to-end test of the raw Kafka client's tracing (#6326)

* test(async-profiler): Add an end-to-end test of a profiled transaction

ContinuousProfilerEndToEndTest starts a sampled transaction with the
TRACE profile lifecycle and checks that its profile chunk reaches
MockSentryServer, linked to the transaction by the profiler ID. It
ports the profiling part of the console sample's system test.

The profiler rejects a traces path with a dot anywhere in its absolute
form, so the test puts it in the temp dir.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(kafka): Add an end-to-end test of the raw Kafka client's tracing

SentryKafkaEndToEndTest publishes a message through a wrapped
KafkaProducer to an in-JVM KRaft broker, consumes it with
SentryKafkaConsumerTracing, and checks what reaches MockSentryServer:
the queue.publish span in the producing transaction, and a queue.process
transaction with the consumer origin and the Kafka system that continues
the producer's trace. It ports the Kafka part of the console sample's
system test, which needed a Redpanda container.

The broker comes from spring-kafka-test 3, which needs Java 17, so the
test classpaths resolve Java 17 variants. The tests run on it anyway.

With its core, profiling and Kafka parts ported, the console sample has
no system test left, so it comes off the system-test runner and the
backend workflow, whose base row moves to the console OTLP sample.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 35] Add an end-to-end test of the agentless OpenTelemetry setup (#6327)

* test(opentelemetry): Add an end-to-end test of the agentless OpenTelemetry setup

AgentlessEndToEndTest builds the OpenTelemetry SDK through its
autoconfiguration, which loads Sentry's customizer, and checks what
reaches MockSentryServer: events, a transaction traced through
OpenTelemetry with its child span and profile, and metrics. It ports
sentry-samples-console-opentelemetry-noagent's system test, which no CI
job ran.

The customizer only initializes Sentry when the environment asks it to,
so the test task sets SENTRY_AUTO_INIT. These are the module's first
tests, so it applies the Kotlin plugin and gets an API dump.

The sample has no system test left, so it comes off the system-test
runner and drops the Kotlin plugin it only needed for the test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and check the exception type in agentless mode

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(opentelemetry): [Sample Tests 36] Add an end-to-end test of the OTLP event linking (#6328)

* test(opentelemetry): Add an end-to-end test of the OTLP event linking

OtlpEndToEndTest captures a message, a log and a metric inside an
OpenTelemetry span with OpenTelemetryOtlpEventProcessor installed, and
checks what reaches MockSentryServer: the event carries the span's trace
and span IDs, and the log and the metric arrive. It ports the
OTLP-specific part of the console OTLP sample's system test, which never
checked the link. The sample's other assertions are the console
sample's, which SentryEndToEndTest covers.

The sample has no system test left, so it comes off the system-test
runner and the backend workflow, whose base row moves to the Spring
Boot 4 OTLP sample, and drops the Kotlin plugin it only needed for the
test.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test(spring-boot): [Sample Tests 37] Move the Boot 4 OTLP sample's tests into the module (#6329)

* test(spring-boot): Move the Boot 4 OTLP sample's tests into the module

Adds an integrationTestOtlp suite to sentry-spring-boot-4: the servlet
app with the OpenTelemetry Spring Boot starter, set up by
sentry-opentelemetry-otlp-spring, and OpenTelemetryOtlpEventProcessor.
It ports the sample's tests, which were the servlet suite's without
OkHttp, and keeps the log and metric attribute checks the sample had
dropped.

The sample's transactions came from Sentry's own tracing, which CI
enabled with SENTRY_TRACES_SAMPLE_RATE, so the suite sets the sample
rate the same way. A new test checks what OTLP mode is for: an error in
a request carries the request's OpenTelemetry trace. Events point at
that trace rather than at Sentry's transaction, so the GraphQL errors
are checked next to their transactions instead of by trace ID, as the
sample did.

The sample has no system tests left, so it comes off the system-test
runner. It was the backend workflow's last sample, so the workflow goes
too. The Spring Boot 4 matrix runs the new suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and port them to the Boot 4 OTLP suite

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 38] Remove the system-test runner and its Python mock server (#6330)

* test: Remove the system-test runner and its Python mock server

Every sample's system test now lives in the module it tests, so the
Python runner, its mock Sentry server, requirements.txt and the Makefile
targets that ran them have nothing left to run.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* test: [Sample Tests 39] Remove the io.sentry.systemtest plugin and sentry-system-test-support (#6331)

* test: Remove the io.sentry.systemtest plugin and sentry-system-test-support

With the runner gone, nothing applies the io.sentry.systemtest
convention plugin or depends on sentry-system-test-support, which held
the HTTP and GraphQL clients and the TestHelper the system tests used.
The envelope matchers it delegated to stay in sentry-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* docs: [Sample Tests 40] Describe the in-module end-to-end tests instead of the system tests (#6332)

* docs: Describe the in-module end-to-end tests instead of the system tests

The e2e_tests rule now covers MockSentryServer, where each kind of
end-to-end test lives, the Spring suites per flavor, the OpenTelemetry
agent fixture, how to run them and the gotchas the migration found. The
test skill runs integration suites by their source set instead of the
Python runner, the new_module rule no longer asks for sample tests, and
AGENTS.md drops sentry-system-test-support.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

* Merge the audit fixes from the branches below, and document the test client and log4j2 suite

The context's TestRestTemplate adds trace headers of its own whenever
Sentry customizes the RestTemplateBuilder, not only in OpenTelemetry
mode, and the Spring Boot modules have an integrationTestLog4j2 suite.

Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>

---------

Co-authored-by: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

ship-it PR is ready to merge from a reviewer perspective

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants