|
15 | 15 | psql_orioledb-17 = self'.packages."psql_orioledb-17/bin"; |
16 | 16 | inherit (self.supabase) defaults; |
17 | 17 | }; |
| 18 | + bashlog = builtins.fetchurl { |
| 19 | + url = "https://raw.githubusercontent.com/Zordrak/bashlog/master/log.sh"; |
| 20 | + sha256 = "1vrjcbzls0ba2qkg7ffddz2gxqn2rlj3wyvril2gz0mfi89y9vk9"; |
| 21 | + }; |
18 | 22 | in |
19 | 23 | { |
20 | 24 | checks = |
|
151 | 155 | ) filteredSqlTests; |
152 | 156 | sortedTestList = builtins.sort (a: b: a < b) testList; |
153 | 157 | in |
154 | | - pkgs.runCommand "postgres-${pgpkg.version}-check-harness" |
155 | | - { |
156 | | - nativeBuildInputs = with pkgs; [ |
157 | | - coreutils |
158 | | - bash |
159 | | - perl |
160 | | - pgpkg |
161 | | - pg_prove |
162 | | - pg_regress |
163 | | - procps |
164 | | - start-postgres-server-bin |
165 | | - which |
166 | | - getkey-script |
167 | | - supabase-groonga |
168 | | - python3 |
169 | | - netcat |
170 | | - ]; |
171 | | - } |
172 | | - '' |
173 | | - set -e |
| 158 | + pkgs.writeShellApplication rec { |
| 159 | + name = "postgres-${pgpkg.version}-check-harness"; |
| 160 | + bashOptions = [ |
| 161 | + "nounset" |
| 162 | + "pipefail" |
| 163 | + ]; |
| 164 | + runtimeInputs = with pkgs; [ |
| 165 | + coreutils |
| 166 | + bash |
| 167 | + perl |
| 168 | + pgpkg |
| 169 | + pg_prove |
| 170 | + pg_regress |
| 171 | + procps |
| 172 | + start-postgres-server-bin |
| 173 | + which |
| 174 | + getkey-script |
| 175 | + supabase-groonga |
| 176 | + python3 |
| 177 | + netcat |
| 178 | + ]; |
174 | 179 |
|
175 | | - # Start HTTP mock server for http extension tests |
| 180 | + text = '' |
| 181 | +
|
| 182 | + #shellcheck disable=SC1091 |
| 183 | + source ${bashlog} |
| 184 | + #shellcheck disable=SC1091 |
| 185 | + source ${pkgs.stdenv}/setup |
| 186 | + export PATH="${lib.makeBinPath runtimeInputs}:$PATH" |
| 187 | +
|
| 188 | + export BASHLOG_FILE=1 |
| 189 | + export BASHLOG_FILE_PATH=debug.log |
176 | 190 | # Use a build-specific directory for coordination |
177 | 191 | BUILD_TMP=$(mktemp -d) |
| 192 | +
|
| 193 | + # Function to log command execution with stdout and stderr |
| 194 | + function log_cmd { |
| 195 | + local cmd_name="$1" |
| 196 | + shift |
| 197 | + log debug "Executing: $cmd_name $*" |
| 198 | + local exit_code=0 |
| 199 | + echo "\$ $cmd_name $*" >> debug.log |
| 200 | +
|
| 201 | + "$cmd_name" "$@" >> debug.log 2>&1 || exit_code=$? |
| 202 | + log debug "Exit code: $exit_code" |
| 203 | + return $exit_code |
| 204 | + } |
| 205 | +
|
| 206 | + function on_exit { |
| 207 | + local exit_code=$? |
| 208 | + kill $HTTP_MOCK_PID 2>/dev/null || true |
| 209 | + rm -rf "$BUILD_TMP" |
| 210 | + if [ $exit_code -ne 0 ]; then |
| 211 | + log error "An error occurred. Exit code: $exit_code" |
| 212 | + log error "Debug logs:" |
| 213 | + cat debug.log || log error "No debug.log file found" |
| 214 | + fi |
| 215 | + } |
| 216 | + trap on_exit EXIT |
| 217 | + trap "" DEBUG |
| 218 | +
|
| 219 | + function check_postgres_ready { |
| 220 | + for i in {1..60}; do |
| 221 | + if log_cmd pg_isready -h localhost -p ${pgPort} -U supabase_admin -q; then |
| 222 | + log info "PostgreSQL is ready" |
| 223 | + break |
| 224 | + fi |
| 225 | + sleep 1 |
| 226 | + if [ "$i" -eq 60 ]; then |
| 227 | + log error "PostgreSQL failed to start" |
| 228 | + exit 1 |
| 229 | + fi |
| 230 | + done |
| 231 | + } |
| 232 | +
|
| 233 | + # Start HTTP mock server for http extension tests |
178 | 234 | HTTP_MOCK_PORT_FILE="$BUILD_TMP/http-mock-port" |
179 | 235 |
|
180 | | - echo "Starting HTTP mock server (will find free port)..." |
181 | | - HTTP_MOCK_PORT_FILE="$HTTP_MOCK_PORT_FILE" ${pkgs.python3}/bin/python3 ${./tests/http-mock-server.py} & |
| 236 | + log info "Starting HTTP mock server (will find free port)..." |
| 237 | + HTTP_MOCK_PORT_FILE="$HTTP_MOCK_PORT_FILE" log_cmd ${pkgs.python3}/bin/python3 ${./tests/http-mock-server.py} & |
182 | 238 | HTTP_MOCK_PID=$! |
183 | 239 |
|
184 | 240 | # Clean up on exit |
185 | | - trap "kill $HTTP_MOCK_PID 2>/dev/null || true; rm -rf '$BUILD_TMP'" EXIT |
186 | 241 |
|
187 | 242 | # Wait for server to start and write port file |
188 | 243 | for i in {1..10}; do |
189 | 244 | if [ -f "$HTTP_MOCK_PORT_FILE" ]; then |
190 | 245 | HTTP_MOCK_PORT=$(cat "$HTTP_MOCK_PORT_FILE") |
191 | | - echo "HTTP mock server started on port $HTTP_MOCK_PORT" |
| 246 | + log info "HTTP mock server started on port $HTTP_MOCK_PORT" |
192 | 247 | break |
193 | 248 | fi |
194 | 249 | sleep 1 |
195 | 250 | done |
196 | 251 |
|
197 | 252 | if [ ! -f "$HTTP_MOCK_PORT_FILE" ]; then |
198 | | - echo "Failed to start HTTP mock server" |
| 253 | + log error "Failed to start HTTP mock server" |
199 | 254 | exit 1 |
200 | 255 | fi |
201 | 256 |
|
|
205 | 260 | #First we need to create a generic pg cluster for pgtap tests and run those |
206 | 261 | export GRN_PLUGINS_DIR=${pkgs.supabase-groonga}/lib/groonga/plugins |
207 | 262 | PGTAP_CLUSTER=$(mktemp -d) |
208 | | - initdb --locale=C --username=supabase_admin -D "$PGTAP_CLUSTER" |
| 263 | + log info "Creating temporary PostgreSQL cluster at $PGTAP_CLUSTER" |
| 264 | + log_cmd initdb --locale=C --username=supabase_admin -D "$PGTAP_CLUSTER" |
209 | 265 | substitute ${./tests/postgresql.conf.in} "$PGTAP_CLUSTER"/postgresql.conf \ |
210 | 266 | --subst-var-by PGSODIUM_GETKEY_SCRIPT "${getkey-script}/bin/pgsodium-getkey" |
211 | | - echo "listen_addresses = '*'" >> "$PGTAP_CLUSTER"/postgresql.conf |
| 267 | + echo "listen_addresses = '127.0.0.1'" >> "$PGTAP_CLUSTER"/postgresql.conf |
212 | 268 | echo "port = ${pgPort}" >> "$PGTAP_CLUSTER"/postgresql.conf |
213 | | - echo "host all all 127.0.0.1/32 trust" >> $PGTAP_CLUSTER/pg_hba.conf |
214 | | - echo "Checking shared_preload_libraries setting:" |
215 | | - grep -rn "shared_preload_libraries" "$PGTAP_CLUSTER"/postgresql.conf |
| 269 | + echo "host all all 127.0.0.1/32 trust" >> "$PGTAP_CLUSTER/pg_hba.conf" |
| 270 | + log info "Checking shared_preload_libraries setting:" |
| 271 | + log info "$(grep -rn "shared_preload_libraries" "$PGTAP_CLUSTER"/postgresql.conf)" |
216 | 272 | # Remove timescaledb if running orioledb-17 check |
217 | | - echo "I AM ${pgpkg.version}====================================================" |
| 273 | + log info "pgpkg.version is: ${pgpkg.version}" |
| 274 | + #shellcheck disable=SC2193 |
218 | 275 | if [[ "${pgpkg.version}" == *"17"* ]]; then |
219 | 276 | perl -pi -e 's/ timescaledb,//g' "$PGTAP_CLUSTER/postgresql.conf" |
220 | 277 | fi |
221 | 278 | #NOTE in the future we may also need to add the orioledb extension to the cluster when cluster is oriole |
222 | | - echo "PGTAP_CLUSTER directory contents:" |
223 | | - ls -la "$PGTAP_CLUSTER" |
224 | 279 |
|
225 | 280 | # Check if postgresql.conf exists |
226 | 281 | if [ ! -f "$PGTAP_CLUSTER/postgresql.conf" ]; then |
227 | | - echo "postgresql.conf is missing!" |
| 282 | + log error "postgresql.conf is missing!" |
228 | 283 | exit 1 |
229 | 284 | fi |
230 | 285 |
|
231 | 286 | # PostgreSQL startup |
232 | 287 | if [[ "$(uname)" == "Darwin" ]]; then |
233 | | - pg_ctl -D "$PGTAP_CLUSTER" -l "$PGTAP_CLUSTER"/postgresql.log -o "-k "$PGTAP_CLUSTER" -p ${pgPort} -d 5" start 2>&1 |
| 288 | + log_cmd pg_ctl -D "$PGTAP_CLUSTER" -l "$PGTAP_CLUSTER/postgresql.log" -o "-k $PGTAP_CLUSTER -p ${pgPort} -d 5" start |
234 | 289 | else |
235 | 290 | mkdir -p "$PGTAP_CLUSTER/sockets" |
236 | | - pg_ctl -D "$PGTAP_CLUSTER" -l "$PGTAP_CLUSTER"/postgresql.log -o "-k $PGTAP_CLUSTER/sockets -p ${pgPort} -d 5" start 2>&1 |
| 291 | + log_cmd pg_ctl -D "$PGTAP_CLUSTER" -l "$PGTAP_CLUSTER/postgresql.log" -o "-k $PGTAP_CLUSTER/sockets -p ${pgPort} -d 5" start |
237 | 292 | fi || { |
238 | | - echo "pg_ctl failed to start PostgreSQL" |
239 | | - echo "Contents of postgresql.log:" |
| 293 | + log error "pg_ctl failed to start PostgreSQL" |
| 294 | + log error "Contents of postgresql.log:" |
240 | 295 | cat "$PGTAP_CLUSTER"/postgresql.log |
241 | 296 | exit 1 |
242 | 297 | } |
243 | | - for i in {1..60}; do |
244 | | - if pg_isready -h ${self.supabase.defaults.host} -p ${pgPort}; then |
245 | | - echo "PostgreSQL is ready" |
246 | | - break |
247 | | - fi |
248 | | - sleep 1 |
249 | | - if [ $i -eq 60 ]; then |
250 | | - echo "PostgreSQL is not ready after 60 seconds" |
251 | | - echo "PostgreSQL status:" |
252 | | - pg_ctl -D "$PGTAP_CLUSTER" status |
253 | | - echo "PostgreSQL log content:" |
254 | | - cat "$PGTAP_CLUSTER"/postgresql.log |
255 | | - exit 1 |
256 | | - fi |
257 | | - done |
258 | | - createdb -p ${pgPort} -h ${self.supabase.defaults.host} --username=supabase_admin testing |
259 | | - if ! psql -p ${pgPort} -h ${self.supabase.defaults.host} --username=supabase_admin -d testing -v ON_ERROR_STOP=1 -Xf ${./tests/prime.sql}; then |
260 | | - echo "Error executing SQL file. PostgreSQL log content:" |
| 298 | +
|
| 299 | + log info "Waiting for PostgreSQL to be ready..." |
| 300 | + check_postgres_ready |
| 301 | +
|
| 302 | + log info "Creating test database" |
| 303 | + log_cmd createdb -p ${pgPort} -h localhost --username=supabase_admin testing |
| 304 | +
|
| 305 | + log info "Loading prime SQL file" |
| 306 | + if ! log_cmd psql -p ${pgPort} -h localhost --username=supabase_admin -d testing -v ON_ERROR_STOP=1 -Xf ${./tests/prime.sql}; then |
| 307 | + log error "Error executing SQL file. PostgreSQL log content:" |
261 | 308 | cat "$PGTAP_CLUSTER"/postgresql.log |
262 | 309 | pg_ctl -D "$PGTAP_CLUSTER" stop |
263 | 310 | exit 1 |
264 | 311 | fi |
265 | 312 |
|
266 | 313 | # Create a table to store test configuration |
267 | | - psql -p ${pgPort} -h ${self.supabase.defaults.host} --username=supabase_admin -d testing -c " |
| 314 | + log info "Creating test_config table" |
| 315 | + log_cmd psql -p ${pgPort} -h localhost --username=supabase_admin -d testing -c " |
268 | 316 | CREATE TABLE IF NOT EXISTS test_config (key TEXT PRIMARY KEY, value TEXT); |
269 | 317 | INSERT INTO test_config (key, value) VALUES ('http_mock_port', '$HTTP_MOCK_PORT') |
270 | 318 | ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value; |
271 | 319 | " |
272 | 320 | SORTED_DIR=$(mktemp -d) |
273 | 321 | for t in $(printf "%s\n" ${builtins.concatStringsSep " " sortedTestList}); do |
274 | | - psql -p ${pgPort} -h ${self.supabase.defaults.host} --username=supabase_admin -d testing -f "${./tests/sql}/$t.sql" || true |
| 322 | + log info "Running pgtap test: $t.sql" |
| 323 | + #XXX enable ON_ERROR_STOP ? |
| 324 | + log_cmd psql -p ${pgPort} -h localhost --username=supabase_admin -d testing -f "${./tests/sql}/$t.sql" |
275 | 325 | done |
276 | 326 | rm -rf "$SORTED_DIR" |
277 | | - pg_ctl -D "$PGTAP_CLUSTER" stop |
278 | | - rm -rf $PGTAP_CLUSTER |
| 327 | + log_cmd pg_ctl -D "$PGTAP_CLUSTER" stop |
| 328 | + rm -rf "$PGTAP_CLUSTER" |
279 | 329 |
|
280 | 330 | # End of pgtap tests |
281 | 331 | # from here on out we are running pg_regress tests, we use a different cluster for this |
282 | 332 | # which is start by the start-postgres-server-bin script |
283 | 333 | # start-postgres-server-bin script closely matches our AMI setup, configurations and migrations |
284 | 334 |
|
| 335 | + log info "Starting PostgreSQL server for pg_regress tests" |
285 | 336 | unset GRN_PLUGINS_DIR |
286 | | - ${start-postgres-server-bin}/bin/start-postgres-server ${getVersionArg pgpkg} --daemonize |
| 337 | + if ! log_cmd ${start-postgres-server-bin}/bin/start-postgres-server ${getVersionArg pgpkg} --daemonize; then |
| 338 | + log error "Failed to start PostgreSQL server for pg_regress tests" |
| 339 | + exit 1 |
| 340 | + fi |
287 | 341 |
|
288 | | - for i in {1..60}; do |
289 | | - if pg_isready -h ${self.supabase.defaults.host} -p ${pgPort} -U supabase_admin -q; then |
290 | | - echo "PostgreSQL is ready" |
291 | | - break |
292 | | - fi |
293 | | - sleep 1 |
294 | | - if [ $i -eq 60 ]; then |
295 | | - echo "PostgreSQL failed to start" |
296 | | - exit 1 |
297 | | - fi |
298 | | - done |
| 342 | + check_postgres_ready |
299 | 343 |
|
300 | | - if ! psql -p ${pgPort} -h ${self.supabase.defaults.host} --no-password --username=supabase_admin -d postgres -v ON_ERROR_STOP=1 -Xf ${./tests/prime.sql}; then |
301 | | - echo "Error executing SQL file" |
| 344 | + log info "Loading prime SQL file" |
| 345 | + if ! log_cmd psql -p ${pgPort} -h localhost --no-password --username=supabase_admin -d postgres -v ON_ERROR_STOP=1 -Xf ${./tests/prime.sql} 2>&1; then |
| 346 | + log error "Error executing SQL file" |
302 | 347 | exit 1 |
303 | 348 | fi |
304 | 349 |
|
305 | 350 | # Create a table to store test configuration for pg_regress tests |
306 | | - psql -p ${pgPort} -h ${self.supabase.defaults.host} --no-password --username=supabase_admin -d postgres -c " |
| 351 | + log info "Creating test_config table for pg_regress tests" |
| 352 | + log_cmd psql -p ${pgPort} -h localhost --no-password --username=supabase_admin -d postgres -c " |
307 | 353 | CREATE TABLE IF NOT EXISTS test_config (key TEXT PRIMARY KEY, value TEXT); |
308 | 354 | INSERT INTO test_config (key, value) VALUES ('http_mock_port', '$HTTP_MOCK_PORT') |
309 | 355 | ON CONFLICT (key) DO UPDATE SET value = EXCLUDED.value; |
310 | 356 | " |
311 | 357 |
|
312 | | - mkdir -p $out/regression_output |
313 | | - if ! pg_regress \ |
| 358 | + #shellcheck disable=SC2154 |
| 359 | + mkdir -p "$out/regression_output" |
| 360 | + log info "Running pg_regress tests" |
| 361 | + if ! log_cmd pg_regress \ |
314 | 362 | --use-existing \ |
315 | 363 | --dbname=postgres \ |
316 | 364 | --inputdir=${./tests} \ |
317 | | - --outputdir=$out/regression_output \ |
318 | | - --host=${self.supabase.defaults.host} \ |
| 365 | + --outputdir="$out/regression_output" \ |
| 366 | + --host=localhost \ |
319 | 367 | --port=${pgPort} \ |
320 | 368 | --user=supabase_admin \ |
321 | | - ${builtins.concatStringsSep " " sortedTestList}; then |
322 | | - echo "pg_regress tests failed" |
323 | | - cat $out/regression_output/regression.diffs |
| 369 | + ${builtins.concatStringsSep " " sortedTestList} 2>&1; then |
| 370 | + log error "pg_regress tests failed" |
| 371 | + cat "$out/regression_output/regression.diffs" |
324 | 372 | exit 1 |
325 | 373 | fi |
| 374 | + log info "pg_regress tests completed successfully" |
326 | 375 |
|
327 | | - echo "Running migrations tests" |
328 | | - pg_prove -p ${pgPort} -U supabase_admin -h ${self.supabase.defaults.host} -d postgres -v ${../migrations/tests}/test.sql |
329 | | -
|
330 | | - # Copy logs to output |
331 | | - for logfile in $(find /tmp -name postgresql.log -type f); do |
332 | | - cp "$logfile" $out/postgresql.log |
333 | | - done |
334 | | - exit 0 |
| 376 | + log info "Running migrations tests" |
| 377 | + log_cmd pg_prove -p ${pgPort} -U supabase_admin -h localhost -d postgres -v ${../migrations/tests}/test.sql |
| 378 | + log info "Migrations tests completed successfully" |
335 | 379 | ''; |
| 380 | + }; |
336 | 381 | in |
337 | 382 | { |
338 | | - psql_15 = makeCheckHarness self'.packages."psql_15/bin"; |
339 | | - psql_17 = makeCheckHarness self'.packages."psql_17/bin"; |
340 | | - psql_orioledb-17 = makeCheckHarness self'.packages."psql_orioledb-17/bin"; |
| 383 | + psql_15 = pkgs.runCommand "run-check-harness-psql-15" { } ( |
| 384 | + lib.getExe (makeCheckHarness self'.packages."psql_15/bin") |
| 385 | + ); |
| 386 | + psql_17 = pkgs.runCommand "run-check-harness-psql-17" { } ( |
| 387 | + lib.getExe (makeCheckHarness self'.packages."psql_17/bin") |
| 388 | + ); |
| 389 | + psql_orioledb-17 = pkgs.runCommand "run-check-harness-psql-orioledb-17" { } ( |
| 390 | + lib.getExe (makeCheckHarness self'.packages."psql_orioledb-17/bin") |
| 391 | + ); |
341 | 392 | inherit (self'.packages) |
342 | 393 | wal-g-2 |
343 | 394 | wal-g-3 |
|
0 commit comments