Skip to content

Commit 3dfb922

Browse files
authored
IGNITE-28738 Implement basic Rolling Upgrade test using testcontainers (#13184)
1 parent e665ebf commit 3dfb922

15 files changed

Lines changed: 1705 additions & 1 deletion

File tree

.gitignore

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -31,6 +31,10 @@ git-patch-prop-local.sh
3131
**/dotnet/libs/
3232
*.classname*
3333
*.exe
34+
deliveries/docker/apache-ignite/arm64/run.sh
35+
deliveries/docker/apache-ignite/arm64/apache-ignite-*
36+
deliveries/docker/apache-ignite/x86_64/run.sh
37+
deliveries/docker/apache-ignite/x86_64/apache-ignite-*
3438

3539
#Ignore all Intellij IDEA files (except default inspections config)
3640
.idea/

modules/compatibility/DEVNOTES.md

Lines changed: 152 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,152 @@
1+
<!--
2+
Licensed to the Apache Software Foundation (ASF) under one or more
3+
contributor license agreements. See the NOTICE file distributed with
4+
this work for additional information regarding copyright ownership.
5+
The ASF licenses this file to You under the Apache License, Version 2.0
6+
(the "License"); you may not use this file except in compliance with
7+
the License. You may obtain a copy of the License at
8+
9+
http://www.apache.org/licenses/LICENSE-2.0
10+
11+
Unless required by applicable law or agreed to in writing, software
12+
distributed under the License is distributed on an "AS IS" BASIS,
13+
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14+
See the License for the specific language governing permissions and
15+
limitations under the License.
16+
-->
17+
18+
# Compatibility Module — Developer Notes
19+
20+
## Docker Compatibility Tests
21+
22+
This module contains tests that verify upgrade compatibility between Ignite versions using Docker containers.
23+
Docker compatibility tests (e.g. `IgniteRebalanceOnUpgradeTest`) require:
24+
- **Docker** installed and running
25+
- A pre-built Docker image of the source (old) Ignite version (see below)
26+
- The `-Dru.source.image.name` property pointing to that image
27+
- Maven profile `compatibility-docker` — activates Docker-specific build steps (only required for `DOCKER` upgrade mode; not needed in `LOCAL` mode)
28+
29+
Example command:
30+
31+
```bash
32+
export JAVA_TOOL_OPTIONS="-Djavax.net.ssl.trustStoreType=KeychainStore"
33+
./mvnw test -pl modules/compatibility -Pcompatibility-docker,surefire-fork-count-1 \
34+
-DskipTests=false \
35+
-Dtest=org.apache.ignite.compatibility.ru.IgniteRebalanceOnUpgradeTest#testRollingUpgrade \
36+
-Dru.source.image.name=<image_name>
37+
```
38+
39+
## Prerequisites
40+
41+
- [Docker](https://www.docker.com/get-started) (Docker Desktop or Docker Engine) must be installed and running.
42+
43+
## Running IgniteRebalanceOnUpgradeTest
44+
45+
This test verifies that data rebalancing works correctly when upgrading Ignite from a specific version to the current codebase.
46+
It supports two upgrade modes:
47+
48+
- **DOCKER** (default) — all nodes stay in Docker containers; each node is upgraded in-place by swapping its `libs/` directory and restarting.
49+
- **LOCAL** — the source cluster runs in Docker containers, then nodes are upgraded to local host-JVM instances.
50+
51+
### Step 1. Build a local Docker image for the source (old) version
52+
53+
Run the following script from the **project root**, passing the commit hash of the version you want to test against:
54+
55+
```bash
56+
./modules/compatibility/src/test/resources/docker/build_docker_image.sh <commit_hash>
57+
```
58+
59+
> **Note:** If you omit `<commit_hash>`, the script will use the hash of the latest commit in the current branch.
60+
61+
The script will:
62+
1. Checkout the specified commit.
63+
2. Build the project (`./mvnw clean install -T1C -Pall-java,licenses -DskipTests`).
64+
3. Initialize the release (`./mvnw initialize -Prelease`).
65+
4. Build a Docker image tagged as `apacheignite/ignite:<commit_hash>`.
66+
5. Restore the original git state.
67+
68+
> **Note:** If a distribution archive already exists in `target/bin/`, the build steps will be skipped.
69+
70+
> **Note:** If the Docker image `apacheignite/ignite:<commit_hash>` is already built (e.g. from a previous run), you can skip Step 1 entirely and go directly to Step 2.
71+
72+
### Step 2. Run the test
73+
74+
Run `IgniteRebalanceOnUpgradeTest` from your IDE or via Maven. The source version image name **must** be explicitly provided via `-Dru.source.image.name`:
75+
76+
```bash
77+
./mvnw test -pl modules/compatibility -Dtest=IgniteRebalanceOnUpgradeTest \
78+
-Dru.source.image.name=<image_name> \
79+
-Pcompatibility-docker,surefire-fork-count-1
80+
```
81+
82+
---
83+
84+
## Upgrade Modes
85+
86+
### DOCKER mode (default)
87+
88+
All nodes stay in Docker containers throughout the test. Each node is upgraded in-place:
89+
1. The container is gracefully stopped (`docker stop`).
90+
2. Source jars in `/opt/ignite/apache-ignite/libs/` are replaced by target jars from the host.
91+
3. The container is restarted (`docker start`).
92+
93+
The Docker image for the source cluster is the same as in LOCAL mode — only one image is needed.
94+
The target-version jars are provided from the host filesystem.
95+
96+
**Option A: Automatic (recommended)** — use the `compatibility-docker` profile:
97+
98+
```bash
99+
./mvnw test -pl modules/compatibility -Dtest=IgniteRebalanceOnUpgradeTest \
100+
-Dru.source.image.name=<image_name> \
101+
-Psurefire-fork-count-1,compatibility-docker
102+
```
103+
104+
The profile will automatically:
105+
1. Check if `project/target/ignite-target-libs` symlink exists.
106+
2. If not, check for a distribution ZIP in `project/target/bin/`.
107+
3. If the ZIP is missing, build the project and distribution (`mvn install` + `mvn initialize -Prelease`).
108+
4. Extract the ZIP into `project/target/bin/` (the distribution lands in `project/target/bin/apache-ignite-*-bin/`).
109+
5. Create a symlink `project/target/ignite-target-libs``project/target/bin/apache-ignite-*-bin/libs/`:
110+
111+
```bash
112+
ln -s "$(ls -d target/bin/apache-ignite-*-bin/libs)" target/ignite-target-libs
113+
```
114+
115+
> **Note:** Subsequent runs will skip the build if the symlink or the distribution ZIP already exists.
116+
117+
**Option B: Manual** — build, extract, and specify the libs directory:
118+
119+
```bash
120+
./mvnw clean install -T1C -Pall-java -DskipTests
121+
./mvnw initialize -Prelease
122+
cd target/bin && unzip apache-ignite-*-bin.zip && cd ../..
123+
124+
./mvnw test -pl modules/compatibility -Dtest=IgniteRebalanceOnUpgradeTest \
125+
-Dru.source.image.name=<image_name> \
126+
-Dru.target.libs.dir=target/bin/apache-ignite-<version>-bin/libs \
127+
-Psurefire-fork-count-1
128+
```
129+
130+
### LOCAL mode
131+
132+
The source (old-version) cluster starts in Docker containers. During rolling upgrade each container is stopped and replaced by a local host-JVM node with the same `consistentId` and persistence directory.
133+
134+
- Controlled by `-Dru.upgrade.mode=LOCAL`.
135+
136+
```bash
137+
./mvnw test -pl modules/compatibility -Dtest=IgniteRebalanceOnUpgradeTest \
138+
-Dru.upgrade.mode=LOCAL \
139+
-Dru.source.image.name=<image_name> \
140+
-Psurefire-fork-count-1
141+
```
142+
143+
---
144+
145+
## System Properties
146+
147+
| Property | Default | Class | Description |
148+
|------------------------|-------------------------------------------|-------|--------------------------------------------------------------------------------------------|
149+
| `ru.upgrade.mode` | `DOCKER` | `IgniteRebalanceOnUpgradeTest` | Upgrade mode: `LOCAL` or `DOCKER` |
150+
| `ru.source.image.name` | - | `IgniteRebalanceOnUpgradeTest` | The source (old-version) Docker image name, e.g. `apacheignite/ignite:2.18.0` |
151+
| `ru.target.libs.dir` | `<project.dir>/target/ignite-target-libs` | `IgniteContainer` | Host directory with target-version jars (DOCKER mode only) |
152+
| `ru.local.work.dir` | `<project.dir>/target/test-ignite-work` | `IgniteContainer` | Local directory bind-mounted as Ignite work directory (persists across container restarts) |

modules/compatibility/pom.xml

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -123,6 +123,19 @@
123123
<scope>test</scope>
124124
</dependency>
125125

126+
<dependency>
127+
<groupId>org.testcontainers</groupId>
128+
<artifactId>testcontainers</artifactId>
129+
<version>${testcontainers.version}</version>
130+
<scope>test</scope>
131+
</dependency>
132+
133+
<dependency>
134+
<groupId>org.apache.logging.log4j</groupId>
135+
<artifactId>log4j-slf4j2-impl</artifactId>
136+
<scope>test</scope>
137+
</dependency>
138+
126139
<!-- Note: when adding new Ignite module dependency please register it in
127140
org.apache.ignite.compatibility.testframework.junits.IgniteCompatibilityAbstractTest.getDependencies()
128141
method. This will allow to use original version dependency instead current code base. -->
@@ -158,4 +171,34 @@
158171
</plugin>
159172
</plugins>
160173
</build>
174+
175+
<profiles>
176+
<profile>
177+
<id>compatibility-docker</id>
178+
<build>
179+
<plugins>
180+
<plugin>
181+
<groupId>org.codehaus.mojo</groupId>
182+
<artifactId>exec-maven-plugin</artifactId>
183+
<executions>
184+
<execution>
185+
<id>prepare-docker-target-libs</id>
186+
<goals>
187+
<goal>exec</goal>
188+
</goals>
189+
<phase>generate-test-resources</phase>
190+
<configuration>
191+
<executable>bash</executable>
192+
<arguments>
193+
<argument>${project.basedir}/src/test/resources/docker/build_distrib.sh</argument>
194+
<argument>${project.basedir}/../..</argument>
195+
</arguments>
196+
</configuration>
197+
</execution>
198+
</executions>
199+
</plugin>
200+
</plugins>
201+
</build>
202+
</profile>
203+
</profiles>
161204
</project>

0 commit comments

Comments
 (0)