122 lines
3.7 KiB
Python
122 lines
3.7 KiB
Python
#!/usr/bin/env python3
|
|
"""
|
|
zuptsdk Python binding test
|
|
SPDX-License-Identifier: AGPL-3.0-or-later
|
|
"""
|
|
import os
|
|
import sys
|
|
import tempfile
|
|
|
|
# Add path so we can import without installing
|
|
sys.path.insert(0, os.path.dirname(os.path.abspath(__file__)))
|
|
os.environ.setdefault("ZUPTSDK_LIBRARY",
|
|
os.path.join(os.path.dirname(__file__), "..", "..", "build", "libzuptsdk.so.1"))
|
|
|
|
import zuptsdk
|
|
|
|
PASS = 0
|
|
FAIL = 0
|
|
|
|
def test(name, fn):
|
|
global PASS, FAIL
|
|
try:
|
|
fn()
|
|
print(f" {name:<60} PASS")
|
|
PASS += 1
|
|
except Exception as e:
|
|
print(f" {name:<60} FAIL: {e!r}")
|
|
FAIL += 1
|
|
|
|
|
|
print(f"\n zuptsdk Python bindings — version {zuptsdk.__version__}\n")
|
|
|
|
DATA = b"Hello world from Python via cffi!\n" * 10
|
|
|
|
|
|
def t_version():
|
|
assert zuptsdk.__version__ == "1.0.0", f"got {zuptsdk.__version__}"
|
|
|
|
|
|
def t_roundtrip_plain():
|
|
with zuptsdk.Context() as ctx:
|
|
arc = ctx.compress_buffer(DATA, name="hello.txt")
|
|
assert isinstance(arc, bytes)
|
|
assert len(arc) > 0
|
|
out = ctx.extract_buffer(arc)
|
|
assert out == DATA
|
|
|
|
|
|
def t_roundtrip_password():
|
|
with zuptsdk.Context() as ctx:
|
|
arc = ctx.compress_buffer(DATA, name="secret.txt",
|
|
password=b"correct horse battery staple")
|
|
out = ctx.extract_buffer(arc, password=b"correct horse battery staple")
|
|
assert out == DATA
|
|
|
|
|
|
def t_wrong_password():
|
|
with zuptsdk.Context() as ctx:
|
|
arc = ctx.compress_buffer(DATA, name="x.txt", password=b"good")
|
|
try:
|
|
ctx.extract_buffer(arc, password=b"bad")
|
|
except zuptsdk.ZuptError:
|
|
return
|
|
raise AssertionError("wrong password was accepted")
|
|
|
|
|
|
def t_secure_buf_password():
|
|
with zuptsdk.Context() as ctx, zuptsdk.SecureBuf(b"locked-pw") as pw:
|
|
arc = ctx.compress_buffer(DATA, name="x.txt", password=pw)
|
|
out = ctx.extract_buffer(arc, password=pw)
|
|
assert out == DATA
|
|
|
|
|
|
def t_pq_keypair():
|
|
with zuptsdk.Context() as ctx:
|
|
kp = ctx.generate_keypair()
|
|
with tempfile.TemporaryDirectory() as td:
|
|
kp.save(os.path.join(td, "mykey"))
|
|
arc = ctx.compress_buffer(DATA, name="pq.txt", public_key=kp.public)
|
|
out = ctx.extract_buffer(arc, private_key=kp.private)
|
|
assert out == DATA
|
|
|
|
|
|
def t_verify_and_info():
|
|
with zuptsdk.Context() as ctx:
|
|
arc = ctx.compress_buffer(DATA, name="v.txt")
|
|
assert ctx.verify(arc) is True
|
|
info = ctx.info(arc)
|
|
assert info.format_major >= 1
|
|
assert info.is_encrypted is False
|
|
assert len(info.uuid) == 36, info.uuid
|
|
|
|
|
|
def t_corrupted_archive():
|
|
with zuptsdk.Context() as ctx:
|
|
# Use enough data that flipping a byte mid-stream lands in the
|
|
# compressed payload, not in a zero-padded region.
|
|
big = DATA * 100
|
|
arc = bytearray(ctx.compress_buffer(big, name="c.txt"))
|
|
# Flip a byte two-thirds of the way through — well into compressed
|
|
# data, well before the index/footer.
|
|
if len(arc) > 200:
|
|
offset = (len(arc) * 2) // 3
|
|
arc[offset] ^= 0xFF
|
|
try:
|
|
ctx.verify(bytes(arc))
|
|
except zuptsdk.ZuptError:
|
|
return
|
|
raise AssertionError("corrupted archive accepted")
|
|
|
|
|
|
test("version constant", t_version)
|
|
test("roundtrip plain", t_roundtrip_plain)
|
|
test("roundtrip password (bytes)", t_roundtrip_password)
|
|
test("wrong password rejected", t_wrong_password)
|
|
test("roundtrip with SecureBuf", t_secure_buf_password)
|
|
test("PQ keypair generate + roundtrip", t_pq_keypair)
|
|
test("verify and info", t_verify_and_info)
|
|
test("corrupted archive rejected", t_corrupted_archive)
|
|
|
|
print(f"\n Results: {PASS} passed, {FAIL} failed\n")
|
|
sys.exit(0 if FAIL == 0 else 1)
|