test: Edge-Case-Dateien + Tests (leer/gross/verschluesselt/Sonderzeichen)
/testdata/edge/: empty.txt, leer.bin (0 Byte), Name mit Umlauten+Leerzeichen+ Klammern, Unicode/Emoji/RTL-Inhalt, Datei ohne Endung, passwortgeschuetztes PDF (pikepdf) + ZIP, riesig.dat (26 MB > MAX_BIN_SIZE). TestFileEdgeCases prueft graceful Handling (kein Crash, 'Datei zu gross', PDF-Lesefehler sauber gemeldet). gen_edge.py + upload_ocis.sh erweitert. 76 Tests gruen.
This commit is contained in:
@@ -85,3 +85,11 @@ python3 -m venv /tmp/gen && /tmp/gen/bin/pip install fpdf2 python-docx openpyxl
|
||||
sudo tests/testdata/upload_ocis.sh # -> mcptest oCIS /testdata/
|
||||
/tmp/gen/bin/python tests/testdata/gen_maildir.py # -> maildir mit Anhaengen
|
||||
```
|
||||
|
||||
### Edge-Cases
|
||||
|
||||
`/testdata/edge/` + `TestFileEdgeCases`: leere Datei, 0-Byte-Binary, Name mit
|
||||
Umlauten/Leerzeichen/Klammern, Unicode/Emoji/RTL-Inhalt, Datei ohne Endung,
|
||||
passwortgeschuetztes PDF + ZIP, uebergrosse Datei (26 MB > 25-MB-Limit ->
|
||||
"Datei zu gross"). Alle werden graceful behandelt (kein Crash). Generator:
|
||||
`gen_edge.py` (braucht pikepdf + zip), Upload via `upload_ocis.sh`.
|
||||
|
||||
@@ -455,3 +455,49 @@ class TestFileTypes:
|
||||
{"name": "read_file", "arguments": {"path": path}})
|
||||
types = {c["type"] for c in result["result"]["content"]}
|
||||
assert types & expected, f"{path}: erwartet eins von {expected}, bekam {types}"
|
||||
|
||||
|
||||
# ============================================================
|
||||
# File Edge Cases (leere/grosse/verschluesselte/Sonderzeichen-Dateien)
|
||||
# ============================================================
|
||||
|
||||
class TestFileEdgeCases:
|
||||
PORT = SERVERS["files"]
|
||||
|
||||
def _read(self, path):
|
||||
token = get_token(self.PORT)
|
||||
r = mcp_call(self.PORT, token, "tools/call",
|
||||
{"name": "read_file", "arguments": {"path": path}})
|
||||
return r["result"]["content"]
|
||||
|
||||
def test_empty_text_file(self):
|
||||
c = self._read("testdata/edge/empty.txt")
|
||||
assert c and c[0]["type"] == "text"
|
||||
|
||||
def test_zero_byte_binary(self):
|
||||
c = self._read("testdata/edge/leer.bin")
|
||||
assert c # kein Crash
|
||||
|
||||
def test_umlaut_space_paren_filename(self):
|
||||
c = self._read("testdata/edge/Ärger Übersicht (Größe).txt")
|
||||
assert c[0]["type"] == "text" and "Umlauten" in c[0]["text"]
|
||||
|
||||
def test_unicode_emoji_rtl_content(self):
|
||||
c = self._read("testdata/edge/unicode.txt")
|
||||
assert "😀" in c[0]["text"] and "مرحبا" in c[0]["text"]
|
||||
|
||||
def test_no_extension(self):
|
||||
c = self._read("testdata/edge/README_NOEXT")
|
||||
assert c and c[0]["type"] in ("text", "resource")
|
||||
|
||||
def test_encrypted_pdf_graceful(self):
|
||||
c = self._read("testdata/edge/geschuetzt.pdf")
|
||||
assert c and c[0]["type"] in ("text", "resource") # kein Crash
|
||||
|
||||
def test_password_protected_zip(self):
|
||||
c = self._read("testdata/edge/geheim.zip")
|
||||
assert any(x["type"] == "resource" for x in c)
|
||||
|
||||
def test_oversized_file_rejected(self):
|
||||
c = self._read("testdata/edge/riesig.dat")
|
||||
assert c[0]["type"] == "text" and "zu gross" in c[0]["text"]
|
||||
|
||||
Vendored
+20
@@ -0,0 +1,20 @@
|
||||
import os, zipfile, subprocess, pikepdf
|
||||
D="/tmp/mcptest-files-edge"; os.makedirs(D,exist_ok=True)
|
||||
def p(f): return os.path.join(D,f)
|
||||
# 1. leere Dateien
|
||||
open(p("empty.txt"),"w").close()
|
||||
open(p("leer.bin"),"wb").close()
|
||||
# 2. Umlaute + Leerzeichen + Klammern im Namen
|
||||
open(p("Ärger Übersicht (Größe).txt"),"w").write("Datei mit Umlauten und Leerzeichen im Namen.\n")
|
||||
# 3. Inhalt mit Sonderzeichen/Emoji/RTL
|
||||
open(p("unicode.txt"),"w").write("Emoji 😀🎉, RTL مرحبا, Tab\tNull-ish, Zeilen\n\n\n")
|
||||
# 4. keine Extension
|
||||
open(p("README_NOEXT"),"w").write("Datei ohne Dateiendung.\n")
|
||||
# 5. passwortgeschuetztes PDF
|
||||
pikepdf.open("/tmp/mcptest-files/document.pdf").save(p("geschuetzt.pdf"), encryption=pikepdf.Encryption(user="geheim",owner="geheim"))
|
||||
# 6. passwortgeschuetztes ZIP
|
||||
subprocess.run(["zip","-q","-j","-P","geheim",p("geheim.zip"),"/tmp/mcptest-files/notes.txt"],check=True)
|
||||
# 7. uebergrosse Datei (26 MB > MAX_BIN_SIZE 25 MB)
|
||||
with open(p("riesig.dat"),"wb") as f: f.seek(26_000_000-1); f.write(b"\0")
|
||||
print("Edge-Cases:")
|
||||
for f in sorted(os.listdir(D)): print(f" {os.path.getsize(p(f)):>9} {f}")
|
||||
Vendored
+10
@@ -9,3 +9,13 @@ curl -s -o /dev/null -u "$AUTH" -X MKCOL "$BASE/testdata/" || true
|
||||
for d in images audio video documents text archives; do curl -s -o /dev/null -u "$AUTH" -X MKCOL "$BASE/testdata/$d/" || true; done
|
||||
for f in /tmp/mcptest-files/*; do n=$(basename "$f"); curl -s -o /dev/null -u "$AUTH" -T "$f" "$BASE/testdata/$(sub "$n")/$n"; done
|
||||
echo "Upload fertig."
|
||||
# Edge-Cases (/tmp/mcptest-files-edge -> /testdata/edge/, URL-encoded)
|
||||
if [ -d /tmp/mcptest-files-edge ]; then
|
||||
curl -s -o /dev/null -u "$AUTH" -X MKCOL "$BASE/testdata/edge/" || true
|
||||
python3 - "$OCIS_PW" <<'PYEOF'
|
||||
import os,sys,subprocess,urllib.parse
|
||||
pw=sys.argv[1]; B="http://127.0.0.1:9200/remote.php/dav/files/mcptest/testdata/edge"
|
||||
for f in sorted(os.listdir("/tmp/mcptest-files-edge")):
|
||||
subprocess.run(["curl","-s","-o","/dev/null","-u",f"mcptest:{pw}","-T",f"/tmp/mcptest-files-edge/{f}",f"{B}/{urllib.parse.quote(f)}"])
|
||||
PYEOF
|
||||
fi
|
||||
|
||||
Reference in New Issue
Block a user