Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
22 changes: 20 additions & 2 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
Expand Up @@ -271,8 +271,26 @@ jobs:
if: always()
run: docker compose -f misc/supabase/docker-compose.yml down -v

regtest-itest:
name: "Integration regtest tests"
# Tests that require a running Redis cluster
redis-tests:
name: "Redis Cache Tests"
runs-on: self-hosted
timeout-minutes: 30
needs: pre-commit-checks
steps:
- name: checkout
uses: actions/checkout@v5
- uses: cachix/cachix-action@v17
with:
name: cashudevkit
authToken: ${{ secrets.CACHIX_AUTH_TOKEN }}
useDaemon: false
continue-on-error: true
- name: Run clippy and tests for Redis cache
run: nix develop -i -L .#regtest --command just test-redis

regtest-ln-itest:
name: "Integration regtest LN tests"
runs-on: self-hosted
timeout-minutes: 30
needs: [pre-commit-checks, build-itest-binaries]
Expand Down
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,8 @@ static-bin/
.aider*
**/postgres_data/
.pg_data/
.redis_cluster/
.redis_single/
**/.env
logs/
tor-data
Expand Down
174 changes: 172 additions & 2 deletions flake.nix
Original file line number Diff line number Diff line change
Expand Up @@ -848,6 +848,13 @@
pgStatus
pgConnect

# Redis
redis
startRedisSingle
stopRedisSingle
startRedisCluster
stopRedisCluster

# Needed for github ci
libz
]
Expand Down Expand Up @@ -902,6 +909,20 @@
echo "" >&2
'';

redisShellHook = ''
# Redis environment variables (single-node defaults)
export CDK_MINTD_CACHE_REDIS_URL="redis://127.0.0.1:6379"
export CDK_MINTD_CACHE_REDIS_CLUSTER_NODES="redis://127.0.0.1:7001,redis://127.0.0.1:7002,redis://127.0.0.1:7003"

echo "" >&2
echo "Redis commands available:" >&2
echo " start-redis-single - Start a single-node Redis on port 6379" >&2
echo " stop-redis-single - Stop the single-node Redis" >&2
echo " start-redis-cluster - Start a 3-node Redis cluster on ports 7001-7003" >&2
echo " stop-redis-cluster - Stop the Redis cluster" >&2
echo "" >&2
'';

