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

Caideyipi pushed a commit to branch daily-it-logical-backup-18623
in repository https://gitbox.apache.org/repos/asf/iotdb.git

commit 7249a7f31110234fad831c4c9188bb740a4240e3
Author: Caideyipi <[email protected]>
AuthorDate: Fri Oct 23 12:53:06 2026 +0800

    [Test] Add daily IT coverage for logical backup
---
 .github/workflows/logical-backup-daily-it.yml      |  48 +++++++
 .../treemodel/manual/IoTDBPipeLogicalBackupIT.java | 141 +++++++++++++++++++++
 2 files changed, 189 insertions(+)

diff --git a/.github/workflows/logical-backup-daily-it.yml 
b/.github/workflows/logical-backup-daily-it.yml
new file mode 100644
index 00000000000..21be30edbc3
--- /dev/null
+++ b/.github/workflows/logical-backup-daily-it.yml
@@ -0,0 +1,48 @@
+name: Logical Backup Daily IT
+
+on:
+  pull_request:
+    branches:
+      - feat/pipe-logical-backup-sink
+    paths:
+      - .github/workflows/logical-backup-daily-it.yml
+      - 
integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/manual/IoTDBPipeLogicalBackupIT.java
+
+concurrency:
+  group: logical-backup-daily-it-${{ github.event.pull_request.number }}
+  cancel-in-progress: true
+
+jobs:
+  logical-backup:
+    runs-on: ubuntu-latest
+    steps:
+      - uses: actions/checkout@v5
+      - name: Set up JDK 17
+        uses: actions/setup-java@v5
+        with:
+          distribution: corretto
+          java-version: 17
+        env:
+          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
+      - name: Cache Maven packages
+        uses: actions/cache@v5
+        with:
+          path: ~/.m2
+          key: ${{ runner.os }}-m2-${{ hashFiles('**/pom.xml') }}
+          restore-keys: ${{ runner.os }}-m2-
+      - name: Run logical backup daily IT
+        run: >-
+          mvn -B -ntp clean verify
+          -Pwith-integration-tests
+          -DskipUTs
+          -Dit.test=IoTDBPipeLogicalBackupIT
+          -Dfailsafe.failIfNoSpecifiedTests=false
+          -DintegrationTest.forkCount=1
+          -DConfigNodeMaxHeapSize=256
+          -DDataNodeMaxHeapSize=1024
+          -DDataNodeMaxDirectMemorySize=768
+          -DClusterConfigurations=ScalableSingleNodeMode,ScalableSingleNodeMode
+          -Drat.skip=true
+          -pl integration-test
+          -am
+          -PMultiClusterIT2DualTreeManual
diff --git 
a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/manual/IoTDBPipeLogicalBackupIT.java
 
b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/manual/IoTDBPipeLogicalBackupIT.java
index 4629bcb8875..5b1d9ab0e39 100644
--- 
a/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/manual/IoTDBPipeLogicalBackupIT.java
+++ 
b/integration-test/src/test/java/org/apache/iotdb/pipe/it/dual/treemodel/manual/IoTDBPipeLogicalBackupIT.java
@@ -39,6 +39,7 @@ import org.junit.runner.RunWith;
 import java.io.ByteArrayInputStream;
 import java.io.InputStream;
 import java.nio.charset.StandardCharsets;
+import java.nio.file.Files;
 import java.nio.file.Path;
 import java.sql.Connection;
 import java.sql.ResultSet;
@@ -258,6 +259,146 @@ public class IoTDBPipeLogicalBackupIT extends 
AbstractPipeDualTreeModelManualIT
     }
   }
 
