mirror of
https://github.com/joyieldInc/predixy.git
synced 2026-02-05 01:42:24 +08:00
Update tests for Redis parity
This commit is contained in:
parent
28e20dfe80
commit
9c974494a7
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# predixy - A high performance and full features proxy for redis.
|
||||
# Copyright (C) 2017 Joyield, Inc. <joyield.com@gmail.com>
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Verify EVAL/EVALSHA rejects multi-key cross-shard scripts
|
||||
#
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Verify MGET returns WRONGTYPE for non-string keys
|
||||
#
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Verify MSETNX does not partially apply changes when it returns 0
|
||||
#
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Exercise server write mismatch handling to ensure proxy stays alive
|
||||
#
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# predixy - A high performance and full features proxy for redis.
|
||||
# Copyright (C) 2017 Joyield, Inc. <joyield.com@gmail.com>
|
||||
@ -105,7 +105,7 @@ def test():
|
||||
for stat in stats:
|
||||
if not run(stat):
|
||||
succ = False
|
||||
time.sleep(0.2)
|
||||
time.sleep(0.01)
|
||||
print('---------------------------------')
|
||||
if succ:
|
||||
print('Good! PubSub test pass')
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Verify subscribe/psubscribe confirmation with long channel/pattern names
|
||||
#
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Verify pubsub message responses include message data
|
||||
#
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Minimal test to reproduce pubsub message queueing issue in Predixy
|
||||
# Tests pass against Redis (6379) but fail against Predixy (7617)
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Verify pubsub parser state does not reuse old messages
|
||||
#
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Verify subscription confirmations arrive before messages
|
||||
#
|
||||
|
||||
157
test/run.sh
157
test/run.sh
@ -1,6 +1,6 @@
|
||||
#!/bin/bash
|
||||
# Run predixy tests
|
||||
# Starts predixy, runs tests, and stops predixy when done
|
||||
# Starts fresh Redis and Predixy instances, runs tests, and stops them when done
|
||||
|
||||
# Get the directory where this script is located
|
||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||
@ -22,17 +22,84 @@ if [ ! -f "$PREDIXY_BIN" ]; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Start predixy in the background
|
||||
echo "Starting predixy..."
|
||||
PREDIXY_PID=$("$PREDIXY_BIN" "$CONFIG_FILE" > /dev/null 2>&1 & echo $!)
|
||||
# Check if redis-server is available
|
||||
if ! command -v redis-server &> /dev/null; then
|
||||
echo "Error: 'redis-server' command not found"
|
||||
echo "Please install Redis"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Set up trap to ensure predixy is stopped on exit
|
||||
trap "echo 'Stopping predixy...'; kill $PREDIXY_PID 2>/dev/null || true; wait $PREDIXY_PID 2>/dev/null || true" EXIT INT TERM
|
||||
|
||||
# Wait for predixy to start (check if port is listening)
|
||||
PREDIXY_PORT=7617
|
||||
# Use fixed ports for test instances
|
||||
TEST_REDIS_PORT=6380
|
||||
TEST_PREDIXY_PORT=7618
|
||||
TIMEOUT=10 # seconds
|
||||
echo "Waiting for predixy to start on port $PREDIXY_PORT..."
|
||||
|
||||
# Create temporary directory for test configs
|
||||
TMP_DIR=$(mktemp -d)
|
||||
trap "rm -rf '$TMP_DIR'" EXIT INT TERM
|
||||
|
||||
# Cleanup function
|
||||
cleanup() {
|
||||
echo "Cleaning up test instances..."
|
||||
if [ -n "$REDIS_PID" ]; then
|
||||
kill $REDIS_PID 2>/dev/null || true
|
||||
wait $REDIS_PID 2>/dev/null || true
|
||||
fi
|
||||
if [ -n "$PREDIXY_PID" ]; then
|
||||
kill $PREDIXY_PID 2>/dev/null || true
|
||||
wait $PREDIXY_PID 2>/dev/null || true
|
||||
fi
|
||||
rm -rf "$TMP_DIR"
|
||||
}
|
||||
|
||||
# Set up trap to ensure cleanup on exit
|
||||
trap cleanup EXIT INT TERM
|
||||
|
||||
# Start fresh Redis instance
|
||||
echo "Starting fresh Redis on port $TEST_REDIS_PORT..."
|
||||
REDIS_PID=$(redis-server --port $TEST_REDIS_PORT --save "" --appendonly no > /dev/null 2>&1 & echo $!)
|
||||
if [ -z "$REDIS_PID" ] || ! kill -0 $REDIS_PID 2>/dev/null; then
|
||||
echo "Error: Failed to start Redis"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Wait for Redis to be ready
|
||||
echo "Waiting for Redis to start on port $TEST_REDIS_PORT..."
|
||||
if ! uv run python3 "$SCRIPT_DIR/wait_for_port.py" localhost $TEST_REDIS_PORT $TIMEOUT; then
|
||||
echo "Error: Redis failed to start"
|
||||
exit 1
|
||||
fi
|
||||
echo "Redis is ready"
|
||||
|
||||
# Create temporary Predixy config pointing to test Redis
|
||||
TEST_PREDIXY_CONFIG="$TMP_DIR/predixy_test.conf"
|
||||
cat > "$TEST_PREDIXY_CONFIG" <<EOF
|
||||
Name PredixyTest
|
||||
Bind 0.0.0.0:$TEST_PREDIXY_PORT
|
||||
WorkerThreads 1
|
||||
ClientTimeout 300
|
||||
LogVerbSample 0
|
||||
LogDebugSample 0
|
||||
LogInfoSample 10000
|
||||
LogNoticeSample 1
|
||||
LogWarnSample 1
|
||||
LogErrorSample 1
|
||||
|
||||
Include $PROJECT_ROOT/conf/auth.conf
|
||||
|
||||
StandaloneServerPool {
|
||||
RefreshMethod fixed
|
||||
Group test {
|
||||
+ 127.0.0.1:$TEST_REDIS_PORT
|
||||
}
|
||||
}
|
||||
|
||||
Include $PROJECT_ROOT/conf/latency.conf
|
||||
EOF
|
||||
|
||||
# Start fresh Predixy instance
|
||||
echo "Starting fresh Predixy on port $TEST_PREDIXY_PORT..."
|
||||
PREDIXY_PID=$("$PREDIXY_BIN" "$TEST_PREDIXY_CONFIG" > /dev/null 2>&1 & echo $!)
|
||||
|
||||
# Check if process died before waiting for port
|
||||
if ! kill -0 $PREDIXY_PID 2>/dev/null; then
|
||||
@ -40,48 +107,56 @@ if ! kill -0 $PREDIXY_PID 2>/dev/null; then
|
||||
exit 1
|
||||
fi
|
||||
|
||||
# Wait for port to become available
|
||||
if uv run python3 "$SCRIPT_DIR/wait_for_port.py" localhost $PREDIXY_PORT $TIMEOUT; then
|
||||
echo "predixy is ready"
|
||||
else
|
||||
# Wait for Predixy to start
|
||||
echo "Waiting for Predixy to start on port $TEST_PREDIXY_PORT..."
|
||||
if ! uv run python3 "$SCRIPT_DIR/wait_for_port.py" localhost $TEST_PREDIXY_PORT $TIMEOUT; then
|
||||
# Check if process died during wait
|
||||
if ! kill -0 $PREDIXY_PID 2>/dev/null; then
|
||||
echo "Error: predixy process died"
|
||||
fi
|
||||
exit 1
|
||||
fi
|
||||
echo "Predixy is ready"
|
||||
|
||||
# Run tests
|
||||
echo "Running tests..."
|
||||
cd "$PROJECT_ROOT"
|
||||
|
||||
BASIC_EXIT=0
|
||||
PUBSUB_REDIS_EXIT=0
|
||||
PUBSUB_MINIMAL_EXIT=0
|
||||
PUBSUB_EXIT=0
|
||||
PUBSUB_MESSAGE_EXIT=0
|
||||
PUBSUB_ORDER_EXIT=0
|
||||
PUBSUB_RESET_EXIT=0
|
||||
NULL_RESPONSE_EXIT=0
|
||||
PUBSUB_LONG_EXIT=0
|
||||
TRANSACTION_FORBID_EXIT=0
|
||||
MGET_WRONG_TYPE_EXIT=0
|
||||
MSETNX_ATOMICITY_EXIT=0
|
||||
EVAL_CROSS_SHARD_EXIT=0
|
||||
TEST_EXIT=0
|
||||
|
||||
uv run python3 test/basic.py || BASIC_EXIT=$?
|
||||
uv run python3 test/pubsub_minimal.py -p 7617 || PUBSUB_REDIS_EXIT=$?
|
||||
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_message_response.py -p 7617 || PUBSUB_MESSAGE_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/null_response_handling.py -p 7617 || NULL_RESPONSE_EXIT=$?
|
||||
uv run python3 test/pubsub_long_name.py -p 7617 || PUBSUB_LONG_EXIT=$?
|
||||
uv run python3 test/transaction_forbid.py -p 7617 || TRANSACTION_FORBID_EXIT=$?
|
||||
uv run python3 test/mget_wrong_type.py -p 7617 || MGET_WRONG_TYPE_EXIT=$?
|
||||
uv run python3 test/msetnx_atomicity.py -p 7617 || MSETNX_ATOMICITY_EXIT=$?
|
||||
uv run python3 test/eval_cross_shard.py -p 7617 || EVAL_CROSS_SHARD_EXIT=$?
|
||||
run_test() {
|
||||
local test_file=$1
|
||||
shift
|
||||
local port=$1
|
||||
shift
|
||||
uv run python3 "$test_file" -p "$port" "$@" || TEST_EXIT=$((TEST_EXIT + $?))
|
||||
}
|
||||
|
||||
TESTS=(
|
||||
"test/basic.py"
|
||||
"test/pubsub_minimal.py"
|
||||
"test/pubsub.py"
|
||||
"test/pubsub_message_response.py"
|
||||
"test/pubsub_subscription_order.py"
|
||||
"test/pubsub_parser_reset.py"
|
||||
"test/null_response_handling.py"
|
||||
"test/pubsub_long_name.py"
|
||||
"test/transaction_forbid.py"
|
||||
"test/mget_wrong_type.py"
|
||||
"test/msetnx_atomicity.py"
|
||||
"test/eval_cross_shard.py"
|
||||
)
|
||||
|
||||
run_tests_for_port() {
|
||||
local port=$1
|
||||
shift
|
||||
echo "Running tests against port $port..."
|
||||
for test_file in "${TESTS[@]}"; do
|
||||
run_test "$test_file" "$port"
|
||||
done
|
||||
}
|
||||
|
||||
run_tests_for_port $TEST_REDIS_PORT
|
||||
run_tests_for_port $TEST_PREDIXY_PORT
|
||||
|
||||
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 + MGET_WRONG_TYPE_EXIT + MSETNX_ATOMICITY_EXIT + EVAL_CROSS_SHARD_EXIT))
|
||||
exit $TEST_EXIT
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
#!/usr/bin/env python
|
||||
#!/usr/bin/env python3
|
||||
#
|
||||
# Verify forbidden command in transaction returns error without closing connection
|
||||
#
|
||||
@ -20,19 +20,21 @@ def run_test(host, port):
|
||||
return False
|
||||
|
||||
try:
|
||||
c.execute_command("SELECT", "0")
|
||||
print("FAIL: SELECT should be forbidden in transaction")
|
||||
r = c.execute_command("SELECT", "0")
|
||||
if r not in (b"QUEUED", "QUEUED", False):
|
||||
print("FAIL: SELECT should be queued in transaction:", r)
|
||||
return False
|
||||
except Exception as exc:
|
||||
print("FAIL: SELECT should be queued in transaction, got exception:", exc)
|
||||
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)
|
||||
if r not in (b"QUEUED", "QUEUED", False):
|
||||
print("FAIL: PING should be queued in transaction:", r)
|
||||
return False
|
||||
except Exception as exc:
|
||||
print("FAIL: PING after error exception:", exc)
|
||||
print("FAIL: PING should be queued in transaction exception:", exc)
|
||||
return False
|
||||
|
||||
try:
|
||||
|
||||
Loading…
Reference in New Issue
Block a user