Files
managed-containerd/tests/test-promote-database.py

226 lines
5.0 KiB
Python
Executable File

#!/usr/bin/env python3
import importlib.util
import sys
import time
import types
from pathlib import Path
fake_psycopg2 = types.ModuleType("psycopg2")
fake_psycopg2.Error = Exception
fake_psycopg2.OperationalError = OSError
fake_extras = types.ModuleType("psycopg2.extras")
fake_extras.RealDictCursor = object
fake_psycopg2.extras = fake_extras
sys.modules["psycopg2"] = fake_psycopg2
sys.modules["psycopg2.extras"] = fake_extras
spec = importlib.util.spec_from_file_location(
"postgresql_plugin",
Path("plugins/postgresql/plugin.py"),
)
plugin = importlib.util.module_from_spec(spec)
spec.loader.exec_module(plugin)
def standby_monitor(*, eligible=True):
return {
"ha": {
"ocf_rc": plugin.OCF_SUCCESS,
"health": "healthy",
"ha_role": "unpromoted",
"state": "streaming",
"promotion_eligible": eligible,
},
"role": "standby",
"in_recovery": True,
"streaming": True,
}
def peer_state(*primaries):
return {
"peers": [],
"writable_primaries": list(primaries),
"writable_primary_count": len(primaries),
}
config = {
"PACEMAKER_NODE_NAME": "david-eve",
"PGPASSWORD_FILE": "/run/secrets/postgres_password",
"PG_REPLICATION_PEERS": (
"david-prodesk=192.168.1.4:5432,"
"david-macbookpro=192.168.1.5:5432,"
"david-eve=192.168.1.3:5432"
),
"PGUSER": "david",
"PGDATABASE": "david",
}
def fresh_state():
return {
"postgresql": {
"notification": {
"type": "pre",
"operation": "promote",
"promote_uname": "david-eve",
"demote_uname": "david-prodesk",
"received_at": time.time(),
},
},
}
plugin.read_secret = lambda path: "test-password"
plugin.monitor = lambda config, runtime_state: standby_monitor()
plugin.probe_replication_peers = (
lambda config, password: peer_state()
)
print("===== PROMOTE DATABASE ACTION =====")
runtime_state = fresh_state()
result = plugin.promote_database(
config,
runtime_state,
{},
)
assert result["ocf_rc"] == plugin.OCF_SUCCESS
assert result["ready"] is True
assert result["mutation"] is False
assert result["reason"] == "promotion_preflight_ready"
assert result["target_node"] == "david-eve"
assert result["previous_primary_node"] == "david-prodesk"
assert result["writable_primary_count"] == 0
assert result["checks"]["local_target"] is True
assert result["checks"]["local_standby"] is True
assert result["checks"]["promotion_eligible"] is True
assert result["checks"]["no_reachable_writable_primary"] is True
print("valid_promotion_preflight accepted")
runtime_state = fresh_state()
runtime_state["postgresql"]["notification"]["promote_uname"] = (
"david-macbookpro"
)
result = plugin.promote_database(
config,
runtime_state,
{},
)
assert result["ocf_rc"] == 1
assert result["ready"] is False
assert result["reason"] == "local_node_not_target"
print("wrong_target rejected")
runtime_state = fresh_state()
runtime_state["postgresql"]["notification"]["received_at"] = (
time.time() - 121
)
result = plugin.promote_database(
config,
runtime_state,
{},
)
assert result["ocf_rc"] == 1
assert result["reason"] == "notification_stale"
print("stale_notification rejected")
result = plugin.promote_database(
config,
{},
{},
)
assert result["ocf_rc"] == 1
assert result["reason"] == "notification_missing"
print("missing_notification rejected")
runtime_state = fresh_state()
plugin.monitor = lambda config, runtime_state: {
"ha": {
"ocf_rc": plugin.OCF_RUNNING_PROMOTED,
"promotion_eligible": True,
},
"role": "primary",
"in_recovery": False,
}
result = plugin.promote_database(
config,
runtime_state,
{},
)
assert result["ocf_rc"] == 1
assert result["ready"] is False
assert result["reason"] == "local_not_promotion_eligible"
assert result["checks"]["local_standby"] is False
print("local_primary rejected")
plugin.monitor = lambda config, runtime_state: standby_monitor(
eligible=False
)
result = plugin.promote_database(
config,
fresh_state(),
{},
)
assert result["ocf_rc"] == 1
assert result["ready"] is False
assert result["checks"]["promotion_eligible"] is False
print("ineligible_standby rejected")
plugin.monitor = lambda config, runtime_state: standby_monitor()
plugin.probe_replication_peers = (
lambda config, password: peer_state("david-prodesk")
)
result = plugin.promote_database(
config,
fresh_state(),
{},
)
assert result["ocf_rc"] == plugin.OCF_ERR_GENERIC
assert result["ready"] is False
assert result["mutation"] is False
assert result["reason"] == "reachable_writable_primary"
assert result["writable_primary_count"] == 1
assert result["writable_primaries"] == ["david-prodesk"]
assert result["checks"]["no_reachable_writable_primary"] is False
print("existing_primary rejected")
print()
print("PROMOTE_DATABASE_TEST_PASS=1")