示例#1
0
    def test_start(self, mock_frompidfile, mock_frompid, mock_popen):
        mock_frompidfile.return_value._is_postmaster_process.return_value = False
        mock_frompid.return_value = "proc 123"
        mock_popen.return_value.pid = 123
        self.assertEqual(PostmasterProcess.start('true', '/tmp', '/tmp/test.conf', []), "proc 123")
        mock_frompid.assert_called_with(123)

        mock_frompidfile.side_effect = psutil.NoSuchProcess(123)
        self.assertEqual(PostmasterProcess.start('true', '/tmp', '/tmp/test.conf', []), "proc 123")

        mock_popen.side_effect = Exception
        self.assertIsNone(PostmasterProcess.start('true', '/tmp', '/tmp/test.conf', []))
示例#2
0
    def test_from_pidfile(self, mock_read, mock_init, mock_create_time):
        mock_init.side_effect = psutil.NoSuchProcess(123)
        mock_read.return_value = {}
        self.assertIsNone(PostmasterProcess.from_pidfile(''))
        mock_read.return_value = {"pid": "foo"}
        self.assertIsNone(PostmasterProcess.from_pidfile(''))
        mock_read.return_value = {"pid": "123"}
        self.assertIsNone(PostmasterProcess.from_pidfile(''))

        mock_init.side_effect = None
        with patch.object(psutil.Process, 'pid', 123), \
                patch.object(psutil.Process, 'ppid', return_value=124), \
                patch('os.getpid', return_value=125) as mock_ospid, \
                patch('os.getppid', return_value=126):

            self.assertIsNotNone(PostmasterProcess.from_pidfile(''))

            mock_create_time.return_value = 100000
            mock_read.return_value = {"pid": "123", "start_time": "200000"}
            self.assertIsNone(PostmasterProcess.from_pidfile(''))

            mock_read.return_value = {"pid": "123", "start_time": "foobar"}
            self.assertIsNotNone(PostmasterProcess.from_pidfile(''))

            mock_ospid.return_value = 123
            mock_read.return_value = {"pid": "123", "start_time": "100000"}
            self.assertIsNone(PostmasterProcess.from_pidfile(''))
示例#3
0
    def test_signal_kill(self, mock_kill, mock_children, mock_suspend):
        proc = PostmasterProcess(123)

        # all processes successfully stopped
        mock_children.return_value = [Mock()]
        mock_children.return_value[0].kill.side_effect = psutil.NoSuchProcess(
            123)
        self.assertTrue(proc.signal_kill())

        # postmaster has gone before suspend
        mock_suspend.side_effect = psutil.NoSuchProcess(123)
        self.assertTrue(proc.signal_kill())

        # postmaster has gone before we got a list of children
        mock_suspend.side_effect = psutil.AccessDenied()
        mock_children.side_effect = psutil.NoSuchProcess(123)
        self.assertTrue(proc.signal_kill())

        # postmaster has gone after we got a list of children
        mock_children.side_effect = psutil.AccessDenied()
        mock_kill.side_effect = psutil.NoSuchProcess(123)
        self.assertTrue(proc.signal_kill())

        # failed to kill postmaster
        mock_kill.side_effect = psutil.AccessDenied()
        self.assertFalse(proc.signal_kill())
示例#4
0
    def test_signal_stop(self, mock_send_signal):
        proc = PostmasterProcess(-123)
        self.assertEqual(proc.signal_stop('immediate'), False)

        mock_send_signal.side_effect = [None, psutil.NoSuchProcess(123), psutil.AccessDenied()]
        proc = PostmasterProcess(123)
        self.assertEqual(proc.signal_stop('immediate'), None)
        self.assertEqual(proc.signal_stop('immediate'), True)
        self.assertEqual(proc.signal_stop('immediate'), False)
示例#5
0
    def test_signal_stop_nt(self, mock_os):
        mock_os.configure_mock(name="nt")
        proc = PostmasterProcess(-123)
        self.assertEqual(proc.signal_stop('immediate'), False)

        proc = PostmasterProcess(123)
        self.assertEqual(proc.signal_stop('immediate'), None)
        self.assertEqual(proc.signal_stop('immediate'), False)
        self.assertEqual(proc.signal_stop('immediate'), True)
