-
Notifications
You must be signed in to change notification settings - Fork 4
Expand file tree
/
Copy pathhttp_mock.bash
More file actions
199 lines (181 loc) · 5.91 KB
/
Copy pathhttp_mock.bash
File metadata and controls
199 lines (181 loc) · 5.91 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
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
# shellcheck shell=bash
# Local HTTP mock for Weblate POST tests (no real network).
MOCK_WEBLATE_PID=""
MOCK_WEBLATE_PORT=""
MOCK_WEBLATE_PORT_FILE=""
MOCK_WEBLATE_BASE_URL=""
MOCK_WEBLATE_REQUEST_LOG=""
MOCK_WEBLATE_SERVER_SCRIPT=""
_CURL_ORIG_PATH=""
start_weblate_mock_server() {
local status="${MOCK_WEBLATE_STATUS:-202}"
local body="${MOCK_WEBLATE_BODY:-{\"status\":\"accepted\"}}"
local delay="${MOCK_WEBLATE_DELAY_SEC:-0}"
MOCK_WEBLATE_REQUEST_LOG="$(mktemp)"
MOCK_WEBLATE_PORT_FILE="$(mktemp)"
MOCK_WEBLATE_SERVER_SCRIPT="$(mktemp)"
cat >"$MOCK_WEBLATE_SERVER_SCRIPT" <<'PYEOF'
import os
import time
from http.server import BaseHTTPRequestHandler, HTTPServer
status = int(os.environ.get("MOCK_WEBLATE_STATUS", "202"))
body = os.environ.get("MOCK_WEBLATE_BODY", '{"status":"accepted"}')
delay = float(os.environ.get("MOCK_WEBLATE_DELAY_SEC", "0"))
request_log = os.environ["MOCK_WEBLATE_REQUEST_LOG"]
port_file = os.environ["MOCK_WEBLATE_PORT_FILE"]
class Handler(BaseHTTPRequestHandler):
def log_message(self, fmt, *args):
pass
def do_POST(self):
if delay > 0:
time.sleep(delay)
length = int(self.headers.get("Content-Length", "0"))
payload = self.rfile.read(length).decode("utf-8", errors="replace")
with open(request_log, "w", encoding="utf-8") as f:
f.write(f"PATH={self.path}\n")
for key, value in self.headers.items():
f.write(f"HEADER:{key}: {value}\n")
f.write("BODY_START\n")
f.write(payload)
f.write("\nBODY_END\n")
encoded = body.encode("utf-8")
self.send_response(status)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(encoded)))
self.end_headers()
self.wfile.write(encoded)
server = HTTPServer(("127.0.0.1", 0), Handler)
with open(port_file, "w", encoding="utf-8") as f:
f.write(str(server.server_port))
server.serve_forever()
PYEOF
export MOCK_WEBLATE_STATUS="$status" MOCK_WEBLATE_BODY="$body" MOCK_WEBLATE_DELAY_SEC="$delay"
export MOCK_WEBLATE_REQUEST_LOG MOCK_WEBLATE_PORT_FILE
python3 "$MOCK_WEBLATE_SERVER_SCRIPT" &
MOCK_WEBLATE_PID=$!
local i=0 port=""
while [[ -z "$port" ]]; do
if [[ -s "$MOCK_WEBLATE_PORT_FILE" ]]; then
port="$(<"$MOCK_WEBLATE_PORT_FILE")"
if python3 -c "import socket; s=socket.create_connection(('127.0.0.1', $port), 0.2); s.close()" 2>/dev/null; then
break
fi
port=""
fi
if ! kill -0 "$MOCK_WEBLATE_PID" 2>/dev/null; then
stop_weblate_mock_server
echo "http_mock: mock server exited before binding" >&2
return 1
fi
i=$((i + 1))
if [[ $i -gt 50 ]]; then
stop_weblate_mock_server
echo "http_mock: mock server failed to start" >&2
return 1
fi
sleep 0.05
done
MOCK_WEBLATE_PORT="$port"
MOCK_WEBLATE_BASE_URL="http://127.0.0.1:${MOCK_WEBLATE_PORT}/"
export MOCK_WEBLATE_PORT MOCK_WEBLATE_BASE_URL
}
stop_weblate_mock_server() {
if [[ -n "${MOCK_WEBLATE_PID:-}" ]]; then
kill "$MOCK_WEBLATE_PID" 2>/dev/null || true
wait "$MOCK_WEBLATE_PID" 2>/dev/null || true
fi
[[ -n "${MOCK_WEBLATE_SERVER_SCRIPT:-}" && -f "$MOCK_WEBLATE_SERVER_SCRIPT" ]] && rm -f "$MOCK_WEBLATE_SERVER_SCRIPT"
[[ -n "${MOCK_WEBLATE_REQUEST_LOG:-}" && -f "$MOCK_WEBLATE_REQUEST_LOG" ]] && rm -f "$MOCK_WEBLATE_REQUEST_LOG"
[[ -n "${MOCK_WEBLATE_PORT_FILE:-}" && -f "$MOCK_WEBLATE_PORT_FILE" ]] && rm -f "$MOCK_WEBLATE_PORT_FILE"
MOCK_WEBLATE_PID=""
MOCK_WEBLATE_PORT=""
MOCK_WEBLATE_PORT_FILE=""
MOCK_WEBLATE_BASE_URL=""
MOCK_WEBLATE_REQUEST_LOG=""
MOCK_WEBLATE_SERVER_SCRIPT=""
unset MOCK_WEBLATE_STATUS MOCK_WEBLATE_BODY MOCK_WEBLATE_DELAY_SEC
}
install_curl_timeout_stub() {
install_curl_stub
}
install_curl_stub() {
_CURL_ORIG_PATH="$PATH"
local wrapper_dir
wrapper_dir="$(mktemp -d)"
REAL_CURL="$(command -v curl)"
export REAL_CURL
cat >"$wrapper_dir/curl" <<'EOF'
#!/usr/bin/env bash
if [[ -n "${MOCK_CURL_EXIT:-}" ]]; then
echo "mock curl: simulated exit ${MOCK_CURL_EXIT}" >&2
exit "$MOCK_CURL_EXIT"
fi
if [[ "${MOCK_CURL_TIMEOUT:-}" == "1" ]]; then
echo "mock curl: simulated timeout" >&2
exit 28
fi
exec "$REAL_CURL" "$@"
EOF
chmod +x "$wrapper_dir/curl"
CURL_WRAPPER_DIR="$wrapper_dir"
export PATH="$wrapper_dir:$PATH"
}
restore_curl_stub() {
if [[ -n "${_CURL_ORIG_PATH:-}" ]]; then
export PATH="$_CURL_ORIG_PATH"
fi
if [[ -n "${CURL_WRAPPER_DIR:-}" && -d "$CURL_WRAPPER_DIR" ]]; then
rm -rf "$CURL_WRAPPER_DIR"
fi
unset CURL_WRAPPER_DIR REAL_CURL _CURL_ORIG_PATH MOCK_CURL_TIMEOUT MOCK_CURL_EXIT
unset MOCK_SLACK_REQUEST_LOG MOCK_SLACK_STATUS
}
install_slack_curl_stub() {
_CURL_ORIG_PATH="$PATH"
local wrapper_dir
wrapper_dir="$(mktemp -d)"
REAL_CURL="$(command -v curl)"
export REAL_CURL
MOCK_SLACK_REQUEST_LOG="$(mktemp)"
export MOCK_SLACK_REQUEST_LOG
MOCK_SLACK_STATUS="${MOCK_SLACK_STATUS:-200}"
export MOCK_SLACK_STATUS
cat >"$wrapper_dir/curl" <<'EOF'
#!/usr/bin/env bash
if [[ -n "${MOCK_CURL_EXIT:-}" ]]; then
echo "mock curl: simulated exit ${MOCK_CURL_EXIT}" >&2
exit "$MOCK_CURL_EXIT"
fi
if [[ "${MOCK_CURL_TIMEOUT:-}" == "1" ]]; then
echo "mock curl: simulated timeout" >&2
exit 28
fi
if [[ -n "${SLACK_WEBHOOK_URL:-}" && " $* " == *" ${SLACK_WEBHOOK_URL} "* ]]; then
body=""
prev=""
for arg in "$@"; do
if [[ "$prev" == "--data" || "$prev" == "-d" ]]; then
body="$arg"
fi
prev="$arg"
done
{
echo "URL=$SLACK_WEBHOOK_URL"
echo "BODY_START"
printf '%s' "$body"
echo
echo "BODY_END"
} >"${MOCK_SLACK_REQUEST_LOG}"
exit 0
fi
exec "$REAL_CURL" "$@"
EOF
chmod +x "$wrapper_dir/curl"
CURL_WRAPPER_DIR="$wrapper_dir"
export PATH="$wrapper_dir:$PATH"
}
restore_slack_curl_stub() {
[[ -n "${MOCK_SLACK_REQUEST_LOG:-}" && -f "$MOCK_SLACK_REQUEST_LOG" ]] && rm -f "$MOCK_SLACK_REQUEST_LOG"
unset MOCK_SLACK_REQUEST_LOG MOCK_SLACK_STATUS
restore_curl_stub
}