Skip to content

Commit 9e1a7c6

Browse files
committed
test: include read-only test for postgrest
1 parent f234104 commit 9e1a7c6

File tree

1 file changed

+182
-15
lines changed

1 file changed

+182
-15
lines changed

testinfra/test_ami_nix.py

Lines changed: 182 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -510,12 +510,24 @@ def test_postgrest_ending_empty_key_query_parameter_is_removed(host):
510510

511511

512512
def test_postgresql_version(host):
513-
"""Print the PostgreSQL version being tested."""
513+
"""Print the PostgreSQL version being tested and ensure it's >= 14."""
514514
result = run_ssh_command(host['ssh'], "sudo -u postgres psql -c 'SELECT version();'")
515515
if result['succeeded']:
516516
print(f"\nPostgreSQL Version:\n{result['stdout']}")
517+
# Extract version number from the output
518+
version_line = result['stdout'].strip().split('\n')[2] # Skip header and get the actual version
519+
# Extract major version number (e.g., "15.8" -> 15)
520+
import re
521+
version_match = re.search(r'PostgreSQL (\d+)\.', version_line)
522+
if version_match:
523+
major_version = int(version_match.group(1))
524+
print(f"PostgreSQL major version: {major_version}")
525+
assert major_version >= 14, f"PostgreSQL version {major_version} is less than 14"
526+
else:
527+
assert False, "Could not parse PostgreSQL version number"
517528
else:
518529
print(f"\nFailed to get PostgreSQL version: {result['stderr']}")
530+
assert False, "Failed to get PostgreSQL version"
519531

520532
# Also get the version from the command line
521533
result = run_ssh_command(host['ssh'], "sudo -u postgres psql --version")
@@ -524,27 +536,182 @@ def test_postgresql_version(host):
524536
else:
525537
print(f"Failed to get PostgreSQL client version: {result['stderr']}")
526538

539+
print("✓ PostgreSQL version is >= 14")
540+
541+
542+
def test_libpq5_version(host):
543+
"""Print the libpq5 version installed."""
544+
# Try different package managers to find libpq5
545+
result = run_ssh_command(host['ssh'], "dpkg -l | grep libpq5 || true")
546+
if result['succeeded'] and result['stdout'].strip():
547+
print(f"\nlibpq5 package info:\n{result['stdout']}")
548+
else:
549+
print("\nlibpq5 not found via dpkg")
550+
551+
# Also try to find libpq.so files
552+
result = run_ssh_command(host['ssh'], "find /usr -name '*libpq*' -type f 2>/dev/null | head -10")
553+
if result['succeeded'] and result['stdout'].strip():
554+
print(f"\nlibpq files found:\n{result['stdout']}")
555+
else:
556+
print("\nNo libpq files found")
557+
558+
# Check if we can get version from a libpq file
559+
result = run_ssh_command(host['ssh'], "ldd /usr/bin/psql | grep libpq || true")
560+
if result['succeeded'] and result['stdout'].strip():
561+
print(f"\npsql libpq dependency:\n{result['stdout']}")
562+
else:
563+
print("\nCould not find libpq dependency for psql")
564+
527565
# This test always passes, it's just for informational purposes
528566
assert True
529567

530568

531-
def test_postgrest_logs_no_target_session_attrs_error(host):
532-
"""Check that PostgREST logs don't contain the target_session_attrs error."""
533-
# Check recent PostgREST logs for the specific error
534-
result = run_ssh_command(host['ssh'], "sudo journalctl -u postgrest --since '1 hour ago' | grep -i 'target_session_attrs' || true")
569+
def test_postgrest_read_only_session_attrs(host):
570+
"""Test PostgREST with target_session_attrs=read-only and check for session errors."""
571+
# First, check if PostgreSQL is configured for read-only mode
572+
result = run_ssh_command(host['ssh'], "sudo -u postgres psql -c \"SHOW default_transaction_read_only;\"")
573+
if result['succeeded']:
574+
default_read_only = result['stdout'].strip()
575+
print(f"PostgreSQL default_transaction_read_only: {default_read_only}")
576+
else:
577+
print("Could not check PostgreSQL read-only setting")
578+
default_read_only = "unknown"
579+
580+
# Check if PostgreSQL is in recovery mode (standby)
581+
result = run_ssh_command(host['ssh'], "sudo -u postgres psql -c \"SELECT pg_is_in_recovery();\"")
582+
if result['succeeded']:
583+
in_recovery = result['stdout'].strip()
584+
print(f"PostgreSQL pg_is_in_recovery: {in_recovery}")
585+
else:
586+
print("Could not check PostgreSQL recovery status")
587+
in_recovery = "unknown"
535588

