Exemplo n.º 1
0
def test_notify_level(config_name):

    start_maestral_daemon_process(config_name, timeout=20)
    m = MaestralProxy(config_name)

    runner = CliRunner()
    result = runner.invoke(main, ["notify", "level", "-c", m.config_name])

    level_name = level_number_to_name(m.notification_level)

    assert result.exit_code == 0
    assert level_name in result.output

    level_name = "SYNCISSUE"
    level_number = level_name_to_number(level_name)
    result = runner.invoke(
        main, ["notify", "level", level_name, "-c", m.config_name])

    assert result.exit_code == 0
    assert level_name in result.output
    assert m.notification_level == level_number

    result = runner.invoke(main,
                           ["notify", "level", "INVALID", "-c", m.config_name])

    assert result.exit_code == 2
    assert isinstance(result.exception, SystemExit)
Exemplo n.º 2
0
def test_remote_exceptions(config_name):

    # start daemon process
    start_maestral_daemon_process(config_name, timeout=20)

    # create proxy and call a remote method which raises an error
    with MaestralProxy(config_name) as m:
        with pytest.raises(NotLinkedError):
            m.get_account_info()

    # stop daemon
    stop_maestral_daemon_process(config_name)
Exemplo n.º 3
0
    def test_remote_exceptions(self):

        # start daemon process
        start_maestral_daemon_process(self.config_name)

        # create proxy and call a remote method which raises an error
        with MaestralProxy(self.config_name) as m:
            with self.assertRaises(NotLinkedError):
                m.get_account_info()

        # stop daemon
        stop_maestral_daemon_process(self.config_name)

        # clean up config
        remove_configuration(self.config_name)
Exemplo n.º 4
0
def test_notify_snooze(config_name):

    start_maestral_daemon_process(config_name, timeout=20)
    m = MaestralProxy(config_name)

    runner = CliRunner()
    result = runner.invoke(main,
                           ["notify", "snooze", "20", "-c", m.config_name])

    assert result.exit_code == 0
    assert 0 < m.notification_snooze <= 20

    result = runner.invoke(main,
                           ["notify", "snooze", "0", "-c", m.config_name])

    assert result.exit_code == 0
    assert m.notification_snooze == 0
Exemplo n.º 5
0
def test_stop(config_name):

    res = start_maestral_daemon_process(config_name, timeout=20)
    assert res is Start.Ok

    runner = CliRunner()
    result = runner.invoke(main, ["stop", "-c", config_name])

    assert result.exit_code == 0
Exemplo n.º 6
0
def test_start(config_name):

    res = start_maestral_daemon_process(config_name, timeout=20)
    assert res is Start.Ok

    runner = CliRunner()
    result = runner.invoke(main, ["start", "-c", config_name])

    assert result.exit_code == 0, result.output
    assert "already running" in result.output
Exemplo n.º 7
0
def start_daemon_subprocess_with_cli_feedback(config_name):
    """Wrapper around `daemon.start_maestral_daemon_process`
    with command line feedback."""
    from maestral.daemon import start_maestral_daemon_process, Start

    click.echo('Starting Maestral...', nl=False)
    res = start_maestral_daemon_process(config_name)
    if res == Start.Ok:
        click.echo('\rStarting Maestral...        ' + OK)
    else:
        click.echo('\rStarting Maestral...        ' + FAILED)
Exemplo n.º 8
0
def test_lifecycle(config_name):

    # start daemon process
    res = start_maestral_daemon_process(config_name, timeout=20)
    assert res is Start.Ok

    # retry start daemon process
    res = start_maestral_daemon_process(config_name, timeout=20)
    assert res is Start.AlreadyRunning

    # retry start daemon in-process
    with pytest.raises(RuntimeError):
        start_maestral_daemon(config_name)

    # stop daemon
    res = stop_maestral_daemon_process(config_name)
    assert res is Stop.Ok

    # retry stop daemon
    res = stop_maestral_daemon_process(config_name)
    assert res is Stop.NotRunning
Exemplo n.º 9
0
    def test_lifecycle_detached(self):

        # start daemon process
        res = start_maestral_daemon_process(self.config_name)
        self.assertEqual(res, Start.Ok)

        # retry start daemon process
        res = start_maestral_daemon_process(self.config_name)
        self.assertEqual(res, Start.AlreadyRunning)

        # retry start daemon in-process
        with self.assertRaises(RuntimeError):
            start_maestral_daemon(self.config_name)

        # stop daemon
        res = stop_maestral_daemon_process(self.config_name)
        self.assertEqual(res, Stop.Ok)

        # retry stop daemon
        res = stop_maestral_daemon_process(self.config_name)
        self.assertEqual(res, Stop.NotRunning)

        # clean up config
        remove_configuration(self.config_name)
Exemplo n.º 10
0
def test_connection(config_name):

    # start daemon process
    res = start_maestral_daemon_process(config_name, timeout=20)
    assert res is Start.Ok

    # create proxy
    with MaestralProxy(config_name) as m:
        assert m.config_name == config_name
        assert not m._is_fallback
        assert isinstance(m._m, Proxy)

    # stop daemon
    res = stop_maestral_daemon_process(config_name)
    assert res is Stop.Ok
Exemplo n.º 11
0
def test_lifecycle_attached(config_name):

    # start daemon process
    res = start_maestral_daemon_process(config_name, detach=False)
    assert res is Start.Ok

    # check that we have attached process
    ctx = mp.get_context("spawn" if IS_MACOS else "fork")
    daemon = ctx.active_children()[0]
    assert daemon.name == "maestral-daemon"

    # stop daemon
    res = stop_maestral_daemon_process(config_name)
    assert res is Stop.Ok

    # retry stop daemon
    res = stop_maestral_daemon_process(config_name)
    assert res is Stop.NotRunning
