From 7dc64b7a763cba01c31dfd2dff2b17162e4c104e Mon Sep 17 00:00:00 2001
From: Kurdakov Alexander <kusancho12@gmail.com>
Date: Wed, 2 Oct 2024 00:41:53 +0300
Subject: [PATCH] feat: new argument for `picodata expel`

New argument `--timeout` for `picodata expel`.
---
 CHANGELOG.md               |  3 +++
 src/cli/args.rs            | 10 ++++++++++
 src/cli/expel.rs           |  1 +
 test/int/test_expelling.py | 30 ++++++++++++++++++++++++++++++
 4 files changed, 44 insertions(+)

diff --git a/CHANGELOG.md b/CHANGELOG.md
index 0d033b9df7..07e09f03aa 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -21,6 +21,9 @@ with the `YY.MINOR.MICRO` scheme.
 - Default authentication method changed from `CHAP-SHA1` to `MD5` both for user creation and in connect CLI. This change affects new user creation and all system users (except the `pico_service` user), as a command-line interface of `picodata connect` and `picodata expel`. Also, default schema version at cluster boot is now `1`, not `0` as it was previously.
 Connection via `Pgproto` no longer requires additional manual step to change the authentication method. However if you use `iproto` the admin will have to manually change the authentication type.
 
+- New `picodata connect` and `picodata expel` argument `--timeout` for specifying
+the timeout for address resolving operation.
+
 - Support human numbers to configure memtx.memory.
   Supported suffixes: K, M, G, T, 1K = 1024
   (e.g picodata run --memtx-memory 10G)
diff --git a/src/cli/args.rs b/src/cli/args.rs
index e839795fe8..f6f5a74f77 100644
--- a/src/cli/args.rs
+++ b/src/cli/args.rs
@@ -378,6 +378,16 @@ pub struct Expel {
     )]
     /// The preferred authentication method.
     pub auth_method: AuthMethod,
+
+    #[clap(
+        short = 't',
+        long = "timeout",
+        value_name = "TIMEOUT",
+        default_value = "5",
+        env = "PICODATA_CONNECT_TIMEOUT"
+    )]
+    /// Connection timeout in seconds.
+    pub timeout: u64,
 }
 
 impl Expel {
diff --git a/src/cli/expel.rs b/src/cli/expel.rs
index bb80361a1d..8119db08f3 100644
--- a/src/cli/expel.rs
+++ b/src/cli/expel.rs
@@ -13,6 +13,7 @@ pub async fn tt_expel(args: args::Expel) -> Result<(), Error> {
         Some("admin"),
         args.password_file.as_deref(),
         args.auth_method,
+        args.timeout,
     )?;
 
     let req = ExpelRequest {
diff --git a/test/int/test_expelling.py b/test/int/test_expelling.py
index ab99b006c2..21a619cad3 100644
--- a/test/int/test_expelling.py
+++ b/test/int/test_expelling.py
@@ -1,4 +1,6 @@
 import pytest
+import sys
+import pexpect  # type: ignore
 from conftest import Cluster, Instance, Retriable, log_crawler
 
 
@@ -108,3 +110,31 @@ def test_raft_id_after_expel(cluster: Cluster):
 
     i4 = cluster.add_instance()
     assert i4.raft_id == 4
+
+
+def test_expel_timeout(cluster: Cluster):
+    cluster.deploy(instance_count=1)
+    [i1] = cluster.instances
+    timeout = 1
+
+    # If the peer is not resolving, by default we hang on
+    # for 5 seconds. We can change it by specifying `timeout`.
+    cli = pexpect.spawn(
+        cwd=i1.data_dir,
+        command=i1.binary_path,
+        args=[
+            "expel",
+            "random_instance_id",
+            f"--timeout={timeout}",
+            "--peer=10001",
+        ],
+        encoding="utf-8",
+        timeout=10,
+    )
+    cli.logfile = sys.stdout
+
+    cli.expect_exact("Enter password for admin:")
+    cli.sendline("wrong_password")
+
+    cli.expect_exact("CRITICAL: connect timeout")
+    cli.expect_exact(pexpect.EOF)
-- 
GitLab