536-
if result['stdout'].strip():
537-
print(f"\nFound target_session_attrs errors in PostgREST logs:\n{result['stdout']}")
538-
assert False, "PostgREST logs contain target_session_attrs errors"
589+
# Find PostgreSQL configuration file
590+
result = run_ssh_command(host['ssh'], "sudo -u postgres psql -c \"SHOW config_file;\"")
591+
if result['succeeded']:
592+
config_file = result['stdout'].strip().split('\n')[2].strip() # Skip header and get the actual path
593+
print(f"PostgreSQL config file: {config_file}")
539594
else:
540-
print("\nNo target_session_attrs errors found in PostgREST logs")
595+
print("Could not find PostgreSQL config file")
596+
config_file = "/etc/postgresql/15/main/postgresql.conf" # Default fallback
597+
598+
# Backup PostgreSQL config
599+
result = run_ssh_command(host['ssh'], f"sudo cp {config_file} {config_file}.backup")
600+
assert result['succeeded'], "Failed to backup PostgreSQL config"
601+
602+
# Add read-only setting to PostgreSQL config
603+
result = run_ssh_command(host['ssh'], f"echo 'default_transaction_read_only = on' | sudo tee -a {config_file}")
604+
assert result['succeeded'], "Failed to add read-only setting to PostgreSQL config"
605+
606+
# Restart PostgreSQL to apply the new configuration
607+
result = run_ssh_command(host['ssh'], "sudo systemctl restart postgresql")
608+
assert result['succeeded'], "Failed to restart PostgreSQL"
541609

542-
# Also check for the specific error pattern mentioned
543-
result = run_ssh_command(host['ssh'], "sudo journalctl -u postgrest --since '1 hour ago' | grep -i 'invalid target_session_attrs value.*read-only' || true")
610+
# Wait for PostgreSQL to start up
611+
sleep(5)
544612

