@@ -510,12 +510,24 @@ def test_postgrest_ending_empty_key_query_parameter_is_removed(host):
510
510
511
511
512
512
def test_postgresql_version (host ):
513
- """Print the PostgreSQL version being tested."""
513
+ """Print the PostgreSQL version being tested and ensure it's >= 14 ."""
514
514
result = run_ssh_command (host ['ssh' ], "sudo -u postgres psql -c 'SELECT version();'" )
515
515
if result ['succeeded' ]:
516
516
print (f"\n PostgreSQL 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"
517
528
else :
518
529
print (f"\n Failed to get PostgreSQL version: { result ['stderr' ]} " )
530
+ assert False , "Failed to get PostgreSQL version"
519
531
520
532
# Also get the version from the command line
521
533
result = run_ssh_command (host ['ssh' ], "sudo -u postgres psql --version" )
@@ -524,27 +536,182 @@ def test_postgresql_version(host):
524
536
else :
525
537
print (f"Failed to get PostgreSQL client version: { result ['stderr' ]} " )
526
538
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"\n libpq5 package info:\n { result ['stdout' ]} " )
548
+ else :
549
+ print ("\n libpq5 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"\n libpq files found:\n { result ['stdout' ]} " )
555
+ else :
556
+ print ("\n No 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"\n psql libpq dependency:\n { result ['stdout' ]} " )
562
+ else :
563
+ print ("\n Could not find libpq dependency for psql" )
564
+
527
565
# This test always passes, it's just for informational purposes
528
566
assert True
529
567
530
568
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"
535
588
536
- if result ['stdout' ].strip ():
537
- print (f"\n Found 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 } " )
539
594
else :
540
- print ("\n No 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"
541
609
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 )
544
612
545
- if result ['stdout' ].strip ():
546
- print (f"\n Found 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 } " )
548
618
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"\n Found '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 ("\n No '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" )
550
717
0 commit comments