#!/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) runtime_state = { "postgresql": { "notification": { "type": "pre", "operation": "demote", "demote_uname": "david-eve", "promote_uname": "david-prodesk", "received_at": time.time(), }, }, } result = plugin.demote_prepare( { "PACEMAKER_NODE_NAME": "david-eve", "PG_REPLICATION_PEERS": ( "david-prodesk=192.168.1.4:5432," "david-eve=192.168.1.3:5432" ), }, runtime_state, {}, ) assert result["ocf_rc"] == 0 assert result["ready"] is False assert result["identity_validated"] is True assert result["reason"] == "database_checks_pending" assert result["checks"]["database_checks"] is False assert result["checks"]["peer_map"] is True assert result["successor_host"] == "192.168.1.4" assert result["successor_port"] == 5432 assert result["mutation"] is False assert result["successor_node"] == "david-prodesk" print("valid_prepare accepted") result = plugin.demote_prepare( {"PACEMAKER_NODE_NAME": "david-macbookpro"}, runtime_state, {}, ) assert result["ocf_rc"] == 1 assert result["reason"] == "local_node_not_target" print("wrong_target rejected") runtime_state["postgresql"]["notification"]["received_at"] = ( time.time() - 121 ) result = plugin.demote_prepare( {"PACEMAKER_NODE_NAME": "david-eve"}, runtime_state, {}, ) assert result["ocf_rc"] == 1 assert result["reason"] == "notification_stale" print("stale_notification rejected") runtime_state["postgresql"]["notification"]["received_at"] = time.time() runtime_state["postgresql"]["notification"]["promote_uname"] = "" result = plugin.demote_prepare( {"PACEMAKER_NODE_NAME": "david-eve"}, runtime_state, {}, ) assert result["ocf_rc"] == 1 assert result["reason"] == "successor_missing" print("missing_successor rejected") print() print("DEMOTE_PREPARE_TEST_PASS=1") result = plugin.demote_prepare( { "PACEMAKER_NODE_NAME": "david-eve", "PG_REPLICATION_PEERS": ( "david-macbookpro=192.168.1.5:5432" ), }, { "postgresql": { "notification": { "type": "pre", "operation": "demote", "demote_uname": "david-eve", "promote_uname": "david-prodesk", "received_at": time.time(), }, }, }, {}, ) assert result["ocf_rc"] == 1 assert result["reason"] == "successor_not_configured" print("unconfigured_successor rejected")