master
sh 173 lines 3.75 KB
Raw
1 #!/usr/bin/env bash
2 set -euo pipefail
3
4 # Colors for output
5 RED='\033[0;31m'
6 YELLOW='\033[1;33m'
7 GRAY='\033[0;90m'
8 NC='\033[0m' # No Color
9
10 # Execute command with visibility
11 run() {
12 # Print the command being executed
13 printf >&2 '%s%s >%s ' "$GRAY" "$(pwd)" "$NC"
14 printf >&2 '%s' "$YELLOW"
15 printf >&2 "%q " "$@"
16 printf >&2 '%s\n' "$NC"
17
18 # Execute the command
19 set +e
20 "$@"
21 local exit_code=$?
22 set -e
23 if [ $exit_code -ne 0 ]; then
24 echo -e >&2 "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
25 echo -e >&2 "${RED}[ERROR]${NC} Command failed with exit code ${exit_code}: ${YELLOW}$1${NC}"
26 echo -e >&2 "${RED} Full command:${NC} $*"
27 echo -e >&2 "${RED} Working dir:${NC} $(pwd)"
28 echo -e >&2 "${RED}━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━${NC}"
29 return $exit_code
30 fi
31 }
32
33 # Execute command in background with visibility
34 LAST_BG_PID=""
35 run_bg() {
36 printf >&2 '%s%s >%s ' "$GRAY" "$(pwd)" "$NC"
37 printf >&2 '%s' "$YELLOW"
38 printf >&2 "%q " "$@"
39 printf >&2 '%s\n' "$NC"
40 "$@" &
41 LAST_BG_PID=$!
42 }
43
44 SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
45 E2E_DIR="$SCRIPT_DIR/e2e"
46
47 DBS=(postgres mysql mssql mongodb redis clickhouse elasticsearch couchbase proxysql cockroachdb yugabytedb oracledb rethinkdb)
48 JOBS=1
49 ONLY=""
50
51 usage() {
52 cat <<'USAGE'
53 Usage: ./e2e.sh [--only db1,db2] [--jobs N] [--list]
54
55 Options:
56 --only Comma-separated list of DBs to run (e.g. postgres,mysql)
57 --jobs Max number of concurrent DB runs (default: 1)
58 --list Show available DBs
59 --help Show this help
60 USAGE
61 }
62
63 list_dbs() {
64 printf '%s\n' "${DBS[@]}"
65 }
66
67 while [ $# -gt 0 ]; do
68 case "$1" in
69 --only)
70 ONLY="${2:-}"
71 if [ -z "$ONLY" ]; then
72 echo "--only requires a value" >&2
73 usage
74 exit 1
75 fi
76 shift 2
77 ;;
78 --jobs)
79 JOBS="${2:-}"
80 if [ -z "$JOBS" ]; then
81 echo "--jobs requires a value" >&2
82 usage
83 exit 1
84 fi
85 shift 2
86 ;;
87 --list)
88 list_dbs
89 exit 0
90 ;;
91 --help|-h)
92 usage
93 exit 0
94 ;;
95 *)
96 echo "Unknown option: $1" >&2
97 usage
98 exit 1
99 ;;
100 esac
101 done
102
103 if ! [[ "$JOBS" =~ ^[0-9]+$ ]] || [ "$JOBS" -le 0 ]; then
104 echo "--jobs must be a positive integer" >&2
105 exit 1
106 fi
107
108 if [ -n "$ONLY" ]; then
109 IFS=',' read -r -a DBS <<< "${ONLY// /}"
110 fi
111
112 for db in "${DBS[@]}"; do
113 if [ ! -f "$E2E_DIR/${db}.sh" ]; then
114 echo "Unknown DB script: $db" >&2
115 exit 1
116 fi
117 done
118
119 pids=()
120 names=()
121 failures=()
122
123 wait_for_any() {
124 local i pid status db
125 while true; do
126 for i in "${!pids[@]}"; do
127 pid="${pids[$i]}"
128 if ! kill -0 "$pid" 2>/dev/null; then
129 set +e
130 wait "$pid"
131 status=$?
132 set -e
133 db="${names[$i]}"
134 if [ $status -ne 0 ]; then
135 failures+=("$db")
136 fi
137 unset 'pids[i]' 'names[i]'
138 pids=("${pids[@]}")
139 names=("${names[@]}")
140 return 0
141 fi
142 done
143 sleep 0.2
144 done
145 }
146
147 start_job() {
148 local db="$1"
149 local script="$E2E_DIR/${db}.sh"
150 local pid
151 run_bg bash "$script"
152 pid="$LAST_BG_PID"
153 pids+=("$pid")
154 names+=("$db")
155 }
156
157 for db in "${DBS[@]}"; do
158 start_job "$db"
159 while [ "${#pids[@]}" -ge "$JOBS" ]; do
160 wait_for_any
161 done
162 done
163
164 while [ "${#pids[@]}" -gt 0 ]; do
165 wait_for_any
166 done
167
168 if [ "${#failures[@]}" -ne 0 ]; then
169 printf >&2 "%s\n" "E2E failures: ${failures[*]}"
170 exit 1
171 fi
172
173 echo "E2E checks passed." >&2