Files
agent-radar 1a3a4ccde1
Creator App Tests / PR Spam Gate (push) Skipped
Frontend Tests / PR Spam Gate (push) Skipped
NPM Format (website & console) / PR Spam Gate (push) Skipped
Pre-commit Checks / PR Spam Gate (push) Skipped
QwenPaw Creator Plugin Release / check-version (push) Canceled after 0s
QwenPaw Creator Plugin Release / upload-oss (push) Canceled after 0s
Tests / PR Spam Gate (push) Skipped
CodeQL / CodeQL (python) (push) Canceled after 0s
CodeQL / CodeQL (typescript) (push) Canceled after 0s
Creator App Tests / Creator Backend Tests (push) Canceled after 0s
Creator App Tests / Creator UI Build & Tests (push) Canceled after 0s
E2E Smoke Tests / Playwright UI Smoke (push) Canceled after 0s
Frontend Tests / Detect console changes (push) Canceled after 0s
NPM Format (website & console) / website format check (push) Canceled after 0s
NPM Format (website & console) / console format check (push) Canceled after 0s
Pre-commit Checks / Pre-commit (push) Canceled after 0s
QwenPaw Data Plugin Release / check-version (push) Canceled after 0s
Tests / Detect code changes (push) Canceled after 0s
Frontend Tests / Vitest Unit Tests (push) Canceled after 0s
Frontend Tests / Frontend Summary (push) Canceled after 0s
QwenPaw Data Plugin Release / upload-oss (push) Canceled after 0s
Tests / Maintainer Approval (push) Canceled after 0s
Tests / Unit Tests - py3.11 - macos-latest (push) Canceled after 0s
Tests / Unit Tests - py3.11 - ubuntu-latest (push) Canceled after 0s
Tests / Unit Tests - py3.13 - ubuntu-latest (push) Canceled after 0s
Tests / Unit Tests - py3.11 - windows-latest (push) Canceled after 0s
Tests / Contract Tests - py3.11 - macos-latest (push) Canceled after 0s
Tests / Contract Tests - py3.11 - ubuntu-latest (push) Canceled after 0s
Tests / Contract Tests - py3.13 - ubuntu-latest (push) Canceled after 0s
Tests / Contract Tests - py3.11 - windows-latest (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - macos-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - macos-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - macos-latest - p2 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - fallback (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - ubuntu-latest - p2 (push) Canceled after 0s
Tests / Integrated Tests - py3.13 - ubuntu-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.13 - ubuntu-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.13 - ubuntu-latest - p2 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - windows-latest - p0 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - windows-latest - p1 (push) Canceled after 0s
Tests / Integrated Tests - py3.11 - windows-latest - p2 (push) Canceled after 0s
Tests / Coverage Report (push) Canceled after 0s
Tests / Test Summary (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:01:50 +08:00

159 lines
4.4 KiB
Python

# -*- coding: utf-8 -*-
from __future__ import annotations
import threading
import zipfile
from types import SimpleNamespace
import pytest
from qwenpaw.backup._ops import create as create_module
from qwenpaw.backup._ops.create import BackupCancelled
from qwenpaw.backup._ops.create_helpers import add_agent_workspaces
from qwenpaw.backup.models import BackupMeta, BackupScope
def test_successful_create_atomically_publishes_archive(
tmp_path,
monkeypatch,
):
destination = tmp_path / "backup.zip"
meta = BackupMeta(
name="complete",
scope=BackupScope(
include_agents=False,
include_global_config=False,
include_secrets=False,
include_skill_pool=False,
),
)
events: list[dict] = []
monkeypatch.setattr(create_module, "BACKUP_DIR", tmp_path)
monkeypatch.setattr(create_module, "zip_path", lambda _id: destination)
monkeypatch.setattr(
create_module,
"load_config",
lambda: SimpleNamespace(agents=SimpleNamespace(profiles={})),
)
result = create_module.create_backup(
meta,
[],
events.append,
threading.Event(),
)
assert result.id == meta.id
assert destination.is_file()
assert not destination.with_suffix(".tmp").exists()
with zipfile.ZipFile(destination) as archive:
assert "meta.json" in archive.namelist()
assert events[-1] == {"type": "saving", "percent": 90}
def test_workspace_cancel_is_checked_between_files(tmp_path):
workspace = tmp_path / "workspace"
workspace.mkdir()
(workspace / "a.txt").write_text("a", encoding="utf-8")
(workspace / "b.txt").write_text("b", encoding="utf-8")
stop_event = threading.Event()
written: list[str] = []
class RecordingZip:
def write(self, _path, arcname):
written.append(arcname)
stop_event.set()
completed = add_agent_workspaces(
RecordingZip(),
[("agent-1", SimpleNamespace(workspace_dir=str(workspace)))],
stop_event=stop_event,
)
assert completed is False
assert len(written) == 1
def test_cancelled_create_removes_temp_and_final_archive(
tmp_path,
monkeypatch,
):
destination = tmp_path / "backup.zip"
stop_event = threading.Event()
meta = BackupMeta(
name="cancelled",
scope=BackupScope(
include_agents=False,
include_global_config=False,
include_secrets=False,
include_skill_pool=False,
),
)
monkeypatch.setattr(create_module, "BACKUP_DIR", tmp_path)
monkeypatch.setattr(create_module, "zip_path", lambda _id: destination)
monkeypatch.setattr(
create_module,
"load_config",
lambda: SimpleNamespace(agents=SimpleNamespace(profiles={})),
)
def cancel_during_collection(*_args, **_kwargs):
stop_event.set()
return []
monkeypatch.setattr(
create_module,
"add_files_to_zip",
cancel_during_collection,
)
with pytest.raises(BackupCancelled):
create_module.create_backup(meta, [], lambda _event: None, stop_event)
assert not destination.exists()
assert not destination.with_suffix(".tmp").exists()
def test_cancelled_during_signing_removes_temp_and_final_archive(
tmp_path,
monkeypatch,
):
destination = tmp_path / "backup.zip"
stop_event = threading.Event()
meta = BackupMeta(
name="cancelled-during-signing",
scope=BackupScope(
include_agents=False,
include_global_config=False,
include_secrets=False,
include_skill_pool=False,
),
)
monkeypatch.setattr(create_module, "BACKUP_DIR", tmp_path)
monkeypatch.setattr(create_module, "zip_path", lambda _id: destination)
monkeypatch.setattr(
create_module,
"load_config",
lambda: SimpleNamespace(agents=SimpleNamespace(profiles={})),
)
def cancel_during_signing(_src_zip, signed_meta, *, dest_zip):
dest_zip.write_bytes(b"published")
stop_event.set()
return signed_meta
monkeypatch.setattr(
create_module,
"replace_meta_with_local_signature",
cancel_during_signing,
)
with pytest.raises(BackupCancelled):
create_module.create_backup(meta, [], lambda _event: None, stop_event)
assert not destination.exists()
assert not destination.with_suffix(".tmp").exists()