Exemplo n.º 12
0
    def test_connection(self):

        # start daemon process
        res = start_maestral_daemon_process(self.config_name)
        self.assertEqual(Start.Ok, res)

        # create proxy
        with MaestralProxy(self.config_name) as m:
            self.assertEqual(m.config_name, self.config_name)
            self.assertFalse(m._is_fallback)
            self.assertIsInstance(m._m, Proxy)

        # stop daemon
        res = stop_maestral_daemon_process(self.config_name)
        self.assertEqual(res, Stop.Ok)

        # clean up config
        remove_configuration(self.config_name)
Exemplo n.º 13
0
    def get_or_start_maestral_daemon(self) -> MaestralProxy:

        res = start_maestral_daemon_process(self.config_name)

        if res == Start.Failed:
            title = "Could not start Maestral"
            message = (
                "Could not start or connect to sync daemon. Please try again "
                "and contact the developer if this issue persists.")
            self.alert(title, message, level="error")
            stop_maestral_daemon_process(self.config_name)
            super().exit()
        elif res == Start.AlreadyRunning:
            self._started = False
        elif res == Start.Ok:
            self._started = True

        return MaestralProxy(self.config_name)
Exemplo n.º 14
0
    def test_lifecycle_attached(self):

        # start daemon process
        res = start_maestral_daemon_process(self.config_name, detach=False)
        self.assertEqual(res, Start.Ok)

        # check that we have attached process
        ctx = mp.get_context("spawn" if IS_MACOS else "fork")
        daemon = ctx.active_children()[0]
        self.assertEqual(daemon.name, "maestral-daemon")

        # stop daemon
        res = stop_maestral_daemon_process(self.config_name)
        self.assertEqual(res, Stop.Ok)

        # retry stop daemon
        res = stop_maestral_daemon_process(self.config_name)
        self.assertEqual(res, Stop.NotRunning)

        # clean up config
        remove_configuration(self.config_name)
Exemplo n.º 15
0
    def _get_or_start_maestral_daemon(self):

        pid = get_maestral_pid(self.config_name)
        if pid:
            self._started = False
        else:
            if IS_MACOS_BUNDLE:
                res = start_maestral_daemon_thread(self.config_name)
            else:
                res = start_maestral_daemon_process(self.config_name)
            if res == Start.Failed:
                title = 'Could not start Maestral'
                message = ('Could not start or connect to sync daemon. Please try again '
                           'and contact the developer if this issue persists.')
                show_dialog(title, message, level='error')
                self.quit()
            elif res == Start.AlreadyRunning:
                self._started = False
            elif res == Start.Ok:
                self._started = True

        return get_maestral_proxy(self.config_name)
Exemplo n.º 16
0
def proxy(m):
    m.stop_sync()
    start_maestral_daemon_process(m.config_name, timeout=20)
    yield MaestralProxy(m.config_name)

    stop_maestral_daemon_process(m.config_name)
Exemplo n.º 17
0
def start(foreground: bool, verbose: bool, config_name: str) -> None:

    # ---- run setup if necessary ------------------------------------------------------

    # We run the setup in the current process. This avoids starting a subprocess despite
    # running with the --foreground flag, prevents leaving a zombie process if the setup
    # fails with an exception and does not confuse systemd.

    from maestral.main import Maestral

    m = Maestral(config_name, log_to_stdout=verbose)

    if m.pending_link:  # this may raise KeyringAccessError
        link_dialog(m)

    if m.pending_dropbox_folder:
        path = select_dbx_path_dialog(config_name, allow_merge=True)

        while True:
            try:
                m.create_dropbox_directory(path)
                break
            except OSError:
                click.echo(
                    "Could not create folder. Please make sure that you have "
                    "permissions to write to the selected location or choose a "
                    "different location."
                )

        exclude_folders_q = click.confirm(
            "Would you like to exclude any folders from syncing?",
        )

        if exclude_folders_q:
            click.echo(
                "Please choose which top-level folders to exclude. You can exclude\n"
                'individual files or subfolders later with "maestral excluded add".\n'
            )

            click.echo("Loading...", nl=False)

            # get all top-level Dropbox folders
            entries = m.list_folder("/", recursive=False)
            excluded_items: List[str] = []

            click.echo("\rLoading...   Done")

            # paginate through top-level folders, ask to exclude
            for e in entries:
                if e["type"] == "FolderMetadata":
                    yes = click.confirm(
                        'Exclude "{path_display}" from sync?'.format(**e)
                    )
                    if yes:
                        path_lower = cast(str, e["path_lower"])
                        excluded_items.append(path_lower)

            m.set_excluded_items(excluded_items)

    # free resources
    del m

    if foreground:
        # stop daemon process after setup and restart in our current process
        stop_maestral_daemon_process(config_name)
        start_maestral_daemon(config_name, log_to_stdout=verbose, start_sync=True)
    else:

        # start daemon process
        click.echo("Starting Maestral...", nl=False)

        res = start_maestral_daemon_process(
            config_name, log_to_stdout=verbose, start_sync=True
        )

        if res == Start.Ok:
            click.echo("\rStarting Maestral...        " + OK)
        elif res == Start.AlreadyRunning:
            click.echo("\rStarting Maestral...        Already running.")
        else:
            click.echo("\rStarting Maestral...        " + FAILED)
            click.echo("Please check logs for more information.")