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.
|
# predixy - A high performance and full features proxy for redis.
|
||||||
# Copyright (C) 2017 Joyield, Inc. <joyield.com@gmail.com>
|
# 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
|
# 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
|
# 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
|
# 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
|
# 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.
|
# predixy - A high performance and full features proxy for redis.
|
||||||
# Copyright (C) 2017 Joyield, Inc. <joyield.com@gmail.com>
|
# Copyright (C) 2017 Joyield, Inc. <joyield.com@gmail.com>
|
||||||
@ -105,7 +105,7 @@ def test():
|
|||||||
for stat in stats:
|
for stat in stats:
|
||||||
if not run(stat):
|
if not run(stat):
|
||||||
succ = False
|
succ = False
|
||||||
time.sleep(0.2)
|
time.sleep(0.01)
|
||||||
print('---------------------------------')
|
print('---------------------------------')
|
||||||
if succ:
|
if succ:
|
||||||
print('Good! PubSub test pass')
|
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
|
# 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
|
# 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
|
# Minimal test to reproduce pubsub message queueing issue in Predixy
|
||||||
# Tests pass against Redis (6379) but fail against Predixy (7617)
|
# 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
|
# 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
|
# Verify subscription confirmations arrive before messages
|
||||||
#
|
#
|
||||||
|
|||||||
157
test/run.sh
157
test/run.sh
@ -1,6 +1,6 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# Run predixy tests
|
# 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
|
# Get the directory where this script is located
|
||||||
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
@ -22,17 +22,84 @@ if [ ! -f "$PREDIXY_BIN" ]; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Start predixy in the background
|
# Check if redis-server is available
|
||||||
echo "Starting predixy..."
|
if ! command -v redis-server &> /dev/null; then
|
||||||
PREDIXY_PID=$("$PREDIXY_BIN" "$CONFIG_FILE" > /dev/null 2>&1 & echo $!)
|
echo "Error: 'redis-server' command not found"
|
||||||
|
echo "Please install Redis"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
|
||||||
# Set up trap to ensure predixy is stopped on exit
|
# Use fixed ports for test instances
|
||||||
trap "echo 'Stopping predixy...'; kill $PREDIXY_PID 2>/dev/null || true; wait $PREDIXY_PID 2>/dev/null || true" EXIT INT TERM
|
TEST_REDIS_PORT=6380
|
||||||
|
TEST_PREDIXY_PORT=7618
|
||||||
# Wait for predixy to start (check if port is listening)
|
|
||||||
PREDIXY_PORT=7617
|
|
||||||
TIMEOUT=10 # seconds
|
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
|
# Check if process died before waiting for port
|
||||||
if ! kill -0 $PREDIXY_PID 2>/dev/null; then
|
if ! kill -0 $PREDIXY_PID 2>/dev/null; then
|
||||||
@ -40,48 +107,56 @@ if ! kill -0 $PREDIXY_PID 2>/dev/null; then
|
|||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
|
||||||
# Wait for port to become available
|
# Wait for Predixy to start
|
||||||
if uv run python3 "$SCRIPT_DIR/wait_for_port.py" localhost $PREDIXY_PORT $TIMEOUT; then
|
echo "Waiting for Predixy to start on port $TEST_PREDIXY_PORT..."
|
||||||
echo "predixy is ready"
|
if ! uv run python3 "$SCRIPT_DIR/wait_for_port.py" localhost $TEST_PREDIXY_PORT $TIMEOUT; then
|
||||||
else
|
|
||||||
# Check if process died during wait
|
# Check if process died during wait
|
||||||
if ! kill -0 $PREDIXY_PID 2>/dev/null; then
|
if ! kill -0 $PREDIXY_PID 2>/dev/null; then
|
||||||
echo "Error: predixy process died"
|
echo "Error: predixy process died"
|
||||||
fi
|
fi
|
||||||
exit 1
|
exit 1
|
||||||
fi
|
fi
|
||||||
|
echo "Predixy is ready"
|
||||||
|
|
||||||
# Run tests
|
# Run tests
|
||||||
echo "Running tests..."
|
echo "Running tests..."
|
||||||
cd "$PROJECT_ROOT"
|
cd "$PROJECT_ROOT"
|
||||||
|
|
||||||
BASIC_EXIT=0
|
TEST_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
|
|
||||||
|
|
||||||
uv run python3 test/basic.py || BASIC_EXIT=$?
|
run_test() {
|
||||||
uv run python3 test/pubsub_minimal.py -p 7617 || PUBSUB_REDIS_EXIT=$?
|
local test_file=$1
|
||||||
uv run python3 test/pubsub_minimal.py -p 6379 || PUBSUB_MINIMAL_EXIT=$?
|
shift
|
||||||
uv run python3 test/pubsub.py || PUBSUB_EXIT=$?
|
local port=$1
|
||||||
uv run python3 test/pubsub_message_response.py -p 7617 || PUBSUB_MESSAGE_EXIT=$?
|
shift
|
||||||
uv run python3 test/pubsub_subscription_order.py -p 7617 || PUBSUB_ORDER_EXIT=$?
|
uv run python3 "$test_file" -p "$port" "$@" || TEST_EXIT=$((TEST_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=$?
|
TESTS=(
|
||||||
uv run python3 test/transaction_forbid.py -p 7617 || TRANSACTION_FORBID_EXIT=$?
|
"test/basic.py"
|
||||||
uv run python3 test/mget_wrong_type.py -p 7617 || MGET_WRONG_TYPE_EXIT=$?
|
"test/pubsub_minimal.py"
|
||||||
uv run python3 test/msetnx_atomicity.py -p 7617 || MSETNX_ATOMICITY_EXIT=$?
|
"test/pubsub.py"
|
||||||
uv run python3 test/eval_cross_shard.py -p 7617 || EVAL_CROSS_SHARD_EXIT=$?
|
"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
|
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
|
# Verify forbidden command in transaction returns error without closing connection
|
||||||
#
|
#
|
||||||
@ -20,19 +20,21 @@ def run_test(host, port):
|
|||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
c.execute_command("SELECT", "0")
|
r = c.execute_command("SELECT", "0")
|
||||||
print("FAIL: SELECT should be forbidden in transaction")
|
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
|
return False
|
||||||
except Exception:
|
|
||||||
pass
|
|
||||||
|
|
||||||
try:
|
try:
|
||||||
r = c.execute_command("PING")
|
r = c.execute_command("PING")
|
||||||
if r not in (b"PONG", "PONG", True):
|
if r not in (b"QUEUED", "QUEUED", False):
|
||||||
print("FAIL: PING after error:", r)
|
print("FAIL: PING should be queued in transaction:", r)
|
||||||
return False
|
return False
|
||||||
except Exception as exc:
|
except Exception as exc:
|
||||||
print("FAIL: PING after error exception:", exc)
|
print("FAIL: PING should be queued in transaction exception:", exc)
|
||||||
return False
|
return False
|
||||||
|
|
||||||
try:
|
try:
|
||||||
|
|||||||
Loading…
Reference in New Issue
Block a user