Backup automatico script del 2026-09-27 07:00

This commit is contained in:
daniele committed 2026-09-27 07:00:02 +02:00
1 parent f347badf3b
commit 09dcbbdadb
24 files changed
+1164 -193

No files matched your search

@@ -0,0 +1,115 @@
#!/usr/bin/env python3
"""Test dei contesti condivisi su directory e DB temporanei (non tocca i dati reali).
Uso (dentro il container):
docker exec loogle-mcp python /srv/scripts/test_shared_contexts.py
"""
import json
import os
import sys
import tempfile
TMP = tempfile.mkdtemp(prefix="shared-ctx-test-")
os.environ["MCP_CONTEXT_ROOT"] = os.path.join(TMP, "context")
os.environ["MCP_DB"] = os.path.join(TMP, "test.db")
sys.path.insert(0, "/srv")
from app.db import init_db # noqa: E402
from app.context import store # noqa: E402
from app.knowledge import indexer # noqa: E402
from app.mcp import tools # noqa: E402
init_db()
queued = []
indexer.submit_background = lambda label, fn, *a, **k: queued.append((label, fn.__name__, a))
failures = 0
def claims(user, admin=False):
scope = "context:read context:write" + (" admin" if admin else "")
return {"sub": user, "scope": scope}
def call(user, name, args, admin=False):
out = tools.call_tool(name, args, claims(user, admin))
return json.loads(out["content"][0]["text"])
def check(label, cond):
global failures
failures += 0 if cond else 1
print(f"{'OK ' if cond else 'FAIL'} {label}")
def raises(exc, fn, *a, **k):
try:
fn(*a, **k)
except exc:
return True
except Exception as other: # noqa: BLE001
print(" eccezione inattesa:", type(other).__name__, other)
return False
# 1. Progetto personale di daniele, poi condiviso
p = call("daniele", "create_project", {"title": "Stampa 3D X2D", "tags": ["stampa-3d"]})
pid = p["id"]
call("daniele", "save_context", {"project_id": pid, "content": "## Dotazione\n- PLA 4 kg"})
check("lucia non vede il progetto personale di daniele",
pid not in [x["id"] for x in call("lucia", "list_projects", {})["projects"]])
check("lucia non può leggerlo", raises(FileNotFoundError, call, "lucia", "get_project_context", {"project_id": pid}))
m = call("daniele", "share_project", {"project_id": pid})
check("share_project -> shared/family/owner", m.get("shared") and m.get("shared_with") == "family" and m.get("owner") == "daniele")
check("la cartella è passata nello spazio condiviso",
os.path.isfile(os.path.join(TMP, "context", "_shared", "projects", pid, "context.md"))
and not os.path.exists(os.path.join(TMP, "context", "daniele", "projects", pid)))
check("reindicizzazione vettori accodata", any(q[1] == "_move_project_vectors" for q in queued))
# 2. Tutta la famiglia legge e aggiorna
for u in ("lucia", "davide", "luca"):
ids = {x["id"]: x for x in call(u, "list_projects", {})["projects"]}
check(f"{u} vede il contesto condiviso", pid in ids and ids[pid].get("shared"))
ctx = call("lucia", "get_project_context", {"project_id": pid})
check("lucia legge la storia (sessione di daniele)", "PLA 4 kg" in ctx["context_md"] and ctx["recent_sessions"])
rev = ctx["meta"].get("revision", 0)
m = call("lucia", "save_context", {"project_id": pid, "mode": "replace",
"content": "## Dotazione\n- PLA 4 kg\n- PETG 1 kg (comprato da Lucia)",
"if_revision": rev})
check("lucia aggiorna, updated_by=lucia", m.get("updated_by") == "lucia")
check("daniele vede la modifica di lucia", "PETG 1 kg" in call("daniele", "get_project_context", {"project_id": pid})["context_md"])
sessions = os.listdir(os.path.join(TMP, "context", "_shared", "projects", pid, "sessions"))
check("il nome della sessione indica l'autore", any(s.endswith("-lucia.md") for s in sessions))
check("conflitto: if_revision superata -> errore e nessuna sovrascrittura",
raises(store.ConflictError, store.save_context, "davide", pid, "x", "replace", if_revision=rev)
and "PETG 1 kg" in call("davide", "get_project_context", {"project_id": pid})["context_md"])
check("indicizzazione del contesto completo accodata", any(q[1] == "index_project_context" for q in queued))
# 3. Permessi: archiviare / rendere personale
check("lucia non può archiviare", raises(PermissionError, call, "lucia", "archive_project", {"project_id": pid}))
check("lucia non può riportarlo personale", raises(PermissionError, call, "lucia", "share_project", {"project_id": pid, "shared": False}))
check("admin può archiviare", call("davide", "archive_project", {"project_id": pid}, admin=True).get("archived") is True)
call("daniele", "archive_project", {"project_id": pid, "archived": False})
m = call("daniele", "share_project", {"project_id": pid, "shared": False})
check("il proprietario lo riporta personale", not m.get("shared") and "owner" not in m)
check("dopo: lucia non lo vede più", pid not in [x["id"] for x in call("lucia", "list_projects", {})["projects"]])
check("dopo: daniele lo ha di nuovo personale con la storia",
"PETG 1 kg" in call("daniele", "get_project_context", {"project_id": pid})["context_md"])
# 4. Creazione diretta condivisa, ID unici tra i due spazi, risorse MCP
s = call("lucia", "create_project", {"title": "Stampa 3D X2D", "shared": True})
check("create_project shared=true con ID diverso dal personale di daniele", s.get("shared") and s["id"] != pid)
check("daniele raggiunge sia il suo personale sia il nuovo condiviso",
call("daniele", "get_project_context", {"project_id": s["id"]})["meta"].get("shared")
and not call("daniele", "get_project_context", {"project_id": pid})["meta"].get("shared"))
call("luca", "create_project", {"title": "Omonimo"})
call("daniele", "create_project", {"title": "Omonimo"})
check("share_project rifiuta un ID usato da un personale di un altro utente",
raises(ValueError, call, "daniele", "share_project", {"project_id": "omonimo"}))
uris = [r["uri"] for r in tools.list_resources(claims("luca"))]
check("risorsa condivisa visibile a luca", f"loogle://context/_shared/{s['id']}" in uris)
res = tools.read_resource(f"loogle://context/_shared/{s['id']}", claims("luca"))
check("luca legge la risorsa condivisa", res["text"].startswith("# Stampa 3D X2D"))
print(f"Errori: {failures}")
sys.exit(1 if failures else 0)
Reference in new issue
Block a user
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.