From 4c3fcbc45ac804b3455f07d66401c142118158a7 Mon Sep 17 00:00:00 2001 From: ryyst Date: Sun, 5 Oct 2025 22:59:25 +0300 Subject: [PATCH] test: refactor integration tests to use daemon commands MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Update integration_test.sh to use new daemon management commands instead of manual background processes and PIDs: - Replace `kvs config.yaml &` with `kvs start config.yaml` - Replace `kill $pid` with `kvs stop config.yaml` - Update log file paths to use ~/.kvs/logs/ - Add integration_test/ directory to gitignore All tests now use clean daemon lifecycle management. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- .gitignore | 1 + integration_test.sh | 209 ++++++++++++++++++++++++++++++-------------- 2 files changed, 142 insertions(+), 68 deletions(-) diff --git a/.gitignore b/.gitignore index c935c34..fb5e89c 100644 --- a/.gitignore +++ b/.gitignore @@ -2,6 +2,7 @@ .kvs/ data/ data*/ +integration_test/ *.yaml !config.yaml kvs diff --git a/integration_test.sh b/integration_test.sh index 4bb3796..183544f 100755 --- a/integration_test.sh +++ b/integration_test.sh @@ -45,6 +45,7 @@ cleanup() { log_info "Cleaning up test environment..." pkill -f "$BINARY" 2>/dev/null || true rm -rf "$TEST_DIR" 2>/dev/null || true + rm -rf "$HOME/.kvs" 2>/dev/null || true # Clean up PID and log files from home dir sleep 2 # Allow processes to fully terminate } @@ -53,7 +54,7 @@ wait_for_service() { local port=$1 local timeout=${2:-30} local count=0 - + while [ $count -lt $timeout ]; do if curl -s "http://localhost:$port/health" >/dev/null 2>&1; then return 0 @@ -64,6 +65,15 @@ wait_for_service() { return 1 } +# Get log file path for a config file (matches daemon naming convention) +get_log_file() { + local config=$1 + local abs_path=$(realpath "$config") + local basename=$(basename "$config") + local dirname=$(basename $(dirname "$abs_path")) + echo "$HOME/.kvs/logs/${dirname}_${basename}.log" +} + # Test 1: Build verification test_build() { test_start "Binary build verification" @@ -82,7 +92,7 @@ test_build() { # Test 2: Basic functionality test_basic_functionality() { test_start "Basic functionality test" - + # Create basic config cat > basic.yaml </dev/null 2>&1 & - local pid=$! - + + # Start node using daemon command + $BINARY start basic.yaml >/dev/null 2>&1 + sleep 2 + if wait_for_service 8090; then # Test basic CRUD local put_result=$(curl -s -X PUT http://localhost:8090/kv/test/basic \ -H "Content-Type: application/json" \ -d '{"message":"hello world"}') - + local get_result=$(curl -s http://localhost:8090/kv/test/basic) - local message=$(echo "$get_result" | jq -r '.data.message' 2>/dev/null) # Adjusted jq path - + local message=$(echo "$get_result" | jq -r '.data.message' 2>/dev/null) + if [ "$message" = "hello world" ]; then log_success "Basic CRUD operations work" else @@ -116,9 +126,9 @@ EOF else log_error "Basic test node failed to start" fi - - kill $pid 2>/dev/null || true - sleep 2 + + $BINARY stop basic.yaml >/dev/null 2>&1 + sleep 1 } # Test 3: Cluster formation @@ -160,23 +170,22 @@ allow_anonymous_write: true cluster_secret: "$CLUSTER_SECRET" EOF - # Start nodes - $BINARY cluster1.yaml >/dev/null 2>&1 & - local pid1=$! - + # Start nodes using daemon commands + $BINARY start cluster1.yaml >/dev/null 2>&1 + sleep 2 + if ! wait_for_service 8101; then log_error "Cluster node 1 failed to start" - kill $pid1 2>/dev/null || true + $BINARY stop cluster1.yaml >/dev/null 2>&1 return 1 fi - - sleep 2 # Give node 1 a moment to fully initialize - $BINARY cluster2.yaml >/dev/null 2>&1 & - local pid2=$! - + + $BINARY start cluster2.yaml >/dev/null 2>&1 + sleep 2 + if ! wait_for_service 8102; then log_error "Cluster node 2 failed to start" - kill $pid1 $pid2 2>/dev/null || true + $BINARY stop cluster1.yaml cluster2.yaml >/dev/null 2>&1 return 1 fi @@ -224,9 +233,9 @@ EOF else log_error "Cluster formation failed (N1 members: $node1_members, N2 members: $node2_members)" fi - - kill $pid1 $pid2 2>/dev/null || true - sleep 2 + + $BINARY stop cluster1.yaml cluster2.yaml >/dev/null 2>&1 + sleep 1 } # Test 4: Conflict resolution (Merkle Tree based) @@ -274,16 +283,15 @@ allow_anonymous_write: true cluster_secret: "$CLUSTER_SECRET" EOF - # Start nodes + # Start nodes using daemon commands # Node 1 started first, making it "older" for tie-breaker if timestamps are equal - "$BINARY" conflict1.yaml >conflict1.log 2>&1 & - local pid1=$! - + $BINARY start conflict1.yaml >/dev/null 2>&1 + sleep 2 + if wait_for_service 8111; then + $BINARY start conflict2.yaml >/dev/null 2>&1 sleep 2 - $BINARY conflict2.yaml >conflict2.log 2>&1 & - local pid2=$! - + if wait_for_service 8112; then # Get initial data (full StoredValue) local node1_initial_full=$(curl -s http://localhost:8111/kv/test/conflict/data) @@ -344,8 +352,10 @@ EOF log_error "Resolved data has inconsistent UUID/Timestamp: N1_UUID=$node1_final_uuid, N1_TS=$node1_final_timestamp, N2_UUID=$node2_final_uuid, N2_TS=$node2_final_timestamp" fi - # Optionally, check logs for conflict resolution messages - if grep -q "Conflict resolved" conflict1.log conflict2.log 2>/dev/null; then + # Check logs for conflict resolution messages + local log1=$(get_log_file conflict1.yaml) + local log2=$(get_log_file conflict2.yaml) + if grep -q "Conflict resolved" "$log1" "$log2" 2>/dev/null; then log_success "Conflict resolution messages found in logs" else log_error "No 'Conflict resolved' messages found in logs, but data converged." @@ -357,14 +367,14 @@ EOF else log_error "Conflict node 2 failed to start" fi - - kill $pid2 2>/dev/null || true + + $BINARY stop conflict2.yaml >/dev/null 2>&1 else log_error "Conflict node 1 failed to start" fi - - kill $pid1 2>/dev/null || true - sleep 2 + + $BINARY stop conflict1.yaml >/dev/null 2>&1 + sleep 1 else cd "$TEST_DIR" log_error "Failed to create conflict test data. Ensure test_conflict.go is correct." @@ -388,22 +398,21 @@ allow_anonymous_read: false allow_anonymous_write: false EOF - # Start node - $BINARY auth_test.yaml >auth_test.log 2>&1 & - local pid=$! - + # Start node using daemon command + $BINARY start auth_test.yaml >/dev/null 2>&1 + sleep 3 # Allow daemon to start and root account creation + if wait_for_service 8095; then - sleep 2 # Allow root account creation - # Extract the token from logs - local token=$(grep "Token:" auth_test.log | sed 's/.*Token: //' | tr -d '\n\r') - + local log_file=$(get_log_file auth_test.yaml) + local token=$(grep "Token:" "$log_file" | sed 's/.*Token: //' | tr -d '\n\r') + if [ -z "$token" ]; then log_error "Failed to extract authentication token from logs" - kill $pid 2>/dev/null || true + $BINARY stop auth_test.yaml >/dev/null 2>&1 return fi - + # Test 1: Admin endpoints should fail without authentication local no_auth_response=$(curl -s -X POST http://localhost:8095/api/users -H "Content-Type: application/json" -d '{"nickname":"test","password":"test"}') if echo "$no_auth_response" | grep -q "Unauthorized"; then @@ -411,7 +420,7 @@ EOF else log_error "Admin endpoints should reject unauthenticated requests, got: $no_auth_response" fi - + # Test 2: Admin endpoints should work with valid authentication local auth_response=$(curl -s -X POST http://localhost:8095/api/users -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d '{"nickname":"authtest","password":"authtest"}') if echo "$auth_response" | grep -q "uuid"; then @@ -419,7 +428,7 @@ EOF else log_error "Admin endpoints should work with authentication, got: $auth_response" fi - + # Test 3: KV endpoints should require auth when anonymous access is disabled local kv_no_auth=$(curl -s -X PUT http://localhost:8095/kv/test/auth -H "Content-Type: application/json" -d '{"test":"auth"}') if echo "$kv_no_auth" | grep -q "Unauthorized"; then @@ -427,7 +436,7 @@ EOF else log_error "KV endpoints should require auth when anonymous access disabled, got: $kv_no_auth" fi - + # Test 4: KV endpoints should work with valid authentication local kv_auth=$(curl -s -X PUT http://localhost:8095/kv/test/auth -H "Content-Type: application/json" -H "Authorization: Bearer $token" -d '{"test":"auth"}') if echo "$kv_auth" | grep -q "uuid\|timestamp" || [ -z "$kv_auth" ]; then @@ -435,12 +444,12 @@ EOF else log_error "KV endpoints should work with authentication, got: $kv_auth" fi - - kill $pid 2>/dev/null || true - sleep 2 + + $BINARY stop auth_test.yaml >/dev/null 2>&1 + sleep 1 else log_error "Auth test node failed to start" - kill $pid 2>/dev/null || true + $BINARY stop auth_test.yaml >/dev/null 2>&1 fi } @@ -461,19 +470,18 @@ allow_anonymous_read: false allow_anonymous_write: false EOF - # Start node - $BINARY metadata_test.yaml >metadata_test.log 2>&1 & - local pid=$! + # Start node using daemon command + $BINARY start metadata_test.yaml >/dev/null 2>&1 + sleep 3 # Allow daemon to start and root account creation if wait_for_service 8096; then - sleep 2 # Allow root account creation - # Extract the token from logs - local token=$(grep "Token:" metadata_test.log | sed 's/.*Token: //' | tr -d '\n\r') + local log_file=$(get_log_file metadata_test.yaml) + local token=$(grep "Token:" "$log_file" | sed 's/.*Token: //' | tr -d '\n\r') if [ -z "$token" ]; then log_error "Failed to extract authentication token from logs" - kill $pid 2>/dev/null || true + $BINARY stop metadata_test.yaml >/dev/null 2>&1 return fi @@ -525,14 +533,78 @@ EOF log_error "Metadata endpoints should require authentication, got code: $no_auth_code" fi - kill $pid 2>/dev/null || true - sleep 2 + $BINARY stop metadata_test.yaml >/dev/null 2>&1 + sleep 1 else log_error "Metadata test node failed to start" - kill $pid 2>/dev/null || true + $BINARY stop metadata_test.yaml >/dev/null 2>&1 fi } +# Test 7: Daemon commands (start, stop, status, restart) +test_daemon_commands() { + test_start "Daemon command tests (start, stop, status, restart)" + + # Create daemon test config + cat > daemon_test.yaml </dev/null 2>&1 + sleep 3 # Allow daemon to start + + if wait_for_service 8097 5; then + log_success "Daemon 'start' command works" + + # Test 2: Status command shows running + local status_output=$($BINARY status daemon_test.yaml 2>&1) + if echo "$status_output" | grep -q "RUNNING"; then + log_success "Daemon 'status' command shows RUNNING" + else + log_error "Daemon 'status' should show RUNNING, got: $status_output" + fi + + # Test 3: Stop command + $BINARY stop daemon_test.yaml >/dev/null 2>&1 + sleep 2 + + # Check that service is actually stopped + if ! curl -s "http://localhost:8097/health" >/dev/null 2>&1; then + log_success "Daemon 'stop' command works" + else + log_error "Daemon should be stopped but is still responding" + fi + + # Test 4: Restart command + $BINARY restart daemon_test.yaml >/dev/null 2>&1 + sleep 3 + + if wait_for_service 8097 5; then + log_success "Daemon 'restart' command works" + + # Clean up + $BINARY stop daemon_test.yaml >/dev/null 2>&1 + sleep 1 + else + log_error "Daemon 'restart' failed to start service" + fi + else + log_error "Daemon 'start' command failed" + fi + + # Ensure cleanup + pkill -f "daemon_test.yaml" 2>/dev/null || true + sleep 1 +} + # Main test execution main() { echo "==================================================" @@ -552,6 +624,7 @@ main() { test_conflict_resolution test_authentication_middleware test_metadata_management + test_daemon_commands # Results echo "=================================================="