Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Don't assert exact exception type when StackOverflowError is thrown #2815

Merged

Conversation

Marcono1234
Copy link
Collaborator

Purpose

Make test more robust

Description

In https://github.com/google/gson/actions/runs/13467912934/job/37637273646?pr=2814 the JDK 21 build randomly failed:

Error:  com.google.gson.functional.CircularReferenceTest.testSelfReferenceArrayFieldSerialization -- Time elapsed: 0.034 s <<< FAILURE!
java.lang.AssertionError: unexpected exception type thrown; expected:<java.lang.StackOverflowError> but was:<java.lang.InternalError>
	...
Caused by: java.lang.InternalError: java.lang.StackOverflowError
	at java.base/jdk.internal.reflect.MethodHandleObjectFieldAccessorImpl.get(MethodHandleObjectFieldAccessorImpl.java:63)
	at java.base/java.lang.reflect.Field.get(Field.java:444)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$2.write(ReflectiveTypeAdapterFactory.java:240)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:489)
	at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:1521)
	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:73)
	at com.google.gson.internal.bind.ArrayTypeAdapter.write(ArrayTypeAdapter.java:109)
	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:73)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$2.write(ReflectiveTypeAdapterFactory.java:247)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:489)
	at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:1521)
	at com.google.gson.internal.bind.TypeAdapterRuntimeTypeWrapper.write(TypeAdapterRuntimeTypeWrapper.java:73)
	at com.google.gson.internal.bind.ArrayTypeAdapter.write(ArrayTypeAdapter.java:109)
	...
Caused by: java.lang.StackOverflowError
	at java.base/java.lang.invoke.DirectMethodHandle$Accessor.checkCast(DirectMethodHandle.java:516)
	at java.base/java.lang.invoke.DirectMethodHandle.checkCast(DirectMethodHandle.java:599)
	at java.base/jdk.internal.reflect.MethodHandleObjectFieldAccessorImpl.get(MethodHandleObjectFieldAccessorImpl.java:57)
	at java.base/java.lang.reflect.Field.get(Field.java:444)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$2.write(ReflectiveTypeAdapterFactory.java:240)
	at com.google.gson.internal.bind.ReflectiveTypeAdapterFactory$Adapter.write(ReflectiveTypeAdapterFactory.java:489)
	at com.google.gson.Gson$FutureTypeAdapter.write(Gson.java:1521)
	...

The test CircularReferenceTest#testSelfReferenceArrayFieldSerialization expects a StackOverflowError, and indeed that error occurred. However, it happened inside the JDK code and that wrapped it in an InternalError.
So to make the test more reliable it should not assume that the StackOverflowError actually reaches the assertion but just that any exception reaches it.

Checklist

  • New code follows the Google Java Style Guide
    This is automatically checked by mvn verify, but can also be checked on its own using mvn spotless:check.
    Style violations can be fixed using mvn spotless:apply; this can be done in a separate commit to verify that it did not cause undesired changes.
  • If necessary, new public API validates arguments, for example rejects null
  • New public API has Javadoc
    • Javadoc uses @since $next-version$
      ($next-version$ is a special placeholder which is automatically replaced during release)
  • If necessary, new unit tests have been added
    • Assertions in unit tests use Truth, see existing tests
    • No JUnit 3 features are used (such as extending class TestCase)
    • If this pull request fixes a bug, a new test was added for a situation which failed previously and is now fixed
  • mvn clean verify javadoc:jar passes without errors

assertThrowsStackOverflow(() -> gson.toJson(obj));
}

/** Asserts that a {@link StackOverflowError} is thrown. */
Copy link
Member

Choose a reason for hiding this comment

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

But it doesn't assert that, does it? 🙂 I think we can probably assume that StackOverflowError is at least in the cause chain, and probably that it is the root cause. So then this?

Throwable t = assertThrows(Throwable.class, runnable);
assertThat(Throwables.getRootCause(t)).isInstanceOf(StackOverflowError.class);

Copy link
Collaborator Author

Choose a reason for hiding this comment

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

But it doesn't assert that, does it?

Yes you are right. My intention was to indicate that this methods is intended for cases where a StackOverflowError is expected, but then the implementation admits that it cannot reliably detect that.


I think we can probably assume that StackOverflowError is at least in the cause chain

Yes that could be an option. Let's just hope that there is no JDK code which sets it only as 'suppressed exception', or which entirely discards the cause.

Copy link
Member

Choose a reason for hiding this comment

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

Right. If that ever happens, we can adjust accordingly.

assertThrowsStackOverflow(() -> gson.toJson(obj));
}

/** Asserts that a {@link StackOverflowError} is thrown. */
Copy link
Member

Choose a reason for hiding this comment

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

Right. If that ever happens, we can adjust accordingly.

@eamonnmcmanus eamonnmcmanus merged commit 0e591c2 into google:main Feb 23, 2025
11 checks passed
@Marcono1234 Marcono1234 deleted the marcono1234/StackOverflowError-assertion branch February 23, 2025 20:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

2 participants