Exemplo n.º 1
0
    def test_passive_node_forward_config_path(
        self, subprocess_mock, command_mock, monkeypatch, tmpdir
    ):
        """
        Tests that the config file path is used in the primary node command only if
        forward_config_path is set.

        :param MagicMock subprocess_mock: Mock of
            barman.command_wrappers.BarmanSubProcess
        :param MagicMock command_mock: Mock of
            barman.command_wrappers.Command
        :param monkeypatch monkeypatch: pytest patcher
        :param py.local.path tmpdir: pytest temporary directory
        """
        # GIVEN a simple passive node configuration with the default value of
        # forward_config_path
        config = self._create_mock_config(tmpdir)

        # AND barman is invoked with the -c option, simulated here by directly
        # storing the path to the config file in the config_file attribute
        config.config_file = "/path/to/barman.conf"

        # AND a mock barman server which provides successful responses
        server = barman.server.Server(config.get_server("main"))
        monkeypatch.setattr(barman, "__config__", config)
        command = command_mock.return_value
        command.out = json.dumps(EXPECTED_MINIMAL)

        # WHEN cron is executed for the passive server
        server.cron()
        # THEN barman is invoked on the primary node with no -c option
        assert command.call_args_list[0][0][0] == "barman sync-info main"
        # WHEN forward_config_path is set to true for the server and cron is executed
        config.get_server("main").forward_config_path = True
        server.cron()
        # THEN barman is invoked on the primary node with a -c option which provides
        # the path to the barman config file
        assert (
            command.call_args_list[1][0][0]
            == "barman -c /path/to/barman.conf sync-info main"
        )
Exemplo n.º 2
0
    def test_passive_node_cron(self, subprocess_mock, command_mock,
                               monkeypatch, tmpdir, capsys):
        """
        check the passive node version of cron command

        :param MagicMock subprocess_mock: Mock of
            barman.command_wrappers.BarmanSubProcess
        :param MagicMock command_mock: Mock of
            barman.command_wrappers.Command
        :param monkeypatch monkeypatch: pytest patcher
        :param py.local.path tmpdir: pytest temporary directory
        :param capsys: fixture for reading sysout
        """
        # We need to setup a server object
        barman_home = tmpdir.mkdir("barman_home")
        backup_dir = barman_home.mkdir("main")
        wals_dir = backup_dir.mkdir("wals")
        # Build the configuration for the server using
        # a fake configuration object filled with test values
        config = build_config_from_dicts(
            global_conf=dict(barman_home=str(barman_home)),
            main_conf=dict(compression=None,
                           wals_directory=str(wals_dir),
                           primary_ssh_command='ssh fakeuser@fakehost'))
        server = barman.server.Server(config.get_server('main'))
        # Make the configuration available through the global namespace
        # (required to invoke a subprocess to retrieve the config file name)
        monkeypatch.setattr(barman, '__config__', config)
        # We need to build a test response from the remote server.
        # We use the out property of the command_mock for
        # returning the test response
        command_mock.return_value.out = json.dumps(EXPECTED_MINIMAL)
        server.cron()
        (out, err) = capsys.readouterr()
        # Assertion block 1: the execution of the cron command for passive
        # node should be successful
        assert "Starting copy of backup" in out
        assert "Started copy of WAL files for server" in out

        # Modify the response of the fake remote call
        primary_info = dict(EXPECTED_MINIMAL)
        primary_info['backups'] = []
        primary_info['wals'] = []
        command_mock.return_value.out = json.dumps(primary_info)
        server.cron()
        (out, err) = capsys.readouterr()
        # Assertion block 2: No backup or wal synchronisation required
        assert "No backup synchronisation required" in out
        assert "No WAL synchronisation required for server" in out

        # Add a backup to the remote response
        primary_info = dict(EXPECTED_MINIMAL)
        backup_info_dict = LocalBackupInfo(server,
                                           backup_id='1234567891').to_json()
        primary_info['backups']['1234567891'] = backup_info_dict
        command_mock.return_value.out = json.dumps(primary_info)
        server.cron()
        (out, err) = capsys.readouterr()
        # Assertion block 3: start the copy the first backup
        # of the list (1234567890),
        # and not the one second one (1234567891)
        assert "Starting copy of backup 1234567890" in out
        assert "Started copy of WAL files for server main" in out
        assert "1234567891" not in out

        # Patch on the fly the Lockfile object, testing the locking
        # management of the method.
        with mock.patch.multiple('barman.server',
                                 ServerBackupSyncLock=mock.DEFAULT,
                                 ServerWalSyncLock=mock.DEFAULT) as lock_mocks:
            for item in lock_mocks:
                lock_mocks[item].side_effect = LockFileBusy()
            primary_info = dict(EXPECTED_MINIMAL)
            primary_info['backups']['1234567891'] = backup_info_dict
            command_mock.return_value.out = json.dumps(primary_info)
            server.sync_cron(keep_descriptors=False)
            (out, err) = capsys.readouterr()
            assert "A synchronisation process for backup 1234567890" in out
            assert "WAL synchronisation already running" in out