"""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()