Skip to content

Commit 4ee9358

Browse files
committed
Add serializeAndDeserializeAreEqual
Checks that serialization/deserialization can be performed. Issue gh-16443
1 parent e5ea75f commit 4ee9358

File tree

1 file changed

+51
-0
lines changed

1 file changed

+51
-0
lines changed

config/src/test/java/org/springframework/security/SpringSecurityCoreVersionSerializableTests.java

+51
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616

1717
package org.springframework.security;
1818

19+
import java.io.ByteArrayInputStream;
20+
import java.io.ByteArrayOutputStream;
1921
import java.io.File;
2022
import java.io.FileInputStream;
2123
import java.io.FileOutputStream;
@@ -35,12 +37,14 @@
3537
import java.util.Collection;
3638
import java.util.Date;
3739
import java.util.HashMap;
40+
import java.util.HashSet;
3841
import java.util.List;
3942
import java.util.Map;
4043
import java.util.Set;
4144
import java.util.stream.Collectors;
4245
import java.util.stream.Stream;
4346

47+
import org.apache.commons.lang3.ObjectUtils;
4448
import org.apereo.cas.client.validation.AssertionImpl;
4549
import org.instancio.Instancio;
4650
import org.instancio.InstancioApi;
@@ -192,6 +196,7 @@
192196
import org.springframework.security.web.firewall.RequestRejectedException;
193197
import org.springframework.security.web.server.firewall.ServerExchangeRejectedException;
194198
import org.springframework.security.web.session.HttpSessionCreatedEvent;
199+
import org.springframework.util.ReflectionUtils;
195200

196201
import static org.assertj.core.api.Assertions.assertThat;
197202
import static org.assertj.core.api.Assertions.fail;
@@ -512,6 +517,52 @@ class SpringSecurityCoreVersionSerializableTests {
512517
(r) -> new HttpSessionCreatedEvent(new MockHttpSession()));
513518
}
514519

520+
@ParameterizedTest
521+
@MethodSource("getClassesToSerialize")
522+
void serializeAndDeserializeAreEqual(Class<?> clazz) throws Exception {
523+
Object expected = instancioWithDefaults(clazz).create();
524+
assertThat(expected).isInstanceOf(clazz);
525+
try (ByteArrayOutputStream out = new ByteArrayOutputStream();
526+
ObjectOutputStream objectOutputStream = new ObjectOutputStream(out)) {
527+
objectOutputStream.writeObject(expected);
528+
objectOutputStream.flush();
529+
530+
try (ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
531+
ObjectInputStream objectInputStream = new ObjectInputStream(in)) {
532+
Object deserialized = objectInputStream.readObject();
533+
// Ignore transient fields Event classes extend from EventObject which has
534+
// transient source property
535+
Set<String> transientFieldNames = new HashSet();
536+
Set<Class<?>> visitedClasses = new HashSet();
537+
collectTransientFieldNames(transientFieldNames, visitedClasses, clazz);
538+
assertThat(deserialized).usingRecursiveComparison()
539+
.ignoringFields(transientFieldNames.toArray(new String[0]))
540+
// RuntimeExceptions do not fully work but ensure the message does
541+
.withComparatorForType((lhs, rhs) -> ObjectUtils.compare(lhs.getMessage(), rhs.getMessage()),
542+
RuntimeException.class)
543+
.isEqualTo(expected);
544+
}
545+
}
546+
}
547+
548+
private static void collectTransientFieldNames(Set<String> transientFieldNames, Set<Class<?>> visitedClasses,
549+
Class<?> clazz) {
550+
if (!visitedClasses.add(clazz) || clazz.isPrimitive()) {
551+
return;
552+
}
553+
ReflectionUtils.doWithFields(clazz, (field) -> {
554+
if (Modifier.isTransient(field.getModifiers())) {
555+
transientFieldNames.add(field.getName());
556+
}
557+
collectTransientFieldNames(transientFieldNames, visitedClasses, field.getType());
558+
});
559+
}
560+
561+
@Test
562+
void debug() throws Exception {
563+
serializeAndDeserializeAreEqual(JaasAuthenticationFailedEvent.class);
564+
}
565+
515566
@ParameterizedTest
516567
@MethodSource("getClassesToSerialize")
517568
@Disabled("This method should only be used to serialize the classes once")

0 commit comments

Comments
 (0)