summaryrefslogtreecommitdiffstats
path: root/packages/meshbay-node/tests/test_upload_sealed.py
diff options
context:
space:
mode:
Diffstat (limited to 'packages/meshbay-node/tests/test_upload_sealed.py')
-rw-r--r--packages/meshbay-node/tests/test_upload_sealed.py42
1 files changed, 21 insertions, 21 deletions
diff --git a/packages/meshbay-node/tests/test_upload_sealed.py b/packages/meshbay-node/tests/test_upload_sealed.py
index 7c1be96..7f78ba7 100644
--- a/packages/meshbay-node/tests/test_upload_sealed.py
+++ b/packages/meshbay-node/tests/test_upload_sealed.py
@@ -80,14 +80,14 @@ def test_the_wire_message_carries_no_filename_and_no_plaintext(tmp_path):
assert b"JPEGDATA" not in blob, "the file content is on the wire in clear"
-def test_the_ack_carries_no_stored_name(tmp_path):
+async def test_the_ack_carries_no_stored_name(tmp_path):
"""
`stored_as` is the name the node settled on — it finds a free one rather
than replacing anything — and naming it in clear would hand back exactly
what the request took the trouble to hide.
"""
session = _session(tmp_path)
- session._do_file_upload(sealed_upload(
+ await session._do_file_upload(sealed_upload(
session, filename="holiday.jpg", data=b"x", dir=_root(session).name))
ack = [m for m in session.sent if m.get("type") == MNP.FILE_UPLOAD_ACK][-1]
@@ -98,7 +98,7 @@ def test_the_ack_carries_no_stored_name(tmp_path):
"dir": _root(session).name}
-def test_the_ack_names_the_upload_so_one_refusal_fails_one_upload(tmp_path):
+async def test_the_ack_names_the_upload_so_one_refusal_fails_one_upload(tmp_path):
"""
`filename` used to be the correlation key on both sides. It cannot be one
any more, and `upload_id` replaces it — a client-chosen label, opaque to
@@ -107,10 +107,10 @@ def test_the_ack_names_the_upload_so_one_refusal_fails_one_upload(tmp_path):
for one file used to fail every upload in flight.
"""
session = _session(tmp_path)
- session._do_file_upload(sealed_upload(
+ await session._do_file_upload(sealed_upload(
session, filename="a.txt", data=b"x", dir=_root(session).name,
upload_id="upload-A"))
- session._do_file_upload(sealed_upload(
+ await session._do_file_upload(sealed_upload(
session, filename="../evil", data=b"x", dir=_root(session).name,
upload_id="upload-B"))
@@ -121,14 +121,14 @@ def test_the_ack_names_the_upload_so_one_refusal_fails_one_upload(tmp_path):
# ── What is refused ──────────────────────────────────────────────────────────
-def test_a_plaintext_upload_is_refused(tmp_path):
+async def test_a_plaintext_upload_is_refused(tmp_path):
"""
The MNP 1.x shape, which is what an un-updated client sends. Refused with a
code and a message saying which side is old — never accepted "just this
once", because a path that still takes plaintext is not a sealed path.
"""
session = _session(tmp_path)
- session._do_file_upload({
+ await session._do_file_upload({
"filename": "note.txt", "dir": _root(session).name,
"chunk_index": 0, "total_chunks": 1, "data": b"x",
})
@@ -137,7 +137,7 @@ def test_a_plaintext_upload_is_refused(tmp_path):
assert not _wrote_anything(tmp_path)
-def test_a_tampered_chunk_is_refused(tmp_path):
+async def test_a_tampered_chunk_is_refused(tmp_path):
"""
AES-GCM's tag, asserted where it matters: a flipped bit in the ciphertext
must stop the upload, not produce a corrupt file with a plausible name.
@@ -146,13 +146,13 @@ def test_a_tampered_chunk_is_refused(tmp_path):
msg = sealed_upload(session, filename="note.txt", data=b"x" * 64,
dir=_root(session).name)
msg["ct"] = bytes([msg["ct"][0] ^ 0x01]) + msg["ct"][1:]
- session._do_file_upload(msg)
+ await session._do_file_upload(msg)
assert _errors(session)[0]["code"] == "upload_not_sealed"
assert not _wrote_anything(tmp_path)
-def test_an_upload_sealed_for_another_group_is_refused(tmp_path):
+async def test_an_upload_sealed_for_another_group_is_refused(tmp_path):
"""
The group is the AAD, so a node hosting two groups cannot have a chunk
moved between them — and a member of one cannot write into the other by
@@ -163,20 +163,20 @@ def test_an_upload_sealed_for_another_group_is_refused(tmp_path):
session._ctx["gek"], "some-other-group",
upload_id="u1", chunk_index=0, total_chunks=1,
filename="note.txt", data=b"x", dir=_root(session).name)
- session._do_file_upload(msg)
+ await session._do_file_upload(msg)
assert _errors(session)[0]["code"] == "upload_not_sealed"
assert not _wrote_anything(tmp_path)
-def test_an_upload_under_another_key_is_refused(tmp_path):
+async def test_an_upload_under_another_key_is_refused(tmp_path):
"""A peer past the handshake with the wrong GEK still writes nothing."""
session = _session(tmp_path)
msg = file_upload_wire(
generate_gek(), GROUP,
upload_id="u1", chunk_index=0, total_chunks=1,
filename="note.txt", data=b"x", dir=_root(session).name)
- session._do_file_upload(msg)
+ await session._do_file_upload(msg)
assert _errors(session)[0]["code"] == "upload_not_sealed"
assert not _wrote_anything(tmp_path)
@@ -199,7 +199,7 @@ def test_an_ack_replayed_as_a_request_does_not_open(tmp_path):
file_upload_payload(session._ctx["gek"], GROUP, ack)
-def test_a_group_with_no_key_refuses_rather_than_falling_back(tmp_path):
+async def test_a_group_with_no_key_refuses_rather_than_falling_back(tmp_path):
"""
A node whose group has no GEK yet cannot open anything. It must say so, not
read the message as though it were the old plaintext shape.
@@ -208,7 +208,7 @@ def test_a_group_with_no_key_refuses_rather_than_falling_back(tmp_path):
msg = sealed_upload(session, filename="note.txt", data=b"x",
dir=_root(session).name)
session._ctx["gek"] = b""
- session._do_file_upload(msg)
+ await session._do_file_upload(msg)
assert _errors(session)[0]["code"] == "no_group_key"
assert not _wrote_anything(tmp_path)
@@ -216,7 +216,7 @@ def test_a_group_with_no_key_refuses_rather_than_falling_back(tmp_path):
# ── What must still work ─────────────────────────────────────────────────────
-def test_a_multi_chunk_upload_reassembles(tmp_path):
+async def test_a_multi_chunk_upload_reassembles(tmp_path):
"""
Every chunk is sealed under its own nonce, and the node appends in order.
Nothing about the seal may change what lands on disk.
@@ -225,7 +225,7 @@ def test_a_multi_chunk_upload_reassembles(tmp_path):
body = bytes(range(256)) * 40
parts = [body[i:i + 1024] for i in range(0, len(body), 1024)]
for i, part in enumerate(parts):
- session._do_file_upload(sealed_upload(
+ await session._do_file_upload(sealed_upload(
session, filename="blob.bin", data=part,
chunk_index=i, total_chunks=len(parts), dir=_root(session).name))
@@ -247,7 +247,7 @@ def test_two_identical_chunks_do_not_reuse_a_nonce(tmp_path):
assert a["ct"] != b["ct"]
-def test_a_sealed_payload_is_authenticated_not_validated(tmp_path):
+async def test_a_sealed_payload_is_authenticated_not_validated(tmp_path):
"""
Opening a payload proves a member wrote it, not that they wrote something
sensible. A member can seal anything, so the fields still need their types
@@ -261,7 +261,7 @@ def test_a_sealed_payload_is_authenticated_not_validated(tmp_path):
{"filename": "note.txt", "data": "not bytes"},
{"filename": "note.txt"}):
session.sent.clear()
- session._do_file_upload({
+ await session._do_file_upload({
"type": MNP.FILE_UPLOAD, "v": "2.0", "upload_id": "u1",
"chunk_index": 0, "total_chunks": 1,
**seal(session._ctx["gek"], PURPOSE_UPLOAD, MNP.FILE_UPLOAD,
@@ -273,13 +273,13 @@ def test_a_sealed_payload_is_authenticated_not_validated(tmp_path):
assert not _wrote_anything(tmp_path)
-def test_a_peer_controlled_chunk_index_cannot_crash_the_handler(tmp_path):
+async def test_a_peer_controlled_chunk_index_cannot_crash_the_handler(tmp_path):
"""`chunk_index` is outside the seal by necessity, so it is unchecked input."""
session = _session(tmp_path)
msg = sealed_upload(session, filename="note.txt", data=b"x",
dir=_root(session).name)
msg["chunk_index"] = "zero"
- session._do_file_upload(msg)
+ await session._do_file_upload(msg)
assert _errors(session)[0]["code"] == "bad_chunk_index"
assert not _wrote_anything(tmp_path)