-
Notifications
You must be signed in to change notification settings - Fork 2
Expand file tree
/
Copy pathtest-codeql-path-valid.sh
More file actions
executable file
·169 lines (147 loc) · 5.18 KB
/
test-codeql-path-valid.sh
File metadata and controls
executable file
·169 lines (147 loc) · 5.18 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
#!/usr/bin/env bash
set -euo pipefail
##
## Test: Server must start successfully when CODEQL_PATH points to a valid
## CodeQL binary, even when codeql is NOT on PATH.
##
## Usage:
## ./server/scripts/test-codeql-path-valid.sh <codeql-binary> [<server-bundle>]
##
## Arguments:
## <codeql-binary> Absolute path to a valid CodeQL CLI binary
## <server-bundle> Path to the server JS bundle (default: server/dist/codeql-development-mcp-server.js)
##
## Environment:
## CLEAN_PATH Optional. When set, PATH is replaced with this value so that
## codeql is not discoverable via PATH. When unset, the current
## PATH is used as-is (useful for local testing).
##
## Exit codes:
## 0 Server started successfully and was shut down cleanly
## 1 Server failed to start or exited prematurely
##
SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
REPO_ROOT="$(cd "${SCRIPT_DIR}/../.." && pwd)"
if [[ $# -lt 1 ]]; then
echo "Usage: $0 <codeql-binary> [<server-bundle>]"
exit 1
fi
CODEQL_BINARY="$1"
SERVER_BUNDLE="${2:-server/dist/codeql-development-mcp-server.js}"
# Resolve relative paths against the repo root
if [[ ! "${SERVER_BUNDLE}" = /* ]]; then
SERVER_BUNDLE="${REPO_ROOT}/${SERVER_BUNDLE}"
fi
if [[ ! -f "${SERVER_BUNDLE}" ]]; then
echo "::error::Server bundle not found: ${SERVER_BUNDLE}"
exit 1
fi
if [[ ! -f "${CODEQL_BINARY}" ]]; then
echo "::error::CodeQL binary not found: ${CODEQL_BINARY}"
exit 1
fi
# Replace PATH with CLEAN_PATH when provided (CI strips codeql from PATH)
if [[ -n "${CLEAN_PATH:-}" ]]; then
export PATH="${CLEAN_PATH}"
fi
export CODEQL_PATH="${CODEQL_BINARY}"
echo "=== Test: Server must start with valid CODEQL_PATH ==="
echo " SERVER_BUNDLE=${SERVER_BUNDLE}"
echo " CODEQL_PATH=${CODEQL_PATH}"
echo " codeql in PATH: $(command -v codeql 2>/dev/null || echo 'not found')"
STDERR_FILE="$(mktemp)"
cleanup() {
rm -f "${STDERR_FILE}"
# Kill the server if still running
if [[ -n "${SERVER_PID:-}" ]] && kill -0 "${SERVER_PID}" 2>/dev/null; then
kill "${SERVER_PID}" 2>/dev/null || true
wait "${SERVER_PID}" 2>/dev/null || true
fi
# Kill the FIFO feeder and its children (e.g. sleep) if still running
if [[ -n "${FEEDER_PID:-}" ]]; then
kill "${FEEDER_PID}" 2>/dev/null || true
# Also kill the process group to catch child processes like sleep
kill -- -"${FEEDER_PID}" 2>/dev/null || true
fi
# Remove the FIFO
if [[ -n "${FIFO:-}" ]]; then
rm -f "${FIFO}"
fi
}
trap cleanup EXIT
# Start the server in the background.
# Use a long-running stdin feeder as a SEPARATE backgrounded process, then
# connect it to the server via a named pipe (FIFO) to avoid bash subshell
# PID issues with `A | B &`.
#
# On Windows (MSYS2/Git Bash), mkfifo creates MSYS2-specific named pipes
# that native Windows processes (node.exe) cannot read from reliably.
# Force the process-substitution fallback on Windows, which creates a
# Windows-compatible pipe handle that node.exe can read from correctly.
FIFO=""
case "$(uname -s)" in
MINGW*|MSYS*|CYGWIN*)
# Windows: skip mkfifo — native node.exe cannot read from MSYS2 FIFOs.
;;
*)
FIFO="$(mktemp -u)"
mkfifo "${FIFO}" 2>/dev/null || { FIFO=""; }
;;
esac
if [[ -n "${FIFO}" ]]; then
# Feed the FIFO in the background so the server's stdin stays open
( sleep 30 > "${FIFO}" ) &
FEEDER_PID=$!
node "${SERVER_BUNDLE}" < "${FIFO}" > /dev/null 2> "${STDERR_FILE}" &
SERVER_PID=$!
else
# Fallback: use process substitution to keep stdin open.
# On Windows, Git Bash converts process substitution into a Windows
# pipe handle that node.exe (native process) can read correctly.
node "${SERVER_BUNDLE}" < <(sleep 30) > /dev/null 2> "${STDERR_FILE}" &
SERVER_PID=$!
fi
echo " Server PID: ${SERVER_PID}"
# Give the server time to either start successfully or crash
sleep 5
# Helper: check whether stderr proves the server started successfully and
# resolved the CodeQL CLI via CODEQL_PATH.
check_startup_logs() {
echo ""
echo "--- startup logs ---"
cat "${STDERR_FILE}"
if grep -q "CODEQL_PATH" "${STDERR_FILE}"; then
echo "✅ Server logged CODEQL_PATH resolution"
else
echo "⚠️ CODEQL_PATH not mentioned in stderr (non-fatal)"
fi
# The definitive success marker logged by the server
if grep -q "McpServer started successfully" "${STDERR_FILE}"; then
return 0
fi
return 1
}
if kill -0 "${SERVER_PID}" 2>/dev/null; then
check_startup_logs
echo ""
echo "✅ PASS: Server is running after 5 seconds (PID ${SERVER_PID})"
# Cleanup is handled by the EXIT trap
exit 0
else
wait "${SERVER_PID}" 2>/dev/null && EXIT_CODE=0 || EXIT_CODE=$?
# On Windows, process substitution may not keep stdin open reliably.
# When the STDIO transport receives EOF the server shuts down cleanly
# (exit 0) even though startup succeeded.
# Accept that as a pass when the logs prove the server started correctly.
if [[ "${EXIT_CODE}" -eq 0 ]] && check_startup_logs; then
echo ""
echo "✅ PASS: Server started successfully (exited cleanly after stdin EOF)"
exit 0
fi
echo ""
echo "::error::Server exited prematurely with code ${EXIT_CODE}"
echo "--- stderr ---"
cat "${STDERR_FILE}"
# Cleanup is handled by the EXIT trap
exit 1
fi