545-
if result['stdout'].strip():
546-
print(f"\nFound specific target_session_attrs read-only error:\n{result['stdout']}")
547-
assert False, "PostgREST logs contain invalid target_session_attrs read-only error"
613+
# Verify the change took effect
614+
result = run_ssh_command(host['ssh'], "sudo -u postgres psql -c \"SHOW default_transaction_read_only;\"")
615+
if result['succeeded']:
616+
new_default_read_only = result['stdout'].strip()
617+
print(f"PostgreSQL default_transaction_read_only after change: {new_default_read_only}")
548618
else:
549-
print("No invalid target_session_attrs read-only errors found in PostgREST logs")
619+
print("Could not verify PostgreSQL read-only setting change")
620+
621+
# First, backup the current PostgREST config
622+
result = run_ssh_command(host['ssh'], "sudo cp /etc/postgrest/base.conf /etc/postgrest/base.conf.backup")
623+
assert result['succeeded'], "Failed to backup PostgREST config"
624+
625+
try:
626+
# Read the current config to get the db-uri
627+
result = run_ssh_command(host['ssh'], "sudo cat /etc/postgrest/base.conf | grep '^db-uri'")
628+
assert result['succeeded'], "Failed to read current db-uri"
629+
630+
current_db_uri = result['stdout'].strip()
631+
print(f"Current db-uri: {current_db_uri}")
632+
633+
# Extract just the URI part (remove the db-uri = " prefix and trailing quote)
634+
uri_start = current_db_uri.find('"') + 1
635+
uri_end = current_db_uri.rfind('"')
636+
base_uri = current_db_uri[uri_start:uri_end]
637+
638+
# Modify the URI to add target_session_attrs=read-only
639+
if '?' in base_uri:
640+
# URI already has parameters, add target_session_attrs
641+
modified_uri = base_uri + "&target_session_attrs=read-only"
642+
else:
643+
# URI has no parameters, add target_session_attrs
644+
modified_uri = base_uri + "?target_session_attrs=read-only"
645+
646+
print(f"Modified URI: {modified_uri}")
647+
648+
# Use awk to replace the db-uri line more reliably
649+
result = run_ssh_command(host['ssh'], f"sudo awk '{{if ($1 == \"db-uri\") print \"db-uri = \\\"{modified_uri}\\\"\"; else print $0}}' /etc/postgrest/base.conf > /tmp/new_base.conf && sudo mv /tmp/new_base.conf /etc/postgrest/base.conf")
650+
assert result['succeeded'], "Failed to update db-uri in config"
651+
652+
# Verify the change was made correctly
653+
result = run_ssh_command(host['ssh'], "sudo cat /etc/postgrest/base.conf | grep '^db-uri'")
654+
print(f"Updated db-uri line: {result['stdout'].strip()}")
655+
656+
# Also show the full config to debug
657+
result = run_ssh_command(host['ssh'], "sudo cat /etc/postgrest/base.conf")
658+
print(f"Full config after change:\n{result['stdout']}")
659+
660+
# Restart PostgREST to apply the new configuration
661+
result = run_ssh_command(host['ssh'], "sudo systemctl restart postgrest")
662+
assert result['succeeded'], "Failed to restart PostgREST"
663+
664+
# Wait a moment for PostgREST to start up
665+
sleep(5)
666+
667+
# Check if PostgREST is running
668+
result = run_ssh_command(host['ssh'], "sudo systemctl is-active postgrest")
669+
if not (result['succeeded'] and result['stdout'].strip() == 'active'):
670+
# If PostgREST failed to start, check the logs to see why
671+
log_result = run_ssh_command(host['ssh'], "sudo journalctl -u postgrest --since '5 minutes ago' --no-pager")
672+
print(f"PostgREST failed to start. Recent logs:\n{log_result['stdout']}")
673+
assert False, "PostgREST failed to start after config change"
674+
675+
# Make a test request to trigger any potential session errors
676+
try:
677+
response = requests.get(
678+
f"http://{host['ip']}/rest/v1/",
679+
headers={"apikey": anon_key, "authorization": f"Bearer {anon_key}"},
680+
timeout=10
681+
)
682+
print(f"Test request status: {response.status_code}")
683+
except Exception as e:
684+
print(f"Test request failed: {str(e)}")
685+
686+
# Check PostgREST logs for "session is not read-only" errors
687+
result = run_ssh_command(host['ssh'], "sudo journalctl -u postgrest --since '5 minutes ago' | grep -i 'session is not read-only' || true")
688+
689+
if result['stdout'].strip():
690+
print(f"\nFound 'session is not read-only' errors in PostgREST logs:\n{result['stdout']}")
691+
assert False, "PostgREST logs contain 'session is not read-only' errors even though PostgreSQL is configured for read-only mode"
692+
else:
693+
print("\nNo 'session is not read-only' errors found in PostgREST logs")
694+
695+
finally:
696+
# Restore the original configuration
697+
result = run_ssh_command(host['ssh'], "sudo cp /etc/postgrest/base.conf.backup /etc/postgrest/base.conf")
698+
if result['succeeded']:
699+
result = run_ssh_command(host['ssh'], "sudo systemctl restart postgrest")
700+
if result['succeeded']:
701+
print("Restored original PostgREST configuration")
702+
else:
703+
print("Warning: Failed to restart PostgREST after restoring config")
704+
else:
705+
print("Warning: Failed to restore original PostgREST configuration")
706+
707+
# Restore PostgreSQL to original configuration
708+
result = run_ssh_command(host['ssh'], f"sudo cp {config_file}.backup {config_file}")
709+
if result['succeeded']:
710+
result = run_ssh_command(host['ssh'], "sudo systemctl restart postgresql")
711+
if result['succeeded']:
712+
print("Restored PostgreSQL to original configuration")
713+
else:
714+
print("Warning: Failed to restart PostgreSQL after restoring config")
715+
else:
716+
print("Warning: Failed to restore PostgreSQL configuration")
550717

0 commit comments

Comments
 (0)