# PostgreSQL configuration
postgresConf = {
pgUser = "cdk_user";
Expand Down Expand Up @@ -978,6 +999,155 @@
${pkgs.postgresql_16}/bin/psql "postgresql://${postgresConf.pgUser}:${postgresConf.pgPassword}@localhost:${postgresConf.pgPort}/${postgresConf.pgDatabase}"
'';

# Script to start a 3-node Redis cluster (ports 7001-7003)
startRedisCluster = pkgs.writeShellScriptBin "start-redis-cluster" ''
set -e
REDIS_DIR="$PWD/.redis_cluster"
mkdir -p "$REDIS_DIR"

_start_node() {
local port=$1
local pidfile="$REDIS_DIR/redis-$port.pid"

# Skip if already running
_pid=""
[ -f "$pidfile" ] && _pid=$(cat "$pidfile" 2>/dev/null || true)
if [ -n "$_pid" ] && kill -0 "$_pid" 2>/dev/null; then
echo "Redis node on port $port already running (pid $_pid)"
return
fi

${pkgs.redis}/bin/redis-server \
--port $port \
--cluster-enabled yes \
--cluster-config-file "$REDIS_DIR/nodes-$port.conf" \
--cluster-node-timeout 5000 \
--cluster-announce-ip 127.0.0.1 \
--appendonly no \
--save "" \
--daemonize yes \
--logfile "$REDIS_DIR/redis-$port.log" \
--pidfile "$pidfile"

echo "Started Redis node on port $port"
}

echo "Starting Redis cluster nodes..."
_start_node 7001
_start_node 7002
_start_node 7003

# Wait for all nodes to be ready
echo "Waiting for nodes to be ready..."
for port in 7001 7002 7003; do
ready=0
for i in $(seq 1 20); do
if ${pkgs.redis}/bin/redis-cli -p $port ping 2>/dev/null | grep -q PONG; then
ready=1
break
fi
sleep 0.5
done
if [ "$ready" -eq 0 ]; then
echo "ERROR: Redis node on port $port failed to start within 10 seconds" >&2
exit 1
fi
done

# Create the cluster if not already formed
CLUSTER_STATE=$(${pkgs.redis}/bin/redis-cli -p 7001 cluster info 2>/dev/null | grep cluster_state | cut -d: -f2 | tr -d '[:space:]')
if [ "$CLUSTER_STATE" = "ok" ]; then
echo "Redis cluster already initialized"
else
echo "Forming Redis cluster..."
${pkgs.redis}/bin/redis-cli --cluster create \
127.0.0.1:7001 127.0.0.1:7002 127.0.0.1:7003 \
--cluster-replicas 0 --cluster-yes
fi

echo "Redis cluster ready. Nodes: redis://127.0.0.1:7001, redis://127.0.0.1:7002, redis://127.0.0.1:7003"
'';

# Script to stop the Redis cluster
stopRedisCluster = pkgs.writeShellScriptBin "stop-redis-cluster" ''
REDIS_DIR="$PWD/.redis_cluster"
for port in 7001 7002 7003; do
pidfile="$REDIS_DIR/redis-$port.pid"
if [ -f "$pidfile" ]; then
pid=$(cat "$pidfile")
if kill -0 "$pid" 2>/dev/null; then
echo "Stopping Redis node on port $port (pid $pid)..."
kill "$pid"
else
echo "Redis node on port $port not running (stale pid file)"
fi
rm -f "$pidfile"
else
echo "No pid file for Redis node on port $port"
fi
done
echo "Redis cluster stopped."
'';

# Script to start a single-node Redis (port 6379)
startRedisSingle = pkgs.writeShellScriptBin "start-redis-single" ''
set -e
REDIS_DIR="$PWD/.redis_single"
mkdir -p "$REDIS_DIR"
PIDFILE="$REDIS_DIR/redis-6379.pid"

# Skip if already running
_pid=""
[ -f "$PIDFILE" ] && _pid=$(cat "$PIDFILE" 2>/dev/null || true)
if [ -n "$_pid" ] && kill -0 "$_pid" 2>/dev/null; then
echo "Single-node Redis already running (pid $_pid)"
exit 0
fi

${pkgs.redis}/bin/redis-server \
--port 6379 \
--appendonly no \
--save "" \
--daemonize yes \
--logfile "$REDIS_DIR/redis-6379.log" \
--pidfile "$PIDFILE"

# Wait for the node to be ready
ready=0
for i in $(seq 1 20); do
if ${pkgs.redis}/bin/redis-cli -p 6379 ping 2>/dev/null | grep -q PONG; then
ready=1
break
fi
sleep 0.5
done
if [ "$ready" -eq 0 ]; then
echo "ERROR: Single-node Redis failed to start within 10 seconds" >&2
exit 1
fi

echo "Single-node Redis ready at redis://127.0.0.1:6379"
'';

# Script to stop the single-node Redis
stopRedisSingle = pkgs.writeShellScriptBin "stop-redis-single" ''
REDIS_DIR="$PWD/.redis_single"
PIDFILE="$REDIS_DIR/redis-6379.pid"
if [ -f "$PIDFILE" ]; then
pid=$(cat "$PIDFILE")
if kill -0 "$pid" 2>/dev/null; then
echo "Stopping single-node Redis (pid $pid)..."
kill "$pid"
else
echo "Single-node Redis not running (stale pid file)"
fi
rm -f "$PIDFILE"
else
echo "No pid file for single-node Redis"
fi
echo "Single-node Redis stopped."
'';

# Helper to build a statically-linked binary package (Linux only)
# bin: the cargo binary name (e.g. "cdk-mintd")
# name: the output binary name prefix (e.g. "cdk-mintd-ldk")
Expand Down Expand Up @@ -1315,7 +1485,7 @@

stable = pkgs.mkShell (
{
shellHook = commonShellHook + pgShellHook;
shellHook = commonShellHook + pgShellHook + redisShellHook;
buildInputs = baseBuildInputs ++ [
stable_toolchain
];
Expand All @@ -1327,7 +1497,7 @@

regtest = pkgs.mkShell (
{
shellHook = commonShellHook + pgShellHook;
shellHook = commonShellHook + pgShellHook + redisShellHook;
buildInputs =
baseBuildInputs
++ regtestBuildInputs
Expand Down
34 changes: 34 additions & 0 deletions justfile
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,40 @@ test-pure db="memory":
CDK_TEST_DB_TYPE={{db}} cargo test -p cdk-integration-tests --test wallet_saga -- --test-threads 1
fi

# Run Redis cache clippy and unit tests against both single-node and cluster Redis.
# Starts a single-node Redis (port 6379) and a 3-node cluster (ports 7001-7003)
# using Nix-managed scripts, mirrors both code paths in cdk-axum cache.
test-redis:
#!/usr/bin/env bash
set -euo pipefail
if [ ! -f Cargo.toml ]; then
cd {{invocation_directory()}}
fi

# Start both Redis topologies and stop them on exit
trap 'stop-redis-single; stop-redis-cluster' EXIT
start-redis-single
Comment thread
GEET3001 marked this conversation as resolved.
start-redis-cluster

# ── single-node path (use_cluster=false) ──────────────────────────────────
echo "=== Testing single-node Redis (CDK_MINTD_CACHE_REDIS_USE_CLUSTER=false) ==="
CDK_MINTD_CACHE_BACKEND=redis \
CDK_MINTD_CACHE_REDIS_USE_CLUSTER=false \
CDK_MINTD_CACHE_REDIS_URL=redis://127.0.0.1:6379 \
cargo clippy -p cdk-axum --features redis -- -D warnings
CDK_MINTD_CACHE_BACKEND=redis \
CDK_MINTD_CACHE_REDIS_USE_CLUSTER=false \
CDK_MINTD_CACHE_REDIS_URL=redis://127.0.0.1:6379 \
cargo test -p cdk-axum --features redis --lib

# ── cluster path (use_cluster=true) ───────────────────────────────────────
echo "=== Testing cluster Redis (CDK_MINTD_CACHE_REDIS_USE_CLUSTER=true) ==="
CDK_MINTD_CACHE_BACKEND=redis \
CDK_MINTD_CACHE_REDIS_USE_CLUSTER=true \
CDK_MINTD_CACHE_REDIS_CLUSTER_NODES=redis://127.0.0.1:7001,redis://127.0.0.1:7002,redis://127.0.0.1:7003 \
cargo test -p cdk-axum --features redis --lib


# Mutation Testing Commands

# Run mutation tests on a specific crate
Expand Down