Skip to content

Commit

Permalink
mst-test-suite integration
Browse files Browse the repository at this point in the history
  • Loading branch information
DavidBuchanan314 committed Dec 11, 2024
1 parent c518924 commit 51fb0f6
Show file tree
Hide file tree
Showing 4 changed files with 88 additions and 0 deletions.
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "mst-test-suite"]
path = mst-test-suite
url = https://github.com/DavidBuchanan314/mst-test-suite
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -251,6 +251,7 @@ Here's how to package, test, and ship a new release.
```sh
source local/bin/activate.csh
python -m unittest discover
python -m unittest arroba.tests.mst_test_suite # more extensive, slower tests (deliberately excluded from autodiscovery)
```
1. Bump the version number in `pyproject.toml` and `docs/conf.py`. `git grep` the old version number to make sure it only appears in the changelog. Change the current changelog entry in `README.md` for this new version from _unreleased_ to the current date.
1. Build the docs. If you added any new modules, add them to the appropriate file(s) in `docs/source/`. Then run `./docs/build.sh`. Check that the generated HTML looks fine by opening `docs/_build/html/index.html` and looking around.
Expand Down
83 changes: 83 additions & 0 deletions arroba/tests/mst_test_suite.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,83 @@
import os
import json

import dag_cbor
import dag_cbor.random
from multiformats import CID, varint

from tqdm import tqdm

from ..diff import Change, Diff
from ..mst import MST
from ..storage import MemoryStorage, Block
from . import testutil

class MSTSuiteTest(testutil.TestCase):

def setUp(self):
super().setUp()
self.diff_testcases = {}
# recursively search for test cases in JSON format.
# for now we only know how to process "mst-diff" test cases - more types will be added
# in the future
self.test_suite_base = "./mst-test-suite/"
for path in [os.path.join(dp, f) for dp, _, fn in os.walk(self.test_suite_base + "/tests/") for f in fn]:
if not path.endswith(".json"):
continue
with open(path) as json_file:
testcase = json.load(json_file)
if testcase.get("$type") == "mst-diff":
self.diff_testcases[path] = testcase

def populate_storage_from_car(self, storage: MemoryStorage, car_path: str) -> CID:
# ad-hoc CAR parser, returns the root CID
with open(self.test_suite_base + car_path, "rb") as carfile:
car_header = dag_cbor.decode(carfile.read(varint.decode(carfile)))
while True:
try:
block = carfile.read(varint.decode(carfile))
except ValueError:
break
cid = CID.decode(block[:36])
storage.blocks[cid] = Block(cid=cid, encoded=block[36:])
return car_header["roots"][0]

def test_diffs(self):
for testname, testcase in tqdm(self.diff_testcases.items()):
storage = MemoryStorage()
root_a = self.populate_storage_from_car(storage, testcase["inputs"]["mst_a"])
root_b = self.populate_storage_from_car(storage, testcase["inputs"]["mst_b"])
mst_a = MST.load(storage=storage, cid=root_a)
mst_b = MST.load(storage=storage, cid=root_b)

diff: Diff = Diff.of(mst_b, mst_a)

ops_list = []
for created in diff.adds.values():
ops_list.append({
"rpath": created.key,
"old_value": None,
"new_value": created.cid.encode("base32")
})
for updated in diff.updates.values():
ops_list.append({
"rpath": updated.key,
"old_value": updated.prev.encode("base32"),
"new_value": updated.cid.encode("base32")
})
for removed in diff.deletes.values():
ops_list.append({
"rpath": removed.key,
"old_value": removed.cid.encode("base32"),
"new_value": None
})

# sort the lists for comparison, per mst-test-suite's rules
created_list = sorted(cid.encode("base32") for cid in diff.new_cids)
deleted_list = sorted(cid.encode("base32") for cid in diff.removed_cids)
ops_list.sort(key=lambda x: x["rpath"])

self.assertEqual(ops_list, testcase["results"]["record_ops"], f"{testname} record_ops")
self.assertEqual(created_list, testcase["results"]["created_nodes"], f"{testname} created_nodes") # currently fails!
self.assertEqual(deleted_list, testcase["results"]["deleted_nodes"], f"{testname} deleted_nodes")
# TODO: implement checks for proof_nodes, firehose_cids (test data hasn't been generated yet)
1 change: 1 addition & 0 deletions mst-test-suite
Submodule mst-test-suite added at 1cfaab

0 comments on commit 51fb0f6

Please sign in to comment.