Merge pull request #2 from wtsi-hgi/feature/arv-view
[arvados.git] / services / fuse / tests / test_inodes.py
1 import arvados_fuse
2 import mock
3 import unittest
4 import llfuse
5
6 class InodeTests(unittest.TestCase):
7     def test_inodes_basic(self):
8         cache = arvados_fuse.InodeCache(1000, 4)
9         inodes = arvados_fuse.Inodes(cache)
10
11         # Check that ent1 gets added to inodes
12         ent1 = mock.MagicMock()
13         ent1.in_use.return_value = False
14         ent1.persisted.return_value = True
15         ent1.clear.return_value = True
16         ent1.objsize.return_value = 500
17         inodes.add_entry(ent1)
18         self.assertIn(ent1.inode, inodes)
19         self.assertIs(inodes[ent1.inode], ent1)
20         self.assertEqual(500, cache.total())
21
22     def test_inodes_not_persisted(self):
23         cache = arvados_fuse.InodeCache(1000, 4)
24         inodes = arvados_fuse.Inodes(cache)
25
26         ent1 = mock.MagicMock()
27         ent1.in_use.return_value = False
28         ent1.persisted.return_value = True
29         ent1.clear.return_value = True
30         ent1.objsize.return_value = 500
31         inodes.add_entry(ent1)
32
33         # ent2 is not persisted, so it doesn't
34         # affect the cache total
35         ent2 = mock.MagicMock()
36         ent2.in_use.return_value = False
37         ent2.persisted.return_value = False
38         ent2.objsize.return_value = 600
39         inodes.add_entry(ent2)
40         self.assertEqual(500, cache.total())
41
42     def test_inode_cleared(self):
43         cache = arvados_fuse.InodeCache(1000, 4)
44         inodes = arvados_fuse.Inodes(cache)
45
46         # Check that ent1 gets added to inodes
47         ent1 = mock.MagicMock()
48         ent1.in_use.return_value = False
49         ent1.persisted.return_value = True
50         ent1.clear.return_value = True
51         ent1.objsize.return_value = 500
52         inodes.add_entry(ent1)
53
54         # ent3 is persisted, adding it should cause ent1 to get cleared
55         ent3 = mock.MagicMock()
56         ent3.in_use.return_value = False
57         ent3.persisted.return_value = True
58         ent3.objsize.return_value = 600
59         ent3.clear.return_value = True
60
61         self.assertFalse(ent1.clear.called)
62         inodes.add_entry(ent3)
63
64         # Won't clear anything because min_entries = 4
65         self.assertEqual(2, len(cache._entries))
66         self.assertFalse(ent1.clear.called)
67         self.assertEqual(1100, cache.total())
68
69         # Change min_entries
70         cache.min_entries = 1
71         cache.cap_cache()
72         self.assertEqual(600, cache.total())
73         self.assertTrue(ent1.clear.called)
74
75         # Touching ent1 should cause ent3 to get cleared
76         self.assertFalse(ent3.clear.called)
77         cache.touch(ent1)
78         self.assertTrue(ent3.clear.called)
79         self.assertEqual(500, cache.total())
80
81     def test_clear_false(self):
82         cache = arvados_fuse.InodeCache(1000, 4)
83         inodes = arvados_fuse.Inodes(cache)
84
85         ent1 = mock.MagicMock()
86         ent1.in_use.return_value = False
87         ent1.persisted.return_value = True
88         ent1.clear.return_value = True
89         ent1.objsize.return_value = 500
90         inodes.add_entry(ent1)
91
92         ent3 = mock.MagicMock()
93         ent3.in_use.return_value = False
94         ent3.persisted.return_value = True
95         ent3.objsize.return_value = 600
96         ent3.clear.return_value = True
97         inodes.add_entry(ent3)
98
99         cache.min_entries = 1
100
101         # ent1, ent3 clear return false, can't be cleared
102         ent1.clear.return_value = False
103         ent3.clear.return_value = False
104         ent1.clear.called = False
105         ent3.clear.called = False
106         self.assertFalse(ent1.clear.called)
107         self.assertFalse(ent3.clear.called)
108         cache.touch(ent3)
109         self.assertTrue(ent1.clear.called)
110         self.assertTrue(ent3.clear.called)
111         self.assertEqual(1100, cache.total())
112
113         # ent1 clear return false, so ent3
114         # gets cleared
115         ent1.clear.return_value = False
116         ent3.clear.return_value = True
117         ent1.clear.called = False
118         ent3.clear.called = False
119         cache.touch(ent3)
120         self.assertTrue(ent1.clear.called)
121         self.assertTrue(ent3.clear.called)
122         self.assertEqual(500, cache.total())
123
124     def test_delete(self):
125         cache = arvados_fuse.InodeCache(1000, 4)
126         inodes = arvados_fuse.Inodes(cache)
127
128         ent1 = mock.MagicMock()
129         ent1.in_use.return_value = False
130         ent1.persisted.return_value = True
131         ent1.clear.return_value = True
132         ent1.objsize.return_value = 500
133         inodes.add_entry(ent1)
134
135         ent3 = mock.MagicMock()
136         ent3.in_use.return_value = False
137         ent3.persisted.return_value = True
138         ent3.objsize.return_value = 600
139         ent3.clear.return_value = True
140
141         # Delete ent1
142         self.assertEqual(500, cache.total())
143         ent1.clear.return_value = True
144         ent1.ref_count = 0
145         with llfuse.lock:
146             inodes.del_entry(ent1)
147         self.assertEqual(0, cache.total())
148         cache.touch(ent3)
149         self.assertEqual(600, cache.total())