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;
+        }
     }
 }