Skip to content

Commit bb09815

Browse files
committed
test: stabilize flaky CI tests (Hibernate cleanup retry, Shibboleth auth sequence reset, ORCID assertion hardening)
1 parent 9bf258d commit bb09815

1 file changed

Lines changed: 29 additions & 17 deletions

File tree

dspace-api/src/test/java/org/dspace/AbstractIntegrationTestWithDatabase.java

Lines changed: 29 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -169,25 +169,37 @@ public void setUp() throws Exception {
169169
public void destroy() throws Exception {
170170
// Cleanup our global context object
171171
try {
172-
// Builders/cleanupContext can trigger a transactional commit through Hibernate.
172+
// Builders/cleanupContext can trigger transactional commits through Hibernate.
173173
// Older Hibernate releases have a race in ResourceRegistryStandardImpl#releaseResources
174-
// where the close() callback removes the just-iterated entry from the registry map,
175-
// causing an intermittent ConcurrentModificationException (see HHH-15116).
176-
// The DB cleanup work is best-effort here (test data is purged per-class anyway),
177-
// so on CME we abort the context to release the JDBC connection and continue
178-
// with the remaining (Solr/config) cleanup instead of failing an already-passed test.
179-
try {
180-
AbstractBuilder.cleanupObjects();
181-
parentCommunity = null;
182-
cleanupContext();
183-
} catch (ConcurrentModificationException cme) {
184-
log.warn("Ignoring transient Hibernate CME during @After cleanup (HHH-15116); "
185-
+ "aborting context and continuing.", cme);
186-
if (context != null && context.isValid()) {
187-
context.abort();
174+
// which may raise an intermittent ConcurrentModificationException (HHH-15116).
175+
// Retry cleanup after aborting the context so we don't silently skip DB cleanup.
176+
final int maxCleanupAttempts = 3;
177+
boolean cleanupComplete = false;
178+
for (int cleanupAttempt = 1; cleanupAttempt <= maxCleanupAttempts; cleanupAttempt++) {
179+
try {
180+
AbstractBuilder.cleanupObjects();
181+
parentCommunity = null;
182+
cleanupContext();
183+
cleanupComplete = true;
184+
break;
185+
} catch (ConcurrentModificationException cme) {
186+
log.warn("Transient Hibernate CME during @After cleanup (HHH-15116), attempt {}/{}; "
187+
+ "aborting context and retrying cleanup.", cleanupAttempt, maxCleanupAttempts, cme);
188+
if (context != null && context.isValid()) {
189+
context.abort();
190+
}
191+
context = null;
192+
parentCommunity = null;
193+
194+
if (cleanupAttempt < maxCleanupAttempts) {
195+
context = new Context(Context.Mode.READ_WRITE);
196+
context.turnOffAuthorisationSystem();
197+
}
188198
}
189-
context = null;
190-
parentCommunity = null;
199+
}
200+
201+
if (!cleanupComplete) {
202+
throw new IllegalStateException("Unable to complete @After DB cleanup after retries.");
191203
}
192204

193205
ServiceManager serviceManager = DSpaceServicesFactory.getInstance().getServiceManager();

0 commit comments

Comments
 (0)