Skip to content

Commit 691770e

Browse files
author
avandras
committed
Add the first unit tests
1 parent 76048a7 commit 691770e

File tree

1 file changed

+144
-0
lines changed

1 file changed

+144
-0
lines changed

tests/test_multisite.py

Lines changed: 144 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,144 @@
1+
import json
2+
import os
3+
import sys
4+
import unittest
5+
6+
import etcd
7+
8+
from copy import deepcopy
9+
from unittest.mock import MagicMock, Mock, mock_open, patch, PropertyMock
10+
11+
from patroni import config, dcs
12+
from patroni import multisite
13+
from patroni.multisite import MultisiteController
14+
from patroni.dcs import Member
15+
from patroni.dcs.etcd import AbstractEtcdClientWithFailover
16+
17+
from tests.test_ha import Config
18+
from .test_etcd import etcd_read, etcd_write, socket_getaddrinfo
19+
from .test_ha import get_cluster_initialized_with_leader
20+
21+
# def get_cluster_config():
22+
# return Config({"name": "", "scope": "alpha", "namespace": "batman", "loop_wait": 10, "ttl": 30, "retry_timeout": 10,
23+
# "multisite": {"ttl": 90}})
24+
25+
PATRONI_CONFIG = """
26+
scope: mstest
27+
restapi:
28+
listen: 0.0.0.0:8008
29+
bootstrap:
30+
postgresql:
31+
name: foo
32+
data_dir: data/postgresql0
33+
pg_rewind:
34+
username: postgres
35+
password: postgres
36+
etcd:
37+
host: localhost
38+
multisite:
39+
name: mstest
40+
namespace: /multisite/
41+
etcd:
42+
host: localhost
43+
host: 127.0.0.1
44+
port: 5432
45+
ttl: 90
46+
retry_timeout: 40
47+
"""
48+
49+
STANDBY_CONFIG = {
50+
"host": "10.0.0.1",
51+
"port": 5432,
52+
"create_replica_methods": ["basebackup"],
53+
"leader_site": "other_dc"
54+
}
55+
56+
def get_member():
57+
return Member.from_node(1, 'other_dc', 1, json.dumps(STANDBY_CONFIG))
58+
59+
def get_member_with_wrong_data():
60+
c = deepcopy(STANDBY_CONFIG)
61+
c.pop("host")
62+
with patch.dict(STANDBY_CONFIG, c):
63+
return Member.from_node(1, 'other_dc', 1, json.dumps(c))
64+
65+
# def get_clusterleader():
66+
67+
68+
@patch.object(etcd.Client, 'write', etcd_write)
69+
# @patch.object(etcd.Client, 'read', etcd_read)
70+
@patch.object(etcd.Client, 'delete', Mock(side_effect=etcd.EtcdException))
71+
class TestMultisite(unittest.TestCase):
72+
73+
@patch('patroni.dcs.dcs_modules', Mock(return_value=['patroni.dcs.etcd']))
74+
@patch.object(etcd.Client, 'read', etcd_read)
75+
def setUp(self):
76+
super(TestMultisite, self).setUp()
77+
os.environ[Config.PATRONI_CONFIG_VARIABLE] = PATRONI_CONFIG
78+
79+
self.config = Config(None)
80+
self.multisite = MultisiteController(self.config)
81+
82+
def test_get_dcs_config(self):
83+
# test if keys are inherited from 'main' config
84+
# assert elements of the returned msconfig match what's expected
85+
86+
# TODO: check if host and port are used from main config if not in config
87+
msconfig, _ = MultisiteController.get_dcs_config(self.config)
88+
self.assertEqual(msconfig["multisite"], True)
89+
self.assertEqual(msconfig["ttl"], 90)
90+
self.assertEqual(msconfig["scope"], "mstest")
91+
92+
def test_status(self):
93+
s = self.multisite.status()
94+
self.assertEqual(s["status"], "Leader")
95+
self.assertEqual(s["name"], "mstest")
96+
97+
# TODO: test standby_config and Standby as status
98+
99+
def test_set_standby_config(self):
100+
r = self.multisite._set_standby_config(get_member_with_wrong_data())
101+
self.assertTrue(r)
102+
self.assertEqual(self.multisite.get_active_standby_config(), {"restore_command": "false"})
103+
104+
r = self.multisite._set_standby_config(get_member())
105+
self.assertTrue(r)
106+
self.assertEqual(self.multisite.get_active_standby_config(), STANDBY_CONFIG)
107+
r = self.multisite._set_standby_config(get_member())
108+
self.assertFalse(r)
109+
110+
def test_observe_leader(self):
111+
# no leader
112+
with patch('patroni.dcs.Cluster.leader_name', ''), \
113+
patch('patroni.multisite.MultisiteController._disconnected_operation') as disco:
114+
self.multisite._observe_leader()
115+
disco.assert_called_once()
116+
with patch('patroni.dcs.Cluster.leader', get_cluster_initialized_with_leader().leader), \
117+
patch('patroni.multisite.MultisiteController._set_standby_config') as ssc:
118+
# can we avoid producing another instance? when trying to patch either multisite or the already patched
119+
# object, I receive AttributeError: can't delete attribute
120+
os.environ[Config.PATRONI_CONFIG_VARIABLE] = PATRONI_CONFIG.replace('name: mstest', 'name: leader')
121+
self.config = Config(None)
122+
self.m = MultisiteController(self.config)
123+
124+
self.m._observe_leader()
125+
self.assertIsNone(self.m.get_active_standby_config())
126+
127+
self.multisite._observe_leader()
128+
ssc.assert_called_once()
129+
130+
131+
132+
133+
def test_resolve_leader(self):
134+
# can we test these Event() based things?
135+
pass
136+
137+
138+
# def test_get_dcs_config_exception(self):
139+
# print(self.config.local_configuration)
140+
# with patch(self.config.local_configuration, new_callable=PropertyMock) as local_config:
141+
# local_config["multisite"]["etcd"]["host"] = ""
142+
# self.assertRaises(Exception, MultisiteController.get_dcs_config)
143+
# # _local_configuration["multisite"]["etcd"]["host"])
144+
# # self.assertRaises(Exception, _) # FIXME: ? into separate case?

0 commit comments

Comments
 (0)