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

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

commit 23531bde82fcfa9ab9780dc898307601873c4c68
Author: Kirill Tkalenko <tkalkir...@yandex.ru>
AuthorDate: Fri Sep 19 12:22:37 2025 +0300

    IGNITE-26095 wip
---
 ...ItPartitionRaftLogOneNodeCompatibilityTest.java | 94 ++++++++++++++++++++++
 ...RaftLogWithChangeReplicasCompatibilityTest.java | 74 +++++++++++++++++
 .../ignite/internal/CompatibilityTestBase.java     |  2 +-
 .../org/apache/ignite/internal/IgniteCluster.java  |  5 ++
 4 files changed, 174 insertions(+), 1 deletion(-)

diff --git 
a/modules/compatibility-tests/src/integrationTest/java/org/apache/ignite/internal/ItPartitionRaftLogOneNodeCompatibilityTest.java
 
b/modules/compatibility-tests/src/integrationTest/java/org/apache/ignite/internal/ItPartitionRaftLogOneNodeCompatibilityTest.java
new file mode 100644
index 00000000000..a08095729fb
--- /dev/null
+++ 
b/modules/compatibility-tests/src/integrationTest/java/org/apache/ignite/internal/ItPartitionRaftLogOneNodeCompatibilityTest.java
@@ -0,0 +1,94 @@
+/*
+ * 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;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+import static org.hamcrest.Matchers.is;
+
+import java.io.IOException;
+import java.nio.file.Files;
+import java.nio.file.Path;
+import java.util.stream.Stream;
+import org.apache.ignite.Ignite;
+import org.apache.ignite.internal.util.IgniteUtils;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedClass;
+import org.junit.jupiter.params.provider.MethodSource;
+
+/** Partition raft log compatibility tests for one node. */
+@ParameterizedClass
+@MethodSource("baseVersions")
+public class ItPartitionRaftLogOneNodeCompatibilityTest extends 
CompatibilityTestBase {
+    private static final String TABLE_NAME = "TEST_TABLE";
+
+    @Override
+    protected int nodesCount() {
+        return 1;
+    }
+
+    @Override
+    protected boolean restartWithCurrentEmbeddedVersion() {
+        return false;
+    }
+
+    @Override
+    protected void setupBaseVersion(Ignite baseIgnite) {
+        sql(baseIgnite, String.format("CREATE TABLE %s(ID INT PRIMARY KEY, VAL 
VARCHAR)", TABLE_NAME));
+
+        String insertDml = String.format("INSERT INTO %s (ID, VAL) VALUES (?, 
?)", TABLE_NAME);
+
+        baseIgnite.transactions().runInTransaction(tx -> {
+            for (int i = 0; i < 10; i++) {
+                sql(baseIgnite, tx, insertDml, i, "str_" + i);
+            }
+        });
+    }
+
+    /** Tests a simple node restart scenario with reapplying a partition raft 
log. */
+    @Test
+    void testSimpleRestart() {
+        cluster.stop();
+
+        cleanTableStoragesDir();
+
+        cluster.startEmbedded(nodesCount(), false);
+
+        assertThat(sql(String.format("SELECT * FROM %s", TABLE_NAME)), 
hasSize(10));
+    }
+
+    private void cleanTableStoragesDir() {
+        Path dbDir = 
workDir.resolve(cluster.clusterName()).resolve(cluster.nodeName(0)).resolve("partitions").resolve("db");
+
+        assertThat(dbDir.toString(), isDirectoryExistsAndNotEmpty(dbDir), 
is(true));
+
+        assertThat(dbDir.toString(), IgniteUtils.deleteIfExists(dbDir), 
is(true));
+    }
+
+    private static boolean isDirectoryExistsAndNotEmpty(Path path) {
+        if (!Files.exists(path) || !Files.isDirectory(path)) {
+            return false;
+        }
+
+        try (Stream<Path> list = Files.list(path)) {
+            return list.findAny().isPresent();
+        } catch (IOException e) {
+            return false;
+        }
+    }
+}
diff --git 
a/modules/compatibility-tests/src/integrationTest/java/org/apache/ignite/internal/ItPartitionRaftLogWithChangeReplicasCompatibilityTest.java
 
b/modules/compatibility-tests/src/integrationTest/java/org/apache/ignite/internal/ItPartitionRaftLogWithChangeReplicasCompatibilityTest.java
new file mode 100644
index 00000000000..a7eaecdfec9
--- /dev/null
+++ 
b/modules/compatibility-tests/src/integrationTest/java/org/apache/ignite/internal/ItPartitionRaftLogWithChangeReplicasCompatibilityTest.java
@@ -0,0 +1,74 @@
+/*
+ * 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;
+
+import static org.hamcrest.MatcherAssert.assertThat;
+import static org.hamcrest.Matchers.hasSize;
+
+import org.apache.ignite.Ignite;
+import org.junit.jupiter.api.Test;
+import org.junit.jupiter.params.ParameterizedClass;
+import org.junit.jupiter.params.provider.MethodSource;
+
+/** Partition Raft log compatibility tests when adding replicas. */
+@ParameterizedClass
+@MethodSource("baseVersions")
+public class ItPartitionRaftLogWithAddReplicasCompatibilityTest extends 
CompatibilityTestBase {
+    private static final String ZONE_NAME = "TEST_ZONE";
+
+    private static final String TABLE_NAME = "TEST_TABLE";
+
+    @Override
+    protected int nodesCount() {
+        return 1;
+    }
+
+    @Override
+    protected boolean restartWithCurrentEmbeddedVersion() {
+        return false;
+    }
+
+    @Override
+    protected void setupBaseVersion(Ignite baseIgnite) {
+        sql(baseIgnite, String.format("CREATE ZONE %s WITH PARTITIONS=1, 
REPLICAS=1, STORAGE_PROFILES='default'", ZONE_NAME));
+
+        sql(baseIgnite, String.format("CREATE TABLE %s(ID INT PRIMARY KEY, VAL 
VARCHAR) ZONE %s", TABLE_NAME, ZONE_NAME));
+
+        String insertDml = String.format("INSERT INTO %s (ID, VAL) VALUES (?, 
?) ", TABLE_NAME);
+
+        baseIgnite.transactions().runInTransaction(tx -> {
+            for (int i = 0; i < 10; i++) {
+                sql(baseIgnite, tx, insertDml, i, "str_" + i);
+            }
+        });
+    }
+
+    @Test
+    void testIncreaseReplicas() throws Exception {
+        cluster.stop();
+
+        cluster.startEmbedded(nodesCount() + 2, true);
+
+        sql(String.format("ALTER ZONE %s SET REPLICAS=3", ZONE_NAME));
+
+        // Let's wait for replication to complete on other nodes.
+        Thread.sleep(3_000);
+
+        assertThat(sql(String.format("SELECT * FROM %s", TABLE_NAME)), 
hasSize(10));
+    }
+}
diff --git 
a/modules/compatibility-tests/src/testFixtures/java/org/apache/ignite/internal/CompatibilityTestBase.java
 
b/modules/compatibility-tests/src/testFixtures/java/org/apache/ignite/internal/CompatibilityTestBase.java
index dbc87e64f9f..948559e35f6 100644
--- 
a/modules/compatibility-tests/src/testFixtures/java/org/apache/ignite/internal/CompatibilityTestBase.java
+++ 
b/modules/compatibility-tests/src/testFixtures/java/org/apache/ignite/internal/CompatibilityTestBase.java
@@ -77,7 +77,7 @@ public abstract class CompatibilityTestBase extends 
BaseIgniteAbstractTest {
 
     // Force per class template work directory so that non-static field 
doesn't get overwritten by the BeforeEach callback.
     @WorkDirectory(forcePerClassTemplate = true)
-    private Path workDir;
+    protected Path workDir;
 
     protected IgniteCluster cluster;
 
diff --git 
a/modules/compatibility-tests/src/testFixtures/java/org/apache/ignite/internal/IgniteCluster.java
 
b/modules/compatibility-tests/src/testFixtures/java/org/apache/ignite/internal/IgniteCluster.java
index a56c8889ca0..0f46446a02e 100644
--- 
a/modules/compatibility-tests/src/testFixtures/java/org/apache/ignite/internal/IgniteCluster.java
+++ 
b/modules/compatibility-tests/src/testFixtures/java/org/apache/ignite/internal/IgniteCluster.java
@@ -348,4 +348,9 @@ public class IgniteCluster {
             throw new RuntimeException(e);
         }
     }
+
+    /** Returns cluster name. */
+    public String clusterName() {
+        return clusterConfiguration.clusterName();
+    }
 }

Reply via email to