You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@causeway.apache.org by da...@apache.org on 2026/06/08 07:37:19 UTC
(causeway) 14/27: CAUSEWAY-4023: adds replay command sync tests
This is an automated email from the ASF dual-hosted git repository.
danhaywood pushed a commit to branch CAUSEWAY-4025
in repository https://gitbox.apache.org/repos/asf/causeway.git
commit 18361b2905485e2d85f69e011de5dfa06ec2f9fd
Author: Dan Haywood <da...@haywood-associates.co.uk>
AuthorDate: Mon Jun 8 06:56:07 2026 +0100
CAUSEWAY-4023: adds replay command sync tests
---
.../applib/dom/CommandLogEntrySyncTest.java | 82 ++++++++++++++++++++++
.../CommandSubscriberForCommandLogTest.java | 71 +++++++++++++++----
2 files changed, 141 insertions(+), 12 deletions(-)
diff --git a/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/dom/CommandLogEntrySyncTest.java b/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/dom/CommandLogEntrySyncTest.java
index 8e319a90cb7..62a04ec4c5c 100644
--- a/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/dom/CommandLogEntrySyncTest.java
+++ b/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/dom/CommandLogEntrySyncTest.java
@@ -33,11 +33,17 @@
import org.apache.causeway.applib.services.bookmark.Bookmark;
import org.apache.causeway.applib.services.command.Command;
import org.apache.causeway.commons.functional.Try;
+import org.apache.causeway.schema.cmd.v2.CommandDto;
class CommandLogEntrySyncTest {
+ private static final UUID INTERACTION_ID = UUID.fromString("11111111-1111-1111-1111-111111111111");
+ private static final String USERNAME = "sven";
+ private static final Timestamp TIMESTAMP = Timestamp.from(Instant.parse("2026-06-08T09:59:59Z"));
private static final Timestamp STARTED_AT = Timestamp.from(Instant.parse("2026-06-08T10:00:00Z"));
private static final Timestamp COMPLETED_AT = Timestamp.from(Instant.parse("2026-06-08T10:00:01Z"));
+ private static final Bookmark TARGET = Bookmark.forLogicalTypeNameAndIdentifier("demo.Customer", "target");
+ private static final String LOGICAL_MEMBER_IDENTIFIER = "demo.Customer#act()";
private static final Bookmark RESULT = Bookmark.forLogicalTypeNameAndIdentifier("demo.Customer", "1");
@Test
@@ -53,6 +59,19 @@ void sync_execution_metadata_preserves_recorded_outcome_for_replay_entries() {
verify(commandLogEntry, never()).setException((Throwable) null);
}
+ @Test
+ void sync_execution_metadata_preserves_recorded_command_data_for_replay_entries() {
+ final var commandDto = mock(CommandDto.class);
+ final var command = commandWithAllData(commandDto);
+ final var commandLogEntry = commandLogEntry(ReplayState.OK);
+
+ commandLogEntry.syncExecutionMetadata(command);
+
+ verify(commandLogEntry).setStartedAt(STARTED_AT);
+ verify(commandLogEntry).setCompletedAt(COMPLETED_AT);
+ verifyRecordedCommandDataWasNotOverwritten(commandLogEntry, commandDto);
+ }
+
@Test
void sync_execution_metadata_updates_outcome_for_non_replay_entries() {
final var command = commandWithExecutionMetadataAndResult();
@@ -66,6 +85,28 @@ void sync_execution_metadata_updates_outcome_for_non_replay_entries() {
verify(commandLogEntry).setException((Throwable) null);
}
+ @Test
+ void sync_keeps_full_synchronization_for_non_replay_entries() {
+ final var commandDto = mock(CommandDto.class);
+ final var command = commandWithAllData(commandDto);
+ final var commandLogEntry = commandLogEntry(ReplayState.UNDEFINED);
+
+ commandLogEntry.sync(command);
+
+ verifyFullSync(commandLogEntry, commandDto);
+ }
+
+ @Test
+ void sync_keeps_full_synchronization_for_entries_with_unset_replay_state() {
+ final var commandDto = mock(CommandDto.class);
+ final var command = commandWithAllData(commandDto);
+ final var commandLogEntry = commandLogEntry(null);
+
+ commandLogEntry.sync(command);
+
+ verifyFullSync(commandLogEntry, commandDto);
+ }
+
private static Command commandWithExecutionMetadataAndResult() {
final var command = new Command(UUID.randomUUID());
command.updater().setStartedAt(STARTED_AT);
@@ -74,9 +115,50 @@ private static Command commandWithExecutionMetadataAndResult() {
return command;
}
+ private static Command commandWithAllData(final CommandDto commandDto) {
+ final var command = mock(Command.class);
+ when(command.getInteractionId()).thenReturn(INTERACTION_ID);
+ when(command.getUsername()).thenReturn(USERNAME);
+ when(command.getTimestamp()).thenReturn(TIMESTAMP);
+ when(command.getCommandDto()).thenReturn(commandDto);
+ when(command.getTarget()).thenReturn(TARGET);
+ when(command.getLogicalMemberIdentifier()).thenReturn(LOGICAL_MEMBER_IDENTIFIER);
+ when(command.getStartedAt()).thenReturn(STARTED_AT);
+ when(command.getCompletedAt()).thenReturn(COMPLETED_AT);
+ when(command.getResult()).thenReturn(RESULT);
+ when(command.getException()).thenReturn(null);
+ return command;
+ }
+
private static CommandLogEntry commandLogEntry(final ReplayState replayState) {
final var commandLogEntry = mock(CommandLogEntry.class, CALLS_REAL_METHODS);
when(commandLogEntry.getReplayState()).thenReturn(replayState);
return commandLogEntry;
}
+
+ private static void verifyRecordedCommandDataWasNotOverwritten(
+ final CommandLogEntry commandLogEntry,
+ final CommandDto commandDto) {
+ verify(commandLogEntry, never()).setInteractionId(INTERACTION_ID);
+ verify(commandLogEntry, never()).setUsername(USERNAME);
+ verify(commandLogEntry, never()).setTimestamp(TIMESTAMP);
+ verify(commandLogEntry, never()).setCommandDto(commandDto);
+ verify(commandLogEntry, never()).setTarget(TARGET);
+ verify(commandLogEntry, never()).setLogicalMemberIdentifier(LOGICAL_MEMBER_IDENTIFIER);
+ }
+
+ private static void verifyFullSync(
+ final CommandLogEntry commandLogEntry,
+ final CommandDto commandDto) {
+ verify(commandLogEntry).setInteractionId(INTERACTION_ID);
+ verify(commandLogEntry).setUsername(USERNAME);
+ verify(commandLogEntry).setTimestamp(TIMESTAMP);
+ verify(commandLogEntry).setCommandDto(commandDto);
+ verify(commandLogEntry).setTarget(TARGET);
+ verify(commandLogEntry).setLogicalMemberIdentifier(LOGICAL_MEMBER_IDENTIFIER);
+ verify(commandLogEntry).setStartedAt(STARTED_AT);
+ verify(commandLogEntry).setCompletedAt(COMPLETED_AT);
+ verify(commandLogEntry).setResult(RESULT);
+ verify(commandLogEntry).setException((Throwable) null);
+ }
}
diff --git a/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/subscriber/CommandSubscriberForCommandLogTest.java b/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/subscriber/CommandSubscriberForCommandLogTest.java
index 51463c43a19..569fb148bd8 100644
--- a/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/subscriber/CommandSubscriberForCommandLogTest.java
+++ b/extensions/core/commandlog/applib/src/test/java/org/apache/causeway/extensions/commandlog/applib/subscriber/CommandSubscriberForCommandLogTest.java
@@ -39,10 +39,11 @@ class CommandSubscriberForCommandLogTest {
void on_started_preserves_recorded_command_data_for_replay_entries() {
final var command = new Command(UUID.randomUUID());
final var commandLogEntry = commandLogEntry(ReplayState.PENDING);
- final var subscriber = subscriber(command, commandLogEntry);
+ final var fixture = subscriberFixture(command, commandLogEntry, true, false);
- subscriber.onStarted(command);
+ fixture.subscriber.onStarted(command);
+ verify(commandLogEntry).getReplayState();
verify(commandLogEntry).syncExecutionMetadata(command);
verify(commandLogEntry, never()).sync(command);
}
@@ -51,10 +52,11 @@ void on_started_preserves_recorded_command_data_for_replay_entries() {
void on_completed_preserves_recorded_command_data_for_replay_entries() {
final var command = new Command(UUID.randomUUID());
final var commandLogEntry = commandLogEntry(ReplayState.FAILED);
- final var subscriber = subscriber(command, commandLogEntry);
+ final var fixture = subscriberFixture(command, commandLogEntry, true, false);
- subscriber.onCompleted(command);
+ fixture.subscriber.onCompleted(command);
+ verify(commandLogEntry).getReplayState();
verify(commandLogEntry).syncExecutionMetadata(command);
verify(commandLogEntry, never()).sync(command);
}
@@ -63,10 +65,11 @@ void on_completed_preserves_recorded_command_data_for_replay_entries() {
void on_started_keeps_full_sync_for_exportable_entries() {
final var command = new Command(UUID.randomUUID());
final var commandLogEntry = commandLogEntry(ReplayState.UNDEFINED);
- final var subscriber = subscriber(command, commandLogEntry);
+ final var fixture = subscriberFixture(command, commandLogEntry, true, false);
- subscriber.onStarted(command);
+ fixture.subscriber.onStarted(command);
+ verify(commandLogEntry).getReplayState();
verify(commandLogEntry).sync(command);
verify(commandLogEntry, never()).syncExecutionMetadata(command);
}
@@ -75,28 +78,58 @@ void on_started_keeps_full_sync_for_exportable_entries() {
void on_completed_keeps_full_sync_for_exportable_entries() {
final var command = new Command(UUID.randomUUID());
final var commandLogEntry = commandLogEntry(ReplayState.UNDEFINED);
- final var subscriber = subscriber(command, commandLogEntry);
+ final var fixture = subscriberFixture(command, commandLogEntry, true, false);
- subscriber.onCompleted(command);
+ fixture.subscriber.onCompleted(command);
+ verify(commandLogEntry).getReplayState();
verify(commandLogEntry).sync(command);
verify(commandLogEntry, never()).syncExecutionMetadata(command);
}
+ @Test
+ void on_started_does_not_lookup_entry_when_disabled() {
+ final var command = new Command(UUID.randomUUID());
+ final var commandLogEntry = commandLogEntry(ReplayState.UNDEFINED);
+ final var fixture = subscriberFixture(command, commandLogEntry, false, false);
+
+ fixture.subscriber.onStarted(command);
+
+ verify(fixture.commandLogEntryRepository, never()).findByInteractionId(command.getInteractionId());
+ verify(commandLogEntry, never()).sync(command);
+ verify(commandLogEntry, never()).syncExecutionMetadata(command);
+ }
+
+ @Test
+ void on_completed_does_not_lookup_entry_when_paused() {
+ final var command = new Command(UUID.randomUUID());
+ final var commandLogEntry = commandLogEntry(ReplayState.UNDEFINED);
+ final var fixture = subscriberFixture(command, commandLogEntry, true, true);
+
+ fixture.subscriber.onCompleted(command);
+
+ verify(fixture.commandLogEntryRepository, never()).findByInteractionId(command.getInteractionId());
+ verify(commandLogEntry, never()).sync(command);
+ verify(commandLogEntry, never()).syncExecutionMetadata(command);
+ }
+
private static CommandLogEntry commandLogEntry(final ReplayState replayState) {
final var commandLogEntry = mock(CommandLogEntry.class);
when(commandLogEntry.getReplayState()).thenReturn(replayState);
return commandLogEntry;
}
- private static CommandSubscriberForCommandLog subscriber(
+ private static SubscriberFixture subscriberFixture(
final Command command,
- final CommandLogEntry commandLogEntry) {
+ final CommandLogEntry commandLogEntry,
+ final boolean enabled,
+ final boolean paused) {
final var commandLogEntryRepository = mock(CommandLogEntryRepository.class);
when(commandLogEntryRepository.findByInteractionId(command.getInteractionId()))
.thenReturn(Optional.of(commandLogEntry));
final var commandLogPauseState = mock(CommandLogPauseState.class);
- return new CommandSubscriberForCommandLog(
+ when(commandLogPauseState.isPaused()).thenReturn(paused);
+ final var subscriber = new CommandSubscriberForCommandLog(
commandLogEntryRepository,
null,
null,
@@ -104,8 +137,22 @@ private static CommandSubscriberForCommandLog subscriber(
commandLogPauseState) {
@Override
public boolean isEnabled() {
- return true;
+ return enabled;
}
};
+ return new SubscriberFixture(subscriber, commandLogEntryRepository);
+ }
+
+ private static class SubscriberFixture {
+
+ private final CommandSubscriberForCommandLog subscriber;
+ private final CommandLogEntryRepository commandLogEntryRepository;
+
+ private SubscriberFixture(
+ final CommandSubscriberForCommandLog subscriber,
+ final CommandLogEntryRepository commandLogEntryRepository) {
+ this.subscriber = subscriber;
+ this.commandLogEntryRepository = commandLogEntryRepository;
+ }
}
}