Skip to content

Stop picking a constructor by declaration order in a serialization test - #81

Open
aleksandar-apostolov wants to merge 1 commit into
developfrom
fix/and-1531-composite-serialization-test
Open

aleksandar-apostolov wants to merge 1 commit into
developfrom
fix/and-1531-composite-serialization-test

Conversation

@aleksandar-apostolov

Copy link
Copy Markdown
Collaborator

Goal

Closes AND-1531StreamCompositeEventSerializationImplTest.serialize - neither core nor product returns failure builds its fixture by indexing into getDeclaredConstructors(), whose ordering the JVM spec leaves unspecified.

StreamCompositeSerializationEvent compiles to three constructors — the 2-arg private (StreamClientWsEvent, T), the 4-arg defaults synthetic, and the 3-arg public access bridge. The test calls newInstance(null, null, null), so it only works while .first() happens to return the bridge.

It is green on CI today and red on at least one developer machine, where the 2-arg constructor is emitted first and newInstance throws IllegalArgumentException: wrong number of arguments. Nothing is blocked — this is a latent trap that fires whenever the compiler's emission order shifts.

Implementation

  • Dropped the reflection. external() takes a nullable T, so external<String?>(null) reaches the both-null state through the public factory; the unchecked cast covers the erased type parameter, and neither field is read as a String on this path.
  • Added assertNull on core and product before exercising the serializer. This test's failure mode was its construction step silently ceasing to do what it claimed, and the behaviour assertions alone would have pointed at the serializer rather than the fixture.

No production code touched.

Testing

./gradlew :stream-android-core:testDebugUnitTest — 757 tests, 0 failures, on a machine where this test was previously the one red.

getDeclaredConstructors() ordering is unspecified, so .first() started
returning the 2-arg private constructor instead of the 3-arg access bridge
and newInstance(null, null, null) threw. Reach the both-null state through
the external() factory instead and pin the precondition.
@aleksandar-apostolov aleksandar-apostolov added the pr:test Test-only changes label Sep 14, 2026
@github-actions

Copy link
Copy Markdown
Contributor

PR checklist ✅

All required conditions are satisfied:

  • Title length is OK (or ignored by label).
  • At least one pr: label exists.
  • Sections ### Goal, ### Implementation, and ### Testing are filled, or the PR is bot-authored.
  • An issue is linked (Linear ticket or GitHub issue), or the PR is bot-authored.

🎉 Great job! This PR is ready for review.

@sonarqubecloud

Copy link
Copy Markdown

@aleksandar-apostolov
aleksandar-apostolov marked this pull request as ready for review September 16, 2026 08:07
@coderabbitai

coderabbitai Bot commented Sep 16, 2026

Copy link
Copy Markdown

Important

  • 🔍 Trigger review

This repository does not receive automatic reviews because it has fewer than 10 stars.

⚙️ Run configuration

Configuration used: Repository UI

Review profile: CHILL

Plan: Advanced

Run ID: 70120f98-f62b-4e92-a6d6-1b757b695a26


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

pr:test Test-only changes

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants