summaryrefslogtreecommitdiffstats
path: root/tests/cli_tests
diff options
context:
space:
mode:
Diffstat (limited to 'tests/cli_tests')
-rw-r--r--tests/cli_tests/__init__.py0
-rw-r--r--tests/cli_tests/test_cli_pubsub.py31
-rw-r--r--tests/cli_tests/test_cli_start.py91
-rw-r--r--tests/cli_tests/test_command_input.py75
-rw-r--r--tests/cli_tests/test_completer.py51
-rw-r--r--tests/cli_tests/test_config.py59
-rw-r--r--tests/cli_tests/test_dsn.py53
-rw-r--r--tests/cli_tests/test_history.py42
-rw-r--r--tests/cli_tests/test_on_error.py12
-rw-r--r--tests/cli_tests/test_pager.py117
-rw-r--r--tests/cli_tests/test_self_implemented_command.py14
-rw-r--r--tests/cli_tests/test_shell_pipeline.py21
-rw-r--r--tests/cli_tests/test_string_execute.py39
-rw-r--r--tests/cli_tests/test_transaction.py70
-rw-r--r--tests/cli_tests/test_warning.py51
-rw-r--r--tests/cli_tests/wrappager.py14
16 files changed, 740 insertions, 0 deletions
diff --git a/tests/cli_tests/__init__.py b/tests/cli_tests/__init__.py
new file mode 100644
index 0000000..e69de29
--- /dev/null
+++ b/tests/cli_tests/__init__.py
diff --git a/tests/cli_tests/test_cli_pubsub.py b/tests/cli_tests/test_cli_pubsub.py
new file mode 100644
index 0000000..956e105
--- /dev/null
+++ b/tests/cli_tests/test_cli_pubsub.py
@@ -0,0 +1,31 @@
+def test_subscribe(cli, clean_redis):
+ cli.sendline("subscribe foo")
+ cli.expect("subscribe from")
+ cli.expect("foo")
+ cli.expect("1")
+
+ clean_redis.publish("foo", "test message")
+ cli.expect("from")
+ cli.expect("foo")
+ cli.expect("test message")
+
+ # unsubscribe, send ctrl-c
+ cli.send(chr(3))
+ cli.expect("unsubscribe from")
+ cli.expect("0")
+
+
+def test_subscribe_in_raw_mode(raw_cli, clean_redis):
+ raw_cli.sendline("subscribe foo")
+ raw_cli.expect("subscribe\r")
+ raw_cli.expect("foo\r")
+ raw_cli.expect("1\r")
+
+ clean_redis.publish("foo", "test message")
+ raw_cli.expect("message\r")
+ raw_cli.expect("foo\r")
+ raw_cli.expect("test message")
+
+ # unsubscribe, send ctrl-c
+ raw_cli.send(chr(3))
+ raw_cli.expect("0\r")
diff --git a/tests/cli_tests/test_cli_start.py b/tests/cli_tests/test_cli_start.py
new file mode 100644
index 0000000..8045947
--- /dev/null
+++ b/tests/cli_tests/test_cli_start.py
@@ -0,0 +1,91 @@
+import pexpect
+import pytest
+from textwrap import dedent
+
+
+def test_start_on_connection_error():
+ cli = pexpect.spawn("iredis -p 12345", timeout=1)
+ cli.logfile_read = open("cli_test.log", "ab")
+ cli.expect(r"Error \d+ connecting to 127.0.0.1:12345. Connection refused.")
+ cli.close()
+
+
+def test_start_with_client_name():
+ cli = pexpect.spawn("iredis --client_name custom_name", timeout=2)
+ cli.expect("iredis")
+ cli.sendline("CLIENT GETNAME")
+ cli.expect("custom_name")
+ cli.close()
+
+
+def test_short_help_option(config):
+ c = pexpect.spawn("iredis -h", timeout=2)
+
+ c.expect("Show this message and exit.")
+
+ c = pexpect.spawn("iredis -h 127.0.0.1")
+ c.expect("127.0.0.1:6379>")
+
+ c.close()
+
+
+@pytest.mark.skipif("int(os.environ['REDIS_VERSION']) != 5")
+def test_server_version_in_starting_on5():
+ c = pexpect.spawn("iredis", timeout=2)
+ c.expect("redis-server 5")
+ c.close()
+
+
+@pytest.mark.skipif("int(os.environ['REDIS_VERSION']) != 6")
+def test_server_version_in_starting_on6():
+ c = pexpect.spawn("iredis", timeout=2)
+ c.expect("redis-server 6")
+ c.close()
+
+
+def test_connection_using_url(clean_redis):
+ c = pexpect.spawn("iredis --url redis://localhost:6379/7", timeout=2)
+ c.logfile_read = open("cli_test.log", "ab")
+ c.expect(["iredis", "127.0.0.1:6379[7]>"])
+ c.sendline("set current-db 7")
+ c.expect("OK")
+ c.close()
+
+
+def test_connection_using_url_from_env(clean_redis, monkeypatch):
+ monkeypatch.setenv("IREDIS_URL", "redis://localhost:6379/7")
+ c = pexpect.spawn("iredis", timeout=2)
+ c.logfile_read = open("cli_test.log", "ab")
+ c.expect(["iredis", "localhost:6379[7]>"])
+ c.sendline("set current-db 7")
+ c.expect("OK")
+ c.close()
+
+
+@pytest.mark.xfail(reason="current test in github action, socket not supported.")
+# https://github.community/t5/GitHub-Actions/Job-service-command/td-p/33901#
+# https://help.github.com/en/actions/reference/workflow-syntax-for-github-actions#jobsjob_idservices
+def test_connect_via_socket(fake_redis_socket):
+ config_content = dedent(
+ """
+ [main]
+ log_location = /tmp/iredis1.log
+ no_info=True
+ """
+ )
+ with open("/tmp/iredisrc", "w+") as etc_config:
+ etc_config.write(config_content)
+
+ c = pexpect.spawn("iredis --iredisrc /tmp/iredisrc -s /tmp/test.sock", timeout=2)
+ c.logfile_read = open("cli_test.log", "ab")
+ c.expect("redis /tmp/test.sock")
+
+ c.close()
+
+
+def test_iredis_start_with_prompt():
+ cli = pexpect.spawn("iredis --prompt '{host}abc{port}def{client_name}'", timeout=2)
+ cli.logfile_read = open("cli_test.log", "ab")
+ cli.expect("iredis")
+ cli.expect("127.0.0.1abc6379defNone")
+ cli.close()
diff --git a/tests/cli_tests/test_command_input.py b/tests/cli_tests/test_command_input.py
new file mode 100644
index 0000000..75917cb
--- /dev/null
+++ b/tests/cli_tests/test_command_input.py
@@ -0,0 +1,75 @@
+import os
+import pytest
+
+
+def test_wrong_select_db_index(cli):
+ cli.sendline("select 1")
+ cli.expect(["OK", "127.0.0.1"])
+
+ cli.sendline("select 128")
+ cli.expect(["DB index is out of range", "127.0.0.1:6379[1]>"])
+
+ if int(os.environ["REDIS_VERSION"]) > 5:
+ text = "value is not an integer or out of range"
+ else:
+ text = "invalid DB index"
+
+ cli.sendline("select abc")
+ cli.expect([text, "127.0.0.1:6379[1]>"])
+
+ cli.sendline("select 15")
+ cli.expect("OK")
+
+
+def test_set_command_with_shash(clean_redis, cli):
+ cli.sendline("set a \\hello\\") # legal redis command
+ cli.expect("OK")
+
+ cli.sendline("get a")
+ cli.expect(r"hello")
+
+
+def test_enter_key_binding(clean_redis, cli):
+ cli.send("set")
+ cli.expect("set")
+ cli.send("\033[B") # down
+ cli.sendline() # enter
+
+ cli.sendline(" a 'hello'")
+ cli.expect("OK")
+
+ cli.sendline("get a")
+ cli.expect(r"hello")
+
+
+@pytest.mark.skipif("int(os.environ['REDIS_VERSION']) < 6")
+def test_auth_hidden_password_with_username(clean_redis, cli):
+ cli.send("auth default hello-world")
+ cli.expect("default")
+ cli.expect(r"\*{11}")
+
+
+@pytest.mark.skipif("int(os.environ['REDIS_VERSION']) > 5")
+def test_auth_hidden_password(clean_redis, cli):
+ cli.send("auth hello-world")
+ cli.expect("auth")
+ cli.expect(r"\*{11}")
+
+
+def test_hello_command_is_not_supported(cli):
+ cli.sendline("hello 3")
+ cli.expect("IRedis currently not support RESP3")
+
+
+@pytest.mark.xfail(reason="unstable, maybe due to github action's signal handling")
+def test_abort_reading_connection(cli):
+ cli.sendline("blpop mylist 30")
+ cli.send(chr(3))
+ cli.expect(
+ r"KeyboardInterrupt received! User canceled reading response!", timeout=10
+ )
+
+ cli.sendline("set foo bar")
+ cli.expect("OK")
+ cli.sendline("get foo")
+ cli.expect("bar")
diff --git a/tests/cli_tests/test_completer.py b/tests/cli_tests/test_completer.py
new file mode 100644
index 0000000..4ffd058
--- /dev/null
+++ b/tests/cli_tests/test_completer.py
@@ -0,0 +1,51 @@
+import pytest
+
+
+def test_integer_type_completer(cli):
+ cli.expect("127.0.0.1")
+ cli.send("BITFIELD meykey GET ")
+ cli.expect(["i64", "u63", "u62"])
+ cli.sendline("u4 #0")
+ cli.expect("127.0.0.1")
+
+ cli.send("BITFIELD meykey GET ")
+ cli.expect(["u4", "i64", "u63", "u62"])
+
+
+def test_command_completion_when_a_command_is_another_command_substring(
+ cli, clean_redis
+):
+ cli.expect("127.0.0.1")
+ cli.send("set")
+ cli.expect(["set", "setnx", "setex", "setbit", "setrange"])
+
+ cli.send("n")
+ cli.expect("setnx")
+ cli.send("x")
+ cli.expect("setnx")
+ cli.sendline("foo bar")
+ cli.expect(["1", "127.0.0.1"])
+
+ cli.send("setnx")
+ cli.expect("foo")
+
+
+def test_command_completion_when_space_command(cli, clean_redis):
+ cli.expect("127.0.0.1")
+
+ cli.send("command in")
+ cli.expect("command info")
+
+
+@pytest.mark.skipif("int(os.environ['REDIS_VERSION']) < 6")
+def test_username_completer(cli, iredis_client):
+ iredis_client.execute("acl setuser", "foo1")
+ iredis_client.execute("acl setuser", "bar2")
+
+ cli.expect("127.0.0.1")
+ cli.sendline("acl users")
+ cli.expect("foo1")
+
+ cli.send("acl deluser ")
+ cli.expect("foo1")
+ cli.expect("bar2")
diff --git a/tests/cli_tests/test_config.py b/tests/cli_tests/test_config.py
new file mode 100644
index 0000000..1795c62
--- /dev/null
+++ b/tests/cli_tests/test_config.py
@@ -0,0 +1,59 @@
+import pexpect
+from textwrap import dedent
+from pathlib import Path
+
+
+def test_log_location_config():
+ config_content = dedent(
+ """
+ [main]
+ log_location = /tmp/iredis1.log
+ """
+ )
+ with open("/tmp/iredisrc", "w+") as etc_config:
+ etc_config.write(config_content)
+
+ cli = pexpect.spawn("iredis -n 15 --iredisrc /tmp/iredisrc", timeout=1)
+ cli.expect("127.0.0.1")
+ cli.close()
+
+ log = Path("/tmp/iredis1.log")
+ assert log.exists()
+ with open(log, "r") as logfile:
+ content = logfile.read()
+
+ assert len(content) > 100
+
+
+def test_load_prompt_from_config(iredis_client, clean_redis):
+ config_content = dedent(
+ """
+ [main]
+ prompt = {host}abc{port}xx{db}
+ """
+ )
+ with open("/tmp/iredisrc", "w+") as etc_config:
+ etc_config.write(config_content)
+
+ cli = pexpect.spawn("iredis -n 15 --iredisrc /tmp/iredisrc", timeout=1)
+ cli.expect("iredis")
+ cli.expect("127.0.0.1abc6379xx15")
+ cli.close()
+
+
+def test_prompt_cli_overwrite_config(iredis_client, clean_redis):
+ config_content = dedent(
+ """
+ [main]
+ prompt = {host}abc{port}xx{db}
+ """
+ )
+ with open("/tmp/iredisrc", "w+") as etc_config:
+ etc_config.write(config_content)
+
+ cli = pexpect.spawn(
+ "iredis -n 15 --iredisrc /tmp/iredisrc --prompt='{db}-12345'", timeout=1
+ )
+ cli.expect("iredis")
+ cli.expect("15-12345")
+ cli.close()
diff --git a/tests/cli_tests/test_dsn.py b/tests/cli_tests/test_dsn.py
new file mode 100644
index 0000000..8c9528d
--- /dev/null
+++ b/tests/cli_tests/test_dsn.py
@@ -0,0 +1,53 @@
+import os
+
+import pexpect
+from textwrap import dedent
+import pytest
+
+
+def test_using_dsn():
+ config_content = dedent(
+ """
+ [alias_dsn]
+ local = redis://localhost:6379/15
+ """
+ )
+ with open("/tmp/iredisrc", "w+") as etc_config:
+ etc_config.write(config_content)
+
+ cli = pexpect.spawn("iredis --iredisrc /tmp/iredisrc --dsn local", timeout=1)
+ cli.logfile_read = open("cli_test.log", "ab")
+ cli.expect(["iredis", "localhost:6379[15]>"])
+ cli.close()
+
+ # overwrite with -n
+ cli = pexpect.spawn("iredis --iredisrc /tmp/iredisrc --dsn local -n 3", timeout=1)
+ cli.logfile_read = open("cli_test.log", "ab")
+ cli.expect(["iredis", "localhost:6379[3]>"])
+ cli.close()
+
+ # dsn not exists
+ cli = pexpect.spawn("iredis --iredisrc /tmp/iredisrc --dsn ghost-dsn", timeout=1)
+ cli.expect(["Could not find the specified DSN in the config file."])
+ cli.close()
+ assert cli.status == 1
+
+
+@pytest.mark.skipif(
+ not os.path.exists("/tmp/redis/redis.sock"), reason="unix socket is not found"
+)
+def test_using_dsn_unix():
+ config_content = dedent(
+ """
+ [alias_dsn]
+ unix = unix:///tmp/redis/redis.sock?db=3
+ """
+ )
+ with open("/tmp/iredisrc", "w+") as etc_config:
+ etc_config.write(config_content)
+
+ cli = pexpect.spawn("iredis --iredisrc /tmp/iredisrc --dsn unix", timeout=2)
+ cli.logfile_read = open("cli_test.log", "ab")
+ cli.expect(["iredis", "redis /tmp/redis/redis.sock[3]>"])
+
+ cli.close()
diff --git a/tests/cli_tests/test_history.py b/tests/cli_tests/test_history.py
new file mode 100644
index 0000000..09e6c82
--- /dev/null
+++ b/tests/cli_tests/test_history.py
@@ -0,0 +1,42 @@
+import os
+import pexpect
+from pathlib import Path
+from textwrap import dedent
+
+
+def test_history_not_log_auth(cli):
+ cli.sendline("AUTH 123")
+ cli.expect(["Client sent AUTH, but no password is set", "127.0.0.1"])
+ cli.sendline("set foo bar")
+ cli.expect("OK")
+
+ with open(os.path.expanduser("~/.iredis_history"), "r") as history_file:
+ content = history_file.read()
+
+ assert "set foo bar" in content
+ assert "AUTH" not in content
+
+
+def test_history_create_and_writing_with_config():
+ config_content = dedent(
+ """
+ [main]
+ history_location = /tmp/iredis_history.txt
+ """
+ )
+ with open("/tmp/iredisrc", "w+") as etc_config:
+ etc_config.write(config_content)
+
+ cli = pexpect.spawn("iredis -n 15 --iredisrc /tmp/iredisrc", timeout=2)
+ cli.expect("127.0.0.1")
+ cli.sendline("set hello world")
+ cli.expect("OK")
+ cli.close()
+
+ log = Path("/tmp/iredis_history.txt")
+ assert log.exists()
+
+ with open(log, "r") as logfile:
+ content = logfile.read()
+
+ assert "set hello world" in content
diff --git a/tests/cli_tests/test_on_error.py b/tests/cli_tests/test_on_error.py
new file mode 100644
index 0000000..9ab8927
--- /dev/null
+++ b/tests/cli_tests/test_on_error.py
@@ -0,0 +1,12 @@
+def test_wrong_stream_type(clean_redis, cli):
+ clean_redis.lpush("mylist", "foo")
+ cli.sendline("xrange mylist 0 -1")
+ cli.expect("error")
+ cli.expect("Invalid stream ID specified as stream command argument")
+
+
+def test_wrong_stream_type_in_raw_mode(clean_redis, raw_cli):
+ clean_redis.lpush("mylist", "foo")
+ raw_cli.sendline("xrange mylist 0 -1")
+ raw_cli.expect("ERROR")
+ raw_cli.expect("Invalid stream ID specified as stream command argument")
diff --git a/tests/cli_tests/test_pager.py b/tests/cli_tests/test_pager.py
new file mode 100644
index 0000000..38ced31
--- /dev/null
+++ b/tests/cli_tests/test_pager.py
@@ -0,0 +1,117 @@
+# noqa: F541
+import os
+import sys
+import pexpect
+import pathlib
+from contextlib import contextmanager
+from textwrap import dedent
+
+
+TEST_IREDISRC = "/tmp/.iredisrc.test"
+TEST_PAGER_BOUNDARY = "---boundary---"
+TEST_PAGER_BOUNDARY_NUMBER = "---88938347271---"
+
+env_pager = "{0} {1} {2}".format(
+ sys.executable,
+ os.path.join(pathlib.Path(__file__).parent, "wrappager.py"),
+ TEST_PAGER_BOUNDARY,
+)
+env_pager_numbers = "{0} {1} {2}".format(
+ sys.executable,
+ os.path.join(pathlib.Path(__file__).parent, "wrappager.py"),
+ TEST_PAGER_BOUNDARY_NUMBER,
+)
+
+
+@contextmanager
+def pager_enabled_cli():
+ env = os.environ
+ env["PAGER"] = env_pager
+ child = pexpect.spawn("iredis -n 15", timeout=3, env=env)
+ child.logfile_read = open("cli_test.log", "ab")
+ child.expect("127.0.0.1")
+ try:
+ yield child
+ finally:
+ child.close()
+
+
+def test_using_pager_when_rows_too_high(clean_redis):
+ for index in range(100):
+ clean_redis.lpush("long-list", f"value-{index}")
+ with pager_enabled_cli() as child:
+ child.sendline("lrange long-list 0 -1")
+ child.expect(TEST_PAGER_BOUNDARY)
+ child.expect("value-1")
+ child.expect(TEST_PAGER_BOUNDARY)
+
+
+def test_using_pager_works_for_help():
+ with pager_enabled_cli() as child:
+ child.sendline("help set")
+ child.expect(TEST_PAGER_BOUNDARY)
+ child.expect("Set the string value of a key")
+ child.expect(TEST_PAGER_BOUNDARY)
+
+
+def test_pager_works_for_peek(clean_redis):
+ for index in range(100):
+ clean_redis.lpush("long-list", f"value-{index}")
+ with pager_enabled_cli() as child:
+ child.sendline("peek long-list")
+ child.expect(TEST_PAGER_BOUNDARY)
+ child.expect("(quicklist)")
+ child.expect("value-1")
+ child.expect(TEST_PAGER_BOUNDARY)
+
+
+def test_using_pager_from_config(clean_redis):
+ config_content = dedent(
+ f"""
+ [main]
+ log_location = /tmp/iredis1.log
+ pager = {env_pager_numbers}
+ """
+ )
+
+ with open(TEST_IREDISRC, "w+") as test_iredisrc:
+ test_iredisrc.write(config_content)
+
+ child = pexpect.spawn(f"iredis -n 15 --iredisrc {TEST_IREDISRC}", timeout=3)
+ child.logfile_read = open("cli_test.log", "ab")
+ child.expect("127.0.0.1")
+ for index in range(100):
+ clean_redis.lpush("long-list", f"value-{index}")
+ child.sendline("lrange long-list 0 -1")
+ child.expect(TEST_PAGER_BOUNDARY_NUMBER)
+ child.expect("value-1")
+ child.expect(TEST_PAGER_BOUNDARY_NUMBER)
+ child.close()
+
+
+def test_using_pager_from_config_when_env_config_both_set(clean_redis):
+ config_content = dedent(
+ f"""
+ [main]
+ log_location = /tmp/iredis1.log
+ pager = {env_pager_numbers}
+ """
+ )
+
+ with open(TEST_IREDISRC, "w+") as test_iredisrc:
+ test_iredisrc.write(config_content)
+
+ env = os.environ
+ env["PAGER"] = env_pager
+ child = pexpect.spawn(
+ f"iredis -n 15 --iredisrc {TEST_IREDISRC}", timeout=3, env=env
+ )
+ child.logfile_read = open("cli_test.log", "ab")
+ child.expect("127.0.0.1")
+ for index in range(100):
+ clean_redis.lpush("long-list", f"value-{index}")
+ child.sendline("lrange long-list 0 -1")
+ child.expect(TEST_PAGER_BOUNDARY_NUMBER)
+ child.expect("value-1")
+ child.expect(TEST_PAGER_BOUNDARY_NUMBER)
+ child.close()
diff --git a/tests/cli_tests/test_self_implemented_command.py b/tests/cli_tests/test_self_implemented_command.py
new file mode 100644
index 0000000..328d56b
--- /dev/null
+++ b/tests/cli_tests/test_self_implemented_command.py
@@ -0,0 +1,14 @@
+"""
+check ascii table:
+http://ascii-table.com/ansi-escape-sequences.php
+"""
+
+
+def test_clear(cli):
+ cli.sendline("clear")
+ cli.expect("\\[2J") # clear screen
+
+
+def test_exirt(cli):
+ cli.sendline("EXIT")
+ cli.expect("Goodbye!")
diff --git a/tests/cli_tests/test_shell_pipeline.py b/tests/cli_tests/test_shell_pipeline.py
new file mode 100644
index 0000000..8fe5e14
--- /dev/null
+++ b/tests/cli_tests/test_shell_pipeline.py
@@ -0,0 +1,21 @@
+import pexpect
+
+
+def test_running_disable_shell_pipeline():
+ cli = pexpect.spawn("iredis -n 15 --no-shell", timeout=2)
+ cli.expect("127.0.0.1")
+ cli.sendline("set foo hello")
+ cli.expect("OK")
+ cli.sendline("get foo | grep w")
+ cli.expect(r"hello")
+ cli.close()
+
+
+def test_running_disable_shell_pipeline_with_decode_option():
+ cli = pexpect.spawn("iredis -n 15 --decode=utf-8", timeout=2)
+ cli.expect("127.0.0.1")
+ cli.sendline("set foo hello")
+ cli.expect("OK")
+ cli.sendline("get foo | cat")
+ cli.expect(r"hello")
+ cli.close()
diff --git a/tests/cli_tests/test_string_execute.py b/tests/cli_tests/test_string_execute.py
new file mode 100644
index 0000000..310adab
--- /dev/null
+++ b/tests/cli_tests/test_string_execute.py
@@ -0,0 +1,39 @@
+def test_set(cli):
+ cli.sendline("set foo bar")
+ cli.expect(["OK", "127.0.0.1"])
+
+ cli.sendline("set foo bar nx")
+ cli.expect(["(nil)", "127.0.0.1"])
+
+ cli.sendline("set foo bar xx")
+ cli.expect(["OK", "127.0.0.1"])
+
+ cli.sendline("set foo1 bar xx")
+ cli.expect(["(nil)", "127.0.0.1"])
+
+
+def test_get(cli):
+ cli.sendline("set foo bar")
+ cli.expect("OK")
+
+ cli.sendline("get foo")
+ cli.expect('"bar"')
+
+
+def test_delete_string(clean_redis, cli, config):
+ config.warning = True
+ cli.sendline("set foo bar")
+ cli.expect("OK")
+ cli.sendline("del foo")
+ cli.expect("Do you want to proceed")
+ cli.sendline("yes")
+ cli.expect("1")
+
+ cli.sendline("get foo")
+ cli.expect("(nil)")
+
+
+def test_on_dangerous_commands(cli, config):
+ config.warning = True
+ cli.sendline("keys *")
+ cli.expect("KEYS will hang redis server, use SCAN instead")
diff --git a/tests/cli_tests/test_transaction.py b/tests/cli_tests/test_transaction.py
new file mode 100644
index 0000000..b5c6b4e
--- /dev/null
+++ b/tests/cli_tests/test_transaction.py
@@ -0,0 +1,70 @@
+import pytest
+import pexpect
+
+
+def test_trasaction_rprompt(clean_redis, cli):
+ cli.sendline("multi")
+ cli.expect(["OK", "transaction", "127.0.0.1"])
+
+ cli.sendline("get foo")
+ cli.expect(["QUEUED", "127.0.0.1", "transaction"])
+
+ cli.sendline("set hello world")
+ cli.expect(["QUEUED", "127.0.0.1", "transaction"])
+
+ cli.sendline("ping")
+ cli.expect(["QUEUED", "127.0.0.1", "transaction"])
+
+ cli.sendline("EXEC")
+ cli.expect("(nil)")
+ cli.expect("OK")
+ cli.expect("PONG")
+ cli.expect("127.0.0.1")
+
+ with pytest.raises(pexpect.exceptions.TIMEOUT):
+ cli.expect("transaction")
+
+
+def test_trasaction_syntax_error(cli):
+ cli.sendline("multi")
+ cli.sendline("get foo 1")
+ cli.expect(["wrong number of arguments for 'get' command", "transaction"])
+
+ cli.sendline("EXEC")
+ cli.expect("Transaction discarded because of previous errors.")
+ with pytest.raises(pexpect.exceptions.TIMEOUT):
+ cli.expect("transaction")
+
+
+def test_trasaction_in_raw_mode(clean_redis, raw_cli):
+ clean_redis.set("foo", "bar")
+
+ raw_cli.sendline("multi")
+ raw_cli.expect(["OK", "transaction", "127.0.0.1"])
+
+ raw_cli.sendline("get foo")
+ raw_cli.expect(["QUEUED", "127.0.0.1", "transaction"])
+
+ raw_cli.sendline("EXEC")
+ raw_cli.expect("bar")
+ raw_cli.expect("127.0.0.1")
+
+ with pytest.raises(pexpect.exceptions.TIMEOUT):
+ raw_cli.expect("transaction")
+
+
+def test_exec_return_nil_when_using_watch(clean_redis, cli):
+ cli.sendline("watch foo")
+ cli.expect("OK")
+
+ cli.sendline("multi")
+ cli.expect("OK")
+
+ cli.sendline("get bar")
+ cli.expect("QUEUED")
+
+ # transaction will fail, return nil
+ clean_redis.set("foo", "hello!")
+
+ cli.sendline("exec")
+ cli.expect("(nil)")
diff --git a/tests/cli_tests/test_warning.py b/tests/cli_tests/test_warning.py
new file mode 100644
index 0000000..402c51b
--- /dev/null
+++ b/tests/cli_tests/test_warning.py
@@ -0,0 +1,51 @@
+from iredis.warning import is_dangerous
+
+
+def test_is_dangerous():
+ assert is_dangerous("KEYS") == (
+ True,
+ "KEYS will hang redis server, use SCAN instead",
+ )
+
+
+def test_warning_for_dangerous_command(cli):
+ cli.sendline("config set save '900 1'")
+ cli.expect("Do you want to proceed?")
+ cli.sendline("yes")
+
+ cli.sendline("config get save")
+ cli.expect("900 1")
+
+
+def test_warnings_in_raw_mode(clean_redis, raw_cli):
+ clean_redis.set("foo", "bar")
+ raw_cli.sendline("keys *")
+ raw_cli.expect("Do you want to proceed?")
+ raw_cli.sendline("y")
+ raw_cli.expect("foo")
+
+
+def test_warnings_in_raw_mode_canceled(clean_redis, raw_cli):
+ clean_redis.set("foo", "bar")
+ raw_cli.sendline("keys *")
+ raw_cli.expect("Do you want to proceed?")
+ raw_cli.sendline("n")
+ # the f should never appeared
+ raw_cli.expect("Canceled![^f]+127.0.0.1")
+
+
+def test_warnings_confirmed(clean_redis, cli):
+ clean_redis.set("foo", "bar")
+ cli.sendline("keys *")
+ cli.expect("Do you want to proceed?")
+ cli.sendline("y")
+ cli.expect("foo")
+
+
+def test_warnings_canceled(clean_redis, cli):
+ clean_redis.set("foo", "bar")
+ cli.sendline("keys *")
+ cli.expect("Do you want to proceed?")
+ cli.sendline("n")
+ # the f should never appeared
+ cli.expect("Canceled![^f]+127.0.0.1")
diff --git a/tests/cli_tests/wrappager.py b/tests/cli_tests/wrappager.py
new file mode 100644
index 0000000..dce86ce
--- /dev/null
+++ b/tests/cli_tests/wrappager.py
@@ -0,0 +1,14 @@
+#!/usr/bin/env python
+import sys
+import fileinput
+
+
+def wrappager(boundary):
+ print(boundary)
+ for line in fileinput.input(files="-"):
+ sys.stdout.write(line)
+ print(boundary)
+
+
+if __name__ == "__main__":
+ wrappager(sys.argv[1])