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