Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 63 additions & 2 deletions integration/test_backup_v4.py
Original file line number Diff line number Diff line change
Expand Up @@ -497,13 +497,13 @@ def test_backup_and_restore_with_collection_and_config_1_24_x(


@pytest.mark.parametrize("dynamic_backup_location", [False, True])
def test_cancel_backup(
def test_cancel_backup_create(
client: weaviate.WeaviateClient,
dynamic_backup_location: bool,
tmp_path: pathlib.Path,
request: SubRequest,
) -> None:
"""Cancel backup without waiting."""
"""Cancel backup create without waiting."""
backup_id = unique_backup_id(request.node.name)
if client._connection._weaviate_version.is_lower_than(1, 24, 25):
pytest.skip("Cancel backups is only supported from 1.24.25")
Expand Down Expand Up @@ -543,6 +543,67 @@ def test_cancel_backup(
assert status_resp.status == BackupStatus.CANCELED or status_resp.status == BackupStatus.SUCCESS


@pytest.mark.parametrize("dynamic_backup_location", [False, True])
def test_cancel_backup_restore(
client: weaviate.WeaviateClient,
dynamic_backup_location: bool,
tmp_path: pathlib.Path,
request: SubRequest,
) -> None:
"""Cancel backup restore without waiting."""
backup_id = unique_backup_id(request.node.name)
if client._connection._weaviate_version.is_lower_than(1, 36, 0):
pytest.skip("Cancel restores is only supported from 1.36.0")

backup_location: Optional[wvc.backup.BackupLocationType] = None
if dynamic_backup_location:
backup_location = wvc.backup.BackupLocation.FileSystem(path=str(tmp_path))

c_name = "Restore"
c = client.collections.create(
name=c_name, properties=[Property(name="name", data_type=DataType.TEXT)]
)
c.data.insert({"name": "test"})

resp = client.backup.create(
backup_id=backup_id,
backend=BACKEND,
backup_location=backup_location,
include_collections=[c_name],
wait_for_completion=True,
)
assert resp.status == BackupStatus.SUCCESS

client.collections.delete(c_name)

resp = client.backup.restore(
backup_id=backup_id,
backend=BACKEND,
backup_location=backup_location,
include_collections=[c_name],
)
assert resp.status == BackupStatus.STARTED

assert client.backup.cancel(
backup_id=backup_id, backend=BACKEND, backup_location=backup_location, operation="restore"
)

start = time.time()
while time.time() - start < 5:
status_resp = client.backup.get_restore_status(
backup_id=backup_id, backend=BACKEND, backup_location=backup_location
)
if status_resp.status == BackupStatus.CANCELED:
break
time.sleep(0.1)

status_resp = client.backup.get_restore_status(
backup_id=backup_id, backend=BACKEND, backup_location=backup_location
)
# there can be a race between the cancel and the backup completion
assert status_resp.status == BackupStatus.CANCELED or status_resp.status == BackupStatus.SUCCESS


def test_backup_and_restore_with_roles_and_users(
client_factory: ClientFactory, request: SubRequest
) -> None:
Expand Down
1 change: 1 addition & 0 deletions weaviate/backup/async_.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class _BackupAsync(_BackupExecutor[ConnectionAsync]):
backup_id: str,
backend: BackupStorage,
backup_location: Optional[BackupLocationType] = None,
operation: Literal["create", "restore"] = "create",
) -> bool: ...
async def list_backups(
self, backend: BackupStorage, sort_by_starting_time_asc: Optional[bool] = None
Expand Down
4 changes: 3 additions & 1 deletion weaviate/backup/executor.py
Original file line number Diff line number Diff line change
Expand Up @@ -427,13 +427,15 @@ def cancel(
backup_id: str,
backend: BackupStorage,
backup_location: Optional[BackupLocationType] = None,
operation: Literal["create", "restore"] = "create",
) -> executor.Result[bool]:
"""Cancels a running backup.

Args:
backup_id: The identifier name of the backup. NOTE: Case insensitive.
backend: The backend storage where to create the backup.
backup_location: The dynamic location of a backup. By default None.
operation: The type of the backup operation to cancel, either "create" or "restore". By default "create".

Raises:
weaviate.exceptions.UnexpectedStatusCodeError: If weaviate reports a none OK status.
Expand All @@ -445,7 +447,7 @@ def cancel(
backup_id=backup_id,
backend=backend,
)
path = f"/backups/{backend.value}/{backup_id}"
path = f"/backups/{backend.value}/{backup_id}{'/restore' if operation == 'restore' else ''}"
params: Dict[str, str] = {}

if backup_location is not None:
Expand Down
1 change: 1 addition & 0 deletions weaviate/backup/sync.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ class _Backup(_BackupExecutor[ConnectionSync]):
backup_id: str,
backend: BackupStorage,
backup_location: Optional[BackupLocationType] = None,
operation: Literal["create", "restore"] = "create",
) -> bool: ...
def list_backups(
self, backend: BackupStorage, sort_by_starting_time_asc: Optional[bool] = None
Expand Down
Loading