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