#!/bin/bash # # test-correlation.sh - Test script for log correlation debugging # # This script sends test HTTP (A) and Network (B) events to the logcorrelator # Unix sockets and verifies that correlation is working correctly. # # Usage: # ./test-correlation.sh [options] # # Options: # -h, --http-socket PATH Path to HTTP socket (default: /var/run/logcorrelator/http.socket) # -n, --network-socket PATH Path to Network socket (default: /var/run/logcorrelator/network.socket) # -c, --count NUM Number of test pairs to send (default: 10) # -d, --delay MS Delay between pairs in milliseconds (default: 100) # -v, --verbose Enable verbose output # -m, --metrics-url URL Metrics server URL (default: http://localhost:8080/metrics) # --skip-metrics Skip metrics check # --help Show this help message # set -e # Default values HTTP_SOCKET="/var/run/logcorrelator/http.socket" NETWORK_SOCKET="/var/run/logcorrelator/network.socket" COUNT=10 DELAY_MS=100 VERBOSE=false METRICS_URL="http://localhost:8080/metrics" SKIP_METRICS=false # Colors for output RED='\033[0;31m' GREEN='\033[0;32m' YELLOW='\033[1;33m' BLUE='\033[0;34m' NC='\033[0m' # No Color # Print functions info() { echo -e "${BLUE}[INFO]${NC} $1" } success() { echo -e "${GREEN}[OK]${NC} $1" } warn() { echo -e "${YELLOW}[WARN]${NC} $1" } error() { echo -e "${RED}[ERROR]${NC} $1" } verbose() { if [ "$VERBOSE" = true ]; then echo -e "${BLUE}[DEBUG]${NC} $1" fi } # Show help show_help() { head -20 "$0" | tail -17 | sed 's/^#//' | sed 's/^ //' exit 0 } # Parse arguments while [[ $# -gt 0 ]]; do case $1 in -h|--http-socket) HTTP_SOCKET="$2" shift 2 ;; -n|--network-socket) NETWORK_SOCKET="$2" shift 2 ;; -c|--count) COUNT="$2" shift 2 ;; -d|--delay) DELAY_MS="$2" shift 2 ;; -v|--verbose) VERBOSE=true shift ;; -m|--metrics-url) METRICS_URL="$2" shift 2 ;; --skip-metrics) SKIP_METRICS=true shift ;; --help) show_help ;; *) error "Unknown option: $1" echo "Use --help for usage information" exit 1 ;; esac done # Check if socat or netcat is available if command -v socat &> /dev/null; then SEND_CMD="socat" elif command -v nc &> /dev/null; then SEND_CMD="nc" else error "Neither socat nor nc (netcat) found. Please install one of them." echo " Ubuntu/Debian: apt-get install socat OR apt-get install netcat-openbsd" echo " RHEL/CentOS: yum install socat OR yum install nc" exit 1 fi # Function to send data to Unix socket send_to_socket() { local socket="$1" local data="$2" if [ "$SEND_CMD" = "socat" ]; then echo "$data" | socat - "UNIX-SENDTO:$socket" 2>/dev/null else echo "$data" | nc -U -u "$socket" 2>/dev/null fi } # Function to generate timestamp in nanoseconds get_timestamp_ns() { date +%s%N } # Function to send HTTP (A) event send_http_event() { local src_ip="$1" local src_port="$2" local timestamp="$3" local method="${4:-GET}" local path="${5:-/test}" local host="${6:-example.com}" local json=$(cat < /dev/null; then curl -s "$METRICS_URL" 2>/dev/null || echo "{}" elif command -v wget &> /dev/null; then wget -qO- "$METRICS_URL" 2>/dev/null || echo "{}" else warn "Neither curl nor wget found. Skipping metrics check." echo "{}" fi } # Extract value from JSON (simple grep-based, requires jq for complex queries) get_json_value() { local json="$1" local key="$2" if command -v jq &> /dev/null; then echo "$json" | jq -r ".$key // 0" else # Fallback: simple grep (works for flat JSON) echo "$json" | grep -o "\"$key\":[0-9]*" | cut -d: -f2 || echo "0" fi } # Main test function run_test() { info "Starting correlation test..." info "Configuration:" echo " HTTP Socket: $HTTP_SOCKET" echo " Network Socket: $NETWORK_SOCKET" echo " Test pairs: $COUNT" echo " Delay between: ${DELAY_MS}ms" echo " Metrics URL: $METRICS_URL" echo " Send command: $SEND_CMD" echo "" # Get initial metrics info "Fetching initial metrics..." local initial_metrics=$(get_metrics) local initial_success=$(get_json_value "$initial_metrics" "correlations_success") local initial_failed=$(get_json_value "$initial_metrics" "correlations_failed") local initial_a=$(get_json_value "$initial_metrics" "events_received_a") local initial_b=$(get_json_value "$initial_metrics" "events_received_b") info "Initial metrics:" echo " Events A: $initial_a" echo " Events B: $initial_b" echo " Success: $initial_success" echo " Failed: $initial_failed" echo "" # Send test events info "Sending $COUNT test event pairs..." local base_timestamp=$(get_timestamp_ns) local sent=0 local correlated=0 for i in $(seq 1 $COUNT); do local src_ip="192.168.1.$((i % 254 + 1))" local src_port=$((8000 + i)) # Send A and B with same timestamp (should correlate) local ts_a=$((base_timestamp + i * 1000000)) local ts_b=$ts_a # Same timestamp for perfect correlation send_http_event "$src_ip" "$src_port" "$ts_a" send_network_event "$src_ip" "$src_port" "$ts_b" sent=$((sent + 1)) verbose "Sent pair $i: $src_ip:$src_port" if [ $DELAY_MS -gt 0 ]; then sleep $(echo "scale=3; $DELAY_MS / 1000" | bc) fi done success "Sent $sent event pairs" echo "" # Wait for processing info "Waiting for processing (2 seconds)..." sleep 2 # Get final metrics info "Fetching final metrics..." local final_metrics=$(get_metrics) local final_success=$(get_json_value "$final_metrics" "correlations_success") local final_failed=$(get_json_value "$final_metrics" "correlations_failed") local final_a=$(get_json_value "$final_metrics" "events_received_a") local final_b=$(get_json_value "$final_metrics" "events_received_b") # Calculate deltas local delta_success=$((final_success - initial_success)) local delta_failed=$((final_failed - initial_failed)) local delta_a=$((final_a - initial_a)) local delta_b=$((final_b - initial_b)) echo "" info "Results:" echo " Events A sent: $delta_a (expected: $sent)" echo " Events B sent: $delta_b (expected: $sent)" echo " Correlations: $delta_success" echo " Failures: $delta_failed" echo "" # Validation local test_passed=true if [ "$delta_a" -ne "$sent" ]; then error "Event A count mismatch: got $delta_a, expected $sent" test_passed=false fi if [ "$delta_b" -ne "$sent" ]; then error "Event B count mismatch: got $delta_b, expected $sent" test_passed=false fi if [ "$delta_success" -ne "$sent" ]; then error "Correlation count mismatch: got $delta_success, expected $sent" test_passed=false fi if [ "$delta_failed" -ne 0 ]; then warn "Unexpected correlation failures: $delta_failed" fi if [ "$test_passed" = true ]; then success "All tests passed! Correlation is working correctly." exit 0 else error "Some tests failed. Check the logs for details." exit 1 fi } # Test with time window exceeded run_time_window_test() { info "Running time window test (B arrives after time window)..." local src_ip="192.168.100.1" local src_port="9999" # Send A event local ts_a=$(get_timestamp_ns) send_http_event "$src_ip" "$src_port" "$ts_a" info "Sent A event at timestamp $ts_a" # Wait for time window to expire (default is 10s, we wait 11s) info "Waiting 11 seconds (time window should expire)..." sleep 11 # Send B event local ts_b=$(get_timestamp_ns) send_network_event "$src_ip" "$src_port" "$ts_b" info "Sent B event at timestamp $ts_b" info "This should result in a time_window failure (check metrics)" } # Test with different src_ip run_different_ip_test() { info "Running different IP test (should NOT correlate)..." # Send A with IP 192.168.200.1 local ts=$(get_timestamp_ns) send_http_event "192.168.200.1" "7777" "$ts" info "Sent A event from 192.168.200.1:7777" # Send B with different IP send_network_event "192.168.200.2" "7777" "$ts" info "Sent B event from 192.168.200.2:7777 (different IP)" info "These should NOT correlate (different src_ip)" } # Run tests check_sockets echo "" # Run main test run_test echo "" info "Additional tests available:" echo " --test-time-window Test time window expiration" echo " --test-different-ip Test different IP (no correlation)" # Check for additional test flags if [[ "$@" == *"--test-time-window"* ]]; then echo "" run_time_window_test fi if [[ "$@" == *"--test-different-ip"* ]]; then echo "" run_different_ip_test fi