2024-09-23 13:41:40 +00:00
|
|
|
from pytest import raises
|
|
|
|
|
2023-06-16 13:43:41 +00:00
|
|
|
from os import path
|
2024-08-21 13:55:30 +00:00
|
|
|
from os import mkdir
|
|
|
|
|
2023-12-04 15:35:50 +00:00
|
|
|
from tests.test_backup import backups
|
2023-06-14 11:14:52 +00:00
|
|
|
from tests.common import generate_backup_query
|
2023-06-14 10:09:38 +00:00
|
|
|
|
2023-06-14 12:08:07 +00:00
|
|
|
|
2024-05-24 12:30:27 +00:00
|
|
|
import selfprivacy_api.services as all_services
|
2024-07-24 15:15:31 +00:00
|
|
|
from selfprivacy_api.services import ServiceManager
|
2023-06-14 12:08:07 +00:00
|
|
|
from selfprivacy_api.graphql.common_types.service import service_to_graphql_service
|
2023-08-30 09:03:19 +00:00
|
|
|
from selfprivacy_api.graphql.common_types.backup import (
|
|
|
|
_AutobackupQuotas,
|
|
|
|
AutobackupQuotas,
|
|
|
|
)
|
2023-06-14 10:09:38 +00:00
|
|
|
from selfprivacy_api.jobs import Jobs, JobStatus
|
2024-07-29 10:14:22 +00:00
|
|
|
from selfprivacy_api.backup.storage import Storage
|
|
|
|
from selfprivacy_api.backup.local_secret import LocalBackupSecret
|
2023-06-14 10:09:38 +00:00
|
|
|
|
2024-07-29 12:16:33 +00:00
|
|
|
from tests.test_graphql.test_services import (
|
2024-09-22 14:33:06 +00:00
|
|
|
# TODO: shuffle them to conftest
|
2024-07-29 12:16:33 +00:00
|
|
|
only_dummy_service_and_api,
|
|
|
|
only_dummy_service,
|
|
|
|
dkim_file,
|
|
|
|
)
|
2024-08-21 13:55:30 +00:00
|
|
|
from selfprivacy_api.services import CONFIG_STASH_DIR
|
2024-09-23 13:41:40 +00:00
|
|
|
from tests.test_graphql.common import assert_empty
|
2024-07-29 12:16:33 +00:00
|
|
|
|
|
|
|
|
2023-06-19 14:12:40 +00:00
|
|
|
API_RELOAD_SNAPSHOTS = """
|
|
|
|
mutation TestSnapshotsReload {
|
2023-06-21 03:46:56 +00:00
|
|
|
backup {
|
2023-06-19 14:12:40 +00:00
|
|
|
forceSnapshotsReload {
|
|
|
|
success
|
|
|
|
message
|
|
|
|
code
|
|
|
|
}
|
2023-06-21 03:46:56 +00:00
|
|
|
}
|
2023-06-19 14:12:40 +00:00
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
2024-09-06 11:40:16 +00:00
|
|
|
API_TOTAL_BACKUP = """
|
2024-07-29 12:16:33 +00:00
|
|
|
mutation TestForcedAutobackup {
|
|
|
|
backup {
|
2024-09-06 11:40:16 +00:00
|
|
|
totalBackup{
|
2024-07-29 12:16:33 +00:00
|
|
|
success
|
|
|
|
message
|
|
|
|
code
|
2024-09-22 14:33:06 +00:00
|
|
|
job{
|
|
|
|
uid
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
|
|
|
API_TOTAL_RESTORE = """
|
|
|
|
mutation TestTotalRestore {
|
|
|
|
backup {
|
2024-09-23 12:22:57 +00:00
|
|
|
restoreAll{
|
2024-09-22 14:33:06 +00:00
|
|
|
success
|
|
|
|
message
|
|
|
|
code
|
|
|
|
job{
|
|
|
|
uid
|
|
|
|
}
|
2024-07-29 12:16:33 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
2023-06-19 13:28:02 +00:00
|
|
|
API_SET_AUTOBACKUP_PERIOD_MUTATION = """
|
|
|
|
mutation TestAutobackupPeriod($period: Int) {
|
2023-06-21 03:46:56 +00:00
|
|
|
backup {
|
2023-06-19 13:28:02 +00:00
|
|
|
setAutobackupPeriod(period: $period) {
|
|
|
|
success
|
|
|
|
message
|
|
|
|
code
|
2023-06-21 03:46:56 +00:00
|
|
|
configuration {
|
2023-06-19 13:28:02 +00:00
|
|
|
provider
|
|
|
|
encryptionKey
|
|
|
|
isInitialized
|
|
|
|
autobackupPeriod
|
|
|
|
locationName
|
|
|
|
locationId
|
|
|
|
}
|
|
|
|
}
|
2023-06-21 03:46:56 +00:00
|
|
|
}
|
2023-06-19 13:28:02 +00:00
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
2023-08-28 18:24:29 +00:00
|
|
|
|
|
|
|
API_SET_AUTOBACKUP_QUOTAS_MUTATION = """
|
2023-08-30 09:03:19 +00:00
|
|
|
mutation TestAutobackupQuotas($input: AutobackupQuotasInput!) {
|
2023-08-28 18:24:29 +00:00
|
|
|
backup {
|
|
|
|
setAutobackupQuotas(quotas: $input) {
|
|
|
|
success
|
|
|
|
message
|
|
|
|
code
|
|
|
|
configuration {
|
|
|
|
provider
|
|
|
|
encryptionKey
|
|
|
|
isInitialized
|
|
|
|
autobackupPeriod
|
|
|
|
locationName
|
|
|
|
locationId
|
2023-08-30 09:03:19 +00:00
|
|
|
autobackupQuotas {
|
2023-09-09 00:26:41 +00:00
|
|
|
last
|
2023-08-30 09:03:19 +00:00
|
|
|
daily
|
|
|
|
weekly
|
|
|
|
monthly
|
|
|
|
yearly
|
|
|
|
}
|
2023-08-28 18:24:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
2023-06-16 14:33:48 +00:00
|
|
|
API_REMOVE_REPOSITORY_MUTATION = """
|
|
|
|
mutation TestRemoveRepo {
|
2023-06-21 03:46:56 +00:00
|
|
|
backup {
|
2023-06-16 14:33:48 +00:00
|
|
|
removeRepository {
|
|
|
|
success
|
|
|
|
message
|
|
|
|
code
|
2023-06-21 03:46:56 +00:00
|
|
|
configuration {
|
2023-06-16 14:33:48 +00:00
|
|
|
provider
|
|
|
|
encryptionKey
|
|
|
|
isInitialized
|
|
|
|
autobackupPeriod
|
|
|
|
locationName
|
|
|
|
locationId
|
|
|
|
}
|
|
|
|
}
|
2023-06-21 03:46:56 +00:00
|
|
|
}
|
2023-06-16 14:33:48 +00:00
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
2023-06-16 13:43:41 +00:00
|
|
|
API_INIT_MUTATION = """
|
|
|
|
mutation TestInitRepo($input: InitializeRepositoryInput!) {
|
2023-06-21 03:46:56 +00:00
|
|
|
backup {
|
2023-06-16 13:43:41 +00:00
|
|
|
initializeRepository(repository: $input) {
|
|
|
|
success
|
|
|
|
message
|
|
|
|
code
|
2023-06-21 03:46:56 +00:00
|
|
|
configuration {
|
2023-06-16 13:43:41 +00:00
|
|
|
provider
|
|
|
|
encryptionKey
|
|
|
|
isInitialized
|
|
|
|
autobackupPeriod
|
|
|
|
locationName
|
|
|
|
locationId
|
|
|
|
}
|
|
|
|
}
|
2023-06-21 03:46:56 +00:00
|
|
|
}
|
2023-06-16 13:43:41 +00:00
|
|
|
}
|
|
|
|
"""
|
2023-06-14 13:00:23 +00:00
|
|
|
|
|
|
|
API_RESTORE_MUTATION = """
|
|
|
|
mutation TestRestoreService($snapshot_id: String!) {
|
2023-06-21 03:46:56 +00:00
|
|
|
backup {
|
2023-06-14 13:00:23 +00:00
|
|
|
restoreBackup(snapshotId: $snapshot_id) {
|
|
|
|
success
|
|
|
|
message
|
|
|
|
code
|
2023-06-21 03:46:56 +00:00
|
|
|
job {
|
2023-06-14 13:00:23 +00:00
|
|
|
uid
|
|
|
|
status
|
|
|
|
}
|
|
|
|
}
|
2023-06-21 03:46:56 +00:00
|
|
|
}
|
2023-06-14 13:00:23 +00:00
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
2023-07-28 11:32:48 +00:00
|
|
|
API_FORGET_MUTATION = """
|
|
|
|
mutation TestForgetSnapshot($snapshot_id: String!) {
|
|
|
|
backup {
|
|
|
|
forgetSnapshot(snapshotId: $snapshot_id) {
|
|
|
|
success
|
|
|
|
message
|
|
|
|
code
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
2024-08-07 12:35:34 +00:00
|
|
|
API_LAST_SLICE_QUERY = """
|
|
|
|
lastSlice {
|
|
|
|
id
|
|
|
|
service {
|
|
|
|
id
|
|
|
|
displayName
|
|
|
|
}
|
|
|
|
createdAt
|
|
|
|
reason
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
2023-06-14 11:14:52 +00:00
|
|
|
API_SNAPSHOTS_QUERY = """
|
|
|
|
allSnapshots {
|
|
|
|
id
|
|
|
|
service {
|
|
|
|
id
|
2024-05-24 12:30:27 +00:00
|
|
|
displayName
|
2023-06-14 11:14:52 +00:00
|
|
|
}
|
|
|
|
createdAt
|
2023-09-09 06:52:20 +00:00
|
|
|
reason
|
2023-06-14 11:14:52 +00:00
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
2024-07-29 10:14:22 +00:00
|
|
|
API_BACKUP_SETTINGS_QUERY = """
|
|
|
|
configuration {
|
|
|
|
provider
|
|
|
|
encryptionKey
|
|
|
|
isInitialized
|
|
|
|
autobackupPeriod
|
|
|
|
locationName
|
|
|
|
locationId
|
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
2023-06-14 10:09:38 +00:00
|
|
|
API_BACK_UP_MUTATION = """
|
2023-06-14 13:06:32 +00:00
|
|
|
mutation TestBackupService($service_id: String!) {
|
2023-06-21 03:46:56 +00:00
|
|
|
backup {
|
2023-06-14 10:09:38 +00:00
|
|
|
startBackup(serviceId: $service_id) {
|
|
|
|
success
|
|
|
|
message
|
|
|
|
code
|
2023-06-21 03:46:56 +00:00
|
|
|
job {
|
2023-06-14 10:09:38 +00:00
|
|
|
uid
|
|
|
|
status
|
|
|
|
}
|
|
|
|
}
|
2023-06-21 03:46:56 +00:00
|
|
|
}
|
2023-06-14 10:09:38 +00:00
|
|
|
}
|
|
|
|
"""
|
|
|
|
|
|
|
|
|
2023-06-14 13:00:23 +00:00
|
|
|
def api_restore(authorized_client, snapshot_id):
|
|
|
|
response = authorized_client.post(
|
|
|
|
"/graphql",
|
|
|
|
json={
|
|
|
|
"query": API_RESTORE_MUTATION,
|
|
|
|
"variables": {"snapshot_id": snapshot_id},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
2023-06-14 10:09:38 +00:00
|
|
|
def api_backup(authorized_client, service):
|
|
|
|
response = authorized_client.post(
|
|
|
|
"/graphql",
|
|
|
|
json={
|
|
|
|
"query": API_BACK_UP_MUTATION,
|
|
|
|
"variables": {"service_id": service.get_id()},
|
|
|
|
},
|
2023-06-14 12:41:45 +00:00
|
|
|
)
|
2023-06-14 10:09:38 +00:00
|
|
|
return response
|
|
|
|
|
|
|
|
|
2023-07-28 11:32:48 +00:00
|
|
|
def api_forget(authorized_client, snapshot_id):
|
|
|
|
response = authorized_client.post(
|
|
|
|
"/graphql",
|
|
|
|
json={
|
|
|
|
"query": API_FORGET_MUTATION,
|
|
|
|
"variables": {"snapshot_id": snapshot_id},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
2023-06-19 13:28:02 +00:00
|
|
|
def api_set_period(authorized_client, period):
|
|
|
|
response = authorized_client.post(
|
|
|
|
"/graphql",
|
|
|
|
json={
|
|
|
|
"query": API_SET_AUTOBACKUP_PERIOD_MUTATION,
|
|
|
|
"variables": {"period": period},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
2023-08-30 09:03:19 +00:00
|
|
|
def api_set_quotas(authorized_client, quotas: _AutobackupQuotas):
|
2023-08-28 18:24:29 +00:00
|
|
|
response = authorized_client.post(
|
|
|
|
"/graphql",
|
|
|
|
json={
|
|
|
|
"query": API_SET_AUTOBACKUP_QUOTAS_MUTATION,
|
2024-07-26 19:59:32 +00:00
|
|
|
"variables": {"input": quotas.model_dump()},
|
2023-08-28 18:24:29 +00:00
|
|
|
},
|
|
|
|
)
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
2023-06-16 14:33:48 +00:00
|
|
|
def api_remove(authorized_client):
|
|
|
|
response = authorized_client.post(
|
|
|
|
"/graphql",
|
|
|
|
json={
|
|
|
|
"query": API_REMOVE_REPOSITORY_MUTATION,
|
|
|
|
"variables": {},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
2023-06-19 14:12:40 +00:00
|
|
|
def api_reload_snapshots(authorized_client):
|
|
|
|
response = authorized_client.post(
|
|
|
|
"/graphql",
|
|
|
|
json={
|
|
|
|
"query": API_RELOAD_SNAPSHOTS,
|
|
|
|
"variables": {},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
2024-09-06 11:40:16 +00:00
|
|
|
def api_total_backup(authorized_client):
|
2024-07-29 12:16:33 +00:00
|
|
|
response = authorized_client.post(
|
|
|
|
"/graphql",
|
|
|
|
json={
|
2024-09-06 11:40:16 +00:00
|
|
|
"query": API_TOTAL_BACKUP,
|
2024-07-29 12:16:33 +00:00
|
|
|
"variables": {},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
2024-09-23 12:22:57 +00:00
|
|
|
def api_restore_all(authorized_client):
|
|
|
|
response = authorized_client.post(
|
|
|
|
"/graphql",
|
|
|
|
json={
|
|
|
|
"query": API_TOTAL_RESTORE,
|
|
|
|
"variables": {},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
2024-07-29 10:14:22 +00:00
|
|
|
def api_init(
|
|
|
|
authorized_client,
|
|
|
|
kind,
|
|
|
|
login,
|
|
|
|
password,
|
|
|
|
location_name,
|
|
|
|
location_id,
|
|
|
|
local_secret=None,
|
2023-06-16 13:43:41 +00:00
|
|
|
):
|
|
|
|
response = authorized_client.post(
|
|
|
|
"/graphql",
|
|
|
|
json={
|
|
|
|
"query": API_INIT_MUTATION,
|
|
|
|
"variables": {
|
|
|
|
"input": {
|
|
|
|
"provider": kind,
|
|
|
|
"locationId": location_id,
|
|
|
|
"locationName": location_name,
|
|
|
|
"login": login,
|
|
|
|
"password": password,
|
2024-07-29 10:14:22 +00:00
|
|
|
"localSecret": local_secret,
|
2023-06-16 13:43:41 +00:00
|
|
|
}
|
|
|
|
},
|
|
|
|
},
|
|
|
|
)
|
|
|
|
return response
|
|
|
|
|
|
|
|
|
|
|
|
def assert_ok(data):
|
2023-11-17 14:32:31 +00:00
|
|
|
if data["success"] is False:
|
|
|
|
# convenience for debugging, this should display error
|
|
|
|
# if empty, consider adding helpful messages
|
|
|
|
raise ValueError(data["code"], data["message"])
|
2023-06-16 13:43:41 +00:00
|
|
|
assert data["code"] == 200
|
|
|
|
assert data["success"] is True
|
|
|
|
|
|
|
|
|
2023-06-14 11:14:52 +00:00
|
|
|
def get_data(response):
|
|
|
|
assert response.status_code == 200
|
|
|
|
response = response.json()
|
2023-06-14 11:54:24 +00:00
|
|
|
if (
|
|
|
|
"errors" in response.keys()
|
|
|
|
): # convenience for debugging, this will display error
|
2023-11-22 18:13:07 +00:00
|
|
|
raise ValueError(response["errors"])
|
2023-06-14 11:14:52 +00:00
|
|
|
assert response["data"] is not None
|
|
|
|
data = response["data"]
|
|
|
|
return data
|
|
|
|
|
|
|
|
|
2023-06-14 11:52:57 +00:00
|
|
|
def api_snapshots(authorized_client):
|
2023-06-14 11:14:52 +00:00
|
|
|
response = authorized_client.post(
|
|
|
|
"/graphql",
|
|
|
|
json={"query": generate_backup_query([API_SNAPSHOTS_QUERY])},
|
|
|
|
)
|
|
|
|
data = get_data(response)
|
|
|
|
result = data["backup"]["allSnapshots"]
|
|
|
|
assert result is not None
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
2024-08-07 12:35:34 +00:00
|
|
|
def api_last_slice(authorized_client):
|
|
|
|
response = authorized_client.post(
|
|
|
|
"/graphql",
|
|
|
|
json={"query": generate_backup_query([API_LAST_SLICE_QUERY])},
|
|
|
|
)
|
|
|
|
data = get_data(response)
|
|
|
|
result = data["backup"]["lastSlice"]
|
|
|
|
assert result is not None
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
2024-07-29 10:14:22 +00:00
|
|
|
def api_settings(authorized_client):
|
|
|
|
response = authorized_client.post(
|
|
|
|
"/graphql",
|
|
|
|
json={"query": generate_backup_query([API_BACKUP_SETTINGS_QUERY])},
|
|
|
|
)
|
|
|
|
data = get_data(response)
|
|
|
|
result = data["backup"]["configuration"]
|
|
|
|
assert result is not None
|
|
|
|
return result
|
|
|
|
|
|
|
|
|
2023-06-14 12:08:07 +00:00
|
|
|
def test_dummy_service_convertible_to_gql(dummy_service):
|
|
|
|
gql_service = service_to_graphql_service(dummy_service)
|
|
|
|
assert gql_service is not None
|
|
|
|
|
|
|
|
|
2023-09-20 13:34:44 +00:00
|
|
|
def test_snapshots_empty(authorized_client, dummy_service, backups):
|
2023-06-14 11:52:57 +00:00
|
|
|
snaps = api_snapshots(authorized_client)
|
2023-06-14 11:14:52 +00:00
|
|
|
assert snaps == []
|
|
|
|
|
|
|
|
|
2024-05-24 12:30:27 +00:00
|
|
|
def test_snapshots_orphaned_service(authorized_client, dummy_service, backups):
|
|
|
|
api_backup(authorized_client, dummy_service)
|
|
|
|
snaps = api_snapshots(authorized_client)
|
|
|
|
assert len(snaps) == 1
|
|
|
|
|
|
|
|
all_services.services.remove(dummy_service)
|
2024-07-24 15:15:31 +00:00
|
|
|
assert ServiceManager.get_service_by_id(dummy_service.get_id()) is None
|
2024-05-24 12:30:27 +00:00
|
|
|
|
|
|
|
snaps = api_snapshots(authorized_client)
|
|
|
|
assert len(snaps) == 1
|
|
|
|
assert "Orphaned" in snaps[0]["service"]["displayName"]
|
|
|
|
assert dummy_service.get_id() in snaps[0]["service"]["displayName"]
|
|
|
|
|
|
|
|
|
2023-11-17 14:32:31 +00:00
|
|
|
def test_start_backup(authorized_client, dummy_service, backups):
|
2023-06-14 10:09:38 +00:00
|
|
|
response = api_backup(authorized_client, dummy_service)
|
2023-06-21 03:46:56 +00:00
|
|
|
data = get_data(response)["backup"]["startBackup"]
|
2023-06-14 12:41:45 +00:00
|
|
|
assert data["success"] is True
|
|
|
|
job = data["job"]
|
2023-06-14 12:35:41 +00:00
|
|
|
|
2023-06-14 10:09:38 +00:00
|
|
|
assert Jobs.get_job(job["uid"]).status == JobStatus.FINISHED
|
2023-06-14 12:35:41 +00:00
|
|
|
snaps = api_snapshots(authorized_client)
|
|
|
|
assert len(snaps) == 1
|
|
|
|
snap = snaps[0]
|
2023-06-14 13:00:23 +00:00
|
|
|
|
|
|
|
assert snap["id"] is not None
|
|
|
|
assert snap["id"] != ""
|
2023-06-14 12:35:41 +00:00
|
|
|
assert snap["service"]["id"] == "testservice"
|
2023-06-14 13:00:23 +00:00
|
|
|
|
|
|
|
|
2023-11-17 14:32:31 +00:00
|
|
|
def test_restore(authorized_client, dummy_service, backups):
|
2023-06-14 13:00:23 +00:00
|
|
|
api_backup(authorized_client, dummy_service)
|
|
|
|
snap = api_snapshots(authorized_client)[0]
|
|
|
|
assert snap["id"] is not None
|
|
|
|
|
|
|
|
response = api_restore(authorized_client, snap["id"])
|
2023-06-21 03:46:56 +00:00
|
|
|
data = get_data(response)["backup"]["restoreBackup"]
|
2023-06-14 13:00:23 +00:00
|
|
|
assert data["success"] is True
|
|
|
|
job = data["job"]
|
|
|
|
|
|
|
|
assert Jobs.get_job(job["uid"]).status == JobStatus.FINISHED
|
2023-06-16 13:43:41 +00:00
|
|
|
|
|
|
|
|
2023-11-17 14:32:31 +00:00
|
|
|
def test_reinit(authorized_client, dummy_service, tmpdir, backups):
|
2023-06-16 13:43:41 +00:00
|
|
|
test_repo_path = path.join(tmpdir, "not_at_all_sus")
|
2024-07-29 10:14:22 +00:00
|
|
|
response = api_init(authorized_client, "FILE", "", "", test_repo_path, "")
|
2023-06-21 03:46:56 +00:00
|
|
|
data = get_data(response)["backup"]["initializeRepository"]
|
2023-06-16 13:43:41 +00:00
|
|
|
assert_ok(data)
|
|
|
|
configuration = data["configuration"]
|
|
|
|
assert configuration["provider"] == "FILE"
|
|
|
|
assert configuration["locationId"] == ""
|
|
|
|
assert configuration["locationName"] == test_repo_path
|
|
|
|
assert len(configuration["encryptionKey"]) > 1
|
|
|
|
assert configuration["isInitialized"] is True
|
|
|
|
|
|
|
|
response = api_backup(authorized_client, dummy_service)
|
2023-06-21 03:46:56 +00:00
|
|
|
data = get_data(response)["backup"]["startBackup"]
|
2023-06-16 13:43:41 +00:00
|
|
|
assert data["success"] is True
|
|
|
|
job = data["job"]
|
|
|
|
|
|
|
|
assert Jobs.get_job(job["uid"]).status == JobStatus.FINISHED
|
2023-06-16 14:33:48 +00:00
|
|
|
|
|
|
|
|
2024-07-29 12:16:33 +00:00
|
|
|
def test_migrate_backup_repo(authorized_client, dummy_service, tmpdir, backups):
|
2024-07-29 10:14:22 +00:00
|
|
|
"""
|
|
|
|
Simulate the workflow of migrating to a new server
|
|
|
|
"""
|
|
|
|
# Using an alternative path to be sure that we do not
|
|
|
|
# match only by incident
|
|
|
|
test_repo_path = path.join(tmpdir, "not_at_all_sus")
|
|
|
|
response = api_init(authorized_client, "FILE", "", "", test_repo_path, "")
|
|
|
|
data = get_data(response)["backup"]["initializeRepository"]
|
|
|
|
assert_ok(data)
|
|
|
|
snaps = api_snapshots(authorized_client)
|
|
|
|
assert snaps == []
|
|
|
|
|
|
|
|
# Now, forget what we just did
|
|
|
|
del test_repo_path
|
|
|
|
del response
|
|
|
|
del data
|
|
|
|
del snaps
|
|
|
|
|
|
|
|
# I am a user at my old machine, I make a backup
|
|
|
|
response = api_backup(authorized_client, dummy_service)
|
|
|
|
data = get_data(response)["backup"]["startBackup"]
|
|
|
|
assert_ok(data)
|
|
|
|
|
|
|
|
# Then oh no, we need to migrate, we get our settings.
|
|
|
|
# Because we have forgot everything 2000 times already
|
|
|
|
# Was years, was years.
|
|
|
|
# I still remember login though
|
|
|
|
configuration = api_settings(authorized_client)
|
|
|
|
|
|
|
|
# Ok. Let's now go to another machine
|
|
|
|
# Another machine will not have any settings at all
|
|
|
|
|
|
|
|
Storage.reset()
|
|
|
|
LocalBackupSecret._full_reset()
|
|
|
|
|
|
|
|
# That's it, nothing left
|
|
|
|
new_configuration = api_settings(authorized_client)
|
|
|
|
assert new_configuration["isInitialized"] is False
|
|
|
|
|
|
|
|
# Reinit
|
|
|
|
response = api_init(
|
|
|
|
authorized_client,
|
2024-07-29 10:33:46 +00:00
|
|
|
kind=configuration["provider"],
|
|
|
|
login="", # user provides login and password, configuration endpoint does not
|
|
|
|
password="", # empty for file based repository
|
|
|
|
location_name=configuration["locationName"],
|
|
|
|
location_id=configuration["locationId"],
|
|
|
|
local_secret=configuration["encryptionKey"],
|
2024-07-29 10:14:22 +00:00
|
|
|
)
|
|
|
|
data = get_data(response)["backup"]["initializeRepository"]
|
|
|
|
assert_ok(data)
|
2024-07-29 10:33:46 +00:00
|
|
|
assert data["configuration"] == configuration
|
2024-07-29 10:14:22 +00:00
|
|
|
|
|
|
|
new_configuration = api_settings(authorized_client)
|
|
|
|
assert new_configuration == configuration
|
|
|
|
|
|
|
|
snaps = api_snapshots(authorized_client)
|
|
|
|
assert len(snaps) == 1
|
|
|
|
|
|
|
|
|
2023-11-17 14:32:31 +00:00
|
|
|
def test_remove(authorized_client, generic_userdata, backups):
|
2023-06-16 14:33:48 +00:00
|
|
|
response = api_remove(authorized_client)
|
2023-06-21 03:46:56 +00:00
|
|
|
data = get_data(response)["backup"]["removeRepository"]
|
2023-06-16 14:33:48 +00:00
|
|
|
assert_ok(data)
|
|
|
|
|
|
|
|
configuration = data["configuration"]
|
2023-06-19 11:09:10 +00:00
|
|
|
assert configuration["provider"] == "NONE"
|
2023-06-16 14:33:48 +00:00
|
|
|
assert configuration["locationId"] == ""
|
2023-06-16 15:09:39 +00:00
|
|
|
assert configuration["locationName"] == ""
|
2023-06-16 14:33:48 +00:00
|
|
|
# still generated every time it is missing
|
|
|
|
assert len(configuration["encryptionKey"]) > 1
|
|
|
|
assert configuration["isInitialized"] is False
|
2023-06-19 13:28:02 +00:00
|
|
|
|
2023-09-20 14:28:32 +00:00
|
|
|
|
2023-11-17 14:32:31 +00:00
|
|
|
def test_autobackup_quotas_nonzero(authorized_client, backups):
|
2023-08-30 09:03:19 +00:00
|
|
|
quotas = _AutobackupQuotas(
|
2023-09-09 00:26:41 +00:00
|
|
|
last=3,
|
2023-08-28 18:24:29 +00:00
|
|
|
daily=2,
|
|
|
|
weekly=4,
|
|
|
|
monthly=13,
|
|
|
|
yearly=14,
|
|
|
|
)
|
|
|
|
response = api_set_quotas(authorized_client, quotas)
|
|
|
|
data = get_data(response)["backup"]["setAutobackupQuotas"]
|
|
|
|
assert_ok(data)
|
|
|
|
|
|
|
|
configuration = data["configuration"]
|
2024-07-26 19:59:32 +00:00
|
|
|
assert configuration["autobackupQuotas"] == quotas.model_dump()
|
2023-08-28 18:24:29 +00:00
|
|
|
|
|
|
|
|
2023-11-17 14:32:31 +00:00
|
|
|
def test_autobackup_period_nonzero(authorized_client, backups):
|
2023-06-19 13:28:02 +00:00
|
|
|
new_period = 11
|
|
|
|
response = api_set_period(authorized_client, new_period)
|
2023-06-21 03:46:56 +00:00
|
|
|
data = get_data(response)["backup"]["setAutobackupPeriod"]
|
2023-06-19 13:28:02 +00:00
|
|
|
assert_ok(data)
|
|
|
|
|
|
|
|
configuration = data["configuration"]
|
|
|
|
assert configuration["autobackupPeriod"] == new_period
|
|
|
|
|
|
|
|
|
2023-11-17 14:32:31 +00:00
|
|
|
def test_autobackup_period_zero(authorized_client, backups):
|
2023-06-19 13:28:02 +00:00
|
|
|
new_period = 0
|
|
|
|
# since it is none by default, we better first set it to something non-negative
|
|
|
|
response = api_set_period(authorized_client, 11)
|
|
|
|
# and now we nullify it
|
|
|
|
response = api_set_period(authorized_client, new_period)
|
2023-06-21 03:46:56 +00:00
|
|
|
data = get_data(response)["backup"]["setAutobackupPeriod"]
|
2023-06-19 13:28:02 +00:00
|
|
|
assert_ok(data)
|
|
|
|
|
|
|
|
configuration = data["configuration"]
|
|
|
|
assert configuration["autobackupPeriod"] == None
|
|
|
|
|
|
|
|
|
2023-11-17 14:32:31 +00:00
|
|
|
def test_autobackup_period_none(authorized_client, backups):
|
2023-06-19 13:28:02 +00:00
|
|
|
# since it is none by default, we better first set it to something non-negative
|
|
|
|
response = api_set_period(authorized_client, 11)
|
|
|
|
# and now we nullify it
|
|
|
|
response = api_set_period(authorized_client, None)
|
2023-06-21 03:46:56 +00:00
|
|
|
data = get_data(response)["backup"]["setAutobackupPeriod"]
|
2023-06-19 13:28:02 +00:00
|
|
|
assert_ok(data)
|
|
|
|
|
|
|
|
configuration = data["configuration"]
|
|
|
|
assert configuration["autobackupPeriod"] == None
|
|
|
|
|
|
|
|
|
2023-11-17 14:32:31 +00:00
|
|
|
def test_autobackup_period_negative(authorized_client, backups):
|
2023-06-19 13:28:02 +00:00
|
|
|
# since it is none by default, we better first set it to something non-negative
|
|
|
|
response = api_set_period(authorized_client, 11)
|
|
|
|
# and now we nullify it
|
|
|
|
response = api_set_period(authorized_client, -12)
|
2023-06-21 03:46:56 +00:00
|
|
|
data = get_data(response)["backup"]["setAutobackupPeriod"]
|
2023-06-19 13:28:02 +00:00
|
|
|
assert_ok(data)
|
|
|
|
|
|
|
|
configuration = data["configuration"]
|
|
|
|
assert configuration["autobackupPeriod"] == None
|
2023-06-19 14:12:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
# We cannot really check the effect at this level, we leave it to backend tests
|
|
|
|
# But we still make it run in both empty and full scenarios and ask for snaps afterwards
|
2023-11-17 14:32:31 +00:00
|
|
|
def test_reload_snapshots_bare_bare_bare(authorized_client, dummy_service, backups):
|
2023-06-19 14:12:40 +00:00
|
|
|
api_remove(authorized_client)
|
|
|
|
|
|
|
|
response = api_reload_snapshots(authorized_client)
|
2023-06-21 03:46:56 +00:00
|
|
|
data = get_data(response)["backup"]["forceSnapshotsReload"]
|
2023-06-19 14:12:40 +00:00
|
|
|
assert_ok(data)
|
|
|
|
|
|
|
|
snaps = api_snapshots(authorized_client)
|
|
|
|
assert snaps == []
|
|
|
|
|
|
|
|
|
2024-09-23 13:41:40 +00:00
|
|
|
def test_total_backup_if_dir_exists(
|
2024-08-21 13:55:30 +00:00
|
|
|
authorized_client, only_dummy_service_and_api, backups
|
|
|
|
):
|
|
|
|
# mkdir(CONFIG_STASH_DIR)
|
|
|
|
dummy_service = only_dummy_service_and_api
|
|
|
|
|
2024-09-06 11:40:16 +00:00
|
|
|
response = api_total_backup(authorized_client)
|
2024-08-21 13:55:30 +00:00
|
|
|
# raise ValueError(get_data(response))
|
2024-09-06 11:40:16 +00:00
|
|
|
data = get_data(response)["backup"]["totalBackup"]
|
2024-08-21 13:55:30 +00:00
|
|
|
assert_ok(data)
|
|
|
|
|
|
|
|
snaps = api_snapshots(authorized_client)
|
|
|
|
assert len(snaps) == 2
|
|
|
|
|
|
|
|
|
2024-09-23 13:41:40 +00:00
|
|
|
def test_total_backup(authorized_client, only_dummy_service_and_api, backups):
|
2024-07-29 12:16:33 +00:00
|
|
|
dummy_service = only_dummy_service_and_api
|
|
|
|
|
2024-09-06 11:40:16 +00:00
|
|
|
response = api_total_backup(authorized_client)
|
2024-07-29 12:16:33 +00:00
|
|
|
# raise ValueError(get_data(response))
|
2024-09-06 11:40:16 +00:00
|
|
|
data = get_data(response)["backup"]["totalBackup"]
|
2024-07-29 12:16:33 +00:00
|
|
|
assert_ok(data)
|
|
|
|
|
|
|
|
snaps = api_snapshots(authorized_client)
|
|
|
|
assert len(snaps) == 2
|
|
|
|
|
|
|
|
|
2023-11-17 14:32:31 +00:00
|
|
|
def test_reload_snapshots(authorized_client, dummy_service, backups):
|
2023-06-19 14:12:40 +00:00
|
|
|
response = api_backup(authorized_client, dummy_service)
|
2023-06-21 03:46:56 +00:00
|
|
|
data = get_data(response)["backup"]["startBackup"]
|
2023-06-19 14:12:40 +00:00
|
|
|
|
|
|
|
response = api_reload_snapshots(authorized_client)
|
2023-06-21 03:46:56 +00:00
|
|
|
data = get_data(response)["backup"]["forceSnapshotsReload"]
|
2023-06-19 14:12:40 +00:00
|
|
|
assert_ok(data)
|
|
|
|
|
|
|
|
snaps = api_snapshots(authorized_client)
|
|
|
|
assert len(snaps) == 1
|
2023-07-28 11:32:48 +00:00
|
|
|
|
|
|
|
|
2023-11-17 14:32:31 +00:00
|
|
|
def test_forget_snapshot(authorized_client, dummy_service, backups):
|
2023-07-28 11:32:48 +00:00
|
|
|
response = api_backup(authorized_client, dummy_service)
|
|
|
|
data = get_data(response)["backup"]["startBackup"]
|
|
|
|
|
|
|
|
snaps = api_snapshots(authorized_client)
|
|
|
|
assert len(snaps) == 1
|
|
|
|
|
|
|
|
response = api_forget(authorized_client, snaps[0]["id"])
|
|
|
|
data = get_data(response)["backup"]["forgetSnapshot"]
|
|
|
|
assert_ok(data)
|
|
|
|
|
|
|
|
snaps = api_snapshots(authorized_client)
|
|
|
|
assert len(snaps) == 0
|
|
|
|
|
|
|
|
|
2023-11-17 14:32:31 +00:00
|
|
|
def test_forget_nonexistent_snapshot(authorized_client, dummy_service, backups):
|
2023-07-28 11:32:48 +00:00
|
|
|
snaps = api_snapshots(authorized_client)
|
|
|
|
assert len(snaps) == 0
|
|
|
|
response = api_forget(authorized_client, "898798uekiodpjoiweoiwuoeirueor")
|
|
|
|
data = get_data(response)["backup"]["forgetSnapshot"]
|
|
|
|
assert data["code"] == 404
|
|
|
|
assert data["success"] is False
|
|
|
|
|
|
|
|
snaps = api_snapshots(authorized_client)
|
|
|
|
assert len(snaps) == 0
|
2024-08-07 12:35:34 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_last_slice(authorized_client, only_dummy_service_and_api, backups):
|
2024-09-06 11:40:16 +00:00
|
|
|
api_total_backup(authorized_client)
|
2024-08-07 12:35:34 +00:00
|
|
|
snaps = api_last_slice(authorized_client)
|
|
|
|
|
|
|
|
assert len(snaps) == 2
|
2024-09-23 12:22:57 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_backup_all_restore_all(
|
|
|
|
authorized_client,
|
|
|
|
backups,
|
|
|
|
generic_userdata,
|
|
|
|
dkim_file,
|
|
|
|
only_dummy_service_and_api,
|
|
|
|
catch_nixos_rebuild_calls,
|
|
|
|
):
|
|
|
|
dummy_service = only_dummy_service_and_api
|
|
|
|
fp = catch_nixos_rebuild_calls
|
|
|
|
fp.pass_command(["restic", fp.any()])
|
|
|
|
fp.keep_last_process(True)
|
|
|
|
fp.pass_command(["rclone", fp.any()])
|
|
|
|
fp.keep_last_process(True)
|
|
|
|
fp.pass_command(["lsblk", fp.any()])
|
|
|
|
fp.keep_last_process(True)
|
|
|
|
|
|
|
|
response = api_total_backup(authorized_client)
|
|
|
|
data = get_data(response)["backup"]["totalBackup"]
|
|
|
|
assert_ok(data)
|
|
|
|
|
|
|
|
assert len(api_snapshots(authorized_client)) == 2
|
|
|
|
response = api_restore_all(authorized_client)
|
|
|
|
data = get_data(response)["backup"]["restoreAll"]
|
|
|
|
assert_ok(data)
|
|
|
|
# Just in case
|
|
|
|
assert len(api_snapshots(authorized_client)) == 2
|
2024-09-23 13:41:40 +00:00
|
|
|
|
|
|
|
|
|
|
|
def test_unauthorized(client, dummy_service):
|
|
|
|
quotas = _AutobackupQuotas(
|
|
|
|
last=3,
|
|
|
|
daily=2,
|
|
|
|
weekly=4,
|
|
|
|
monthly=13,
|
|
|
|
yearly=14,
|
|
|
|
)
|
|
|
|
response = api_set_quotas(client, quotas)
|
|
|
|
assert_empty(response)
|
|
|
|
response = api_set_period(client, 11)
|
|
|
|
assert_empty(response)
|
|
|
|
response = api_remove(client)
|
|
|
|
assert_empty(response)
|
|
|
|
response = api_init(client, "FILE", "", "", "/boguspath", "")
|
|
|
|
assert_empty(response)
|
|
|
|
response = api_restore(client, "oiueroiwueo")
|
|
|
|
assert_empty(response)
|
|
|
|
response = api_backup(client, dummy_service)
|
|
|
|
assert_empty(response)
|
|
|
|
response = api_forget(client, "worieuoweiru")
|
|
|
|
assert_empty(response)
|
|
|
|
response = api_total_backup(client)
|
|
|
|
assert_empty(response)
|
|
|
|
response = api_restore_all(client)
|
|
|
|
assert_empty(response)
|
|
|
|
response = api_reload_snapshots(client)
|
|
|
|
assert_empty(response)
|
|
|
|
|
|
|
|
# TODO: make a special error for this in get_data
|
|
|
|
with raises(ValueError):
|
|
|
|
api_last_slice(client)
|
|
|
|
with raises(ValueError):
|
|
|
|
api_snapshots(client)
|