diff --git a/tests/test_api.py b/tests/test_api.py index 5790f8d4..1a3d00ce 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -11,7 +11,7 @@ import socket from test_postgresql import psycopg2_connect, MockCursor -class MockPostgresql(Mock): +class MockPostgresql(object): name = 'test' state = 'running' @@ -23,20 +23,12 @@ class MockPostgresql(Mock): def connection(): return psycopg2_connect() - @staticmethod - def is_running(): - return True - -class MockHa(Mock): +class MockHa(object): dcs = Mock() state_handler = MockPostgresql() - @staticmethod - def schedule_restart(): - return 'restart' - @staticmethod def schedule_reinitialize(): return 'reinitialize' @@ -54,7 +46,7 @@ class MockHa(Mock): return [[None, True, None, None, {}]] -class MockPatroni(Mock): +class MockPatroni(object): postgresql = MockPostgresql() ha = MockHa() diff --git a/tests/test_ctl.py b/tests/test_ctl.py index 806b567d..95dd5a07 100644 --- a/tests/test_ctl.py +++ b/tests/test_ctl.py @@ -5,13 +5,13 @@ import requests.exceptions import unittest from click.testing import CliRunner -from mock import patch, Mock, MagicMock +from mock import patch, Mock from patroni.ctl import ctl, members, store_config, load_config, output_members, post_patroni, get_dcs, \ wait_for_leader, get_all_members, get_any_member, get_cursor, query_member, configure from patroni.etcd import Etcd, Client from patroni.exceptions import PatroniCtlException from psycopg2 import OperationalError -from test_etcd import etcd_read, etcd_write, requests_get, socket_getaddrinfo, MockResponse +from test_etcd import etcd_read, requests_get, socket_getaddrinfo, MockResponse from test_zookeeper import MockKazooClient from test_ha import get_cluster_initialized_without_leader, get_cluster_initialized_with_leader, \ get_cluster_initialized_with_only_leader @@ -44,9 +44,6 @@ def test_rw_config(): @patch('patroni.ctl.load_config', Mock(return_value={'dcs': {'scheme': 'etcd', 'hostname': 'localhost', 'port': 4001}})) -@patch.object(etcd.Client, 'write', etcd_write) -@patch.object(etcd.Client, 'read', etcd_read) -@patch.object(etcd.Client, 'delete', Mock(side_effect=etcd.EtcdException)) class TestCtl(unittest.TestCase): @patch('socket.getaddrinfo', socket_getaddrinfo) @@ -75,71 +72,64 @@ class TestCtl(unittest.TestCase): @patch('patroni.etcd.Etcd.get_cluster', Mock(return_value=get_cluster_initialized_with_leader())) @patch('patroni.etcd.Etcd.get_etcd_client', Mock(return_value=None)) - @patch('patroni.etcd.Etcd.set_failover_value', Mock(return_value=None)) - @patch('patroni.ctl.wait_for_leader', Mock(return_value=get_cluster_initialized_with_leader())) - @patch('requests.get', requests_get) - @patch('requests.post', requests_get) @patch('patroni.ctl.post_patroni', Mock(return_value=MockResponse())) def test_failover(self): - with patch('patroni.etcd.Etcd.get_cluster', Mock(return_value=get_cluster_initialized_with_leader())): - result = self.runner.invoke(ctl, ['failover', 'dummy', '--dcs', '8.8.8.8'], input='''leader + result = self.runner.invoke(ctl, ['failover', 'dummy', '--dcs', '8.8.8.8'], input='''leader other y''') - assert 'leader' in result.output + assert 'leader' in result.output - result = self.runner.invoke(ctl, ['failover', 'dummy', '--dcs', '8.8.8.8'], input='''leader + result = self.runner.invoke(ctl, ['failover', 'dummy', '--dcs', '8.8.8.8'], input='''leader other 2100-01-01T12:23:00 y''') - assert result.exit_code == 0 + assert result.exit_code == 0 - result = self.runner.invoke(ctl, ['failover', 'dummy', '--dcs', '8.8.8.8'], input='''leader + result = self.runner.invoke(ctl, ['failover', 'dummy', '--dcs', '8.8.8.8'], input='''leader other 2030-01-01T12:23:00 y''') - assert result.exit_code == 0 + assert result.exit_code == 0 - # Aborting failover,as we anser NO to the confirmation - result = self.runner.invoke(ctl, ['failover', 'dummy', '--dcs', '8.8.8.8'], input='''leader + # Aborting failover,as we anser NO to the confirmation + result = self.runner.invoke(ctl, ['failover', 'dummy', '--dcs', '8.8.8.8'], input='''leader other N''') - assert result.exit_code == 1 + assert result.exit_code == 1 - # Target and source are equal - result = self.runner.invoke(ctl, ['failover', 'dummy', '--dcs', '8.8.8.8'], input='''leader + # Target and source are equal + result = self.runner.invoke(ctl, ['failover', 'dummy', '--dcs', '8.8.8.8'], input='''leader leader y''') - assert result.exit_code == 1 + assert result.exit_code == 1 - # Reality is not part of this cluster - result = self.runner.invoke(ctl, ['failover', 'dummy', '--dcs', '8.8.8.8'], input='''leader + # Reality is not part of this cluster + result = self.runner.invoke(ctl, ['failover', 'dummy', '--dcs', '8.8.8.8'], input='''leader Reality y''') - assert result.exit_code == 1 + assert result.exit_code == 1 - result = self.runner.invoke(ctl, ['failover', 'dummy', '--force']) - assert 'Member' in result.output + result = self.runner.invoke(ctl, ['failover', 'dummy', '--force']) + assert 'Member' in result.output - result = self.runner.invoke(ctl, ['failover', 'dummy', '--force', - '--scheduled', '2015-01-01T12:00:00+01:00']) - assert result.exit_code == 0 + result = self.runner.invoke(ctl, ['failover', 'dummy', '--force', '--scheduled', '2015-01-01T12:00:00+01:00']) + assert result.exit_code == 0 - # Invalid timestamp - result = self.runner.invoke(ctl, ['failover', 'dummy', '--force', '--scheduled', 'invalid']) - assert result.exit_code != 0 + # Invalid timestamp + result = self.runner.invoke(ctl, ['failover', 'dummy', '--force', '--scheduled', 'invalid']) + assert result.exit_code != 0 - # Invalid timestamp - result = self.runner.invoke(ctl, ['failover', 'dummy', '--force', - '--scheduled', '2115-02-30T12:00:00+01:00']) - assert result.exit_code != 0 + # Invalid timestamp + result = self.runner.invoke(ctl, ['failover', 'dummy', '--force', '--scheduled', '2115-02-30T12:00:00+01:00']) + assert result.exit_code != 0 - # Specifying wrong leader - result = self.runner.invoke(ctl, ['failover', 'dummy', '--dcs', '8.8.8.8'], input='dummy') - assert result.exit_code == 1 + # Specifying wrong leader + result = self.runner.invoke(ctl, ['failover', 'dummy', '--dcs', '8.8.8.8'], input='dummy') + assert result.exit_code == 1 with patch('patroni.etcd.Etcd.get_cluster', Mock(return_value=get_cluster_initialized_with_only_leader())): # No members available @@ -157,7 +147,7 @@ other y''') assert result.exit_code == 1 - with patch('patroni.ctl.post_patroni', Mock(side_effect=Exception())): + with patch('patroni.ctl.post_patroni', Mock(side_effect=Exception)): # Non-responding patroni result = self.runner.invoke(ctl, ['failover', 'dummy', '--dcs', '8.8.8.8'], input='''leader other @@ -165,9 +155,8 @@ other y''') assert 'falling back to DCS' in result.output - mocked = Mock() - mocked.return_value.status_code = 500 - with patch('patroni.ctl.post_patroni', Mock(return_value=mocked)): + with patch('patroni.ctl.post_patroni') as mocked: + mocked.return_value.status_code = 500 result = self.runner.invoke(ctl, ['failover', 'dummy', '--dcs', '8.8.8.8'], input='''leader other @@ -183,17 +172,11 @@ y''') @patch('psycopg2.connect', psycopg2_connect) @patch('patroni.ctl.query_member', Mock(return_value=([['mock column']], None))) + @patch.object(etcd.Client, 'read', etcd_read) def test_query(self): with patch('patroni.ctl.get_dcs', Mock(return_value=self.e)): # Mutually exclusive - result = self.runner.invoke(ctl, [ - 'query', - 'alpha', - '--member', - 'abc', - '--role', - 'master', - ]) + result = self.runner.invoke(ctl, ['query', 'alpha', '--member', 'abc', '--role', 'master']) assert result.exit_code == 1 with self.runner.isolated_filesystem(): @@ -201,17 +184,11 @@ y''') dummy_file.write('SELECT 1') # Mutually exclusive - result = self.runner.invoke(ctl, [ - 'query', - 'alpha', - '--file', - 'dummy', - '--command', - 'dummy', - ]) + result = self.runner.invoke(ctl, ['query', 'alpha', '--file', 'dummy', '--command', 'dummy']) assert result.exit_code == 1 result = self.runner.invoke(ctl, ['query', 'alpha', '--file', 'dummy']) + assert result.exit_code == 0 os.remove('dummy') @@ -226,13 +203,16 @@ y''') '--password', '--dbname', 'postgres'], input='ab\nab') assert 'mock column' in result.output - @patch('patroni.ctl.get_cursor', Mock(return_value=MockConnect().cursor())) def test_query_member(self): - rows = query_member(None, None, None, 'master', 'SELECT pg_is_in_recovery()') - self.assertTrue('False' in str(rows)) + with patch('patroni.ctl.get_cursor', Mock(return_value=MockConnect().cursor())): + rows = query_member(None, None, None, 'master', 'SELECT pg_is_in_recovery()') + self.assertTrue('False' in str(rows)) - rows = query_member(None, None, None, 'replica', 'SELECT pg_is_in_recovery()') - self.assertEquals(rows, (None, None)) + rows = query_member(None, None, None, 'replica', 'SELECT pg_is_in_recovery()') + self.assertEquals(rows, (None, None)) + + with patch('test_postgresql.MockCursor.execute', Mock(side_effect=OperationalError('bla'))): + rows = query_member(None, None, None, 'replica', 'SELECT pg_is_in_recovery()') with patch('patroni.ctl.get_cursor', Mock(return_value=None)): rows = query_member(None, None, None, None, 'SELECT pg_is_in_recovery()') @@ -244,9 +224,6 @@ y''') with patch('patroni.ctl.get_cursor', Mock(side_effect=OperationalError('bla'))): rows = query_member(None, None, None, 'replica', 'SELECT pg_is_in_recovery()') - with patch('test_postgresql.MockCursor.execute', Mock(side_effect=OperationalError('bla'))): - rows = query_member(None, None, None, 'replica', 'SELECT pg_is_in_recovery()') - @patch('patroni.dcs.AbstractDCS.get_cluster', Mock(return_value=get_cluster_initialized_with_leader())) def test_dsn(self): with patch('patroni.ctl.get_dcs', Mock(return_value=self.e)): @@ -254,14 +231,7 @@ y''') assert 'host=127.0.0.1 port=5435' in result.output # Mutually exclusive options - result = self.runner.invoke(ctl, [ - 'dsn', - 'alpha', - '--role', - 'master', - '--member', - 'dummy', - ]) + result = self.runner.invoke(ctl, ['dsn', 'alpha', '--role', 'master', '--member', 'dummy']) assert result.exit_code == 1 # Non-existing member @@ -270,7 +240,6 @@ y''') @patch('patroni.etcd.Etcd.get_cluster', Mock(return_value=get_cluster_initialized_with_leader())) @patch('patroni.etcd.Etcd.get_etcd_client', Mock(return_value=None)) - @patch('requests.get', requests_get) @patch('requests.post', requests_get) def test_restart_reinit(self): result = self.runner.invoke(ctl, ['restart', 'alpha', '--dcs', '8.8.8.8'], input='y') @@ -284,20 +253,15 @@ y''') assert result.exit_code == 1 # Not a member - result = self.runner.invoke(ctl, [ - 'restart', - 'alpha', - '--dcs', - '8.8.8.8', - 'dummy', - '--any', - ], input='y') + result = self.runner.invoke(ctl, ['restart', 'alpha', '--dcs', '8.8.8.8', 'dummy', '--any'], input='y') assert result.exit_code == 1 with patch('requests.post', Mock(return_value=MockResponse())): result = self.runner.invoke(ctl, ['restart', 'alpha', '--dcs', '8.8.8.8'], input='y') + assert result.exit_code == 0 @patch('patroni.etcd.Etcd.get_cluster', Mock(return_value=get_cluster_initialized_with_leader())) + @patch.object(etcd.Client, 'delete', Mock(side_effect=etcd.EtcdException)) def test_remove(self): with patch('patroni.ctl.get_dcs', Mock(return_value=self.e)): result = self.runner.invoke(ctl, ['remove', 'alpha', '--dcs', '8.8.8.8'], input='alpha\nslave') @@ -324,16 +288,15 @@ leader''') @patch('patroni.etcd.Etcd.watch', Mock(return_value=None)) @patch('patroni.etcd.Etcd.get_cluster', Mock(return_value=get_cluster_initialized_with_leader())) def test_wait_for_leader(self): - dcs = self.e - self.assertRaises(PatroniCtlException, wait_for_leader, dcs, 0) + self.assertRaises(PatroniCtlException, wait_for_leader, self.e, 0) - cluster = wait_for_leader(dcs=dcs, timeout=2) + cluster = wait_for_leader(self.e, timeout=2) assert cluster.leader.member.name == 'leader' + @patch('requests.post', Mock(side_effect=requests.exceptions.ConnectionError('foo'))) def test_post_patroni(self): - with patch('requests.post', MagicMock(side_effect=requests.exceptions.ConnectionError('foo'))): - member = get_cluster_initialized_with_leader().leader.member - self.assertRaises(requests.exceptions.ConnectionError, post_patroni, member, 'dummy', {}) + member = get_cluster_initialized_with_leader().leader.member + self.assertRaises(requests.exceptions.ConnectionError, post_patroni, member, 'dummy', {}) def test_ctl(self): self.runner.invoke(ctl, ['list']) @@ -362,20 +325,10 @@ leader''') @patch('patroni.etcd.Etcd.get_cluster', Mock(return_value=get_cluster_initialized_with_leader())) @patch('patroni.etcd.Etcd.get_etcd_client', Mock(return_value=None)) - @patch('requests.get', requests_get) - @patch('requests.post', requests_get) def test_members(self): result = self.runner.invoke(members, ['alpha']) assert result.exit_code == 0 def test_configure(self): - result = self.runner.invoke(configure, [ - '--dcs', - 'abc', - '-c', - 'dummy', - '-n', - 'bla', - ]) - + result = self.runner.invoke(configure, ['--dcs', 'abc', '-c', 'dummy', '-n', 'bla']) assert result.exit_code == 0 diff --git a/tests/test_etcd.py b/tests/test_etcd.py index 9ed5af58..742c57c5 100644 --- a/tests/test_etcd.py +++ b/tests/test_etcd.py @@ -36,16 +36,6 @@ class MockResponse(object): return '' -class MockPostgresql(Mock): - - server_version = '999999' - scope = 'dummy' - - @staticmethod - def last_operation(): - return '0' - - def requests_get(url, **kwargs): members = '[{"id":14855829450254237642,"peerURLs":["http://localhost:2380","http://localhost:7001"],' +\ '"name":"default","clientURLs":["http://localhost:2379","http://localhost:4001"]}]' @@ -73,8 +63,6 @@ def etcd_watch(self, key, index=None, timeout=None, recursive=None): raise etcd.EtcdException elif index == 20729: return etcd.EtcdResult('set', {'value': 'postgresql1', 'modifiedIndex': index + 1}) - elif index == 20731: - return etcd.EtcdResult('set', {'value': 'postgresql2', 'modifiedIndex': index + 1}) def etcd_write(self, key, value, **kwargs): diff --git a/tests/test_postgresql.py b/tests/test_postgresql.py index fdd321df..932e860d 100644 --- a/tests/test_postgresql.py +++ b/tests/test_postgresql.py @@ -54,10 +54,6 @@ class MockCursor(object): def fetchall(self): return self.results - @staticmethod - def close(): - pass - def __iter__(self): for i in self.results: yield i @@ -69,8 +65,9 @@ class MockCursor(object): pass -class MockConnect(Mock): +class MockConnect(object): + server_version = '99999' autocommit = False closed = 0 @@ -83,6 +80,10 @@ class MockConnect(Mock): def __exit__(self, *args): pass + @staticmethod + def close(): + pass + def pg_controldata_string(*args, **kwargs): return b""" diff --git a/tests/test_wale_restore.py b/tests/test_wale_restore.py index 40761051..9e15dc9b 100644 --- a/tests/test_wale_restore.py +++ b/tests/test_wale_restore.py @@ -6,22 +6,6 @@ from mock import MagicMock, patch, PropertyMock from patroni.scripts.wale_restore import WALERestore, main as _main -def fake_cursor_fetchone(*args, **kwargs): - return ('16777216',) - - -def fake_call_fail_for_wal_e(*args, **kwargs): - if len(args) > 0 and 'backup-fetch' in args[0]: - return 1 - return 0 - - -def fake_call_fail_for_base_backup(*args, **kwargs): - if len(args) > 0 and 'backup-fetch' in args[0]: - return 0 - return 1 - - def fake_backup_data(self, *args, **kwargs): """ return the fake result of WAL-E backup-list""" return """name last_modified expanded_size_bytes wal_segment_backup_start wal_segment_offset_backup_start wal_segment_backup_stop wal_segment_offset_backup_stop @@ -52,7 +36,6 @@ base_00000001000000000000007F_00000040 2015-05-18T10:13:25.000Z 167772160 000 @patch('os.makedirs', MagicMock(return_value=True)) @patch('os.path.exists', MagicMock(return_value=True)) @patch('os.path.isdir', MagicMock(return_value=True)) -@patch('psycopg2.extensions.cursor.fetchone', MagicMock(side_effect=fake_cursor_fetchone)) @patch('psycopg2.extensions.cursor', MagicMock(autospec=True)) @patch('psycopg2.extensions.connection', MagicMock(autospec=True)) @patch('psycopg2.connect', MagicMock(autospec=True)) @@ -60,11 +43,7 @@ base_00000001000000000000007F_00000040 2015-05-18T10:13:25.000Z 167772160 000 class TestWALERestore(unittest.TestCase): def setUp(self): - self.wale_restore = WALERestore("batman", "/data", - "host=batman port=5432 user=batman", "/etc", 100, 100, 1, 0) - - def tearDown(self): - pass + self.wale_restore = WALERestore("batman", "/data", "host=batman port=5432 user=batman", "/etc", 100, 100, 1, 0) def test_should_use_s3_to_create_replica(self): with patch('psycopg2.connect', MagicMock(side_effect=psycopg2.Error("foo"))): diff --git a/tests/test_zookeeper.py b/tests/test_zookeeper.py index d671049d..fe991a2c 100644 --- a/tests/test_zookeeper.py +++ b/tests/test_zookeeper.py @@ -14,7 +14,6 @@ class MockKazooClient(Mock): leader = False exists = True - handler = Mock() @property def client_id(self): @@ -34,8 +33,6 @@ class MockKazooClient(Mock): b'postgres://repuser:rep-pass@localhost:5434/postgres?application_name=http://127.0.0.1:8009/patroni', ZnodeStat(0, 0, 0, 0, 0, 0, 0, 0 if self.exists else -1, 0, 0, 0) ) - elif path.endswith('/optime/leader'): - return (b'1', ZnodeStat(0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0)) elif path.endswith('/leader'): if self.leader: return (b'foo', ZnodeStat(0, 0, 0, 0, 0, 0, 0, -1, 0, 0, 0)) @@ -86,8 +83,6 @@ class MockKazooClient(Mock): raise TypeError("Invalid type for 'path' (string expected)") self.exists = False if path == '/service/test/leader': - if self.leader: - return self.leader = True raise Exception elif path == '/service/test/members/buzz':