hdcstorage / tests /test_fs.py
AEUPH's picture
HDCSTORAGE: hyperdimensional computer, webOS and agentic MCP layer (stdlib-only Python)
ad474c9 verified
Raw History Blame Contribute Delete
9.02 kB
"""Tests for the HDC filesystem: exact contents, vector addresses.
Two claims are checked here, and they are different claims: contents round-trip
byte for byte (a filesystem that fudges text is not a filesystem), and directory
records really are hypervectors that rank by similarity (a filesystem that only
does the first thing is just a dict).
"""
import os
import sys
import unittest
sys.path.insert(0, os.path.dirname(os.path.dirname(os.path.abspath(__file__))))
from hdc.fs import FileSystem, seeded # noqa: E402
from hdc.memory import HDCStorage # noqa: E402
D = 2000
class TestContents(unittest.TestCase):
def setUp(self):
self.fs = FileSystem(d=D)
def test_mkdir_creates_parents(self):
self.fs.mkdir("/a/b/c")
self.assertTrue(self.fs.isdir("/a"))
self.assertTrue(self.fs.isdir("/a/b/c"))
def test_write_read_round_trips_exact_text(self):
text = "first line\n\nthird line\nhéllo ✓ 世界"
self.fs.write("/a.txt", text)
self.assertEqual(self.fs.read("/a.txt"), text)
self.assertEqual(self.fs.get("/a.txt").lines, text.splitlines())
def test_append_adds_lines(self):
self.fs.write("/a.txt", "one")
self.fs.append("/a.txt", "two\nthree")
self.assertEqual(self.fs.read("/a.txt"), "one\ntwo\nthree")
def test_write_creates_intermediate_directories(self):
# documented convenience: an editor saving into a new path should not
# have to mkdir first, so write() behaves like mkdir -p
self.fs.write("/nope/deeper/a.txt", "x")
self.assertTrue(self.fs.exists("/nope/deeper/a.txt"))
self.assertTrue(self.fs.isdir("/nope/deeper"))
def test_write_through_a_file_raises(self):
self.fs.write("/plain.txt", "x")
with self.assertRaises(NotADirectoryError):
self.fs.write("/plain.txt/child.txt", "y")
def test_write_over_a_directory_raises(self):
self.fs.mkdir("/dir")
with self.assertRaises(IsADirectoryError):
self.fs.write("/dir", "x")
class TestRemoval(unittest.TestCase):
def setUp(self):
self.fs = FileSystem(d=D)
def test_remove_file_frees_its_cell(self):
# the reason HDCStorage.remove exists: a deleted file must not keep
# paying rent, or every "cells in use" figure is wrong forever
self.fs.write("/a.txt", "x")
before = len(self.fs.storage)
self.assertEqual(self.fs.remove("/a.txt"), 1)
self.assertEqual(len(self.fs.storage), before - 1)
self.assertFalse(self.fs.exists("/a.txt"))
def test_remove_non_empty_directory_raises(self):
self.fs.write("/d/a.txt", "x")
with self.assertRaises(OSError):
self.fs.remove("/d")
def test_recursive_remove_takes_the_subtree(self):
self.fs.write("/d/sub/a.txt", "x")
self.fs.write("/d/b.txt", "y")
before = len(self.fs.storage)
removed = self.fs.remove("/d", recursive=True)
self.assertEqual(removed, 4) # d, sub, a.txt, b.txt
self.assertEqual(len(self.fs.storage), before - removed)
self.assertFalse(self.fs.exists("/d"))
def test_removing_root_is_refused(self):
with self.assertRaises(PermissionError):
self.fs.remove("/")
class TestMoveAndCopy(unittest.TestCase):
def setUp(self):
self.fs = FileSystem(d=D)
def test_rename_moves_a_file(self):
self.fs.write("/a.txt", "content")
self.fs.rename("/a.txt", "/b.txt")
self.assertFalse(self.fs.exists("/a.txt"))
self.assertEqual(self.fs.read("/b.txt"), "content")
def test_rename_directory_rewrites_the_subtree(self):
self.fs.write("/old/sub/a.txt", "x")
self.fs.rename("/old", "/new")
self.assertFalse(self.fs.exists("/old"))
self.assertTrue(self.fs.isdir("/new/sub"))
self.assertEqual(self.fs.read("/new/sub/a.txt"), "x")
# the cells moved with it: the old prefix is gone from storage
self.assertNotIn("fs//old/sub/a.txt", [name for name, _ in self.fs.storage])
def test_rename_onto_an_existing_path_raises(self):
self.fs.write("/a.txt", "a")
self.fs.write("/b.txt", "b")
with self.assertRaises(FileExistsError):
self.fs.rename("/a.txt", "/b.txt")
def test_copy_duplicates_a_tree(self):
self.fs.write("/src/a.txt", "x")
self.fs.write("/src/deep/b.txt", "y")
self.fs.copy("/src", "/dst")
self.assertEqual(self.fs.read("/dst/a.txt"), "x")
self.assertEqual(self.fs.read("/dst/deep/b.txt"), "y")
self.assertEqual(self.fs.read("/src/a.txt"), "x")
def test_copy_over_an_existing_file_overwrites_like_cp(self):
# documented behaviour, not an accident: copying onto a file replaces it
self.fs.write("/a.txt", "old")
self.fs.write("/b.txt", "new")
self.fs.copy("/b.txt", "/a.txt")
self.assertEqual(self.fs.read("/a.txt"), "new")
class TestPaths(unittest.TestCase):
def setUp(self):
self.fs = FileSystem(d=D)
self.fs.write("/home/user/a.txt", "x")
def test_relative_paths_resolve_against_cwd(self):
self.fs.chdir("/home/user")
self.assertEqual(self.fs.read("a.txt"), "x")
self.assertEqual(self.fs.read("./a.txt"), "x")
def test_dotdot_normalises(self):
self.fs.chdir("/home/user")
self.assertEqual(self.fs.normalise("../user/a.txt"), "/home/user/a.txt")
self.assertEqual(self.fs.normalise("../../.."), "/")
def test_chdir_rejects_a_file(self):
with self.assertRaises(NotADirectoryError):
self.fs.chdir("/home/user/a.txt")
def test_missing_paths_raise(self):
with self.assertRaises(FileNotFoundError):
self.fs.read("/nope.txt")
with self.assertRaises(FileNotFoundError):
self.fs.get("/nope.txt")
def test_ls_lists_directories_before_files(self):
self.fs.write("/home/user/b.txt", "x")
self.fs.mkdir("/home/user/zdir")
kinds = [entry["kind"] for entry in self.fs.ls("/home/user")]
self.assertEqual(kinds, ["dir", "file", "file"])
def test_tree_renders_the_branches(self):
rendered = self.fs.tree("/home")
self.assertIn("user/", rendered)
self.assertIn("a.txt", rendered)
self.assertTrue(rendered.startswith("/home"))
class TestSearchIsHyperdimensional(unittest.TestCase):
"""The part that is not a dict: a query is a vector, and ranking is ``sim``."""
def setUp(self):
self.fs = seeded(D)
def test_search_ranks_the_matching_file_first(self):
ranked = self.fs.search("shader notes about edges")
self.assertEqual(ranked[0][0], "/home/user/notes-shader.txt")
scores = dict(ranked)
self.assertGreater(scores["/home/user/notes-shader.txt"],
scores["/home/user/src/hello.hdcasm"])
def test_search_scores_are_similarities(self):
for _path, score in self.fs.search("assembly loop", limit=20):
self.assertGreaterEqual(score, -1.0)
self.assertLessEqual(score, 1.0)
def test_similar_returns_other_paths_with_bounded_scores(self):
ranked = self.fs.similar("/home/user/notes-shader.txt")
self.assertTrue(ranked)
paths = [path for path, _score in ranked]
self.assertNotIn("/home/user/notes-shader.txt", paths)
self.assertNotIn("/", paths)
for _path, score in ranked:
self.assertGreaterEqual(score, -1.0)
self.assertLessEqual(score, 1.0)
def test_counters_move_and_stat_agrees_with_storage(self):
before = self.fs.stat()
self.fs.search("hello")
self.fs.write("/home/user/new.txt", "x")
after = self.fs.stat()
self.assertEqual(after["searches"], before["searches"] + 1)
self.assertEqual(after["writes"], before["writes"] + 1)
self.assertEqual(after["cells"], len(self.fs.storage))
self.assertEqual(after["files"], 6)
class TestSharedStorage(unittest.TestCase):
"""The desktop boots one store for the kernel, the files and the memory map."""
def test_seeded_can_write_into_an_existing_storage(self):
storage = HDCStorage(d=D, label="machine")
filesystem = seeded(D, storage=storage)
self.assertIs(filesystem.storage, storage)
self.assertEqual(filesystem.stat()["cells"], len(storage))
self.assertGreater(len(storage), 0)
self.assertIn("fs//home/user/README.txt", [name for name, _ in storage])
def test_two_filesystems_on_one_storage_see_each_other_cells(self):
storage = HDCStorage(d=D, label="machine")
first = FileSystem(d=D, storage=storage)
first.write("/a.txt", "x")
second = FileSystem(d=D, storage=storage)
self.assertEqual(len(first.storage), len(second.storage))
self.assertEqual(second.stat()["cells"], len(storage))
if __name__ == "__main__":
unittest.main()