diff --git a/.github/workflows/agp-matrix.yml b/.github/workflows/agp-matrix.yml
index 182c0fa19ba..b93bc364acb 100644
--- a/.github/workflows/agp-matrix.yml
+++ b/.github/workflows/agp-matrix.yml
@@ -38,7 +38,7 @@ jobs:
java-version: '17'
- name: Setup Gradle
- uses: gradle/actions/setup-gradle@bb0c460cbf5354b0cddd15bacdf0d6aaa3e5a32b # pin@v3
+ uses: gradle/actions/setup-gradle@707359876a764dbcdb9da0b0ed08291818310c3d # pin@v3
with:
gradle-home-cache-cleanup: true
@@ -69,6 +69,7 @@ jobs:
target: 'aosp_atd'
arch: x86
channel: canary # Necessary for ATDs
+ disk-size: 4096M
script: ./gradlew sentry-android-integration-tests:sentry-uitest-android:connectedReleaseAndroidTest -DtestBuildType=release --daemon
- name: Upload test results
diff --git a/.github/workflows/build.yml b/.github/workflows/build.yml
index 6b885942e9f..5988e278880 100644
--- a/.github/workflows/build.yml
+++ b/.github/workflows/build.yml
@@ -27,7 +27,7 @@ jobs:
java-version: '17'
- name: Setup Gradle
- uses: gradle/actions/setup-gradle@bb0c460cbf5354b0cddd15bacdf0d6aaa3e5a32b # pin@v3
+ uses: gradle/actions/setup-gradle@707359876a764dbcdb9da0b0ed08291818310c3d # pin@v3
with:
gradle-home-cache-cleanup: true
diff --git a/.github/workflows/codeql-analysis.yml b/.github/workflows/codeql-analysis.yml
index 99abfbdca6c..771b5274a66 100644
--- a/.github/workflows/codeql-analysis.yml
+++ b/.github/workflows/codeql-analysis.yml
@@ -34,7 +34,7 @@ jobs:
java-version: '17'
- name: Setup Gradle
- uses: gradle/actions/setup-gradle@bb0c460cbf5354b0cddd15bacdf0d6aaa3e5a32b # pin@v3
+ uses: gradle/actions/setup-gradle@707359876a764dbcdb9da0b0ed08291818310c3d # pin@v3
with:
gradle-home-cache-cleanup: true
diff --git a/.github/workflows/enforce-license-compliance.yml b/.github/workflows/enforce-license-compliance.yml
index 2b87c1d278d..c4a22a909b8 100644
--- a/.github/workflows/enforce-license-compliance.yml
+++ b/.github/workflows/enforce-license-compliance.yml
@@ -11,7 +11,7 @@ jobs:
runs-on: ubuntu-latest
steps:
- name: Setup Gradle
- uses: gradle/actions/setup-gradle@bb0c460cbf5354b0cddd15bacdf0d6aaa3e5a32b # pin@v3
+ uses: gradle/actions/setup-gradle@707359876a764dbcdb9da0b0ed08291818310c3d # pin@v3
with:
gradle-home-cache-cleanup: true
diff --git a/.github/workflows/generate-javadocs.yml b/.github/workflows/generate-javadocs.yml
index b540441fb77..5d358bdf501 100644
--- a/.github/workflows/generate-javadocs.yml
+++ b/.github/workflows/generate-javadocs.yml
@@ -20,7 +20,7 @@ jobs:
java-version: '17'
- name: Setup Gradle
- uses: gradle/actions/setup-gradle@bb0c460cbf5354b0cddd15bacdf0d6aaa3e5a32b # pin@v3
+ uses: gradle/actions/setup-gradle@707359876a764dbcdb9da0b0ed08291818310c3d # pin@v3
with:
gradle-home-cache-cleanup: true
diff --git a/.github/workflows/integration-tests-benchmarks.yml b/.github/workflows/integration-tests-benchmarks.yml
index 58fc933752c..34eea1733c1 100644
--- a/.github/workflows/integration-tests-benchmarks.yml
+++ b/.github/workflows/integration-tests-benchmarks.yml
@@ -37,7 +37,7 @@ jobs:
java-version: '17'
- name: Setup Gradle
- uses: gradle/actions/setup-gradle@bb0c460cbf5354b0cddd15bacdf0d6aaa3e5a32b # pin@v3
+ uses: gradle/actions/setup-gradle@707359876a764dbcdb9da0b0ed08291818310c3d # pin@v3
with:
gradle-home-cache-cleanup: true
@@ -86,7 +86,7 @@ jobs:
java-version: '17'
- name: Setup Gradle
- uses: gradle/actions/setup-gradle@bb0c460cbf5354b0cddd15bacdf0d6aaa3e5a32b # pin@v3
+ uses: gradle/actions/setup-gradle@707359876a764dbcdb9da0b0ed08291818310c3d # pin@v3
with:
gradle-home-cache-cleanup: true
diff --git a/.github/workflows/integration-tests-ui-critical.yml b/.github/workflows/integration-tests-ui-critical.yml
index 815adf9b61d..a28400e50f0 100644
--- a/.github/workflows/integration-tests-ui-critical.yml
+++ b/.github/workflows/integration-tests-ui-critical.yml
@@ -32,7 +32,7 @@ jobs:
java-version: '17'
- name: Setup Gradle
- uses: gradle/actions/setup-gradle@bb0c460cbf5354b0cddd15bacdf0d6aaa3e5a32b # pin@v3
+ uses: gradle/actions/setup-gradle@707359876a764dbcdb9da0b0ed08291818310c3d # pin@v3
with:
gradle-home-cache-cleanup: true
diff --git a/.github/workflows/integration-tests-ui.yml b/.github/workflows/integration-tests-ui.yml
index 6c4ad6564fc..059e3c7424a 100644
--- a/.github/workflows/integration-tests-ui.yml
+++ b/.github/workflows/integration-tests-ui.yml
@@ -32,7 +32,7 @@ jobs:
java-version: '17'
- name: Setup Gradle
- uses: gradle/actions/setup-gradle@bb0c460cbf5354b0cddd15bacdf0d6aaa3e5a32b # pin@v3
+ uses: gradle/actions/setup-gradle@707359876a764dbcdb9da0b0ed08291818310c3d # pin@v3
with:
gradle-home-cache-cleanup: true
diff --git a/.github/workflows/release-build.yml b/.github/workflows/release-build.yml
index 83a3c82f8cb..c625efa8eb9 100644
--- a/.github/workflows/release-build.yml
+++ b/.github/workflows/release-build.yml
@@ -26,7 +26,7 @@ jobs:
java-version: '17'
- name: Setup Gradle
- uses: gradle/actions/setup-gradle@bb0c460cbf5354b0cddd15bacdf0d6aaa3e5a32b # pin@v3
+ uses: gradle/actions/setup-gradle@707359876a764dbcdb9da0b0ed08291818310c3d # pin@v3
with:
gradle-home-cache-cleanup: true
diff --git a/.github/workflows/system-tests-backend.yml b/.github/workflows/system-tests-backend.yml
index 960d73efa1e..ef5e40cf1e9 100644
--- a/.github/workflows/system-tests-backend.yml
+++ b/.github/workflows/system-tests-backend.yml
@@ -56,7 +56,7 @@ jobs:
java-version: '17'
- name: Setup Gradle
- uses: gradle/actions/setup-gradle@bb0c460cbf5354b0cddd15bacdf0d6aaa3e5a32b # pin@v3
+ uses: gradle/actions/setup-gradle@707359876a764dbcdb9da0b0ed08291818310c3d # pin@v3
with:
gradle-home-cache-cleanup: true
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 43142ef1d68..ea0f7b10990 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -40,7 +40,6 @@
- Faster generation of Sentry and Span IDs ([#3818](https://github.com/getsentry/sentry-java/pull/3818))
- Uses faster implementation to convert UUID to SentryID String
- Uses faster Random implementation to generate UUIDs
-- Use a separate `Random` instance per thread to improve SDK performance ([#3835](https://github.com/getsentry/sentry-java/pull/3835))
- Android 15: Add support for 16KB page sizes ([#3851](https://github.com/getsentry/sentry-java/pull/3851))
- See https://developer.android.com/guide/practices/page-sizes for more details
@@ -53,7 +52,6 @@
- Starting a child span from a transaction that wasn't in the current `Context` lead to multiple transactions being created (one for the transaction and another per span created).
- Add `auto.graphql.graphql22` to ignored span origins when using OpenTelemetry ([#3828](https://github.com/getsentry/sentry-java/pull/3828))
- The Spring Boot 3 WebFlux sample now uses our GraphQL v22 integration ([#3828](https://github.com/getsentry/sentry-java/pull/3828))
-- Accept manifest integer values when requiring floating values ([#3823](https://github.com/getsentry/sentry-java/pull/3823))
- All status codes below 400 are now mapped to `SpanStatus.OK` ([#3869](https://github.com/getsentry/sentry-java/pull/3869))
@@ -311,6 +309,20 @@ You may also use `LifecycleHelper.close(token)`, e.g. in case you need to pass t
- Report exceptions returned by Throwable.getSuppressed() to Sentry as exception groups ([#3396] https://github.com/getsentry/sentry-java/pull/3396)
+## 7.17.0
+
+### Features
+
+- Add meta option to set the maximum amount of breadcrumbs to be logged. ([#3836](https://github.com/getsentry/sentry-java/pull/3836))
+- Use a separate `Random` instance per thread to improve SDK performance ([#3835](https://github.com/getsentry/sentry-java/pull/3835))
+
+### Fixes
+
+- Using MaxBreadcrumb with value 0 no longer crashes. ([#3836](https://github.com/getsentry/sentry-java/pull/3836))
+- Accept manifest integer values when requiring floating values ([#3823](https://github.com/getsentry/sentry-java/pull/3823))
+- Fix standalone tomcat jndi issue ([#3873](https://github.com/getsentry/sentry-java/pull/3873))
+ - Using Sentry Spring Boot on a standalone tomcat caused the following error:
+ - Failed to bind properties under 'sentry.parsed-dsn' to io.sentry.Dsn
## 7.16.0
diff --git a/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java b/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java
index 993d05d08a3..45661866fa8 100644
--- a/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java
+++ b/sentry-android-core/src/main/java/io/sentry/android/core/ManifestMetadataReader.java
@@ -104,6 +104,8 @@ final class ManifestMetadataReader {
static final String FORCE_INIT = "io.sentry.force-init";
+ static final String MAX_BREADCRUMBS = "io.sentry.max-breadcrumbs";
+
/** ManifestMetadataReader ctor */
private ManifestMetadataReader() {}
@@ -204,6 +206,9 @@ static void applyMetadata(
SESSION_TRACKING_TIMEOUT_INTERVAL_MILLIS,
options.getSessionTrackingIntervalMillis()));
+ options.setMaxBreadcrumbs(
+ (int) readLong(metadata, logger, MAX_BREADCRUMBS, options.getMaxBreadcrumbs()));
+
options.setEnableActivityLifecycleBreadcrumbs(
readBool(
metadata,
diff --git a/sentry-android-core/src/test/java/io/sentry/android/core/ManifestMetadataReaderTest.kt b/sentry-android-core/src/test/java/io/sentry/android/core/ManifestMetadataReaderTest.kt
index 761b6b3d69e..5d6e915c0bc 100644
--- a/sentry-android-core/src/test/java/io/sentry/android/core/ManifestMetadataReaderTest.kt
+++ b/sentry-android-core/src/test/java/io/sentry/android/core/ManifestMetadataReaderTest.kt
@@ -1402,4 +1402,29 @@ class ManifestMetadataReaderTest {
assertEquals(expectedSampleRate.toDouble(), fixture.options.experimental.sessionReplay.sessionSampleRate)
assertEquals(expectedSampleRate.toDouble(), fixture.options.experimental.sessionReplay.onErrorSampleRate)
}
+
+ @Test
+ fun `applyMetadata reads maxBreadcrumbs to options and sets the value if found`() {
+ // Arrange
+ val bundle = bundleOf(ManifestMetadataReader.MAX_BREADCRUMBS to 1)
+ val context = fixture.getContext(metaData = bundle)
+
+ // Act
+ ManifestMetadataReader.applyMetadata(context, fixture.options, fixture.buildInfoProvider)
+
+ // Assert
+ assertEquals(1, fixture.options.maxBreadcrumbs)
+ }
+
+ @Test
+ fun `applyMetadata reads maxBreadcrumbs to options and keeps default if not found`() {
+ // Arrange
+ val context = fixture.getContext()
+
+ // Act
+ ManifestMetadataReader.applyMetadata(context, fixture.options, fixture.buildInfoProvider)
+
+ // Assert
+ assertEquals(100, fixture.options.maxBreadcrumbs)
+ }
}
diff --git a/sentry-samples/sentry-samples-android/src/main/AndroidManifest.xml b/sentry-samples/sentry-samples-android/src/main/AndroidManifest.xml
index ac854110171..84372b7766d 100644
--- a/sentry-samples/sentry-samples-android/src/main/AndroidManifest.xml
+++ b/sentry-samples/sentry-samples-android/src/main/AndroidManifest.xml
@@ -148,6 +148,9 @@
+
+
+
diff --git a/sentry/src/main/java/io/sentry/Baggage.java b/sentry/src/main/java/io/sentry/Baggage.java
index 954cda7a977..05a59d7053f 100644
--- a/sentry/src/main/java/io/sentry/Baggage.java
+++ b/sentry/src/main/java/io/sentry/Baggage.java
@@ -133,7 +133,7 @@ public static Baggage fromEvent(
final Baggage baggage = new Baggage(options.getLogger());
final SpanContext trace = event.getContexts().getTrace();
baggage.setTraceId(trace != null ? trace.getTraceId().toString() : null);
- baggage.setPublicKey(options.getParsedDsn().getPublicKey());
+ baggage.setPublicKey(options.retrieveParsedDsn().getPublicKey());
baggage.setRelease(event.getRelease());
baggage.setEnvironment(event.getEnvironment());
baggage.setTransaction(event.getTransaction());
@@ -383,7 +383,7 @@ public void setValuesFromTransaction(
final @Nullable String transactionName,
final @Nullable TransactionNameSource transactionNameSource) {
setTraceId(traceId.toString());
- setPublicKey(sentryOptions.getParsedDsn().getPublicKey());
+ setPublicKey(sentryOptions.retrieveParsedDsn().getPublicKey());
setRelease(sentryOptions.getRelease());
setEnvironment(sentryOptions.getEnvironment());
setTransaction(isHighQualityTransactionName(transactionNameSource) ? transactionName : null);
@@ -400,7 +400,7 @@ public void setValuesFromScope(
final @NotNull PropagationContext propagationContext = scope.getPropagationContext();
final @NotNull SentryId replayId = scope.getReplayId();
setTraceId(propagationContext.getTraceId().toString());
- setPublicKey(options.getParsedDsn().getPublicKey());
+ setPublicKey(options.retrieveParsedDsn().getPublicKey());
setRelease(options.getRelease());
setEnvironment(options.getEnvironment());
if (!SentryId.EMPTY_ID.equals(replayId)) {
diff --git a/sentry/src/main/java/io/sentry/DisabledQueue.java b/sentry/src/main/java/io/sentry/DisabledQueue.java
new file mode 100644
index 00000000000..afef111af4a
--- /dev/null
+++ b/sentry/src/main/java/io/sentry/DisabledQueue.java
@@ -0,0 +1,115 @@
+package io.sentry;
+
+import java.io.Serializable;
+import java.util.AbstractCollection;
+import java.util.Iterator;
+import java.util.NoSuchElementException;
+import java.util.Queue;
+import org.jetbrains.annotations.NotNull;
+import org.jetbrains.annotations.Nullable;
+
+final class DisabledQueue extends AbstractCollection implements Queue, Serializable {
+
+ /** Serialization version. */
+ private static final long serialVersionUID = -8423413834657610417L;
+
+ /** Constructor that creates a queue that does not accept any element. */
+ public DisabledQueue() {}
+
+ // -----------------------------------------------------------------------
+ /**
+ * Returns the number of elements stored in the queue.
+ *
+ * @return this queue's size
+ */
+ @Override
+ public int size() {
+ return 0;
+ }
+
+ /**
+ * Returns true if this queue is empty; false otherwise.
+ *
+ * @return false
+ */
+ @Override
+ public boolean isEmpty() {
+ return false;
+ }
+
+ /** Does nothing. */
+ @Override
+ public void clear() {}
+
+ /**
+ * Since the queue is disabled, the element will not be added.
+ *
+ * @param element the element to add
+ * @return false, always
+ */
+ @Override
+ public boolean add(final @NotNull E element) {
+ return false;
+ }
+
+ // -----------------------------------------------------------------------
+
+ /**
+ * Receives an element but do nothing with it.
+ *
+ * @param element the element to add
+ * @return false, always
+ */
+ @Override
+ public boolean offer(@NotNull E element) {
+ return false;
+ }
+
+ @Override
+ public @Nullable E poll() {
+ return null;
+ }
+
+ @Override
+ public @Nullable E element() {
+ return null;
+ }
+
+ @Override
+ public @Nullable E peek() {
+ return null;
+ }
+
+ @Override
+ public @NotNull E remove() {
+ throw new NoSuchElementException("queue is disabled");
+ }
+
+ // -----------------------------------------------------------------------
+
+ /**
+ * Returns an iterator over this queue's elements.
+ *
+ * @return an iterator over this queue's elements
+ */
+ @Override
+ public @NotNull Iterator iterator() {
+ return new Iterator() {
+
+ @Override
+ public boolean hasNext() {
+ return false;
+ }
+
+ @Override
+ public E next() {
+ throw new NoSuchElementException();
+ }
+
+ @Override
+ public void remove() {
+ throw new IllegalStateException();
+ }
+ };
+ }
+}
diff --git a/sentry/src/main/java/io/sentry/DsnUtil.java b/sentry/src/main/java/io/sentry/DsnUtil.java
index 6cc0dc360bd..b6902ad2741 100644
--- a/sentry/src/main/java/io/sentry/DsnUtil.java
+++ b/sentry/src/main/java/io/sentry/DsnUtil.java
@@ -23,7 +23,7 @@ public static boolean urlContainsDsnHost(@Nullable SentryOptions options, @Nulla
return false;
}
- final @NotNull Dsn dsn = options.getParsedDsn();
+ final @NotNull Dsn dsn = options.retrieveParsedDsn();
final @NotNull URI sentryUri = dsn.getSentryUri();
final @Nullable String dsnHost = sentryUri.getHost();
diff --git a/sentry/src/main/java/io/sentry/RequestDetailsResolver.java b/sentry/src/main/java/io/sentry/RequestDetailsResolver.java
index 6083c69e994..bba4dc19ac0 100644
--- a/sentry/src/main/java/io/sentry/RequestDetailsResolver.java
+++ b/sentry/src/main/java/io/sentry/RequestDetailsResolver.java
@@ -21,7 +21,7 @@ public RequestDetailsResolver(final @NotNull SentryOptions options) {
@NotNull
RequestDetails resolve() {
- final Dsn dsn = options.getParsedDsn();
+ final Dsn dsn = options.retrieveParsedDsn();
final URI sentryUri = dsn.getSentryUri();
final String envelopeUrl = sentryUri.resolve(sentryUri.getPath() + "/envelope/").toString();
diff --git a/sentry/src/main/java/io/sentry/Scope.java b/sentry/src/main/java/io/sentry/Scope.java
index 74e6642546b..4dacc8e4dac 100644
--- a/sentry/src/main/java/io/sentry/Scope.java
+++ b/sentry/src/main/java/io/sentry/Scope.java
@@ -786,7 +786,9 @@ public void clearAttachments() {
* @return the breadcrumbs queue
*/
static @NotNull Queue createBreadcrumbsList(final int maxBreadcrumb) {
- return SynchronizedQueue.synchronizedQueue(new CircularFifoQueue<>(maxBreadcrumb));
+ return maxBreadcrumb > 0
+ ? SynchronizedQueue.synchronizedQueue(new CircularFifoQueue<>(maxBreadcrumb))
+ : SynchronizedQueue.synchronizedQueue(new DisabledQueue<>());
}
/**
diff --git a/sentry/src/main/java/io/sentry/Sentry.java b/sentry/src/main/java/io/sentry/Sentry.java
index 7a35720e2dc..e8317365ed9 100644
--- a/sentry/src/main/java/io/sentry/Sentry.java
+++ b/sentry/src/main/java/io/sentry/Sentry.java
@@ -475,7 +475,7 @@ private static boolean preInitConfigurations(final @NotNull SentryOptions option
}
// This creates the DSN object and performs some checks
- options.getParsedDsn();
+ options.retrieveParsedDsn();
return true;
}
diff --git a/sentry/src/main/java/io/sentry/SentryOptions.java b/sentry/src/main/java/io/sentry/SentryOptions.java
index 5110d6c2f0d..8e427251e69 100644
--- a/sentry/src/main/java/io/sentry/SentryOptions.java
+++ b/sentry/src/main/java/io/sentry/SentryOptions.java
@@ -553,13 +553,15 @@ public void addIntegration(@NotNull Integration integration) {
}
/**
- * Evaluates and parses the DSN. May throw an exception if the DSN is invalid.
+ * Evaluates and parses the DSN. May throw an exception if the DSN is invalid. Renamed from
+ * `getParsedDsn` as this would cause an error when deploying as WAR to Tomcat due to `JNDI`
+ * property binding.
*
* @return the parsed DSN or throws if dsn is invalid
*/
@ApiStatus.Internal
@NotNull
- Dsn getParsedDsn() throws IllegalArgumentException {
+ Dsn retrieveParsedDsn() throws IllegalArgumentException {
return parsedDsn.getValue();
}
@@ -2438,7 +2440,7 @@ public void setGlobalHubMode(final @Nullable Boolean globalHubMode) {
*/
void loadLazyFields() {
getSerializer();
- getParsedDsn();
+ retrieveParsedDsn();
getEnvelopeReader();
getDateProvider();
}
diff --git a/sentry/src/test/java/io/sentry/DisabledQueueTest.kt b/sentry/src/test/java/io/sentry/DisabledQueueTest.kt
new file mode 100644
index 00000000000..351f87eaff7
--- /dev/null
+++ b/sentry/src/test/java/io/sentry/DisabledQueueTest.kt
@@ -0,0 +1,93 @@
+package io.sentry
+import org.junit.Assert.assertThrows
+import java.util.NoSuchElementException
+import kotlin.test.Test
+import kotlin.test.assertEquals
+import kotlin.test.assertFalse
+import kotlin.test.assertNull
+
+class DisabledQueueTest {
+
+ @Test
+ fun `size starts empty`() {
+ val queue = DisabledQueue()
+ assertEquals(0, queue.size, "Size should always be zero.")
+ }
+
+ @Test
+ fun `add does not add elements`() {
+ val queue = DisabledQueue()
+ assertFalse(queue.add(1), "add should always return false.")
+ assertEquals(0, queue.size, "Size should still be zero after attempting to add an element.")
+ }
+
+ @Test
+ fun `isEmpty returns false when created`() {
+ val queue = DisabledQueue()
+ assertFalse(queue.isEmpty(), "isEmpty should always return false.")
+ }
+
+ @Test
+ fun `isEmpty always returns false if add function was called`() {
+ val queue = DisabledQueue()
+ queue.add(1)
+
+ assertFalse(queue.isEmpty(), "isEmpty should always return false.")
+ }
+
+ @Test
+ fun `offer does not add elements`() {
+ val queue = DisabledQueue()
+ assertFalse(queue.offer(1), "offer should always return false.")
+ assertEquals(0, queue.size, "Size should still be zero after attempting to offer an element.")
+ }
+
+ @Test
+ fun `poll returns null`() {
+ val queue = DisabledQueue()
+ queue.add(1)
+ assertNull(queue.poll(), "poll should always return null.")
+ }
+
+ @Test
+ fun `peek returns null`() {
+ val queue = DisabledQueue()
+ queue.add(1)
+
+ assertNull(queue.peek(), "peek should always return null.")
+ }
+
+ @Test
+ fun `element returns null`() {
+ val queue = DisabledQueue()
+ assertNull(queue.element(), "element should always return null.")
+ }
+
+ @Test
+ fun `remove throws NoSuchElementException`() {
+ val queue = DisabledQueue()
+ assertThrows(NoSuchElementException::class.java) { queue.remove() }
+ }
+
+ @Test
+ fun `clear does nothing`() {
+ val queue = DisabledQueue()
+ queue.clear() // Should not throw an exception
+ assertEquals(0, queue.size, "Size should remain zero after clear.")
+ }
+
+ @Test
+ fun `iterator has no elements`() {
+ val queue = DisabledQueue()
+ val iterator = queue.iterator()
+ assertFalse(iterator.hasNext(), "Iterator should have no elements.")
+ assertThrows(NoSuchElementException::class.java) { iterator.next() }
+ }
+
+ @Test
+ fun `iterator remove throws IllegalStateException`() {
+ val queue = DisabledQueue()
+ val iterator = queue.iterator()
+ assertThrows(IllegalStateException::class.java) { iterator.remove() }
+ }
+}
diff --git a/sentry/src/test/java/io/sentry/ScopeTest.kt b/sentry/src/test/java/io/sentry/ScopeTest.kt
index 71c6c6f380c..b8025735e8a 100644
--- a/sentry/src/test/java/io/sentry/ScopeTest.kt
+++ b/sentry/src/test/java/io/sentry/ScopeTest.kt
@@ -1029,6 +1029,17 @@ class ScopeTest {
)
}
+ @Test
+ fun `creating a new scope won't crash if max breadcrumbs is set to zero`() {
+ val options = SentryOptions().apply {
+ maxBreadcrumbs = 0
+ }
+ val scope = Scope(options)
+
+ // expect no exception to be thrown
+ // previously was crashing, see https://github.com/getsentry/sentry-java/issues/3313
+ }
+
private fun eventProcessor(): EventProcessor {
return object : EventProcessor {
override fun process(event: SentryEvent, hint: Hint): SentryEvent? {