示例#6
0
    def is_running(self):
        """Returns PostmasterProcess if one is running on the data directory or None. If most recently seen process
        is running updates the cached process based on pid file."""
        if self._postmaster_proc:
            if self._postmaster_proc.is_running():
                return self._postmaster_proc
            self._postmaster_proc = None

        # we noticed that postgres was restarted, force syncing of replication
        self.slots_handler.schedule()

        self._postmaster_proc = PostmasterProcess.from_pidfile(self._data_dir)
        return self._postmaster_proc
示例#7
0
    def test_wait_for_user_backends_to_close(self, mock_wait):
        c1 = Mock()
        c1.cmdline = Mock(return_value=["postgres: startup process   "])
        c2 = Mock()
        c2.cmdline = Mock(return_value=["postgres: postgres postgres [local] idle"])
        c3 = Mock()
        c3.cmdline = Mock(side_effect=psutil.NoSuchProcess(123))
        with patch('psutil.Process.children', Mock(return_value=[c1, c2, c3])):
            proc = PostmasterProcess(123)
            self.assertIsNone(proc.wait_for_user_backends_to_close())
            mock_wait.assert_called_with([c2])

        with patch('psutil.Process.children', Mock(side_effect=psutil.NoSuchProcess(123))):
            proc = PostmasterProcess(123)
            self.assertIsNone(proc.wait_for_user_backends_to_close())
示例#8
0
    def start(self, timeout=None, task=None, block_callbacks=False, role=None):
        """Start PostgreSQL

        Waits for postmaster to open ports or terminate so pg_isready can be used to check startup completion
        or failure.

        :returns: True if start was initiated and postmaster ports are open, False if start failed"""
        # make sure we close all connections established against
        # the former node, otherwise, we might get a stalled one
        # after kill -9, which would report incorrect data to
        # patroni.
        self._connection.close()

        if self.is_running():
            logger.error(
                'Cannot start PostgreSQL because one is already running.')
            self.set_state('starting')
            return True

        if not block_callbacks:
            self.__cb_pending = ACTION_ON_START

        self.set_role(role or self.get_postgres_role_from_data_directory())

        self.set_state('starting')
        self._pending_restart = False

        configuration = self.config.effective_configuration
        self.config.write_postgresql_conf(configuration)
        self.config.resolve_connection_addresses()
        self.config.replace_pg_hba()
        self.config.replace_pg_ident()

        options = [
            '--{0}={1}'.format(p, configuration[p])
            for p in self.config.CMDLINE_OPTIONS
            if p in configuration and p != 'wal_keep_segments'
        ]

        if self.cancellable.is_cancelled:
            return False

        with task or null_context():
            if task and task.is_cancelled:
                logger.info("PostgreSQL start cancelled.")
                return False

            self._postmaster_proc = PostmasterProcess.start(
                self.pgcommand('postgres'), self._data_dir,
                self.config.postgresql_conf, options)

            if task:
                task.complete(self._postmaster_proc)

        start_timeout = timeout
        if not start_timeout:
            try:
                start_timeout = float(self.config.get('pg_ctl_timeout', 60))
            except ValueError:
                start_timeout = 60

        # We want postmaster to open ports before we continue
        if not self._postmaster_proc or not self.wait_for_port_open(
                self._postmaster_proc, start_timeout):
            return False

        ret = self.wait_for_startup(start_timeout)
        if ret is not None:
            return ret
        elif timeout is not None:
            return False
        else:
            return None
示例#9
0
 def test_from_pid(self, mock_init):
     mock_init.side_effect = psutil.NoSuchProcess(123)
     self.assertEqual(PostmasterProcess.from_pid(123), None)
     mock_init.side_effect = None
     self.assertNotEqual(PostmasterProcess.from_pid(123), None)
示例#10
0
 def test_init(self):
     proc = PostmasterProcess(-123)
     self.assertTrue(proc.is_single_user)
示例#11
0
 def test_read_postmaster_pidfile(self):
     with patch.object(builtins, 'open', Mock(side_effect=IOError)):
         self.assertIsNone(PostmasterProcess.from_pidfile(''))
     with patch.object(builtins, 'open', mock_open(read_data='123\n')):
         self.assertIsNone(PostmasterProcess.from_pidfile(''))