Files
pgcat/tests/python/test_pgcat.py

259 lines
7.5 KiB
Python
Raw Normal View History

import os
import signal
import time
2022-02-03 18:02:50 -08:00
2024-09-03 18:38:43 -05:00
import psycopg2
2024-09-03 18:38:43 -05:00
import utils
2024-09-03 18:38:43 -05:00
SHUTDOWN_TIMEOUT = 5
def test_normal_db_access():
2024-09-03 18:38:43 -05:00
utils.pgcat_start()
conn, cur = utils.connect_db(autocommit=False)
cur.execute("SELECT 1")
res = cur.fetchall()
print(res)
2024-09-03 18:38:43 -05:00
utils.cleanup_conn(conn, cur)
2022-02-03 18:02:50 -08:00
2022-02-03 18:13:36 -08:00
def test_admin_db_access():
2024-09-03 18:38:43 -05:00
conn, cur = utils.connect_db(admin=True)
cur.execute("SHOW POOLS")
res = cur.fetchall()
print(res)
2024-09-03 18:38:43 -05:00
utils.cleanup_conn(conn, cur)
def test_shutdown_logic():
# - - - - - - - - - - - - - - - - - -
# NO ACTIVE QUERIES SIGINT HANDLING
# Start pgcat
2024-09-03 18:38:43 -05:00
utils.pgcat_start()
# Create client connection and send query (not in transaction)
2024-09-03 18:38:43 -05:00
conn, cur = utils.connect_db()
cur.execute("BEGIN;")
cur.execute("SELECT 1;")
cur.execute("COMMIT;")
# Send sigint to pgcat
2024-09-03 18:38:43 -05:00
utils.pg_cat_send_signal(signal.SIGINT)
time.sleep(1)
# Check that any new queries fail after sigint since server should close with no active transactions
try:
cur.execute("SELECT 1;")
except psycopg2.OperationalError as e:
pass
else:
# Fail if query execution succeeded
raise Exception("Server not closed after sigint")
2024-09-03 18:38:43 -05:00
utils.cleanup_conn(conn, cur)
utils.pg_cat_send_signal(signal.SIGTERM)
# - - - - - - - - - - - - - - - - - -
# NO ACTIVE QUERIES ADMIN SHUTDOWN COMMAND
# Start pgcat
2024-09-03 18:38:43 -05:00
utils.pgcat_start()
# Create client connection and begin transaction
2024-09-03 18:38:43 -05:00
conn, cur = utils.connect_db()
admin_conn, admin_cur = utils.connect_db(admin=True)
cur.execute("BEGIN;")
cur.execute("SELECT 1;")
cur.execute("COMMIT;")
# Send SHUTDOWN command pgcat while not in transaction
admin_cur.execute("SHUTDOWN;")
time.sleep(1)
# Check that any new queries fail after SHUTDOWN command since server should close with no active transactions
try:
cur.execute("SELECT 1;")
except psycopg2.OperationalError as e:
pass
else:
# Fail if query execution succeeded
raise Exception("Server not closed after sigint")
2024-09-03 18:38:43 -05:00
utils.cleanup_conn(conn, cur)
utils.cleanup_conn(admin_conn, admin_cur)
utils.pg_cat_send_signal(signal.SIGTERM)
# - - - - - - - - - - - - - - - - - -
# HANDLE TRANSACTION WITH SIGINT
# Start pgcat
2024-09-03 18:38:43 -05:00
utils.pgcat_start()
# Create client connection and begin transaction
2024-09-03 18:38:43 -05:00
conn, cur = utils.connect_db()
cur.execute("BEGIN;")
cur.execute("SELECT 1;")
# Send sigint to pgcat while still in transaction
2024-09-03 18:38:43 -05:00
utils.pg_cat_send_signal(signal.SIGINT)
time.sleep(1)
# Check that any new queries succeed after sigint since server should still allow transaction to complete
try:
cur.execute("SELECT 1;")
except psycopg2.OperationalError as e:
# Fail if query fails since server closed
raise Exception("Server closed while in transaction", e.pgerror)
2024-09-03 18:38:43 -05:00
utils.cleanup_conn(conn, cur)
utils.pg_cat_send_signal(signal.SIGTERM)
# - - - - - - - - - - - - - - - - - -
# HANDLE TRANSACTION WITH ADMIN SHUTDOWN COMMAND
# Start pgcat
2024-09-03 18:38:43 -05:00
utils.pgcat_start()
# Create client connection and begin transaction
2024-09-03 18:38:43 -05:00
conn, cur = utils.connect_db()
admin_conn, admin_cur = utils.connect_db(admin=True)
cur.execute("BEGIN;")
cur.execute("SELECT 1;")
# Send SHUTDOWN command pgcat while still in transaction
admin_cur.execute("SHUTDOWN;")
if admin_cur.fetchall()[0][0] != "t":
raise Exception("PgCat unable to send signal")
time.sleep(1)
# Check that any new queries succeed after SHUTDOWN command since server should still allow transaction to complete
try:
cur.execute("SELECT 1;")
except psycopg2.OperationalError as e:
# Fail if query fails since server closed
raise Exception("Server closed while in transaction", e.pgerror)
2024-09-03 18:38:43 -05:00
utils.cleanup_conn(conn, cur)
utils.cleanup_conn(admin_conn, admin_cur)
utils.pg_cat_send_signal(signal.SIGTERM)
# - - - - - - - - - - - - - - - - - -
# NO NEW NON-ADMIN CONNECTIONS DURING SHUTDOWN
# Start pgcat
2024-09-03 18:38:43 -05:00
utils.pgcat_start()
# Create client connection and begin transaction
2024-09-03 18:38:43 -05:00
transaction_conn, transaction_cur = utils.connect_db()
transaction_cur.execute("BEGIN;")
transaction_cur.execute("SELECT 1;")
# Send sigint to pgcat while still in transaction
2024-09-03 18:38:43 -05:00
utils.pg_cat_send_signal(signal.SIGINT)
time.sleep(1)
start = time.perf_counter()
try:
2024-09-03 18:38:43 -05:00
conn, cur = utils.connect_db()
cur.execute("SELECT 1;")
2024-09-03 18:38:43 -05:00
utils.cleanup_conn(conn, cur)
except psycopg2.OperationalError as e:
time_taken = time.perf_counter() - start
if time_taken > 0.1:
raise Exception(
"Failed to reject connection within 0.1 seconds, got", time_taken, "seconds")
pass
else:
raise Exception("Able connect to database during shutdown")
2024-09-03 18:38:43 -05:00
utils.cleanup_conn(transaction_conn, transaction_cur)
utils.pg_cat_send_signal(signal.SIGTERM)
# - - - - - - - - - - - - - - - - - -
# ALLOW NEW ADMIN CONNECTIONS DURING SHUTDOWN
# Start pgcat
2024-09-03 18:38:43 -05:00
utils.pgcat_start()
# Create client connection and begin transaction
2024-09-03 18:38:43 -05:00
transaction_conn, transaction_cur = utils.connect_db()
transaction_cur.execute("BEGIN;")
transaction_cur.execute("SELECT 1;")
# Send sigint to pgcat while still in transaction
2024-09-03 18:38:43 -05:00
utils.pg_cat_send_signal(signal.SIGINT)
time.sleep(1)
try:
2024-09-03 18:38:43 -05:00
conn, cur = utils.connect_db(admin=True)
cur.execute("SHOW DATABASES;")
2024-09-03 18:38:43 -05:00
utils.cleanup_conn(conn, cur)
except psycopg2.OperationalError as e:
raise Exception(e)
2024-09-03 18:38:43 -05:00
utils.cleanup_conn(transaction_conn, transaction_cur)
utils.pg_cat_send_signal(signal.SIGTERM)
# - - - - - - - - - - - - - - - - - -
# ADMIN CONNECTIONS CONTINUING TO WORK AFTER SHUTDOWN
# Start pgcat
2024-09-03 18:38:43 -05:00
utils.pgcat_start()
# Create client connection and begin transaction
2024-09-03 18:38:43 -05:00
transaction_conn, transaction_cur = utils.connect_db()
transaction_cur.execute("BEGIN;")
transaction_cur.execute("SELECT 1;")
2024-09-03 18:38:43 -05:00
admin_conn, admin_cur = utils.connect_db(admin=True)
admin_cur.execute("SHOW DATABASES;")
# Send sigint to pgcat while still in transaction
2024-09-03 18:38:43 -05:00
utils.pg_cat_send_signal(signal.SIGINT)
time.sleep(1)
try:
admin_cur.execute("SHOW DATABASES;")
except psycopg2.OperationalError as e:
raise Exception("Could not execute admin command:", e)
2024-09-03 18:38:43 -05:00
utils.cleanup_conn(transaction_conn, transaction_cur)
utils.cleanup_conn(admin_conn, admin_cur)
utils.pg_cat_send_signal(signal.SIGTERM)
# - - - - - - - - - - - - - - - - - -
# HANDLE SHUTDOWN TIMEOUT WITH SIGINT
# Start pgcat
2024-09-03 18:38:43 -05:00
utils.pgcat_start()
# Create client connection and begin transaction, which should prevent server shutdown unless shutdown timeout is reached
2024-09-03 18:38:43 -05:00
conn, cur = utils.connect_db()
cur.execute("BEGIN;")
cur.execute("SELECT 1;")
# Send sigint to pgcat while still in transaction
2024-09-03 18:38:43 -05:00
utils.pg_cat_send_signal(signal.SIGINT)
# pgcat shutdown timeout is set to SHUTDOWN_TIMEOUT seconds, so we sleep for SHUTDOWN_TIMEOUT + 1 seconds
time.sleep(SHUTDOWN_TIMEOUT + 1)
# Check that any new queries succeed after sigint since server should still allow transaction to complete
try:
cur.execute("SELECT 1;")
except psycopg2.OperationalError as e:
pass
else:
# Fail if query execution succeeded
raise Exception("Server not closed after sigint and expected timeout")
2024-09-03 18:38:43 -05:00
utils.cleanup_conn(conn, cur)
utils.pg_cat_send_signal(signal.SIGTERM)