This is an automated email from the ASF dual-hosted git repository.
ahuber pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/causeway.git
The following commit(s) were added to refs/heads/main by this push:
new 7b6a1bf22e5 CAUSEWAY-3883: don't allow
BackgroundService_IntegTestAbstract to run concurrent (testing)
7b6a1bf22e5 is described below
commit 7b6a1bf22e515b8f5638a5f866c68351607780cf
Author: Andi Huber <[email protected]>
AuthorDate: Thu Jun 26 16:19:28 2025 +0200
CAUSEWAY-3883: don't allow BackgroundService_IntegTestAbstract to run
concurrent (testing)
---
.../commandlog/applib/dom/BackgroundService.java | 30 +++++++++---------
.../BackgroundService_IntegTestAbstract.java | 36 +++++++++++++---------
2 files changed, 36 insertions(+), 30 deletions(-)
diff --git
a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/BackgroundService.java
b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/BackgroundService.java
index ecc931eb0c2..04571a47f23 100644
---
a/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/BackgroundService.java
+++
b/extensions/core/commandlog/applib/src/main/java/org/apache/causeway/extensions/commandlog/applib/dom/BackgroundService.java
@@ -20,6 +20,7 @@
import java.sql.Timestamp;
import java.util.UUID;
+import java.util.concurrent.ForkJoinPool;
import jakarta.inject.Inject;
@@ -61,10 +62,7 @@ public class BackgroundService {
* @see #executeMixin(Class, Object) - to invoke actions that are
implemented as mixins
*/
public <T> AsyncProxy<T> execute(final T object) {
- return wrapperFactory.asyncWrap(object, AsyncControl.defaults()
- .withNoExecute()
- .withCheckRules()
- .listen(new CommandPersistor(commandLogEntryRepository)));
+ return wrapperFactory.asyncWrap(object,
asyncControl().withCheckRules());
}
/**
* Wraps the domain object in a proxy whereby any actions invoked through
the proxy will instead be persisted as a
@@ -73,10 +71,7 @@ public <T> AsyncProxy<T> execute(final T object) {
* @see #executeMixin(Class, Object) - to invoke actions that are
implemented as mixins
*/
public <T> AsyncProxy<T> executeSkipRules(final T object) {
- return wrapperFactory.asyncWrap(object, AsyncControl.defaults()
- .withNoExecute()
- .withSkipRules()
- .listen(new CommandPersistor(commandLogEntryRepository)));
+ return wrapperFactory.asyncWrap(object,
asyncControl().withSkipRules());
}
/**
@@ -86,10 +81,7 @@ public <T> AsyncProxy<T> executeSkipRules(final T object) {
* @see #execute(Object) - to invoke actions that are implemented directly
within the object
*/
public <T> AsyncProxy<T> executeMixin(final Class<T> mixinClass, final
Object mixedIn) {
- return wrapperFactory.asyncWrapMixin(mixinClass, mixedIn,
AsyncControl.defaults()
- .withNoExecute()
- .withCheckRules()
- .listen(new CommandPersistor(commandLogEntryRepository)));
+ return wrapperFactory.asyncWrapMixin(mixinClass, mixedIn,
asyncControl().withCheckRules());
}
/**
@@ -99,10 +91,16 @@ public <T> AsyncProxy<T> executeMixin(final Class<T>
mixinClass, final Object mi
* @see #execute(Object) - to invoke actions that are implemented directly
within the object
*/
public <T> AsyncProxy<T> executeMixinSkipRules(final Class<T> mixinClass,
final Object mixedIn) {
- return wrapperFactory.asyncWrapMixin(mixinClass, mixedIn,
AsyncControl.defaults()
- .withNoExecute()
- .withSkipRules()
- .listen(new CommandPersistor(commandLogEntryRepository)));
+ return wrapperFactory.asyncWrapMixin(mixinClass, mixedIn,
asyncControl().withSkipRules());
+ }
+
+ // -- HELPER
+
+ AsyncControl asyncControl() {
+ return AsyncControl.defaults()
+ .with(ForkJoinPool.commonPool())
+ .withNoExecute()
+ .listen(new CommandPersistor(commandLogEntryRepository));
}
record CommandPersistor(CommandLogEntryRepository
commandLogEntryRepository) implements SyncControl.CommandListener {
diff --git
a/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/integtest/BackgroundService_IntegTestAbstract.java
b/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/integtest/BackgroundService_IntegTestAbstract.java
index 5a3e3dce8e4..0190cb6c198 100644
---
a/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/integtest/BackgroundService_IntegTestAbstract.java
+++
b/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/integtest/BackgroundService_IntegTestAbstract.java
@@ -20,16 +20,16 @@
import java.util.List;
import java.util.concurrent.TimeUnit;
+import java.util.concurrent.locks.ReentrantLock;
import jakarta.inject.Inject;
import org.junit.jupiter.api.AfterAll;
+import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeAll;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
-import org.junit.jupiter.api.extension.ExtendWith;
-import org.mockito.Mock;
-import org.mockito.junit.jupiter.MockitoExtension;
+import org.mockito.Mockito;
import org.quartz.JobExecutionContext;
import static org.assertj.core.api.Assertions.assertThat;
@@ -56,15 +56,26 @@
import lombok.SneakyThrows;
-@ExtendWith(MockitoExtension.class)
public abstract class BackgroundService_IntegTestAbstract extends
CausewayIntegrationTestAbstract {
- @Mock JobExecutionContext mockQuartzJobExecutionContext;
+ @Inject InteractionService interactionService;
+ @Inject BackgroundService backgroundService;
+ @Inject WrapperFactory wrapperFactory;
+ @Inject CommandLogEntryRepository commandLogEntryRepository;
+ @Inject TransactionService transactionService;
+ @Inject RunBackgroundCommandsJob runBackgroundCommandsJob;
+ @Inject BookmarkService bookmarkService;
+ @Inject CounterRepository<? extends Counter> counterRepository;
+
+ JobExecutionContext mockQuartzJobExecutionContext =
Mockito.mock(JobExecutionContext.class);
Bookmark bookmark;
protected abstract <T extends Counter> T newCounter(String name);
+ /// don't allow these tests to run concurrent
+ private final static ReentrantLock LOCK = new ReentrantLock();
+
private static boolean prototypingOrig;
@BeforeAll
@@ -80,6 +91,7 @@ static void reset_environment() {
@BeforeEach
void setup_counter() {
+ LOCK.lock();
transactionService.runTransactional(Propagation.REQUIRES_NEW, () -> {
counterRepository.removeAll();
@@ -98,6 +110,11 @@ void setup_counter() {
assertThat(counter.getNum()).isNull();
}
+ @AfterEach
+ void releaseLock() {
+ LOCK.unlock();
+ }
+
@Test
void async_using_default_executor_service() {
@@ -220,13 +237,4 @@ private void removeAllCommandLogEntriesAndCounters() {
}).ifFailureFail();
}
- @Inject InteractionService interactionService;
- @Inject BackgroundService backgroundService;
- @Inject WrapperFactory wrapperFactory;
- @Inject CommandLogEntryRepository commandLogEntryRepository;
- @Inject TransactionService transactionService;
- @Inject RunBackgroundCommandsJob runBackgroundCommandsJob;
- @Inject BookmarkService bookmarkService;
- @Inject CounterRepository<? extends Counter> counterRepository;
-
}