diff --git a/patroni/postgresql.py b/patroni/postgresql.py index 1120f842..a0424e3a 100644 --- a/patroni/postgresql.py +++ b/patroni/postgresql.py @@ -930,6 +930,14 @@ $$""".format(name, ' '.join(options)), name, password, password) 90313 >>> Postgresql.postgres_version_to_int('10.1') 100100 + >>> Postgresql.postgres_version_to_int('10') + Traceback (most recent call last): + ... + Exception: Invalid PostgreSQL format: X.Y or X.Y.Z is accepted: 10 + >>> Postgresql.postgres_version_to_int('a.b.c') + Traceback (most recent call last): + ... + Exception: Invalid PostgreSQL version: a.b.c """ components = pg_version.split('.') @@ -943,5 +951,5 @@ $$""".format(name, ' '.join(options)), name, password, password) result = [c if int(c) > 10 else '0{0}'.format(c) for c in components] result = int(''.join(result)) except ValueError: - raise Exception("Exception when parsing PostgreSQL version: {0}".format(pg_version)) + raise Exception("Invalid PostgreSQL version: {0}".format(pg_version)) return result diff --git a/tests/test_api.py b/tests/test_api.py index 9a722b42..44e1662d 100644 --- a/tests/test_api.py +++ b/tests/test_api.py @@ -187,6 +187,13 @@ class TestRestApiHandler(unittest.TestCase): def make_request(request): return '{0}{1}\n\n{2}'.format(post, len(request), request) + + # empty request + request = make_request('') + MockRestApiServer(RestApiHandler, request) + # invalid request + request = make_request('foobar=baz') + MockRestApiServer(RestApiHandler, request) # wrong role request = make_request('{"schedule": "2016-08-20 12:45TZ+1", "role": "unknown", "postgres_version": "9.5.3"}') MockRestApiServer(RestApiHandler, request) @@ -206,6 +213,9 @@ class TestRestApiHandler(unittest.TestCase): with patch.object(MockHa, 'schedule_future_restart', Mock(return_value=retval)): request = make_request('{"schedule": "2016-08-29 12:45TZ+1"}') MockRestApiServer(RestApiHandler, request) + with patch.object(MockHa, 'restart', Mock(return_value=(retval, "foo"))): + request = make_request('{"role": "master", "postgres_version": "9.5.2"}') + MockRestApiServer(RestApiHandler, request) def test_do_DELETE_restart(self): for retval in (True, False): diff --git a/tests/test_ha.py b/tests/test_ha.py index b8386fee..0029a80c 100644 --- a/tests/test_ha.py +++ b/tests/test_ha.py @@ -130,7 +130,6 @@ class TestHa(unittest.TestCase): self.ha.old_cluster = self.e.get_cluster() self.ha.cluster = get_cluster_not_initialized_without_leader() self.ha.load_cluster_from_dcs = Mock() - #self.ha.evaluate_scheduled_restart = true def test_update_lock(self): self.p.last_operation = Mock(side_effect=PostgresException('')) @@ -403,8 +402,22 @@ class TestHa(unittest.TestCase): def test_schedule_future_restart(self): self.ha.patroni.scheduled_restart = {} - self.ha.schedule_future_restart({'schedule': '2016-08-30 12:45TZ+1"'}) - self.ha.schedule_future_restart({'schedule': '2016-08-30 12:45TZ+1"'}) + # do the restart 2 times. The first one should succeed, the second one should fail + self.assertTrue(self.ha.schedule_future_restart({'schedule': '2016-08-30 12:45TZ+1"'})) + self.assertFalse(self.ha.schedule_future_restart({'schedule': '2016-08-30 12:45TZ+1"'})) def test_delete_future_restarts(self): self.ha.delete_future_restart() + + def test_evaluate_scheduled_restart(self): + self.p.postmaster_start_time = Mock(return_value='2016-08-31 12:45TZ+1') + with patch.object(self.ha, + 'future_restart_scheduled', Mock(return_value={'postmaster_start_time': '2016-08-30 12:45TZ+1', + 'schedule': '2016-08-31 12:45TZ+1'})): + self.ha.evaluate_scheduled_restart() + with patch.object(self.ha, + 'future_restart_scheduled', Mock(return_value={'postmaster_start_time': '2016-08-31 12:45TZ+1', + 'schedule': '2016-08-31 12:45TZ+1'})): + with patch.object(self.ha, + 'should_run_scheduled_action', Mock(return_value=True)): + self.ha.evaluate_scheduled_restart() diff --git a/tests/test_postgresql.py b/tests/test_postgresql.py index 42dcab0a..0ef36441 100644 --- a/tests/test_postgresql.py +++ b/tests/test_postgresql.py @@ -518,3 +518,9 @@ class TestPostgresql(unittest.TestCase): self.assertEquals(self.p.get_major_version(), 9.4) with patch.object(builtins, 'open', Mock(side_effect=Exception)): self.assertEquals(self.p.get_major_version(), 0.0) + + def test_postmaster_start_time(self): + with patch.object(MockCursor, "fetchone", Mock(return_value=('foo', True, '', '', '', '', False))): + self.assertEqual(self.p.postmaster_start_time(), 'foo') + with patch.object(MockCursor, "execute", side_effect=psycopg2.Error): + self.assertIsNone(self.p.postmaster_start_time())