From c67f012138179afd8a127bd54fa94c07662aa133 Mon Sep 17 00:00:00 2001 From: Nicolas Dandrimont <nicolas@dandrimont.eu> Date: Wed, 4 Oct 2017 22:33:45 +0200 Subject: [PATCH] from_disk: full test coverage --- swh/model/from_disk.py | 8 +-- swh/model/tests/test_from_disk.py | 116 +++++++++++++++++++++++++++++- 2 files changed, 119 insertions(+), 5 deletions(-) diff --git a/swh/model/from_disk.py b/swh/model/from_disk.py index bb108a54..f9f37290 100644 --- a/swh/model/from_disk.py +++ b/swh/model/from_disk.py @@ -299,7 +299,7 @@ class Directory(MerkleNode): def __getitem__(self, key): if not isinstance(key, bytes): - raise ValueError('Can only get a bytes from directory') + raise ValueError('Can only get a bytes from Directory') # Convenience shortcut if key == b'': @@ -313,9 +313,9 @@ class Directory(MerkleNode): def __setitem__(self, key, value): if not isinstance(key, bytes): - raise ValueError('Can only set a bytes directory entry') + raise ValueError('Can only set a bytes Directory entry') if not isinstance(value, (Content, Directory)): - raise ValueError('Can only set a directory entry to a Content or ' + raise ValueError('Can only set a Directory entry to a Content or ' 'Directory') if key == b'': @@ -331,7 +331,7 @@ class Directory(MerkleNode): def __delitem__(self, key): if not isinstance(key, bytes): - raise ValueError('Can only delete a bytes directory entry') + raise ValueError('Can only delete a bytes Directory entry') if b'/' not in key: super().__delitem__(key) diff --git a/swh/model/tests/test_from_disk.py b/swh/model/tests/test_from_disk.py index 3a0a104c..25df48b9 100644 --- a/swh/model/tests/test_from_disk.py +++ b/swh/model/tests/test_from_disk.py @@ -10,7 +10,7 @@ import unittest from swh.model import from_disk from swh.model.from_disk import Content, Directory, DentryPerms -from swh.model.hashutil import DEFAULT_ALGORITHMS, hash_to_bytes +from swh.model.hashutil import DEFAULT_ALGORITHMS, hash_to_bytes, hash_to_hex class ModeToPerms(unittest.TestCase): @@ -481,6 +481,7 @@ class TestContent(DataMixin, unittest.TestCase): conv_content = Content.from_bytes(mode=content['mode'], data=content['data']) self.assertContentEqual(conv_content, content) + self.assertIn(hash_to_hex(conv_content.hash), repr(conv_content)) class SymlinkToContent(DataMixin, unittest.TestCase): @@ -649,6 +650,38 @@ class DirectoryToObjects(DataMixin, unittest.TestCase): len(self.contents) + 1) + def test_directory_to_objects_ignore_name_case(self): + directory = Directory.from_disk( + path=self.tmpdir.name, + dir_filter=from_disk.ignore_named_directories([b'symLiNks'], + case_sensitive=False) + ) + for name, value in self.contents.items(): + self.assertContentEqual(directory[b'contents/' + name], value) + + for name in self.specials: + self.assertContentEqual( + directory[b'specials/' + name], + self.empty_content, + ) + + self.assertEqual( + directory[b'empty1/empty2'].get_data(), + self.empty_directory, + ) + + with self.assertRaisesRegex(KeyError, "b'symlinks'"): + directory[b'symlinks'] + + objs = directory.collect() + + self.assertCountEqual(['content', 'directory'], objs) + + self.assertEqual(len(objs['directory']), 5) + self.assertEqual(len(objs['content']), + len(self.contents) + + 1) + class TarballTest(DataMixin, unittest.TestCase): def setUp(self): @@ -668,3 +701,84 @@ class TarballTest(DataMixin, unittest.TestCase): self.assertDirectoryEqual(obj, data) else: raise self.failureException('Unknown type for %s' % obj) + + +class DirectoryManipulation(DataMixin, unittest.TestCase): + def test_directory_access_nested(self): + d = Directory() + d[b'a'] = Directory() + d[b'a/b'] = Directory() + + self.assertEqual(d[b'a/b'].get_data(), self.empty_directory) + + def test_directory_del_nested(self): + d = Directory() + d[b'a'] = Directory() + d[b'a/b'] = Directory() + + with self.assertRaisesRegex(KeyError, "b'c'"): + del d[b'a/b/c'] + + with self.assertRaisesRegex(KeyError, "b'level2'"): + del d[b'a/level2/c'] + + del d[b'a/b'] + + self.assertEqual(d[b'a'].get_data(), self.empty_directory) + + def test_directory_access_self(self): + d = Directory() + self.assertIs(d, d[b'']) + self.assertIs(d, d[b'/']) + self.assertIs(d, d[b'//']) + + def test_directory_access_wrong_type(self): + d = Directory() + with self.assertRaisesRegex(ValueError, 'bytes from Directory'): + d['foo'] + with self.assertRaisesRegex(ValueError, 'bytes from Directory'): + d[42] + + def test_directory_repr(self): + entries = [b'a', b'b', b'c'] + d = Directory() + for entry in entries: + d[entry] = Directory() + + r = repr(d) + self.assertIn(hash_to_hex(d.hash), r) + + for entry in entries: + self.assertIn(str(entry), r) + + def test_directory_set_wrong_type_name(self): + d = Directory() + with self.assertRaisesRegex(ValueError, 'bytes Directory entry'): + d['foo'] = Directory() + with self.assertRaisesRegex(ValueError, 'bytes Directory entry'): + d[42] = Directory() + + def test_directory_set_nul_in_name(self): + d = Directory() + + with self.assertRaisesRegex(ValueError, 'nul bytes'): + d[b'\x00\x01'] = Directory() + + def test_directory_set_empty_name(self): + d = Directory() + with self.assertRaisesRegex(ValueError, 'must have a name'): + d[b''] = Directory() + with self.assertRaisesRegex(ValueError, 'must have a name'): + d[b'/'] = Directory() + + def test_directory_set_wrong_type(self): + d = Directory() + with self.assertRaisesRegex(ValueError, 'Content or Directory'): + d[b'entry'] = object() + + def test_directory_del_wrong_type(self): + d = Directory() + with self.assertRaisesRegex(ValueError, 'bytes Directory entry'): + del d['foo'] + with self.assertRaisesRegex(ValueError, 'bytes Directory entry'): + del d[42] -- GitLab