tkalkirill commented on code in PR #6743: URL: https://github.com/apache/ignite-3/pull/6743#discussion_r2419438840
########## modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/command/PartitionCommandsCompatibilityTest.java: ########## @@ -0,0 +1,438 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.partition.replicator.network.command; + +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.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.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.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); + + 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); + } + + @Test + void testBuildIndexCommand() { + BuildIndexCommand command = decodeCommand("Ci0BRgIAAAAAAAAAACoAAAAAAAAARQ=="); + + assertEquals(69, command.indexId()); + assertEquals(List.of(uuid()), command.rowIds()); + assertTrue(command.finish()); + } + + @Test + void testBuildIndexCommandV2() { + BuildIndexCommandV2 command = decodeCommand("CjIBRgIAAAAAAAAAACoAAAAAAAAARQg="); + + assertEquals(69, command.indexId()); + assertEquals(List.of(uuid()), command.rowIds()); + assertTrue(command.finish()); + assertEquals(7, command.tableId()); + } + + @Test + void testFinishTxCommandV1() { + FinishTxCommandV1 command = decodeCommand("CikBSAFHAgkrLSJGAAAAAAAAAAAqAAAAAAAAAEU="); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.commit()); + assertTrue(command.full()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + assertEquals(List.of(tablePartitionId()), command.partitionIds()); + } + + @Test + void testFinishTxCommandV2() { + FinishTxCommandV2 command = decodeCommand("CjMBSAFHAgYVCSwXDAMtIkYAAAAAAAAAACoAAAAAAAAARQ=="); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertTrue(command.commit()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + assertEquals(List.of(enlistedPartitionGroup()), command.partitions()); + } + + @Test + void testUpdateAllCommand() { + UpdateAllCommand command = decodeCommand( + "CisBRwErAgAAAAAAAAAAKgAAAAAAAABFChkKEwMEAQIDAdMJRgkrLSIAAAAAAAAAACoAAAAAAAAARQAAAAAAAAAAKgAAAAAAAABF" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(Map.of(uuid(), timedBinaryRowMessage()), command.messageRowsToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + } + + @Test + void testUpdateAllCommandV2() { + UpdateAllCommandV2 command = decodeCommand( + "CjEBRwErAgAAAAAAAAAAKgAAAAAAAABFChkKEwMEAQIDAdMJRggJKy0iAAAAAAAAAAAqAAAAAAAAAEUAAAAAAAAAACoAAAAAAAAARQ==" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(Map.of(uuid(), timedBinaryRowMessage()), command.messageRowsToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + assertEquals(7, command.tableId()); + } + + @Test + void testUpdateCommand() { + UpdateCommand command = decodeCommand( + "CiwBRwErChkKEwMEAQIDAdMJAAAAAAAAAAAqAAAAAAAAAEVGCSstIgAAAAAAAAAAKgAAAAAAAABFAAAAAAAAAAAqAAAAAAAAAEU=" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(uuid(), command.rowUuid()); + assertEquals(timedBinaryRowMessage(), command.messageRowToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + } + + @Test + void testUpdateCommandV2() { + UpdateCommandV2 command = decodeCommand( + "CjABRwErChkKEwMEAQIDAdMJAAAAAAAAAAAqAAAAAAAAAEVGCAkrLSIAAAAAAAAAACoAAAAAAAAARQAAAAAAAAAAKgAAAAAAAABF" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(uuid(), command.rowUuid()); + assertEquals(timedBinaryRowMessage(), command.messageRowToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + assertEquals(7, command.tableId()); + } + + @Test + void testUpdateMinimumActiveTxBeginTimeCommand() { + UpdateMinimumActiveTxBeginTimeCommand command = decodeCommand("Ci5HRtMJ"); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(1234L, command.timestamp()); + } + + @Test + void testWriteIntentSwitchCommand() { + WriteIntentSwitchCommand command = decodeCommand("CioBSAFHRgAAAAAAAAAAKgAAAAAAAABF"); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertTrue(command.commit()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + } + + @Test + void testWriteIntentSwitchCommandV2() { + WriteIntentSwitchCommandV2 command = decodeCommand("Ci8BSAFHRgMJCAAAAAAAAAAAKgAAAAAAAABF"); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertTrue(command.commit()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + assertEquals(Set.of(7, 8), command.tableIds()); + } + + private static HybridTimestamp initiatorTime() { Review Comment: I would prefer to leave it as is, I don't see the need for a constant. ########## modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/command/PartitionCommandsCompatibilityTest.java: ########## @@ -0,0 +1,438 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.partition.replicator.network.command; + +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.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.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.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); + + 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); + } + + @Test + void testBuildIndexCommand() { + BuildIndexCommand command = decodeCommand("Ci0BRgIAAAAAAAAAACoAAAAAAAAARQ=="); + + assertEquals(69, command.indexId()); + assertEquals(List.of(uuid()), command.rowIds()); + assertTrue(command.finish()); + } + + @Test + void testBuildIndexCommandV2() { + BuildIndexCommandV2 command = decodeCommand("CjIBRgIAAAAAAAAAACoAAAAAAAAARQg="); + + assertEquals(69, command.indexId()); + assertEquals(List.of(uuid()), command.rowIds()); + assertTrue(command.finish()); + assertEquals(7, command.tableId()); + } + + @Test + void testFinishTxCommandV1() { + FinishTxCommandV1 command = decodeCommand("CikBSAFHAgkrLSJGAAAAAAAAAAAqAAAAAAAAAEU="); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.commit()); + assertTrue(command.full()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + assertEquals(List.of(tablePartitionId()), command.partitionIds()); + } + + @Test + void testFinishTxCommandV2() { + FinishTxCommandV2 command = decodeCommand("CjMBSAFHAgYVCSwXDAMtIkYAAAAAAAAAACoAAAAAAAAARQ=="); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertTrue(command.commit()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + assertEquals(List.of(enlistedPartitionGroup()), command.partitions()); + } + + @Test + void testUpdateAllCommand() { + UpdateAllCommand command = decodeCommand( + "CisBRwErAgAAAAAAAAAAKgAAAAAAAABFChkKEwMEAQIDAdMJRgkrLSIAAAAAAAAAACoAAAAAAAAARQAAAAAAAAAAKgAAAAAAAABF" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(Map.of(uuid(), timedBinaryRowMessage()), command.messageRowsToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + } + + @Test + void testUpdateAllCommandV2() { + UpdateAllCommandV2 command = decodeCommand( + "CjEBRwErAgAAAAAAAAAAKgAAAAAAAABFChkKEwMEAQIDAdMJRggJKy0iAAAAAAAAAAAqAAAAAAAAAEUAAAAAAAAAACoAAAAAAAAARQ==" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(Map.of(uuid(), timedBinaryRowMessage()), command.messageRowsToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + assertEquals(7, command.tableId()); + } + + @Test + void testUpdateCommand() { + UpdateCommand command = decodeCommand( + "CiwBRwErChkKEwMEAQIDAdMJAAAAAAAAAAAqAAAAAAAAAEVGCSstIgAAAAAAAAAAKgAAAAAAAABFAAAAAAAAAAAqAAAAAAAAAEU=" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(uuid(), command.rowUuid()); + assertEquals(timedBinaryRowMessage(), command.messageRowToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + } + + @Test + void testUpdateCommandV2() { + UpdateCommandV2 command = decodeCommand( + "CjABRwErChkKEwMEAQIDAdMJAAAAAAAAAAAqAAAAAAAAAEVGCAkrLSIAAAAAAAAAACoAAAAAAAAARQAAAAAAAAAAKgAAAAAAAABF" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(uuid(), command.rowUuid()); + assertEquals(timedBinaryRowMessage(), command.messageRowToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + assertEquals(7, command.tableId()); + } + + @Test + void testUpdateMinimumActiveTxBeginTimeCommand() { + UpdateMinimumActiveTxBeginTimeCommand command = decodeCommand("Ci5HRtMJ"); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(1234L, command.timestamp()); + } + + @Test + void testWriteIntentSwitchCommand() { + WriteIntentSwitchCommand command = decodeCommand("CioBSAFHRgAAAAAAAAAAKgAAAAAAAABF"); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertTrue(command.commit()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + } + + @Test + void testWriteIntentSwitchCommandV2() { + WriteIntentSwitchCommandV2 command = decodeCommand("Ci8BSAFHRgMJCAAAAAAAAAAAKgAAAAAAAABF"); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertTrue(command.commit()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + assertEquals(Set.of(7, 8), command.tableIds()); + } + + private static HybridTimestamp initiatorTime() { + return HybridTimestamp.hybridTimestamp(70); + } + + private static HybridTimestamp safeTime() { Review Comment: I would prefer to leave it as is, I don't see the need for a constant. ########## modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/command/PartitionCommandsCompatibilityTest.java: ########## @@ -0,0 +1,438 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.partition.replicator.network.command; + +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.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.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.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); + + 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); + } + + @Test + void testBuildIndexCommand() { + BuildIndexCommand command = decodeCommand("Ci0BRgIAAAAAAAAAACoAAAAAAAAARQ=="); + + assertEquals(69, command.indexId()); + assertEquals(List.of(uuid()), command.rowIds()); + assertTrue(command.finish()); + } + + @Test + void testBuildIndexCommandV2() { + BuildIndexCommandV2 command = decodeCommand("CjIBRgIAAAAAAAAAACoAAAAAAAAARQg="); + + assertEquals(69, command.indexId()); + assertEquals(List.of(uuid()), command.rowIds()); + assertTrue(command.finish()); + assertEquals(7, command.tableId()); + } + + @Test + void testFinishTxCommandV1() { + FinishTxCommandV1 command = decodeCommand("CikBSAFHAgkrLSJGAAAAAAAAAAAqAAAAAAAAAEU="); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.commit()); + assertTrue(command.full()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + assertEquals(List.of(tablePartitionId()), command.partitionIds()); + } + + @Test + void testFinishTxCommandV2() { + FinishTxCommandV2 command = decodeCommand("CjMBSAFHAgYVCSwXDAMtIkYAAAAAAAAAACoAAAAAAAAARQ=="); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertTrue(command.commit()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + assertEquals(List.of(enlistedPartitionGroup()), command.partitions()); + } + + @Test + void testUpdateAllCommand() { + UpdateAllCommand command = decodeCommand( + "CisBRwErAgAAAAAAAAAAKgAAAAAAAABFChkKEwMEAQIDAdMJRgkrLSIAAAAAAAAAACoAAAAAAAAARQAAAAAAAAAAKgAAAAAAAABF" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(Map.of(uuid(), timedBinaryRowMessage()), command.messageRowsToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + } + + @Test + void testUpdateAllCommandV2() { + UpdateAllCommandV2 command = decodeCommand( + "CjEBRwErAgAAAAAAAAAAKgAAAAAAAABFChkKEwMEAQIDAdMJRggJKy0iAAAAAAAAAAAqAAAAAAAAAEUAAAAAAAAAACoAAAAAAAAARQ==" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(Map.of(uuid(), timedBinaryRowMessage()), command.messageRowsToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + assertEquals(7, command.tableId()); + } + + @Test + void testUpdateCommand() { + UpdateCommand command = decodeCommand( + "CiwBRwErChkKEwMEAQIDAdMJAAAAAAAAAAAqAAAAAAAAAEVGCSstIgAAAAAAAAAAKgAAAAAAAABFAAAAAAAAAAAqAAAAAAAAAEU=" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(uuid(), command.rowUuid()); + assertEquals(timedBinaryRowMessage(), command.messageRowToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + } + + @Test + void testUpdateCommandV2() { + UpdateCommandV2 command = decodeCommand( + "CjABRwErChkKEwMEAQIDAdMJAAAAAAAAAAAqAAAAAAAAAEVGCAkrLSIAAAAAAAAAACoAAAAAAAAARQAAAAAAAAAAKgAAAAAAAABF" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(uuid(), command.rowUuid()); + assertEquals(timedBinaryRowMessage(), command.messageRowToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + assertEquals(7, command.tableId()); + } + + @Test + void testUpdateMinimumActiveTxBeginTimeCommand() { + UpdateMinimumActiveTxBeginTimeCommand command = decodeCommand("Ci5HRtMJ"); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(1234L, command.timestamp()); + } + + @Test + void testWriteIntentSwitchCommand() { + WriteIntentSwitchCommand command = decodeCommand("CioBSAFHRgAAAAAAAAAAKgAAAAAAAABF"); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertTrue(command.commit()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + } + + @Test + void testWriteIntentSwitchCommandV2() { + WriteIntentSwitchCommandV2 command = decodeCommand("Ci8BSAFHRgMJCAAAAAAAAAAAKgAAAAAAAABF"); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertTrue(command.commit()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + 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() { Review Comment: I would prefer to leave it as is, I don't see the need for a constant. ########## modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/command/PartitionCommandsCompatibilityTest.java: ########## @@ -0,0 +1,438 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.partition.replicator.network.command; + +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.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.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.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); + + 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); + } + + @Test + void testBuildIndexCommand() { + BuildIndexCommand command = decodeCommand("Ci0BRgIAAAAAAAAAACoAAAAAAAAARQ=="); + + assertEquals(69, command.indexId()); + assertEquals(List.of(uuid()), command.rowIds()); + assertTrue(command.finish()); + } + + @Test + void testBuildIndexCommandV2() { + BuildIndexCommandV2 command = decodeCommand("CjIBRgIAAAAAAAAAACoAAAAAAAAARQg="); + + assertEquals(69, command.indexId()); + assertEquals(List.of(uuid()), command.rowIds()); + assertTrue(command.finish()); + assertEquals(7, command.tableId()); + } + + @Test + void testFinishTxCommandV1() { + FinishTxCommandV1 command = decodeCommand("CikBSAFHAgkrLSJGAAAAAAAAAAAqAAAAAAAAAEU="); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.commit()); + assertTrue(command.full()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + assertEquals(List.of(tablePartitionId()), command.partitionIds()); + } + + @Test + void testFinishTxCommandV2() { + FinishTxCommandV2 command = decodeCommand("CjMBSAFHAgYVCSwXDAMtIkYAAAAAAAAAACoAAAAAAAAARQ=="); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertTrue(command.commit()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + assertEquals(List.of(enlistedPartitionGroup()), command.partitions()); + } + + @Test + void testUpdateAllCommand() { + UpdateAllCommand command = decodeCommand( + "CisBRwErAgAAAAAAAAAAKgAAAAAAAABFChkKEwMEAQIDAdMJRgkrLSIAAAAAAAAAACoAAAAAAAAARQAAAAAAAAAAKgAAAAAAAABF" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(Map.of(uuid(), timedBinaryRowMessage()), command.messageRowsToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + } + + @Test + void testUpdateAllCommandV2() { + UpdateAllCommandV2 command = decodeCommand( + "CjEBRwErAgAAAAAAAAAAKgAAAAAAAABFChkKEwMEAQIDAdMJRggJKy0iAAAAAAAAAAAqAAAAAAAAAEUAAAAAAAAAACoAAAAAAAAARQ==" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(Map.of(uuid(), timedBinaryRowMessage()), command.messageRowsToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + assertEquals(7, command.tableId()); + } + + @Test + void testUpdateCommand() { + UpdateCommand command = decodeCommand( + "CiwBRwErChkKEwMEAQIDAdMJAAAAAAAAAAAqAAAAAAAAAEVGCSstIgAAAAAAAAAAKgAAAAAAAABFAAAAAAAAAAAqAAAAAAAAAEU=" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(uuid(), command.rowUuid()); + assertEquals(timedBinaryRowMessage(), command.messageRowToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + } + + @Test + void testUpdateCommandV2() { + UpdateCommandV2 command = decodeCommand( + "CjABRwErChkKEwMEAQIDAdMJAAAAAAAAAAAqAAAAAAAAAEVGCAkrLSIAAAAAAAAAACoAAAAAAAAARQAAAAAAAAAAKgAAAAAAAABF" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(uuid(), command.rowUuid()); + assertEquals(timedBinaryRowMessage(), command.messageRowToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + assertEquals(7, command.tableId()); + } + + @Test + void testUpdateMinimumActiveTxBeginTimeCommand() { + UpdateMinimumActiveTxBeginTimeCommand command = decodeCommand("Ci5HRtMJ"); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(1234L, command.timestamp()); + } + + @Test + void testWriteIntentSwitchCommand() { + WriteIntentSwitchCommand command = decodeCommand("CioBSAFHRgAAAAAAAAAAKgAAAAAAAABF"); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertTrue(command.commit()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + } + + @Test + void testWriteIntentSwitchCommandV2() { + WriteIntentSwitchCommandV2 command = decodeCommand("Ci8BSAFHRgMJCAAAAAAAAAAAKgAAAAAAAABF"); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertTrue(command.commit()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + 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() { Review Comment: I would prefer to leave it as is, I don't see the need for a constant. ########## modules/partition-replicator/src/test/java/org/apache/ignite/internal/partition/replicator/network/command/PartitionCommandsCompatibilityTest.java: ########## @@ -0,0 +1,438 @@ +/* + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. + * The ASF licenses this file to You under the Apache License, Version 2.0 + * (the "License"); you may not use this file except in compliance with + * the License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package org.apache.ignite.internal.partition.replicator.network.command; + +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.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.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.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); + + 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); + } + + @Test + void testBuildIndexCommand() { + BuildIndexCommand command = decodeCommand("Ci0BRgIAAAAAAAAAACoAAAAAAAAARQ=="); + + assertEquals(69, command.indexId()); + assertEquals(List.of(uuid()), command.rowIds()); + assertTrue(command.finish()); + } + + @Test + void testBuildIndexCommandV2() { + BuildIndexCommandV2 command = decodeCommand("CjIBRgIAAAAAAAAAACoAAAAAAAAARQg="); + + assertEquals(69, command.indexId()); + assertEquals(List.of(uuid()), command.rowIds()); + assertTrue(command.finish()); + assertEquals(7, command.tableId()); + } + + @Test + void testFinishTxCommandV1() { + FinishTxCommandV1 command = decodeCommand("CikBSAFHAgkrLSJGAAAAAAAAAAAqAAAAAAAAAEU="); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.commit()); + assertTrue(command.full()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + assertEquals(List.of(tablePartitionId()), command.partitionIds()); + } + + @Test + void testFinishTxCommandV2() { + FinishTxCommandV2 command = decodeCommand("CjMBSAFHAgYVCSwXDAMtIkYAAAAAAAAAACoAAAAAAAAARQ=="); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertTrue(command.commit()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + assertEquals(List.of(enlistedPartitionGroup()), command.partitions()); + } + + @Test + void testUpdateAllCommand() { + UpdateAllCommand command = decodeCommand( + "CisBRwErAgAAAAAAAAAAKgAAAAAAAABFChkKEwMEAQIDAdMJRgkrLSIAAAAAAAAAACoAAAAAAAAARQAAAAAAAAAAKgAAAAAAAABF" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(Map.of(uuid(), timedBinaryRowMessage()), command.messageRowsToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + } + + @Test + void testUpdateAllCommandV2() { + UpdateAllCommandV2 command = decodeCommand( + "CjEBRwErAgAAAAAAAAAAKgAAAAAAAABFChkKEwMEAQIDAdMJRggJKy0iAAAAAAAAAAAqAAAAAAAAAEUAAAAAAAAAACoAAAAAAAAARQ==" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(Map.of(uuid(), timedBinaryRowMessage()), command.messageRowsToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + assertEquals(7, command.tableId()); + } + + @Test + void testUpdateCommand() { + UpdateCommand command = decodeCommand( + "CiwBRwErChkKEwMEAQIDAdMJAAAAAAAAAAAqAAAAAAAAAEVGCSstIgAAAAAAAAAAKgAAAAAAAABFAAAAAAAAAAAqAAAAAAAAAEU=" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(uuid(), command.rowUuid()); + assertEquals(timedBinaryRowMessage(), command.messageRowToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + } + + @Test + void testUpdateCommandV2() { + UpdateCommandV2 command = decodeCommand( + "CjABRwErChkKEwMEAQIDAdMJAAAAAAAAAAAqAAAAAAAAAEVGCAkrLSIAAAAAAAAAACoAAAAAAAAARQAAAAAAAAAAKgAAAAAAAABF" + ); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertEquals(tablePartitionId(), command.commitPartitionId()); + assertEquals(uuid(), command.rowUuid()); + assertEquals(timedBinaryRowMessage(), command.messageRowToUpdate()); + assertEquals(uuid(), command.txCoordinatorId()); + assertEquals(42L, command.leaseStartTime()); + assertEquals(7, command.tableId()); + } + + @Test + void testUpdateMinimumActiveTxBeginTimeCommand() { + UpdateMinimumActiveTxBeginTimeCommand command = decodeCommand("Ci5HRtMJ"); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(1234L, command.timestamp()); + } + + @Test + void testWriteIntentSwitchCommand() { + WriteIntentSwitchCommand command = decodeCommand("CioBSAFHRgAAAAAAAAAAKgAAAAAAAABF"); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertTrue(command.commit()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + } + + @Test + void testWriteIntentSwitchCommandV2() { + WriteIntentSwitchCommandV2 command = decodeCommand("Ci8BSAFHRgMJCAAAAAAAAAAAKgAAAAAAAABF"); + + assertEquals(initiatorTime(), command.initiatorTime()); + assertEquals(safeTime(), command.safeTime()); + assertEquals(uuid(), command.txId()); + assertTrue(command.full()); + assertTrue(command.commit()); + assertEquals(commitTimestamp(), command.commitTimestamp()); + 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) + .partitionId(44) + .build(); + } + + private ZonePartitionIdMessage zonePartitionId() { + return replicaFactory.zonePartitionIdMessage() + .zoneId(11) + .partitionId(22) + .build(); + } + + private EnlistedPartitionGroupMessage enlistedPartitionGroup() { + return txFactory.enlistedPartitionGroupMessage() + .groupId(zonePartitionId()) + .tableIds(Set.of(33, 44)) + .build(); + } + + private TimedBinaryRowMessage timedBinaryRowMessage() { + return commandFactory.timedBinaryRowMessage() + .binaryRowMessage(binaryRow()) + .timestamp(HybridTimestamp.hybridTimestamp(1234)) + .build(); + } + + private BinaryRowMessage binaryRow() { + return commandFactory.binaryRowMessage() + .binaryTuple(ByteBuffer.wrap(new byte[]{1, 2, 3})) + .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: [c={}, base64='{}']", c.getClass().getSimpleName(), encodeCommand(c)); Review Comment: This will not improve readability; I would prefer to leave it as is. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
