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

jt2594838 pushed a commit to branch support_wal_in_import_data
in repository https://gitbox.apache.org/repos/asf/iotdb.git


The following commit(s) were added to refs/heads/support_wal_in_import_data by 
this push:
     new fa7f2dd1a56 add detailed prompt
fa7f2dd1a56 is described below

commit fa7f2dd1a5699885c086c1fb71748d189693ec4a
Author: Tian Jiang <[email protected]>
AuthorDate: Mon Aug 24 18:48:31 2026 +0800

    add detailed prompt
---
 .../apache/iotdb/db/i18n/ImportWALMessages.java    |  10 +-
 .../apache/iotdb/db/i18n/ImportWALMessages.java    |  10 +-
 .../java/org/apache/iotdb/db/tools/ImportWAL.java  | 137 +++++++++++++-----
 .../org/apache/iotdb/db/tools/ImportWALTest.java   | 158 +++++++++++++++++++--
 4 files changed, 268 insertions(+), 47 deletions(-)

diff --git 
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/ImportWALMessages.java
 
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/ImportWALMessages.java
index 3061a1845be..1be122abbfe 100644
--- 
a/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/ImportWALMessages.java
+++ 
b/iotdb-core/datanode/src/main/i18n/en/org/apache/iotdb/db/i18n/ImportWALMessages.java
@@ -82,8 +82,14 @@ public final class ImportWALMessages {
       "Table-model WAL entries require -db/--database.";
   public static final String EXCEPTION_UNSUPPORTED_WAL_OPERATION_ARG_ABD227A0 =
       "Unsupported WAL operation: %s";
-  public static final String 
MESSAGE_UNSUPPORTED_WAL_OPERATION_ARG_SKIP_THIS_ENTRY_Y_N_DAFBE650 =
-      "Unsupported WAL operation: %s. Skip this entry? [y/N]: ";
+  public static final String
+      
MESSAGE_TREE_MODEL_DELETE_OPERATION_DETECTED_ARG_CHOOSE_E_EXECUTE_S_SKIP_A_EXECUTE_ALL_L_SKIP_ALL_Q_QUIT_11E39FD7
 =
+          "Tree-model delete operation detected: %s. Choose e=execute, s=skip, 
a=execute all, l=skip all, q=quit: ";
+  public static final String
+      
MESSAGE_UNSUPPORTED_WAL_OPERATION_ARG_CHOOSE_S_SKIP_L_SKIP_ALL_Q_QUIT_0A734E52 =
+          "Unsupported WAL operation: %s. Choose s=skip, l=skip all, q=quit: ";
+  public static final String 
EXCEPTION_WAL_REPLAY_WAS_TERMINATED_BY_THE_USER_E0BD6197 =
+      "WAL replay was terminated by the user.";
   public static final String 
EXCEPTION_INSERT_NODE_ARG_CONTAINS_NO_REPLAYABLE_DATA_5DA13453 =
       "Insert node %s contains no replayable data.";
   public static final String 
EXCEPTION_UNSUPPORTED_SNAPSHOT_DATA_TYPE_ARG_7A32D312 =
diff --git 
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/ImportWALMessages.java
 
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/ImportWALMessages.java
index 120c3265999..912ab66ca26 100644
--- 
a/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/ImportWALMessages.java
+++ 
b/iotdb-core/datanode/src/main/i18n/zh/org/apache/iotdb/db/i18n/ImportWALMessages.java
@@ -81,8 +81,14 @@ public final class ImportWALMessages {
       "表模型 WAL 条目要求指定 -db/--database。";
   public static final String EXCEPTION_UNSUPPORTED_WAL_OPERATION_ARG_ABD227A0 =
       "不支持的 WAL 操作:%s";
-  public static final String 
MESSAGE_UNSUPPORTED_WAL_OPERATION_ARG_SKIP_THIS_ENTRY_Y_N_DAFBE650 =
-      "不支持的 WAL 操作:%s。是否跳过此条目?[y/N]:";
+  public static final String
+      
MESSAGE_TREE_MODEL_DELETE_OPERATION_DETECTED_ARG_CHOOSE_E_EXECUTE_S_SKIP_A_EXECUTE_ALL_L_SKIP_ALL_Q_QUIT_11E39FD7
 =
+          "检测到树模型删除操作:%s。请选择 e=执行、s=跳过、a=全部执行、l=全部跳过、q=终止重放:";
+  public static final String
+      
MESSAGE_UNSUPPORTED_WAL_OPERATION_ARG_CHOOSE_S_SKIP_L_SKIP_ALL_Q_QUIT_0A734E52 =
+          "不支持的 WAL 操作:%s。请选择 s=跳过、l=全部跳过、q=终止重放:";
+  public static final String 
EXCEPTION_WAL_REPLAY_WAS_TERMINATED_BY_THE_USER_E0BD6197 =
+      "用户终止了 WAL 重放。";
   public static final String 
EXCEPTION_INSERT_NODE_ARG_CONTAINS_NO_REPLAYABLE_DATA_5DA13453 =
       "Insert node %s 不包含可重放数据。";
   public static final String 
EXCEPTION_UNSUPPORTED_SNAPSHOT_DATA_TYPE_ARG_7A32D312 =
diff --git 
a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/tools/ImportWAL.java 
b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/tools/ImportWAL.java
index 2214b69db92..dd1aca285b4 100644
--- a/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/tools/ImportWAL.java
+++ b/iotdb-core/datanode/src/main/java/org/apache/iotdb/db/tools/ImportWAL.java
@@ -98,7 +98,6 @@ public class ImportWAL {
   private static final String DEFAULT_USER = "root";
   private static final int DEFAULT_THREAD_NUM = 1;
   private static final int SNAPSHOT_TABLET_ROW_LIMIT = 1024;
-  private static final Object CONSOLE_PROMPT_LOCK = new Object();
 
   private ImportWAL() {}
 
@@ -136,11 +135,15 @@ public class ImportWAL {
       final String host = commandLine.getOptionValue("host", DEFAULT_HOST);
       final int port = parsePort(commandLine.getOptionValue("port", 
String.valueOf(DEFAULT_PORT)));
       final String username = commandLine.getOptionValue("username", 
DEFAULT_USER);
+      final WALReplayer.ReplayDecisionController replayDecisionController =
+          new WALReplayer.ReplayDecisionController(System.console());
       final ReplayStatistics statistics =
           replayWALDirectories(
               walFiles,
               threadNum,
-              () -> createWALReplayWorker(host, port, username, password, 
database),
+              () ->
+                  createWALReplayWorker(
+                      host, port, username, password, database, 
replayDecisionController),
               out,
               deleteSource);
       out.printf(
@@ -353,7 +356,8 @@ public class ImportWAL {
       final int port,
       final String username,
       final String password,
-      final String database)
+      final String database,
+      final WALReplayer.ReplayDecisionController replayDecisionController)
       throws IOException {
     final Session treeSession = createSession(host, port, username, password, 
null);
     final Session tableSession =
@@ -363,7 +367,7 @@ public class ImportWAL {
       if (tableSession != null) {
         tableSession.open(false);
       }
-      return new SessionWALReplayer(treeSession, tableSession, database);
+      return new SessionWALReplayer(treeSession, tableSession, database, 
replayDecisionController);
     } catch (final IoTDBConnectionException e) {
       closeSession(tableSession);
       closeSession(treeSession);
@@ -702,8 +706,11 @@ public class ImportWAL {
     private final Session tableSession;
 
     private SessionWALReplayer(
-        final Session treeSession, final Session tableSession, final String 
tableDatabaseName) {
-      super(treeSession, tableSession, tableDatabaseName);
+        final Session treeSession,
+        final Session tableSession,
+        final String tableDatabaseName,
+        final WALReplayer.ReplayDecisionController replayDecisionController) {
+      super(treeSession, tableSession, tableDatabaseName, 
replayDecisionController);
       this.treeSession = treeSession;
       this.tableSession = tableSession;
     }
@@ -720,7 +727,7 @@ public class ImportWAL {
     private final Session treeSession;
     private final Session tableSession;
     private final ConsensusLogToTabletConverter converter;
-    private final UnsupportedEntryPrompt unsupportedEntryPrompt;
+    private final ReplayDecisionPrompt replayDecisionPrompt;
     private final Map<String, List<IMeasurementSchema>> tableTagSchemas = new 
HashMap<>();
 
     WALReplayer(
@@ -729,17 +736,17 @@ public class ImportWAL {
           treeSession,
           tableSession,
           tableDatabaseName,
-          createUnsupportedEntryPrompt(System.console()));
+          new ReplayDecisionController(System.console()));
     }
 
     WALReplayer(
         final Session treeSession,
         final Session tableSession,
         final String tableDatabaseName,
-        final UnsupportedEntryPrompt unsupportedEntryPrompt) {
+        final ReplayDecisionPrompt replayDecisionPrompt) {
       this.treeSession = treeSession;
       this.tableSession = tableSession;
-      this.unsupportedEntryPrompt = unsupportedEntryPrompt;
+      this.replayDecisionPrompt = replayDecisionPrompt;
       converter =
           new ConsensusLogToTabletConverter(
               null, null, ColumnFilterMatcher.matchAll(), tableDatabaseName);
@@ -757,45 +764,111 @@ public class ImportWAL {
         return true;
       }
       if (entry.getValue() instanceof DeleteDataNode deleteDataNode) {
+        final ReplayDecision decision = replayDecisionPrompt.decide(entry, 
true);
+        if (decision == ReplayDecision.SKIP || decision == 
ReplayDecision.SKIP_ALL) {
+          return false;
+        }
+        if (decision == ReplayDecision.TERMINATE) {
+          throw replayTerminatedByUser();
+        }
         replayTreeDelete(deleteDataNode);
         return true;
       }
       if (entry.getValue() instanceof RelationalDeleteDataNode
           || entry.getValue() instanceof ObjectNode) {
-        // A null prompt means no interactive console is available, so 
preserve fail-fast behavior.
-        if (unsupportedEntryPrompt != null && 
unsupportedEntryPrompt.shouldSkip(entry)) {
+        final ReplayDecision decision = replayDecisionPrompt.decide(entry, 
false);
+        if (decision == ReplayDecision.SKIP || decision == 
ReplayDecision.SKIP_ALL) {
           return false;
         }
+        if (decision == ReplayDecision.TERMINATE) {
+          throw replayTerminatedByUser();
+        }
         throw unsupportedOperation(entry);
       }
       return false;
     }
 
-    private static UnsupportedEntryPrompt createUnsupportedEntryPrompt(final 
Console console) {
-      if (console == null) {
-        return null;
-      }
-      return entry -> {
-        synchronized (CONSOLE_PROMPT_LOCK) {
-          final String answer =
-              console.readLine(
-                  ImportWALMessages
-                      
.MESSAGE_UNSUPPORTED_WAL_OPERATION_ARG_SKIP_THIS_ENTRY_Y_N_DAFBE650,
-                  entry.getType());
-          return isSkipConfirmation(answer);
-        }
-      };
+    enum ReplayDecision {
+      EXECUTE,
+      SKIP,
+      EXECUTE_ALL,
+      SKIP_ALL,
+      TERMINATE
     }
 
-    static boolean isSkipConfirmation(final String answer) {
-      return answer != null
-          && ("y".equalsIgnoreCase(answer.trim()) || 
"yes".equalsIgnoreCase(answer.trim()));
+    @FunctionalInterface
+    interface ReplayDecisionPrompt {
+
+      ReplayDecision decide(WALEntry entry, boolean treeDelete);
     }
 
-    @FunctionalInterface
-    interface UnsupportedEntryPrompt {
+    static class ReplayDecisionController implements ReplayDecisionPrompt {
+
+      private final Console console;
+      private ReplayDecision treeDeleteDecision;
+      private boolean skipAllUnsupportedEntries;
 
-      boolean shouldSkip(WALEntry entry);
+      ReplayDecisionController(final Console console) {
+        this.console = console;
+      }
+
+      // The controller is shared by parallel workers so an "all" choice 
applies to the whole
+      // import rather than only to the WAL files assigned to one worker.
+      @Override
+      public synchronized ReplayDecision decide(final WALEntry entry, final 
boolean treeDelete) {
+        if (treeDelete && treeDeleteDecision != null) {
+          return treeDeleteDecision == ReplayDecision.EXECUTE_ALL
+              ? ReplayDecision.EXECUTE
+              : ReplayDecision.SKIP;
+        }
+        if (!treeDelete && skipAllUnsupportedEntries) {
+          return ReplayDecision.SKIP;
+        }
+        if (console == null) {
+          return ReplayDecision.TERMINATE;
+        }
+        final String answer =
+            console.readLine(
+                treeDelete
+                    ? ImportWALMessages
+                        
.MESSAGE_TREE_MODEL_DELETE_OPERATION_DETECTED_ARG_CHOOSE_E_EXECUTE_S_SKIP_A_EXECUTE_ALL_L_SKIP_ALL_Q_QUIT_11E39FD7
+                    : ImportWALMessages
+                        
.MESSAGE_UNSUPPORTED_WAL_OPERATION_ARG_CHOOSE_S_SKIP_L_SKIP_ALL_Q_QUIT_0A734E52,
+                entry.getType());
+        final ReplayDecision decision = parseDecision(answer, treeDelete);
+        rememberAllDecision(decision, treeDelete);
+        return decision;
+      }
+
+      private void rememberAllDecision(final ReplayDecision decision, final 
boolean treeDelete) {
+        if (treeDelete
+            && (decision == ReplayDecision.EXECUTE_ALL || decision == 
ReplayDecision.SKIP_ALL)) {
+          treeDeleteDecision = decision;
+        } else if (!treeDelete && decision == ReplayDecision.SKIP_ALL) {
+          skipAllUnsupportedEntries = true;
+        }
+      }
+
+      static ReplayDecision parseDecision(final String answer, final boolean 
treeDelete) {
+        if (answer == null) {
+          return ReplayDecision.TERMINATE;
+        }
+        return switch (answer.trim().toLowerCase(Locale.ROOT)) {
+          case "e", "execute", "yes", "y" ->
+              treeDelete ? ReplayDecision.EXECUTE : ReplayDecision.TERMINATE;
+          case "s", "skip", "no", "n" -> ReplayDecision.SKIP;
+          case "a", "all", "execute_all" ->
+              treeDelete ? ReplayDecision.EXECUTE_ALL : 
ReplayDecision.TERMINATE;
+          case "l", "skip_all" -> ReplayDecision.SKIP_ALL;
+          case "q", "quit", "terminate", "t" -> ReplayDecision.TERMINATE;
+          default -> ReplayDecision.TERMINATE;
+        };
+      }
+    }
+
+    private static StatementExecutionException replayTerminatedByUser() {
+      return new StatementExecutionException(
+          
ImportWALMessages.EXCEPTION_WAL_REPLAY_WAS_TERMINATED_BY_THE_USER_E0BD6197);
     }
 
     private static StatementExecutionException unsupportedOperation(final 
WALEntry entry) {
diff --git 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/tools/ImportWALTest.java
 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/tools/ImportWALTest.java
index a40f020c18c..6cef00311bf 100644
--- 
a/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/tools/ImportWALTest.java
+++ 
b/iotdb-core/datanode/src/test/java/org/apache/iotdb/db/tools/ImportWALTest.java
@@ -23,6 +23,7 @@ import org.apache.iotdb.commons.path.MeasurementPath;
 import org.apache.iotdb.commons.queryengine.plan.planner.plan.node.PlanNodeId;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.DeleteDataNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.InsertRowNode;
+import org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.ObjectNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.RelationalDeleteDataNode;
 import 
org.apache.iotdb.db.queryengine.plan.planner.plan.node.write.RelationalInsertTabletNode;
 import org.apache.iotdb.db.storageengine.dataregion.memtable.IMemTable;
@@ -75,6 +76,7 @@ import static org.junit.Assert.assertFalse;
 import static org.junit.Assert.assertThrows;
 import static org.junit.Assert.assertTrue;
 import static org.mockito.ArgumentMatchers.any;
+import static org.mockito.ArgumentMatchers.anyLong;
 import static org.mockito.ArgumentMatchers.eq;
 import static org.mockito.Mockito.doAnswer;
 import static org.mockito.Mockito.mock;
@@ -412,23 +414,132 @@ public class ImportWALTest {
             20);
     final Session treeSession = mock(Session.class);
 
-    new ImportWAL.WALReplayer(treeSession, null, null).replay(new 
WALInfoEntry(1, deleteNode));
+    new ImportWAL.WALReplayer(
+            treeSession,
+            null,
+            null,
+            (entry, treeDelete) -> 
ImportWAL.WALReplayer.ReplayDecision.EXECUTE)
+        .replay(new WALInfoEntry(1, deleteNode));
 
     verify(treeSession)
         .deleteData(eq(Arrays.asList("root.sg.d1.s1", "root.sg.d2.*")), 
eq(10L), eq(20L));
   }
 
+  @Test
+  public void testReplayTreeDeleteSkipsAfterConfirmation() throws Exception {
+    final DeleteDataNode deleteNode =
+        new DeleteDataNode(
+            new PlanNodeId(""), List.of(new MeasurementPath("root.sg.d1.s1")), 
10, 20);
+    final Session treeSession = mock(Session.class);
+
+    final boolean replayed =
+        new ImportWAL.WALReplayer(
+                treeSession,
+                null,
+                null,
+                (entry, treeDelete) -> 
ImportWAL.WALReplayer.ReplayDecision.SKIP)
+            .replay(new WALInfoEntry(1, deleteNode));
+
+    assertFalse(replayed);
+    verify(treeSession, never()).deleteData(any(), anyLong(), anyLong());
+  }
+
+  @Test
+  public void testReplayTreeDeleteExecuteAllAndSkipAllDecisions() throws 
Exception {
+    final DeleteDataNode deleteNode =
+        new DeleteDataNode(
+            new PlanNodeId(""), List.of(new MeasurementPath("root.sg.d1.s1")), 
10, 20);
+    final Session treeSession = mock(Session.class);
+    final AtomicInteger executeAllPromptCount = new AtomicInteger();
+    final ImportWAL.WALReplayer.ReplayDecisionPrompt executeAllPrompt =
+        (entry, treeDelete) -> {
+          executeAllPromptCount.incrementAndGet();
+          return ImportWAL.WALReplayer.ReplayDecision.EXECUTE_ALL;
+        };
+    final ImportWAL.WALReplayer firstExecuteAllReplayer =
+        new ImportWAL.WALReplayer(treeSession, null, null, executeAllPrompt);
+    final ImportWAL.WALReplayer secondExecuteAllReplayer =
+        new ImportWAL.WALReplayer(treeSession, null, null, executeAllPrompt);
+
+    assertTrue(firstExecuteAllReplayer.replay(new WALInfoEntry(1, 
deleteNode)));
+    assertTrue(secondExecuteAllReplayer.replay(new WALInfoEntry(2, 
deleteNode)));
+    assertEquals(2, executeAllPromptCount.get());
+    verify(treeSession, times(2)).deleteData(any(), eq(10L), eq(20L));
+
+    final Session skippedTreeSession = mock(Session.class);
+    final AtomicInteger skipAllPromptCount = new AtomicInteger();
+    final ImportWAL.WALReplayer.ReplayDecisionPrompt skipAllPrompt =
+        (entry, treeDelete) -> {
+          skipAllPromptCount.incrementAndGet();
+          return ImportWAL.WALReplayer.ReplayDecision.SKIP_ALL;
+        };
+    final ImportWAL.WALReplayer firstSkipAllReplayer =
+        new ImportWAL.WALReplayer(skippedTreeSession, null, null, 
skipAllPrompt);
+    final ImportWAL.WALReplayer secondSkipAllReplayer =
+        new ImportWAL.WALReplayer(skippedTreeSession, null, null, 
skipAllPrompt);
+
+    assertFalse(firstSkipAllReplayer.replay(new WALInfoEntry(1, deleteNode)));
+    assertFalse(secondSkipAllReplayer.replay(new WALInfoEntry(2, deleteNode)));
+    assertEquals(2, skipAllPromptCount.get());
+    verify(skippedTreeSession, never()).deleteData(any(), anyLong(), 
anyLong());
+  }
+
+  @Test
+  public void testReplayTreeDeleteTerminatesAfterConfirmation() throws 
Exception {
+    final DeleteDataNode deleteNode =
+        new DeleteDataNode(
+            new PlanNodeId(""), List.of(new MeasurementPath("root.sg.d1.s1")), 
10, 20);
+
+    assertThrows(
+        StatementExecutionException.class,
+        () ->
+            new ImportWAL.WALReplayer(
+                    mock(Session.class),
+                    null,
+                    null,
+                    (entry, treeDelete) -> 
ImportWAL.WALReplayer.ReplayDecision.TERMINATE)
+                .replay(new WALInfoEntry(1, deleteNode)));
+  }
+
   /** Covers an unsupported entry when the interactive user explicitly chooses 
to skip it. */
   @Test
   public void testReplayUnsupportedEntrySkipsAfterConfirmation() throws 
Exception {
     final WALEntry entry = mockUnsupportedEntry();
 
     final boolean replayed =
-        new ImportWAL.WALReplayer(mock(Session.class), null, null, ignored -> 
true).replay(entry);
+        new ImportWAL.WALReplayer(
+                mock(Session.class),
+                null,
+                null,
+                (ignored, treeDelete) -> 
ImportWAL.WALReplayer.ReplayDecision.SKIP)
+            .replay(entry);
 
     assertFalse(replayed);
   }
 
+  @Test
+  public void testReplayUnsupportedEntriesSkipAllAfterConfirmation() throws 
Exception {
+    final AtomicInteger promptCount = new AtomicInteger();
+    final ImportWAL.WALReplayer.ReplayDecisionPrompt skipAllPrompt =
+        (entry, treeDelete) -> {
+          promptCount.incrementAndGet();
+          return ImportWAL.WALReplayer.ReplayDecision.SKIP_ALL;
+        };
+    final ImportWAL.WALReplayer relationalDeleteReplayer =
+        new ImportWAL.WALReplayer(mock(Session.class), null, null, 
skipAllPrompt);
+
+    assertFalse(relationalDeleteReplayer.replay(mockUnsupportedEntry()));
+    assertFalse(relationalDeleteReplayer.replay(mockUnsupportedEntry()));
+
+    final WALEntry objectEntry = mock(WALEntry.class);
+    when(objectEntry.getType()).thenReturn(WALEntryType.OBJECT_FILE_NODE);
+    when(objectEntry.getValue()).thenReturn(mock(ObjectNode.class));
+    final ImportWAL.WALReplayer objectNodeReplayer =
+        new ImportWAL.WALReplayer(mock(Session.class), null, null, 
skipAllPrompt);
+    assertFalse(objectNodeReplayer.replay(objectEntry));
+    assertEquals(3, promptCount.get());
+  }
+
   /** Covers an unsupported entry when the interactive user declines the skip 
prompt. */
   @Test
   public void testReplayUnsupportedEntryFailsAfterDecliningSkip() {
@@ -437,7 +548,11 @@ public class ImportWALTest {
     assertThrows(
         StatementExecutionException.class,
         () ->
-            new ImportWAL.WALReplayer(mock(Session.class), null, null, ignored 
-> false)
+            new ImportWAL.WALReplayer(
+                    mock(Session.class),
+                    null,
+                    null,
+                    (ignored, treeDelete) -> 
ImportWAL.WALReplayer.ReplayDecision.TERMINATE)
                 .replay(entry));
   }
 
@@ -448,17 +563,38 @@ public class ImportWALTest {
 
     assertThrows(
         StatementExecutionException.class,
-        () -> new ImportWAL.WALReplayer(mock(Session.class), null, null, 
null).replay(entry));
+        () ->
+            new ImportWAL.WALReplayer(
+                    mock(Session.class),
+                    null,
+                    null,
+                    new 
ImportWAL.WALReplayer.ReplayDecisionController((java.io.Console) null))
+                .replay(entry));
   }
 
-  /** Covers accepted confirmations and the safe default for all other prompt 
answers. */
   @Test
-  public void testUnsupportedEntrySkipConfirmationParsing() {
-    assertTrue(ImportWAL.WALReplayer.isSkipConfirmation("y"));
-    assertTrue(ImportWAL.WALReplayer.isSkipConfirmation(" YES "));
-    assertFalse(ImportWAL.WALReplayer.isSkipConfirmation("n"));
-    assertFalse(ImportWAL.WALReplayer.isSkipConfirmation(""));
-    assertFalse(ImportWAL.WALReplayer.isSkipConfirmation(null));
+  public void testReplayDecisionParsing() {
+    assertEquals(
+        ImportWAL.WALReplayer.ReplayDecision.EXECUTE,
+        ImportWAL.WALReplayer.ReplayDecisionController.parseDecision("e", 
true));
+    assertEquals(
+        ImportWAL.WALReplayer.ReplayDecision.SKIP,
+        ImportWAL.WALReplayer.ReplayDecisionController.parseDecision("s", 
true));
+    assertEquals(
+        ImportWAL.WALReplayer.ReplayDecision.EXECUTE_ALL,
+        ImportWAL.WALReplayer.ReplayDecisionController.parseDecision("a", 
true));
+    assertEquals(
+        ImportWAL.WALReplayer.ReplayDecision.SKIP_ALL,
+        ImportWAL.WALReplayer.ReplayDecisionController.parseDecision("l", 
true));
+    assertEquals(
+        ImportWAL.WALReplayer.ReplayDecision.TERMINATE,
+        ImportWAL.WALReplayer.ReplayDecisionController.parseDecision("a", 
false));
+    assertEquals(
+        ImportWAL.WALReplayer.ReplayDecision.SKIP_ALL,
+        ImportWAL.WALReplayer.ReplayDecisionController.parseDecision("l", 
false));
+    assertEquals(
+        ImportWAL.WALReplayer.ReplayDecision.TERMINATE,
+        ImportWAL.WALReplayer.ReplayDecisionController.parseDecision("q", 
true));
   }
 
   /** Covers a non-aligned snapshot whose measurements have independent time 
axes. */

Reply via email to