Add restore command
This commit is contained in:
176
test/test_restore.py
Normal file
176
test/test_restore.py
Normal file
@@ -0,0 +1,176 @@
|
||||
import argparse
|
||||
from unittest import mock
|
||||
import subprocess
|
||||
import pytest
|
||||
|
||||
from locutus.restore import run_restore
|
||||
|
||||
|
||||
def make_args(config, profile, archive, targetdir):
|
||||
args = argparse.Namespace()
|
||||
args.config = config
|
||||
args.profile = profile
|
||||
args.archive = archive
|
||||
args.targetdir = targetdir
|
||||
return args
|
||||
|
||||
|
||||
@mock.patch('locutus.restore.LocutusConfig')
|
||||
@mock.patch('os.path.isdir', return_value=True)
|
||||
@mock.patch('subprocess.run')
|
||||
def test_restore_by_index_success(
|
||||
mock_run, mock_isdir, mock_config, tmp_path, capsys
|
||||
):
|
||||
mock_config.return_value.get_repo.return_value = '/repo'
|
||||
mock_config.return_value.env = {}
|
||||
archives = ['archA', 'archB', 'archC']
|
||||
mock_run.side_effect = [
|
||||
mock.Mock(stdout='\n'.join(archives) + '\n', returncode=0), # borg list
|
||||
mock.Mock(returncode=0), # borg extract
|
||||
]
|
||||
|
||||
args = make_args('dummy.toml', 'dummy.rc', '1', str(tmp_path))
|
||||
rc = run_restore(args)
|
||||
assert rc == 0
|
||||
out = capsys.readouterr().out
|
||||
assert 'restored to' in out
|
||||
assert 'archB' in out
|
||||
extract_call = mock_run.call_args_list[1][0][0]
|
||||
assert extract_call == ['borg', 'extract', '/repo::archB']
|
||||
|
||||
|
||||
@mock.patch('locutus.restore.LocutusConfig')
|
||||
@mock.patch('os.path.isdir', return_value=True)
|
||||
@mock.patch('subprocess.run')
|
||||
def test_restore_by_name_success(
|
||||
mock_run, mock_isdir, mock_config, tmp_path, capsys
|
||||
):
|
||||
mock_config.return_value.get_repo.return_value = '/repo'
|
||||
mock_config.return_value.env = {}
|
||||
mock_run.return_value.returncode = 0
|
||||
|
||||
args = make_args('dummy.toml', 'dummy.rc', 'named-archive', str(tmp_path))
|
||||
rc = run_restore(args)
|
||||
assert rc == 0
|
||||
out = capsys.readouterr().out
|
||||
assert 'restored to' in out
|
||||
assert 'named-archive' in out
|
||||
call_args = mock_run.call_args[0][0]
|
||||
assert call_args == ['borg', 'extract', '/repo::named-archive']
|
||||
|
||||
|
||||
@mock.patch('locutus.restore.LocutusConfig')
|
||||
@mock.patch('os.path.isdir', return_value=True)
|
||||
@mock.patch('subprocess.run')
|
||||
def test_restore_by_index_out_of_range(
|
||||
mock_run, mock_isdir, mock_config, tmp_path, capsys
|
||||
):
|
||||
mock_config.return_value.get_repo.return_value = '/repo'
|
||||
mock_config.return_value.env = {}
|
||||
archives = ['a', 'b']
|
||||
mock_run.return_value.stdout = '\n'.join(archives) + '\n'
|
||||
mock_run.return_value.returncode = 0
|
||||
|
||||
args = make_args('dummy.toml', 'dummy.rc', '5', str(tmp_path))
|
||||
rc = run_restore(args)
|
||||
assert rc == 1
|
||||
err = capsys.readouterr().err
|
||||
assert 'Archive index out of range' in err
|
||||
|
||||
|
||||
@mock.patch('locutus.restore.LocutusConfig')
|
||||
@mock.patch('os.path.isdir', return_value=True)
|
||||
@mock.patch('subprocess.run')
|
||||
def test_restore_by_index_no_archives(
|
||||
mock_run, mock_isdir, mock_config, tmp_path, capsys
|
||||
):
|
||||
mock_config.return_value.get_repo.return_value = '/repo'
|
||||
mock_config.return_value.env = {}
|
||||
mock_run.return_value.stdout = ''
|
||||
mock_run.return_value.returncode = 0
|
||||
|
||||
args = make_args('dummy.toml', 'dummy.rc', '0', str(tmp_path))
|
||||
rc = run_restore(args)
|
||||
assert rc == 1
|
||||
err = capsys.readouterr().err
|
||||
assert 'No archives found' in err
|
||||
|
||||
|
||||
@mock.patch('locutus.restore.LocutusConfig')
|
||||
@mock.patch('os.path.isdir', return_value=False)
|
||||
def test_restore_invalid_targetdir(mock_isdir, mock_config, capsys):
|
||||
mock_config.return_value.get_repo.return_value = '/repo'
|
||||
mock_config.return_value.env = {}
|
||||
|
||||
args = make_args('dummy.toml', 'dummy.rc', 'archive', '/notadir')
|
||||
rc = run_restore(args)
|
||||
assert rc == 1
|
||||
err = capsys.readouterr().err
|
||||
assert 'does not exist or is not a directory' in err
|
||||
|
||||
|
||||
@mock.patch('locutus.restore.LocutusConfig')
|
||||
def test_restore_no_repo(mock_config, tmp_path, capsys):
|
||||
mock_config.return_value.get_repo.return_value = None
|
||||
mock_config.return_value.env = {}
|
||||
args = make_args('dummy.toml', 'dummy.rc', '0', str(tmp_path))
|
||||
rc = run_restore(args)
|
||||
assert rc == 1
|
||||
err = capsys.readouterr().err
|
||||
assert 'No BORG_REPO configured' in err
|
||||
|
||||
|
||||
@mock.patch('locutus.restore.LocutusConfig')
|
||||
@mock.patch('os.path.isdir', return_value=True)
|
||||
@mock.patch(
|
||||
'subprocess.run',
|
||||
side_effect=subprocess.CalledProcessError(1, ['borg', 'extract']),
|
||||
)
|
||||
def test_restore_extract_calledprocesserror(
|
||||
mock_run, mock_isdir, mock_config, tmp_path, capsys
|
||||
):
|
||||
mock_config.return_value.get_repo.return_value = '/repo'
|
||||
mock_config.return_value.env = {}
|
||||
|
||||
args = make_args('dummy.toml', 'dummy.rc', 'named-archive', str(tmp_path))
|
||||
rc = run_restore(args)
|
||||
assert rc == 1
|
||||
err = capsys.readouterr().err
|
||||
assert 'borg extract failed' in err
|
||||
|
||||
|
||||
@mock.patch('locutus.restore.LocutusConfig')
|
||||
@mock.patch('os.path.isdir', return_value=True)
|
||||
@mock.patch('subprocess.run', side_effect=Exception('fail!'))
|
||||
def test_restore_extract_generic_exception(
|
||||
mock_run, mock_isdir, mock_config, tmp_path, capsys
|
||||
):
|
||||
mock_config.return_value.get_repo.return_value = '/repo'
|
||||
mock_config.return_value.env = {}
|
||||
|
||||
args = make_args('dummy.toml', 'dummy.rc', 'named-archive', str(tmp_path))
|
||||
rc = run_restore(args)
|
||||
assert rc == 1
|
||||
err = capsys.readouterr().err
|
||||
assert 'borg extract failed (unexpected): fail!' in err
|
||||
|
||||
|
||||
def test_restore_usage_message(capsys):
|
||||
args = argparse.Namespace()
|
||||
rc = run_restore(args)
|
||||
assert rc == 1
|
||||
err = capsys.readouterr().err
|
||||
assert 'Usage:' in err
|
||||
|
||||
|
||||
@mock.patch("locutus.restore.LocutusConfig")
|
||||
@mock.patch("os.path.isdir", return_value=True)
|
||||
@mock.patch("subprocess.run", side_effect=Exception("index explode"))
|
||||
def test_restore_index_lookup_generic_exception(mock_run, mock_isdir, mock_config, tmp_path, capsys):
|
||||
mock_config.return_value.get_repo.return_value = "/repo"
|
||||
mock_config.return_value.env = {}
|
||||
args = make_args("dummy.toml", "dummy.rc", "0", str(tmp_path))
|
||||
rc = run_restore(args)
|
||||
assert rc == 1
|
||||
err = capsys.readouterr().err
|
||||
assert "borg restore failed during archive lookup: index explode" in err
|
||||
Reference in New Issue
Block a user