+  @Test
+  public void testTreeContinuousCapturePreservesFilteredDeletionRange() throws 
Exception {
+    TestUtils.executeNonQueries(
+        senderEnv,
+        Arrays.asList(
+            "create database root.logical_backup_delete",
+            "create timeseries root.logical_backup_delete.d.s with 
datatype=INT32,encoding=PLAIN",
+            "insert into root.logical_backup_delete.d(time,s) values(1,10)",
+            "flush"),
+        null);
+    final String pipeName = "logical_backup_tree_delete";
+    final CompletableFuture<Void> writes =
+        CompletableFuture.runAsync(
+            () -> {
+              try {
+                Awaitility.await()
+                    .atMost(30, TimeUnit.SECONDS)
+                    .until(
+                        () -> {
+                          try (final Connection connection = 
senderEnv.getConnection();
+                              final Statement statement = 
connection.createStatement();
+                              final ResultSet result =
+                                  statement.executeQuery("show pipe " + 
pipeName)) {
+                            return result.next();
+                          }
+                        });
+                try (final Connection connection = senderEnv.getConnection();
+                    final Statement statement = connection.createStatement()) {
+                  statement.execute(
+                      "insert into root.logical_backup_delete.d(time,s) 
values(2,20)");
+                  statement.execute(
+                      "insert into root.logical_backup_delete.d(time,s) 
values(3,30)");
+                  statement.execute("delete from 
root.logical_backup_delete.d.s where time <= 2");
+                }
+              } catch (final Exception e) {
+                throw new CompletionException(e);
+              }
+            });
+    final Path parent = temporaryFolder.getRoot().toPath().toAbsolutePath();
+    runConnected(
+        senderEnv,
+        "dump",
+        "--backup-dir",
+        parent.toString(),
+        "--backup-id",
+        "tree-delete",
+        "--pipe-name",
+        pipeName,
+        "--scope",
+        "schema,data",
+        "--model",
+        "tree",
+        "--include",
+        "root.logical_backup_delete.**",
+        "--start-time",
+        "1",
+        "--end-time",
+        "3",
+        "--mode",
+        "continuous",
+        "--until",
+        Instant.now().plusSeconds(20).toString(),
+        "--timeout-seconds",
+        "180",
+        "--poll-interval-seconds",
+        "1");
+    writes.get(30, TimeUnit.SECONDS);
+    final Path backup = parent.resolve("tree-delete");
+    assertLogicalRequests(backup);
+    runConnected(receiverEnv, "restore", "--input", backup.toString());
+    TestUtils.assertDataEventuallyOnEnv(
+        receiverEnv,
+        "select * from root.logical_backup_delete.d",
+        "Time,root.logical_backup_delete.d.s,",
+        new HashSet<>(Arrays.asList("3,30,")));
+  }
+
+  @Test
+  public void testInspectPackAndDeprecatedAliasesKeepBackupPortable() throws 
Exception {
+    TestUtils.executeNonQueries(
+        senderEnv,
+        Arrays.asList(
+            "create database root.logical_backup_alias",
+            "create timeseries root.logical_backup_alias.d.s with 
datatype=INT32,encoding=PLAIN",
+            "insert into root.logical_backup_alias.d(time,s) values(1,10)",
+            "flush"),
+        null);
+    final Path parent = temporaryFolder.getRoot().toPath().toAbsolutePath();
+    runConnected(
+        senderEnv,
+        "dump",
+        "--backup-dir",
+        parent.toString(),
+        "--backup-id",
+        "portable",
+        "--scope",
+        "config,schema,data",
+        "--model",
+        "tree",
+        "--include",
+        "root.logical_backup_alias.**",
+        "--timeout-seconds",
+        "180",
+        "--poll-interval-seconds",
+        "1");
+    final Path backup = parent.resolve("portable");
+    final byte[] manifestBeforePack = 
Files.readAllBytes(backup.resolve("manifest.json"));
+    Assert.assertEquals(
+        0,
+        PipeLogicalBackupTool.run(
+            new String[] {"inspect", "--input", backup.toString(), "--json"}));
+    Assert.assertEquals(
+        0,
+        PipeLogicalBackupTool.run(new String[] {"verify", "--input", 
backup.toString(), "--json"}));
+    final Path archive = parent.resolve("portable.zip");
+    Assert.assertEquals(
+        0,
+        PipeLogicalBackupTool.run(
+            new String[] {"pack", "--input", backup.toString(), "--output", 
archive.toString()}));
+    final Path aliasArchive = parent.resolve("portable-alias.zip");
+    Assert.assertEquals(
+        0,
+        PipeLogicalBackupTool.run(
+            new String[] {
+              "export", "--input", backup.toString(), "--output", 
aliasArchive.toString()
+            }));
+    Assert.assertArrayEquals(
+        manifestBeforePack, 
Files.readAllBytes(backup.resolve("manifest.json")));
+    Assert.assertEquals(
+        0,
+        PipeLogicalBackupTool.run(
+            new String[] {"verify", "--input", archive.toString(), "--json"}));
+    runConnected(receiverEnv, "import", "--input", aliasArchive.toString());
+    TestUtils.assertDataEventuallyOnEnv(
+        receiverEnv,
+        "select * from root.logical_backup_alias.d",
+        "Time,root.logical_backup_alias.d.s,",
+        new HashSet<>(Arrays.asList("1,10,")));
+  }
+
   private static void assertLogicalRequests(final Path backup) throws 
Exception {
     final Set<Short> logicalRequests =
         Set.of(

Reply via email to