This is an automated email from the ASF dual-hosted git repository.

tkalkirill pushed a commit to branch main
in repository https://gitbox.apache.org/repos/asf/ignite-3.git


The following commit(s) were added to refs/heads/main by this push:
     new 3442190ea9a IGNITE-26745 Add a common base class for unit testing of 
raft command backward compatibility (#6800)
3442190ea9a is described below

commit 3442190ea9a3e3122bbe5213d8783d37355cc39d
Author: Kirill Tkalenko <[email protected]>
AuthorDate: Fri Oct 17 11:25:20 2025 +0300

    IGNITE-26745 Add a common base class for unit testing of raft command 
backward compatibility (#6800)
---
 modules/cluster-management/build.gradle            |   2 +-
 .../commands/CmgCommandsCompatibilityTest.java     |  83 +++++-----------
 modules/metastorage/build.gradle                   |   2 +-
 .../MetastorageCommandsCompatibilityTest.java      | 109 ++++++---------------
 modules/partition-replicator/build.gradle          |   1 +
 .../PartitionCommandsCompatibilityTest.java        | 105 ++++++--------------
 .../raft/BaseCommandsCompatibilityTest.java}       |  80 +++++++--------
 modules/replicator/build.gradle                    |   2 +-
 .../ReplicatorCommandsCompatibilityTest.java       |  74 +++-----------
 modules/transactions/build.gradle                  |   2 +-
 .../tx/message/TxCommandsCompatibilityTest.java    |  65 +++---------
 11 files changed, 152 insertions(+), 373 deletions(-)

diff --git a/modules/cluster-management/build.gradle 
b/modules/cluster-management/build.gradle
index af06255f148..804944a6b7d 100644
--- a/modules/cluster-management/build.gradle
+++ b/modules/cluster-management/build.gradle
@@ -51,12 +51,12 @@ dependencies {
     testImplementation project(':ignite-configuration')
     testImplementation project(':ignite-network')
     testImplementation project(':ignite-system-disaster-recovery')
-    testImplementation project(':ignite-raft')
     testImplementation testFixtures(project(':ignite-core'))
     testImplementation testFixtures(project(':ignite-configuration'))
     testImplementation testFixtures(project(':ignite-network'))
     testImplementation testFixtures(project(':ignite-vault'))
     testImplementation testFixtures(project(':ignite-failure-handler'))
+    testImplementation testFixtures(project(':ignite-raft'))
 
     testFixturesImplementation project(':ignite-core')
     testFixturesImplementation project(':ignite-failure-handler')
diff --git 
a/modules/cluster-management/src/test/java/org/apache/ignite/internal/cluster/management/raft/commands/CmgCommandsCompatibilityTest.java
 
b/modules/cluster-management/src/test/java/org/apache/ignite/internal/cluster/management/raft/commands/CmgCommandsCompatibilityTest.java
index cc6313d0fa9..c7974d80b64 100644
--- 
a/modules/cluster-management/src/test/java/org/apache/ignite/internal/cluster/management/raft/commands/CmgCommandsCompatibilityTest.java
+++ 
b/modules/cluster-management/src/test/java/org/apache/ignite/internal/cluster/management/raft/commands/CmgCommandsCompatibilityTest.java
@@ -20,44 +20,44 @@ package 
org.apache.ignite.internal.cluster.management.raft.commands;
 import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertInstanceOf;
 
-import java.util.Base64;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.UUID;
 import org.apache.ignite.internal.cluster.management.ClusterState;
 import org.apache.ignite.internal.cluster.management.ClusterTag;
 import 
org.apache.ignite.internal.cluster.management.network.messages.CmgMessagesFactory;
 import 
org.apache.ignite.internal.cluster.management.network.messages.CmgMessagesSerializationRegistryInitializer;
-import org.apache.ignite.internal.network.MessageSerializationRegistryImpl;
-import 
org.apache.ignite.internal.network.serialization.MessageSerializationRegistry;
+import 
org.apache.ignite.internal.network.serialization.MessageSerializationRegistryInitializer;
+import org.apache.ignite.internal.raft.BaseCommandsCompatibilityTest;
 import org.apache.ignite.internal.raft.Command;
-import org.apache.ignite.internal.raft.Marshaller;
-import org.apache.ignite.internal.raft.util.ThreadLocalOptimizedMarshaller;
-import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 /**
  * Compatibility testing for serialization/deserialization of CMG raft 
commands. It is verified that deserialization of commands that were
  * created on earlier versions of the product will be error-free.
- *
- * <p>For MAC users with aarch64 architecture, you will need to add {@code || 
"aarch64".equals(arch)} to the
- * {@code GridUnsafe#unaligned()} for the tests to pass. For more details, see
- * <a 
href="https://lists.apache.org/thread/67coyvm8mo7106mkndt24yqwtbvb7590";>discussion</a>.</p>
- *
- * <p>To serialize commands, use {@link #serializeAll()} and insert the result 
into the appropriate tests.</p>
  */
-public class CmgCommandsCompatibilityTest extends BaseIgniteAbstractTest {
-    private final MessageSerializationRegistry registry = new 
MessageSerializationRegistryImpl();
-
-    private final Marshaller marshaller = new 
ThreadLocalOptimizedMarshaller(registry);
-
+public class CmgCommandsCompatibilityTest extends 
BaseCommandsCompatibilityTest {
     private final CmgMessagesFactory factory = new CmgMessagesFactory();
 
-    @BeforeEach
-    void setUp() {
-        new 
CmgMessagesSerializationRegistryInitializer().registerFactories(registry);
+    @Override
+    protected Collection<MessageSerializationRegistryInitializer> 
initializers() {
+        return List.of(new CmgMessagesSerializationRegistryInitializer());
+    }
+
+    @Override
+    protected Collection<Command> commandsToSerialize() {
+        return List.of(
+                createChangeMetaStorageInfoCommand(),
+                createInitCmgStateCommand(),
+                createJoinReadyCommand(),
+                createJoinRequestCommand(),
+                createNodesLeaveCommand(),
+                createReadLogicalTopologyCommand(),
+                createReadMetaStorageInfoCommand(),
+                createReadStateCommand(),
+                createReadValidatedNodesCommand()
+        );
     }
 
     @Test
@@ -138,10 +138,6 @@ public class CmgCommandsCompatibilityTest extends 
BaseIgniteAbstractTest {
         assertInstanceOf(ReadValidatedNodesCommand.class, command);
     }
 
-    private static UUID uuid() {
-        return new UUID(42, 69);
-    }
-
     private ClusterNodeMessage createClusterNodeMessage() {
         return factory.clusterNodeMessage()
                 .id(uuid())
@@ -165,33 +161,6 @@ public class CmgCommandsCompatibilityTest extends 
BaseIgniteAbstractTest {
                 .build();
     }
 
-    private <T extends Command> T deserializeCommand(byte[] bytes) {
-        return marshaller.unmarshall(bytes);
-    }
-
-    private <T extends Command> T decodeCommand(String base64) {
-        return deserializeCommand(Base64.getDecoder().decode(base64));
-    }
-
-    @SuppressWarnings("unused")
-    private void serializeAll() {
-        List<Command> commands = List.of(
-                createChangeMetaStorageInfoCommand(),
-                createInitCmgStateCommand(),
-                createJoinReadyCommand(),
-                createJoinRequestCommand(),
-                createNodesLeaveCommand(),
-                createReadLogicalTopologyCommand(),
-                createReadMetaStorageInfoCommand(),
-                createReadStateCommand(),
-                createReadValidatedNodesCommand()
-        );
-
-        for (Command c : commands) {
-            log.info(">>>>> Serialized command: [c={}, base64='{}']", 
c.getClass().getSimpleName(), encodeCommand(c));
-        }
-    }
-
     private ReadValidatedNodesCommand createReadValidatedNodesCommand() {
         return factory.readValidatedNodesCommand().build();
     }
@@ -241,12 +210,4 @@ public class CmgCommandsCompatibilityTest extends 
BaseIgniteAbstractTest {
                 .metastorageRepairingConfigIndex(42L)
                 .build();
     }
-
-    private byte[] serializeCommand(Command c) {
-        return marshaller.marshall(c);
-    }
-
-    private String encodeCommand(Command c) {
-        return Base64.getEncoder().encodeToString(serializeCommand(c));
-    }
 }
diff --git a/modules/metastorage/build.gradle b/modules/metastorage/build.gradle
index e599d32d928..23f113efbde 100644
--- a/modules/metastorage/build.gradle
+++ b/modules/metastorage/build.gradle
@@ -44,7 +44,6 @@ dependencies {
 
     annotationProcessor project(':ignite-network-annotation-processor')
 
-    testImplementation project(':ignite-network')
     testImplementation testFixtures(project(':ignite-core'))
     testImplementation testFixtures(project(':ignite-vault'))
     testImplementation testFixtures(project(':ignite-configuration'))
@@ -52,6 +51,7 @@ dependencies {
     testImplementation testFixtures(project(':ignite-failure-handler'))
     testImplementation testFixtures(project(':ignite-metrics'))
     testImplementation testFixtures(project(':ignite-configuration-system'))
+    testImplementation testFixtures(project(':ignite-raft'))
 
     integrationTestImplementation project(':ignite-cluster-management')
     integrationTestImplementation project(':ignite-network')
diff --git 
a/modules/metastorage/src/test/java/org/apache/ignite/internal/metastorage/command/MetastorageCommandsCompatibilityTest.java
 
b/modules/metastorage/src/test/java/org/apache/ignite/internal/metastorage/command/MetastorageCommandsCompatibilityTest.java
index a9d4887c6c3..e382ac99ce4 100644
--- 
a/modules/metastorage/src/test/java/org/apache/ignite/internal/metastorage/command/MetastorageCommandsCompatibilityTest.java
+++ 
b/modules/metastorage/src/test/java/org/apache/ignite/internal/metastorage/command/MetastorageCommandsCompatibilityTest.java
@@ -24,9 +24,8 @@ import static 
org.junit.jupiter.api.Assertions.assertInstanceOf;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.nio.ByteBuffer;
-import java.util.Base64;
+import java.util.Collection;
 import java.util.List;
-import java.util.UUID;
 import org.apache.ignite.internal.hlc.HybridTimestamp;
 import org.apache.ignite.internal.lang.ByteArray;
 import org.apache.ignite.internal.metastorage.CommandId;
@@ -36,36 +35,46 @@ import org.apache.ignite.internal.metastorage.dsl.Iif;
 import 
org.apache.ignite.internal.metastorage.dsl.MetaStorageMessagesSerializationRegistryInitializer;
 import org.apache.ignite.internal.metastorage.dsl.Operations;
 import org.apache.ignite.internal.metastorage.dsl.Statements;
-import org.apache.ignite.internal.network.MessageSerializationRegistryImpl;
-import 
org.apache.ignite.internal.network.serialization.MessageSerializationRegistry;
+import 
org.apache.ignite.internal.network.serialization.MessageSerializationRegistryInitializer;
+import org.apache.ignite.internal.raft.BaseCommandsCompatibilityTest;
 import org.apache.ignite.internal.raft.Command;
-import org.apache.ignite.internal.raft.Marshaller;
-import org.apache.ignite.internal.raft.util.ThreadLocalOptimizedMarshaller;
-import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 /**
  * Compatibility testing for serialization/deserialization of metastorage raft 
commands. It is verified that deserialization of commands
  * that were created on earlier versions of the product will be error-free.
- *
- * <p>For MAC users with aarch64 architecture, you will need to add {@code || 
"aarch64".equals(arch)} to the
- * {@code GridUnsafe#unaligned()} for the tests to pass. For more details, see
- * <a 
href="https://lists.apache.org/thread/67coyvm8mo7106mkndt24yqwtbvb7590";>discussion</a>.</p>
- *
- * <p>To serialize commands, use {@link #serializeAll()} and insert the result 
into the appropriate tests.</p>
  */
-public class MetastorageCommandsCompatibilityTest extends 
BaseIgniteAbstractTest {
-    private final MessageSerializationRegistry registry = new 
MessageSerializationRegistryImpl();
-
-    private final Marshaller marshaller = new 
ThreadLocalOptimizedMarshaller(registry);
-
+public class MetastorageCommandsCompatibilityTest extends 
BaseCommandsCompatibilityTest {
     private final MetaStorageCommandsFactory factory = new 
MetaStorageCommandsFactory();
 
-    @BeforeEach
-    void setUp() {
-        new 
MetaStorageCommandsSerializationRegistryInitializer().registerFactories(registry);
-        new 
MetaStorageMessagesSerializationRegistryInitializer().registerFactories(registry);
+    @Override
+    protected Collection<MessageSerializationRegistryInitializer> 
initializers() {
+        return List.of(
+                new MetaStorageCommandsSerializationRegistryInitializer(),
+                new MetaStorageMessagesSerializationRegistryInitializer()
+        );
+    }
+
+    @Override
+    protected Collection<Command> commandsToSerialize() {
+        return List.of(
+                createCompactionCommand(),
+                createEvictIdempotentCommandsCacheCommand(),
+                createGetAllCommand(),
+                createGetChecksumCommand(),
+                createGetCommand(),
+                createGetCurrentRevisionsCommand(),
+                createGetPrefixCommand(),
+                createGetRangeCommand(),
+                createInvokeCommand(),
+                createMultiInvokeCommand(),
+                createPutAllCommand(),
+                createPutCommand(),
+                createRemoveAllCommand(),
+                createRemoveByPrefixCommand(),
+                createRemoveCommand(),
+                createSyncTimeCommand()
+        );
     }
 
     @Test
@@ -255,18 +264,6 @@ public class MetastorageCommandsCompatibilityTest extends 
BaseIgniteAbstractTest
         assertEquals(42, command.initiatorTerm());
     }
 
-    private static HybridTimestamp initiatorTime() {
-        return HybridTimestamp.hybridTimestamp(70);
-    }
-
-    private static HybridTimestamp safeTime() {
-        return HybridTimestamp.hybridTimestamp(69);
-    }
-
-    private static UUID uuid() {
-        return new UUID(42, 69);
-    }
-
     private static CommandId commandId() {
         return CommandId.fromString(uuid() + "_cnt_" + 70);
     }
@@ -283,40 +280,6 @@ public class MetastorageCommandsCompatibilityTest extends 
BaseIgniteAbstractTest
         return ByteArray.fromString(key);
     }
 
-    private <T extends Command> T deserializeCommand(byte[] bytes) {
-        return marshaller.unmarshall(bytes);
-    }
-
-    private <T extends Command> T decodeCommand(String base64) {
-        return deserializeCommand(Base64.getDecoder().decode(base64));
-    }
-
-    @SuppressWarnings("unused")
-    private void serializeAll() {
-        List<Command> commands = List.of(
-                createCompactionCommand(),
-                createEvictIdempotentCommandsCacheCommand(),
-                createGetAllCommand(),
-                createGetChecksumCommand(),
-                createGetCommand(),
-                createGetCurrentRevisionsCommand(),
-                createGetPrefixCommand(),
-                createGetRangeCommand(),
-                createInvokeCommand(),
-                createMultiInvokeCommand(),
-                createPutAllCommand(),
-                createPutCommand(),
-                createRemoveAllCommand(),
-                createRemoveByPrefixCommand(),
-                createRemoveCommand(),
-                createSyncTimeCommand()
-        );
-
-        for (Command c : commands) {
-            log.info(">>>>> Serialized command: [c={}, base64='{}']", 
c.getClass().getSimpleName(), encodeCommand(c));
-        }
-    }
-
     private SyncTimeCommand createSyncTimeCommand() {
         return factory.syncTimeCommand()
                 .safeTime(safeTime())
@@ -472,12 +435,4 @@ public class MetastorageCommandsCompatibilityTest extends 
BaseIgniteAbstractTest
                 .compactionRevision(42)
                 .build();
     }
-
-    private byte[] serializeCommand(Command c) {
-        return marshaller.marshall(c);
-    }
-
-    private String encodeCommand(Command c) {
-        return Base64.getEncoder().encodeToString(serializeCommand(c));
-    }
 }
diff --git a/modules/partition-replicator/build.gradle 
b/modules/partition-replicator/build.gradle
index 24fc89780b2..5d725fa9611 100644
--- a/modules/partition-replicator/build.gradle
+++ b/modules/partition-replicator/build.gradle
@@ -57,6 +57,7 @@ dependencies {
     testImplementation testFixtures(project(':ignite-table'))
     testImplementation testFixtures(project(':ignite-transactions'))
     testImplementation testFixtures(project(':ignite-placement-driver-api'))
+    testImplementation testFixtures(project(':ignite-raft'))
 
     integrationTestImplementation 
testFixtures(project(':ignite-cluster-management'))
     integrationTestImplementation testFixtures(project(':ignite-core'))
diff --git 
a/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/command/PartitionCommandsCompatibilityTest.java
 
b/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/command/PartitionCommandsCompatibilityTest.java
index e442a23a928..460f2c84de8 100644
--- 
a/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/command/PartitionCommandsCompatibilityTest.java
+++ 
b/modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/command/PartitionCommandsCompatibilityTest.java
@@ -21,57 +21,61 @@ import static org.junit.jupiter.api.Assertions.assertEquals;
 import static org.junit.jupiter.api.Assertions.assertTrue;
 
 import java.nio.ByteBuffer;
-import java.util.Base64;
+import java.util.Collection;
 import java.util.List;
 import java.util.Map;
 import java.util.Set;
-import java.util.UUID;
 import org.apache.ignite.internal.hlc.HybridTimestamp;
-import org.apache.ignite.internal.network.MessageSerializationRegistryImpl;
-import 
org.apache.ignite.internal.network.serialization.MessageSerializationRegistry;
+import 
org.apache.ignite.internal.network.serialization.MessageSerializationRegistryInitializer;
 import 
org.apache.ignite.internal.partition.replicator.network.PartitionReplicationMessagesFactory;
 import 
org.apache.ignite.internal.partition.replicator.network.PartitionReplicationMessagesSerializationRegistryInitializer;
 import 
org.apache.ignite.internal.partition.replicator.network.replication.BinaryRowMessage;
+import org.apache.ignite.internal.raft.BaseCommandsCompatibilityTest;
 import org.apache.ignite.internal.raft.Command;
-import org.apache.ignite.internal.raft.Marshaller;
-import org.apache.ignite.internal.raft.util.ThreadLocalOptimizedMarshaller;
 import org.apache.ignite.internal.replicator.message.ReplicaMessagesFactory;
 import 
org.apache.ignite.internal.replicator.message.ReplicaMessagesSerializationRegistryInitializer;
 import org.apache.ignite.internal.replicator.message.TablePartitionIdMessage;
 import org.apache.ignite.internal.replicator.message.ZonePartitionIdMessage;
-import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
 import org.apache.ignite.internal.tx.message.EnlistedPartitionGroupMessage;
 import org.apache.ignite.internal.tx.message.TxMessagesFactory;
 import 
org.apache.ignite.internal.tx.message.TxMessagesSerializationRegistryInitializer;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 /**
  * Compatibility testing for serialization/deserialization of partition raft 
commands. It is verified that deserialization of commands that
  * were created on earlier versions of the product will be error-free.
- *
- * <p>For MAC users with aarch64 architecture, you will need to add {@code || 
"aarch64".equals(arch)} to the
- * {@code GridUnsafe#unaligned()} for the tests to pass. For more details, see
- * <a 
href="https://lists.apache.org/thread/67coyvm8mo7106mkndt24yqwtbvb7590";>discussion</a>.</p>
- *
- * <p>To serialize commands, use {@link #serializeAll()} and insert the result 
into the appropriate tests.</p>
  */
-public class PartitionCommandsCompatibilityTest extends BaseIgniteAbstractTest 
{
-    private final MessageSerializationRegistry registry = new 
MessageSerializationRegistryImpl();
-
-    private final Marshaller marshaller = new 
ThreadLocalOptimizedMarshaller(registry);
-
+public class PartitionCommandsCompatibilityTest extends 
BaseCommandsCompatibilityTest {
     private final PartitionReplicationMessagesFactory commandFactory = new 
PartitionReplicationMessagesFactory();
 
     private final ReplicaMessagesFactory replicaFactory = new 
ReplicaMessagesFactory();
 
     private final TxMessagesFactory txFactory = new TxMessagesFactory();
 
-    @BeforeEach
-    void setUp() {
-        new 
PartitionReplicationMessagesSerializationRegistryInitializer().registerFactories(registry);
-        new 
ReplicaMessagesSerializationRegistryInitializer().registerFactories(registry);
-        new 
TxMessagesSerializationRegistryInitializer().registerFactories(registry);
+    @Override
+    protected Collection<MessageSerializationRegistryInitializer> 
initializers() {
+        return List.of(
+                new 
PartitionReplicationMessagesSerializationRegistryInitializer(),
+                new ReplicaMessagesSerializationRegistryInitializer(),
+                new TxMessagesSerializationRegistryInitializer()
+        );
+    }
+
+    @Override
+    protected Collection<Command> commandsToSerialize() {
+        return List.of(
+                createBuildIndexCommand(),
+                createBuildIndexCommandV2(),
+                createFinishTxCommandV1(),
+                createFinishTxCommandV2(),
+                createUpdateAllCommand(),
+                createUpdateAllCommandV2(),
+                createUpdateCommand(),
+                createUpdateCommandV2(),
+                createUpdateMinimumActiveTxBeginTimeCommand(),
+                createWriteIntentSwitchCommand(),
+                createWriteIntentSwitchCommandV2()
+        );
     }
 
     @Test
@@ -221,22 +225,6 @@ public class PartitionCommandsCompatibilityTest extends 
BaseIgniteAbstractTest {
         assertEquals(Set.of(7, 8), command.tableIds());
     }
 
-    private static HybridTimestamp initiatorTime() {
-        return HybridTimestamp.hybridTimestamp(70);
-    }
-
-    private static HybridTimestamp safeTime() {
-        return HybridTimestamp.hybridTimestamp(69);
-    }
-
-    private static HybridTimestamp commitTimestamp() {
-        return HybridTimestamp.hybridTimestamp(71);
-    }
-
-    private static UUID uuid() {
-        return new UUID(42, 69);
-    }
-
     private TablePartitionIdMessage tablePartitionId() {
         return replicaFactory.tablePartitionIdMessage()
                 .tableId(33)
@@ -271,35 +259,6 @@ public class PartitionCommandsCompatibilityTest extends 
BaseIgniteAbstractTest {
                 .build();
     }
 
-    private <T extends Command> T deserializeCommand(byte[] bytes) {
-        return marshaller.unmarshall(bytes);
-    }
-
-    private <T extends Command> T decodeCommand(String base64) {
-        return deserializeCommand(Base64.getDecoder().decode(base64));
-    }
-
-    @SuppressWarnings("unused")
-    private void serializeAll() {
-        List<Command> commands = List.of(
-                createBuildIndexCommand(),
-                createBuildIndexCommandV2(),
-                createFinishTxCommandV1(),
-                createFinishTxCommandV2(),
-                createUpdateAllCommand(),
-                createUpdateAllCommandV2(),
-                createUpdateCommand(),
-                createUpdateCommandV2(),
-                createUpdateMinimumActiveTxBeginTimeCommand(),
-                createWriteIntentSwitchCommand(),
-                createWriteIntentSwitchCommandV2()
-        );
-
-        for (Command c : commands) {
-            log.info(">>>>> Serialized command: [command={}, base64='{}']", 
c.getClass().getSimpleName(), encodeCommand(c));
-        }
-    }
-
     private WriteIntentSwitchCommandV2 createWriteIntentSwitchCommandV2() {
         return commandFactory.writeIntentSwitchCommandV2()
                 .initiatorTime(initiatorTime())
@@ -427,12 +386,4 @@ public class PartitionCommandsCompatibilityTest extends 
BaseIgniteAbstractTest {
                 .finish(true)
                 .build();
     }
-
-    private byte[] serializeCommand(Command c) {
-        return marshaller.marshall(c);
-    }
-
-    private String encodeCommand(Command c) {
-        return Base64.getEncoder().encodeToString(serializeCommand(c));
-    }
 }
diff --git 
a/modules/transactions/src/test/java/org/apache/ignite/internal/tx/message/TxCommandsCompatibilityTest.java
 
b/modules/raft/src/testFixtures/java/org/apache/ignite/internal/raft/BaseCommandsCompatibilityTest.java
similarity index 63%
copy from 
modules/transactions/src/test/java/org/apache/ignite/internal/tx/message/TxCommandsCompatibilityTest.java
copy to 
modules/raft/src/testFixtures/java/org/apache/ignite/internal/raft/BaseCommandsCompatibilityTest.java
index f5902a7655f..207880ab013 100644
--- 
a/modules/transactions/src/test/java/org/apache/ignite/internal/tx/message/TxCommandsCompatibilityTest.java
+++ 
b/modules/raft/src/testFixtures/java/org/apache/ignite/internal/raft/BaseCommandsCompatibilityTest.java
@@ -15,86 +15,82 @@
  * limitations under the License.
  */
 
-package org.apache.ignite.internal.tx.message;
-
-import static org.junit.jupiter.api.Assertions.assertEquals;
+package org.apache.ignite.internal.raft;
 
 import java.util.Base64;
-import java.util.List;
-import java.util.Set;
+import java.util.Collection;
 import java.util.UUID;
+import org.apache.ignite.internal.hlc.HybridTimestamp;
 import org.apache.ignite.internal.network.MessageSerializationRegistryImpl;
 import 
org.apache.ignite.internal.network.serialization.MessageSerializationRegistry;
-import org.apache.ignite.internal.raft.Command;
-import org.apache.ignite.internal.raft.Marshaller;
+import 
org.apache.ignite.internal.network.serialization.MessageSerializationRegistryInitializer;
 import org.apache.ignite.internal.raft.util.ThreadLocalOptimizedMarshaller;
 import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
 import org.junit.jupiter.api.BeforeEach;
-import org.junit.jupiter.api.Test;
 
 /**
- * Compatibility testing for serialization/deserialization of tx raft 
commands. It is verified that deserialization of commands that were
- * created on earlier versions of the product will be error-free.
+ * Base class for unit testing backward compatibility of raft commands.
+ *
+ * <p>To serialize commands, use {@link #serializeAll()} and insert the result 
into the appropriate tests.</p>
  *
  * <p>For MAC users with aarch64 architecture, you will need to add {@code || 
"aarch64".equals(arch)} to the
  * {@code GridUnsafe#unaligned()} for the tests to pass. For more details, see
  * <a 
href="https://lists.apache.org/thread/67coyvm8mo7106mkndt24yqwtbvb7590";>discussion</a>.</p>
- *
- * <p>To serialize commands, use {@link #serializeAll()} and insert the result 
into the appropriate tests.</p>
  */
-public class TxCommandsCompatibilityTest extends BaseIgniteAbstractTest {
+public abstract class BaseCommandsCompatibilityTest extends 
BaseIgniteAbstractTest {
     private final MessageSerializationRegistry registry = new 
MessageSerializationRegistryImpl();
 
     private final Marshaller marshaller = new 
ThreadLocalOptimizedMarshaller(registry);
 
-    private final TxMessagesFactory factory = new TxMessagesFactory();
-
     @BeforeEach
     void setUp() {
-        new 
TxMessagesSerializationRegistryInitializer().registerFactories(registry);
+        initializers().forEach(i -> i.registerFactories(registry));
     }
 
-    @Test
-    void testVacuumTxStatesCommand() {
-        VacuumTxStatesCommand command = 
decodeCommand("Bg4CAAAAAAAAAAAqAAAAAAAAAEU=");
+    /** Returns all {@link MessageSerializationRegistryInitializer} that will 
be needed for testing. */
+    protected abstract Collection<MessageSerializationRegistryInitializer> 
initializers();
 
-        assertEquals(Set.of(uuid()), command.txIds());
-    }
+    /** Returns all commands to be serialized. */
+    protected abstract Collection<Command> commandsToSerialize();
 
-    private static UUID uuid() {
-        return new UUID(42, 69);
+    @SuppressWarnings("unused")
+    private void serializeAll() {
+        for (Command c : commandsToSerialize()) {
+            log.info("Serialized command: [command={}, base64='{}']", 
c.getClass().getSimpleName(), encodeCommand(c));
+        }
     }
 
-    private <T extends Command> T deserializeCommand(byte[] bytes) {
-        return marshaller.unmarshall(bytes);
+    /** Serializes a raft command and encodes it into Base64 string. */
+    private String encodeCommand(Command c) {
+        return Base64.getEncoder().encodeToString(serializeCommand(c));
     }
 
-    private <T extends Command> T decodeCommand(String base64) {
+    /** Deserializes a raft command from Base64 string. */
+    protected <T extends Command> T decodeCommand(String base64) {
         return deserializeCommand(Base64.getDecoder().decode(base64));
     }
 
-    @SuppressWarnings("unused")
-    private void serializeAll() {
-        List<Command> commands = List.of(
-                createVacuumTxStatesCommand()
-        );
+    private byte[] serializeCommand(Command c) {
+        return marshaller.marshall(c);
+    }
 
-        for (Command c : commands) {
-            log.info(">>>>> Serialized command: [c={}, base64='{}']", 
c.getClass().getSimpleName(), encodeCommand(c));
-        }
+    private <T extends Command> T deserializeCommand(byte[] bytes) {
+        return marshaller.unmarshall(bytes);
     }
 
-    private VacuumTxStatesCommand createVacuumTxStatesCommand() {
-        return factory.vacuumTxStatesCommand()
-                .txIds(Set.of(uuid()))
-                .build();
+    protected static UUID uuid() {
+        return new UUID(42, 69);
     }
 
-    private byte[] serializeCommand(Command c) {
-        return marshaller.marshall(c);
+    protected static HybridTimestamp initiatorTime() {
+        return HybridTimestamp.hybridTimestamp(70);
     }
 
-    private String encodeCommand(Command c) {
-        return Base64.getEncoder().encodeToString(serializeCommand(c));
+    protected static HybridTimestamp safeTime() {
+        return HybridTimestamp.hybridTimestamp(69);
+    }
+
+    protected static HybridTimestamp commitTimestamp() {
+        return HybridTimestamp.hybridTimestamp(71);
     }
 }
diff --git a/modules/replicator/build.gradle b/modules/replicator/build.gradle
index 1ab45a03a14..a6d6a8dab00 100644
--- a/modules/replicator/build.gradle
+++ b/modules/replicator/build.gradle
@@ -57,10 +57,10 @@ dependencies {
     integrationTestImplementation testFixtures(project(':ignite-metrics'))
     integrationTestImplementation testFixtures(project(':ignite-raft'))
 
-    testImplementation project(':ignite-network')
     testImplementation testFixtures(project(':ignite-core'))
     testImplementation testFixtures(project(':ignite-placement-driver-api'))
     testImplementation testFixtures(project(':ignite-failure-handler'))
+    testImplementation testFixtures(project(':ignite-raft'))
 
     testFixturesAnnotationProcessor 
project(':ignite-network-annotation-processor')
     testFixturesImplementation project(':ignite-network-api')
diff --git 
a/modules/replicator/src/test/java/org/apache/ignite/internal/replicator/ReplicatorCommandsCompatibilityTest.java
 
b/modules/replicator/src/test/java/org/apache/ignite/internal/replicator/ReplicatorCommandsCompatibilityTest.java
index 290180b1fef..f2de6013200 100644
--- 
a/modules/replicator/src/test/java/org/apache/ignite/internal/replicator/ReplicatorCommandsCompatibilityTest.java
+++ 
b/modules/replicator/src/test/java/org/apache/ignite/internal/replicator/ReplicatorCommandsCompatibilityTest.java
@@ -19,43 +19,35 @@ package org.apache.ignite.internal.replicator;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
-import java.util.Base64;
+import java.util.Collection;
 import java.util.List;
-import java.util.UUID;
-import org.apache.ignite.internal.hlc.HybridTimestamp;
-import org.apache.ignite.internal.network.MessageSerializationRegistryImpl;
-import 
org.apache.ignite.internal.network.serialization.MessageSerializationRegistry;
+import 
org.apache.ignite.internal.network.serialization.MessageSerializationRegistryInitializer;
+import org.apache.ignite.internal.raft.BaseCommandsCompatibilityTest;
 import org.apache.ignite.internal.raft.Command;
-import org.apache.ignite.internal.raft.Marshaller;
-import org.apache.ignite.internal.raft.util.ThreadLocalOptimizedMarshaller;
 import org.apache.ignite.internal.replicator.command.SafeTimeSyncCommand;
 import 
org.apache.ignite.internal.replicator.message.PrimaryReplicaChangeCommand;
 import org.apache.ignite.internal.replicator.message.ReplicaMessagesFactory;
 import 
org.apache.ignite.internal.replicator.message.ReplicaMessagesSerializationRegistryInitializer;
-import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 /**
  * Compatibility testing for serialization/deserialization of replicator raft 
commands. It is verified that deserialization of commands that
  * were created on earlier versions of the product will be error-free.
- *
- * <p>For MAC users with aarch64 architecture, you will need to add {@code || 
"aarch64".equals(arch)} to the
- * {@code GridUnsafe#unaligned()} for the tests to pass. For more details, see
- * <a 
href="https://lists.apache.org/thread/67coyvm8mo7106mkndt24yqwtbvb7590";>discussion</a>.</p>
- *
- * <p>To serialize commands, use {@link #serializeAll()} and insert the result 
into the appropriate tests.</p>
  */
-public class ReplicatorCommandsCompatibilityTest extends 
BaseIgniteAbstractTest {
-    private final MessageSerializationRegistry registry = new 
MessageSerializationRegistryImpl();
-
-    private final Marshaller marshaller = new 
ThreadLocalOptimizedMarshaller(registry);
-
+public class ReplicatorCommandsCompatibilityTest extends 
BaseCommandsCompatibilityTest {
     private final ReplicaMessagesFactory factory = new 
ReplicaMessagesFactory();
 
-    @BeforeEach
-    void setUp() {
-        new 
ReplicaMessagesSerializationRegistryInitializer().registerFactories(registry);
+    @Override
+    protected Collection<MessageSerializationRegistryInitializer> 
initializers() {
+        return List.of(new ReplicaMessagesSerializationRegistryInitializer());
+    }
+
+    @Override
+    protected Collection<Command> commandsToSerialize() {
+        return List.of(
+                createSafeTimeSyncCommand(),
+                createPrimaryReplicaChangeCommand()
+        );
     }
 
     @Test
@@ -74,34 +66,6 @@ public class ReplicatorCommandsCompatibilityTest extends 
BaseIgniteAbstractTest
         assertEquals("node1", command.primaryReplicaNodeName());
     }
 
-    private static HybridTimestamp initiatorTime() {
-        return HybridTimestamp.hybridTimestamp(70);
-    }
-
-    private static UUID uuid() {
-        return new UUID(42, 69);
-    }
-
-    private <T extends Command> T deserializeCommand(byte[] bytes) {
-        return marshaller.unmarshall(bytes);
-    }
-
-    private <T extends Command> T decodeCommand(String base64) {
-        return deserializeCommand(Base64.getDecoder().decode(base64));
-    }
-
-    @SuppressWarnings("unused")
-    private void serializeAll() {
-        List<Command> commands = List.of(
-                createSafeTimeSyncCommand(),
-                createPrimaryReplicaChangeCommand()
-        );
-
-        for (Command c : commands) {
-            log.info(">>>>> Serialized command: [c={}, base64='{}']", 
c.getClass().getSimpleName(), encodeCommand(c));
-        }
-    }
-
     private PrimaryReplicaChangeCommand createPrimaryReplicaChangeCommand() {
         return factory.primaryReplicaChangeCommand()
                 .leaseStartTime(42)
@@ -115,12 +79,4 @@ public class ReplicatorCommandsCompatibilityTest extends 
BaseIgniteAbstractTest
                 .initiatorTime(initiatorTime())
                 .build();
     }
-
-    private byte[] serializeCommand(Command c) {
-        return marshaller.marshall(c);
-    }
-
-    private String encodeCommand(Command c) {
-        return Base64.getEncoder().encodeToString(serializeCommand(c));
-    }
 }
diff --git a/modules/transactions/build.gradle 
b/modules/transactions/build.gradle
index 416d2640ff0..ea2bd4285a7 100644
--- a/modules/transactions/build.gradle
+++ b/modules/transactions/build.gradle
@@ -51,7 +51,6 @@ dependencies {
     implementation libs.fastutil.core
 
     testImplementation project(':ignite-core')
-    testImplementation project(':ignite-raft')
     testImplementation testFixtures(project(':ignite-core'))
     testImplementation testFixtures(project(':ignite-configuration'))
     testImplementation testFixtures(project(':ignite-configuration-system'))
@@ -60,6 +59,7 @@ dependencies {
     testImplementation testFixtures(project(':ignite-low-watermark'))
     testImplementation testFixtures(project(':ignite-transactions'))
     testImplementation testFixtures(project(':ignite-metrics'))
+    testImplementation testFixtures(project(':ignite-raft'))
 
     integrationTestImplementation project(':ignite-api')
     integrationTestImplementation project(':ignite-cluster-management')
diff --git 
a/modules/transactions/src/test/java/org/apache/ignite/internal/tx/message/TxCommandsCompatibilityTest.java
 
b/modules/transactions/src/test/java/org/apache/ignite/internal/tx/message/TxCommandsCompatibilityTest.java
index f5902a7655f..f9ea3e748de 100644
--- 
a/modules/transactions/src/test/java/org/apache/ignite/internal/tx/message/TxCommandsCompatibilityTest.java
+++ 
b/modules/transactions/src/test/java/org/apache/ignite/internal/tx/message/TxCommandsCompatibilityTest.java
@@ -19,39 +19,29 @@ package org.apache.ignite.internal.tx.message;
 
 import static org.junit.jupiter.api.Assertions.assertEquals;
 
-import java.util.Base64;
+import java.util.Collection;
 import java.util.List;
 import java.util.Set;
-import java.util.UUID;
-import org.apache.ignite.internal.network.MessageSerializationRegistryImpl;
-import 
org.apache.ignite.internal.network.serialization.MessageSerializationRegistry;
+import 
org.apache.ignite.internal.network.serialization.MessageSerializationRegistryInitializer;
+import org.apache.ignite.internal.raft.BaseCommandsCompatibilityTest;
 import org.apache.ignite.internal.raft.Command;
-import org.apache.ignite.internal.raft.Marshaller;
-import org.apache.ignite.internal.raft.util.ThreadLocalOptimizedMarshaller;
-import org.apache.ignite.internal.testframework.BaseIgniteAbstractTest;
-import org.junit.jupiter.api.BeforeEach;
 import org.junit.jupiter.api.Test;
 
 /**
  * Compatibility testing for serialization/deserialization of tx raft 
commands. It is verified that deserialization of commands that were
  * created on earlier versions of the product will be error-free.
- *
- * <p>For MAC users with aarch64 architecture, you will need to add {@code || 
"aarch64".equals(arch)} to the
- * {@code GridUnsafe#unaligned()} for the tests to pass. For more details, see
- * <a 
href="https://lists.apache.org/thread/67coyvm8mo7106mkndt24yqwtbvb7590";>discussion</a>.</p>
- *
- * <p>To serialize commands, use {@link #serializeAll()} and insert the result 
into the appropriate tests.</p>
  */
-public class TxCommandsCompatibilityTest extends BaseIgniteAbstractTest {
-    private final MessageSerializationRegistry registry = new 
MessageSerializationRegistryImpl();
-
-    private final Marshaller marshaller = new 
ThreadLocalOptimizedMarshaller(registry);
-
+public class TxCommandsCompatibilityTest extends BaseCommandsCompatibilityTest 
{
     private final TxMessagesFactory factory = new TxMessagesFactory();
 
-    @BeforeEach
-    void setUp() {
-        new 
TxMessagesSerializationRegistryInitializer().registerFactories(registry);
+    @Override
+    protected Collection<MessageSerializationRegistryInitializer> 
initializers() {
+        return List.of(new TxMessagesSerializationRegistryInitializer());
+    }
+
+    @Override
+    protected Collection<Command> commandsToSerialize() {
+        return List.of(createVacuumTxStatesCommand());
     }
 
     @Test
@@ -61,40 +51,9 @@ public class TxCommandsCompatibilityTest extends 
BaseIgniteAbstractTest {
         assertEquals(Set.of(uuid()), command.txIds());
     }
 
-    private static UUID uuid() {
-        return new UUID(42, 69);
-    }
-
-    private <T extends Command> T deserializeCommand(byte[] bytes) {
-        return marshaller.unmarshall(bytes);
-    }
-
-    private <T extends Command> T decodeCommand(String base64) {
-        return deserializeCommand(Base64.getDecoder().decode(base64));
-    }
-
-    @SuppressWarnings("unused")
-    private void serializeAll() {
-        List<Command> commands = List.of(
-                createVacuumTxStatesCommand()
-        );
-
-        for (Command c : commands) {
-            log.info(">>>>> Serialized command: [c={}, base64='{}']", 
c.getClass().getSimpleName(), encodeCommand(c));
-        }
-    }
-
     private VacuumTxStatesCommand createVacuumTxStatesCommand() {
         return factory.vacuumTxStatesCommand()
                 .txIds(Set.of(uuid()))
                 .build();
     }
-
-    private byte[] serializeCommand(Command c) {
-        return marshaller.marshall(c);
-    }
-
-    private String encodeCommand(Command c) {
-        return Base64.getEncoder().encodeToString(serializeCommand(c));
-    }
 }


Reply via email to