Skip to content

Commit 4056f66

Browse files
committed
Fix NPE when deserializing TestIdentifier
Issue: #3819
1 parent 5b13209 commit 4056f66

File tree

3 files changed

+75
-2
lines changed

3 files changed

+75
-2
lines changed

documentation/src/docs/asciidoc/release-notes/release-notes-5.11.0-M2.adoc

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -26,6 +26,7 @@ repository on GitHub.
2626
[[release-notes-5.11.0-M2-junit-platform-bug-fixes]]
2727
==== Bug Fixes
2828

29+
* Fixed a bug where `TestIdentifier` could cause a `NullPointerException` on deserialize when there is no parent identifier. See link:https://github.com/junit-team/junit5/issues/3819[issue 3819].
2930
* ❓
3031

3132
[[release-notes-5.11.0-M2-junit-platform-deprecations-and-breaking-changes]]

junit-platform-launcher/src/main/java/org/junit/platform/launcher/TestIdentifier.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -284,7 +284,8 @@ private void readObject(ObjectInputStream s) throws ClassNotFoundException, IOEx
284284
source = serializedForm.source;
285285
tags = serializedForm.tags;
286286
type = serializedForm.type;
287-
parentId = UniqueId.parse(serializedForm.parentId);
287+
String parentId = serializedForm.parentId;
288+
this.parentId = parentId == null ? null : UniqueId.parse(parentId);
288289
legacyReportingName = serializedForm.legacyReportingName;
289290
}
290291

@@ -307,7 +308,8 @@ private static class SerializedForm implements Serializable {
307308

308309
SerializedForm(TestIdentifier testIdentifier) {
309310
this.uniqueId = testIdentifier.uniqueId.toString();
310-
this.parentId = testIdentifier.parentId.toString();
311+
UniqueId parentId = testIdentifier.parentId;
312+
this.parentId = parentId == null ? null : parentId.toString();
311313
this.displayName = testIdentifier.displayName;
312314
this.legacyReportingName = testIdentifier.legacyReportingName;
313315
this.source = testIdentifier.source;

platform-tests/src/test/java/org/junit/platform/launcher/TestIdentifierTests.java

Lines changed: 70 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,12 @@
1616
import static org.junit.platform.commons.util.SerializationUtils.deserialize;
1717
import static org.junit.platform.commons.util.SerializationUtils.serialize;
1818

19+
import java.util.Optional;
1920
import java.util.Set;
2021

2122
import org.junit.jupiter.api.Test;
2223
import org.junit.platform.engine.TestDescriptor;
24+
import org.junit.platform.engine.TestSource;
2325
import org.junit.platform.engine.TestTag;
2426
import org.junit.platform.engine.UniqueId;
2527
import org.junit.platform.engine.support.descriptor.AbstractTestDescriptor;
@@ -72,6 +74,74 @@ void initialVersionCanBeDeserialized() throws Exception {
7274
}
7375
}
7476

77+
@Test
78+
void identifierWithNoParentCanBeSerializedAndDeserialized() throws Exception {
79+
TestIdentifier ti = TestIdentifier.from(new TestDescriptor() {
80+
@Override
81+
public UniqueId getUniqueId() {
82+
return UniqueId.root("example", "id");
83+
}
84+
85+
@Override
86+
public String getDisplayName() {
87+
return "displayName";
88+
}
89+
90+
@Override
91+
public Set<TestTag> getTags() {
92+
return Set.of();
93+
}
94+
95+
@Override
96+
public Optional<TestSource> getSource() {
97+
return Optional.empty();
98+
}
99+
100+
@Override
101+
public Optional<TestDescriptor> getParent() {
102+
return Optional.empty();
103+
}
104+
105+
@Override
106+
public void setParent(TestDescriptor parent) {
107+
// ignore
108+
}
109+
110+
@Override
111+
public Set<? extends TestDescriptor> getChildren() {
112+
return Set.of();
113+
}
114+
115+
@Override
116+
public void addChild(TestDescriptor descriptor) {
117+
// ignore
118+
}
119+
120+
@Override
121+
public void removeChild(TestDescriptor descriptor) {
122+
// ignore
123+
}
124+
125+
@Override
126+
public void removeFromHierarchy() {
127+
// ignore
128+
}
129+
130+
@Override
131+
public Type getType() {
132+
return Type.TEST;
133+
}
134+
135+
@Override
136+
public Optional<? extends TestDescriptor> findByUniqueId(UniqueId uniqueId) {
137+
return Optional.empty();
138+
}
139+
});
140+
byte[] bytes = serialize(ti);
141+
TestIdentifier dti = (TestIdentifier) deserialize(bytes);
142+
assertEquals(ti, dti);
143+
}
144+
75145
private static void assertDeepEquals(TestIdentifier first, TestIdentifier second) {
76146
assertEquals(first, second);
77147
assertEquals(first.getUniqueId(), second.getUniqueId());

0 commit comments

Comments
 (0)