diff --git a/src/Handler.cpp b/src/Handler.cpp index e6e234c..db10ddf 100644 --- a/src/Handler.cpp +++ b/src/Handler.cpp @@ -554,7 +554,6 @@ bool Handler::preHandleRequest(Request* req, const String& key) req->cmd()); res->setErr(buf); handleResponse(nullptr, req, res); - addPostEvent(c, Multiplexor::ErrorEvent); return true; } default: diff --git a/test/run.sh b/test/run.sh index 9ec4b1f..1b198c3 100755 --- a/test/run.sh +++ b/test/run.sh @@ -64,6 +64,7 @@ PUBSUB_ORDER_EXIT=0 PUBSUB_RESET_EXIT=0 NULL_RESPONSE_EXIT=0 PUBSUB_LONG_EXIT=0 +TRANSACTION_FORBID_EXIT=0 uv run python3 test/basic.py || BASIC_EXIT=$? uv run python3 test/pubsub_minimal.py -p 7617 || PUBSUB_REDIS_EXIT=$? @@ -71,9 +72,10 @@ uv run python3 test/pubsub_minimal.py -p 6379 || PUBSUB_MINIMAL_EXIT=$? uv run python3 test/pubsub.py || PUBSUB_EXIT=$? uv run python3 test/pubsub_subscription_order.py -p 7617 || PUBSUB_ORDER_EXIT=$? uv run python3 test/pubsub_parser_reset.py -p 7617 || PUBSUB_RESET_EXIT=$? +uv run python3 test/transaction_forbid.py -p 7617 || TRANSACTION_FORBID_EXIT=$? uv run python3 test/pubsub_long_name.py -p 7617 || PUBSUB_LONG_EXIT=$? uv run python3 test/null_response_handling.py -p 7617 || NULL_RESPONSE_EXIT=$? uv run python3 test/pubsub_message_response.py -p 7617 || PUBSUB_MESSAGE_EXIT=$? -TEST_EXIT=$((BASIC_EXIT + PUBSUB_REDIS_EXIT + PUBSUB_MINIMAL_EXIT + PUBSUB_EXIT + PUBSUB_MESSAGE_EXIT + PUBSUB_ORDER_EXIT + PUBSUB_RESET_EXIT + NULL_RESPONSE_EXIT + PUBSUB_LONG_EXIT)) +TEST_EXIT=$((BASIC_EXIT + PUBSUB_REDIS_EXIT + PUBSUB_MINIMAL_EXIT + PUBSUB_EXIT + PUBSUB_MESSAGE_EXIT + PUBSUB_ORDER_EXIT + PUBSUB_RESET_EXIT + NULL_RESPONSE_EXIT + PUBSUB_LONG_EXIT + TRANSACTION_FORBID_EXIT)) exit $TEST_EXIT diff --git a/test/transaction_forbid.py b/test/transaction_forbid.py new file mode 100644 index 0000000..54cd4db --- /dev/null +++ b/test/transaction_forbid.py @@ -0,0 +1,56 @@ +#!/usr/bin/env python +# +# Verify forbidden command in transaction returns error without closing connection +# + +import argparse +import sys +import redis + + +def run_test(host, port): + c = redis.StrictRedis(host=host, port=port) + try: + r = c.execute_command("MULTI") + if r not in (b"OK", "OK"): + print("FAIL: MULTI response:", r) + return False + except Exception as exc: + print("FAIL: MULTI error:", exc) + return False + + try: + c.execute_command("SELECT", "0") + print("FAIL: SELECT should be forbidden in transaction") + return False + except Exception: + pass + + try: + r = c.execute_command("PING") + if r not in (b"PONG", "PONG", True): + print("FAIL: PING after error:", r) + return False + except Exception as exc: + print("FAIL: PING after error exception:", exc) + return False + + try: + c.execute_command("DISCARD") + except Exception: + pass + + return True + + +if __name__ == "__main__": + parser = argparse.ArgumentParser(conflict_handler='resolve', description="Transaction forbid test") + parser.add_argument("-h", "--host", default="127.0.0.1") + parser.add_argument("-p", "--port", type=int, default=7617) + args = parser.parse_args() + + if run_test(args.host, args.port): + print("PASS: transaction forbid") + sys.exit(0) + print("FAIL: transaction forbid") + sys.exit(1)