Refactor to make it more apparent when a race condition occurs in concurrent Session access Integration Tests.

This commit is contained in:
John Blum
2022-04-28 15:03:20 -07:00
parent 9aecc6117b
commit fb23ebf55c
3 changed files with 34 additions and 21 deletions

View File

@@ -37,7 +37,9 @@ import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.session.Session;
import org.springframework.session.SessionRepository;
import org.springframework.util.Assert;
import org.springframework.util.ObjectUtils;
import org.springframework.util.StringUtils;
/**
* Abstract base class encapsulating functionality common to all concurrent {@link Session} data access operation
@@ -95,12 +97,23 @@ public abstract class AbstractConcurrentSessionOperationsIntegrationTests extend
return this.sessionRepository;
}
protected @NonNull String getSessionId() {
protected void setSessionId(@Nullable String sessionId) {
this.sessionId.set(sessionId);
}
protected @Nullable String getSessionId() {
return this.sessionId.get();
}
protected void setSessionId(@Nullable String sessionId) {
this.sessionId.set(sessionId);
protected @NonNull String requireSessionId() {
String sessionId = getSessionId();
Assert.state(StringUtils.hasText(sessionId), () -> "Session ID [%s] is not set;"
+ " A race condition may have occurred between the Thread setting the Session ID and the Threads"
+ " using the Session ID due to untimely operations in the Apache Geode client/server topology");
return sessionId;
}
protected @Nullable Session findById(@NonNull String id) {
@@ -116,7 +129,7 @@ public abstract class AbstractConcurrentSessionOperationsIntegrationTests extend
return session;
}
protected void waitOnAvailableSessionId() {
protected void waitOnRequiredSessionId() {
AbstractConcurrentSessionOperationsIntegrationTests.waitOn(() -> Objects.nonNull(this.sessionId.get()));
}
}
@@ -151,7 +164,6 @@ public abstract class AbstractConcurrentSessionOperationsIntegrationTests extend
assertThat(session.getAttributeNames()).containsOnly("attributeOne", "attributeTwo");
save(session);
setSessionId(session.getId());
waitForTick(4);
@@ -170,9 +182,9 @@ public abstract class AbstractConcurrentSessionOperationsIntegrationTests extend
waitForTick(1);
assertTick(1);
waitOnAvailableSessionId();
waitOnRequiredSessionId();
Session session = findById(getSessionId());
Session session = findById(requireSessionId());
assertThat(session).isNotNull();
assertThat(session.getId()).isEqualTo(getSessionId());
@@ -199,8 +211,9 @@ public abstract class AbstractConcurrentSessionOperationsIntegrationTests extend
waitForTick(1);
assertTick(1);
waitOnRequiredSessionId();
Session session = findById(getSessionId());
Session session = findById(requireSessionId());
assertThat(session).isNotNull();
assertThat(session.getId()).isEqualTo(getSessionId());

View File

@@ -54,6 +54,7 @@ import org.springframework.context.annotation.AnnotationConfigApplicationContext
import org.springframework.data.gemfire.config.annotation.CacheServerApplication;
import org.springframework.data.gemfire.config.annotation.ClientCacheApplication;
import org.springframework.lang.NonNull;
import org.springframework.lang.Nullable;
import org.springframework.session.Session;
import org.springframework.session.data.gemfire.config.annotation.web.http.EnableGemFireHttpSession;
import org.springframework.session.data.gemfire.config.annotation.web.http.GemFireHttpSessionConfiguration;
@@ -160,7 +161,7 @@ public class ConcurrentSessionOperationsUsingClientCachingProxyRegionIntegration
Instant beforeLastAccessedTime = Instant.now();
Session session = findById(getSessionId());
Session session = findById(requireSessionId());
assertThat(session).isNotNull();
assertThat(session.getId()).isEqualTo(getSessionId());
@@ -188,7 +189,7 @@ public class ConcurrentSessionOperationsUsingClientCachingProxyRegionIntegration
Instant beforeLastAccessedTime = Instant.now();
Session session = findById(getSessionId());
Session session = findById(requireSessionId());
assertThat(session).isNotNull();
assertThat(session.getId()).isEqualTo(getSessionId());
@@ -218,7 +219,7 @@ public class ConcurrentSessionOperationsUsingClientCachingProxyRegionIntegration
private final Region<Object, Session> sessions;
public RegionPutWithNonDirtySessionTestCase(
ConcurrentSessionOperationsUsingClientCachingProxyRegionIntegrationTests testInstance) {
@NonNull ConcurrentSessionOperationsUsingClientCachingProxyRegionIntegrationTests testInstance) {
super(testInstance);
@@ -226,7 +227,7 @@ public class ConcurrentSessionOperationsUsingClientCachingProxyRegionIntegration
this.sessionSerializer = reregisterDataSerializer(resolveDataSerializer());
}
private DataSerializer reregisterDataSerializer(DataSerializer dataSerializer) {
private @NonNull DataSerializer reregisterDataSerializer(@NonNull DataSerializer dataSerializer) {
InternalDataSerializer.unregister(dataSerializer.getId());
InternalDataSerializer._register(dataSerializer, false);
@@ -234,7 +235,7 @@ public class ConcurrentSessionOperationsUsingClientCachingProxyRegionIntegration
return dataSerializer;
}
private DataSerializer resolveDataSerializer() {
private @NonNull DataSerializer resolveDataSerializer() {
return Arrays.stream(nullSafeArray(InternalDataSerializer.getSerializers(), DataSerializer.class))
.filter(this.sessionSerializerFilter())
@@ -243,7 +244,7 @@ public class ConcurrentSessionOperationsUsingClientCachingProxyRegionIntegration
.orElseThrow(() -> newIllegalStateException(DATA_SERIALIZER_NOT_FOUND_EXCEPTION_MESSAGE));
}
private Predicate<? super DataSerializer> sessionSerializerFilter() {
private @NonNull Predicate<? super DataSerializer> sessionSerializerFilter() {
return dataSerializer -> {
@@ -260,11 +261,11 @@ public class ConcurrentSessionOperationsUsingClientCachingProxyRegionIntegration
};
}
private Session get(String id) {
private @Nullable Session get(@NonNull String id) {
return this.sessions.get(id);
}
private void put(Session session) {
private void put(@NonNull Session session) {
this.sessions.put(session.getId(), session);
@@ -313,9 +314,9 @@ public class ConcurrentSessionOperationsUsingClientCachingProxyRegionIntegration
waitForTick(1);
assertTick(1);
waitOnAvailableSessionId();
waitOnRequiredSessionId();
Session session = get(getSessionId());
Session session = get(requireSessionId());
assertThat(session).isInstanceOf(GemFireSession.class);
assertThat(session.getId()).isEqualTo(getSessionId());

View File

@@ -83,7 +83,6 @@ public class ConcurrentSessionOperationsUsingClientLocalRegionIntegrationTests
assertThat(session.getAttributeNames()).isEmpty();
save(session);
setSessionId(session.getId());
waitForTick(2);
@@ -100,9 +99,9 @@ public class ConcurrentSessionOperationsUsingClientLocalRegionIntegrationTests
waitForTick(1);
assertTick(1);
waitOnAvailableSessionId();
waitOnRequiredSessionId();
Session session = findById(getSessionId());
Session session = findById(requireSessionId());
assertThat(session).isNotNull();
assertThat(session.getId()).isEqualTo(getSessionId());