OLD | NEW |
| (Empty) |
1 #!/usr/bin/env python | |
2 # Copyright (c) 2012 The Chromium Authors. All rights reserved. | |
3 # Use of this source code is governed by a BSD-style license that can be | |
4 # found in the LICENSE file. | |
5 | |
6 import os | |
7 import sys | |
8 import unittest | |
9 | |
10 import object_store | |
11 from in_memory_object_store import InMemoryObjectStore | |
12 from file_system import FileSystem, StatInfo | |
13 from future import Future | |
14 from local_file_system import LocalFileSystem | |
15 from memcache_file_system import MemcacheFileSystem | |
16 | |
17 class _FakeFileSystem(FileSystem): | |
18 def __init__(self): | |
19 self.stat_value = 0 | |
20 self._stat_count = 0 | |
21 self._read_count = 0 | |
22 | |
23 def CheckAndReset(self, read_count=0, stat_count=0): | |
24 try: | |
25 return (self._read_count == read_count and | |
26 self._stat_count == stat_count) | |
27 finally: | |
28 self._read_count = 0 | |
29 self._stat_count = 0 | |
30 | |
31 def Stat(self, path): | |
32 self._stat_count += 1 | |
33 children = dict((path.strip('/') + str(i), self.stat_value) | |
34 for i in range(5)) | |
35 if not path.endswith('/'): | |
36 children[path.rsplit('/', 1)[-1]] = self.stat_value | |
37 return StatInfo(self.stat_value, children) | |
38 | |
39 def Read(self, paths, binary=False): | |
40 self._read_count += 1 | |
41 return Future(value=dict((path, path) for path in paths)) | |
42 | |
43 class MemcacheFileSystemTest(unittest.TestCase): | |
44 def setUp(self): | |
45 self._object_store = InMemoryObjectStore('') | |
46 self._local_fs = LocalFileSystem(os.path.join(sys.path[0], | |
47 'test_data', | |
48 'file_system')) | |
49 | |
50 def _SetReadCacheItem(self, key, value, stat): | |
51 self._object_store.Set(key, (value, stat), object_store.FILE_SYSTEM_READ) | |
52 | |
53 def _SetStatCacheItem(self, key, value): | |
54 self._object_store.Set(key, value, object_store.FILE_SYSTEM_STAT) | |
55 | |
56 def _DeleteReadCacheItem(self, key): | |
57 self._object_store.Delete(key, object_store.FILE_SYSTEM_READ) | |
58 | |
59 def _DeleteStatCacheItem(self, key): | |
60 self._object_store.Delete(key, object_store.FILE_SYSTEM_STAT) | |
61 | |
62 def testReadFiles(self): | |
63 file_system = MemcacheFileSystem(self._local_fs, self._object_store) | |
64 expected = { | |
65 './test1.txt': 'test1\n', | |
66 './test2.txt': 'test2\n', | |
67 './test3.txt': 'test3\n', | |
68 } | |
69 self.assertEqual( | |
70 expected, | |
71 file_system.Read(['./test1.txt', './test2.txt', './test3.txt']).Get()) | |
72 | |
73 def testListDir(self): | |
74 file_system = MemcacheFileSystem(self._local_fs, self._object_store) | |
75 expected = ['dir/'] | |
76 for i in range(7): | |
77 expected.append('file%d.html' % i) | |
78 self._SetReadCacheItem('list/', expected, file_system.Stat('list/').version) | |
79 self.assertEqual(expected, | |
80 sorted(file_system.ReadSingle('list/'))) | |
81 expected.remove('file0.html') | |
82 self._SetReadCacheItem('list/', expected, file_system.Stat('list/').version) | |
83 self.assertEqual(expected, | |
84 sorted(file_system.ReadSingle('list/'))) | |
85 | |
86 def testCaching(self): | |
87 fake_fs = _FakeFileSystem() | |
88 file_system = MemcacheFileSystem(fake_fs, self._object_store) | |
89 self.assertEqual('bob/bob0', file_system.ReadSingle('bob/bob0')) | |
90 self.assertTrue(fake_fs.CheckAndReset(read_count=1, stat_count=1)) | |
91 | |
92 # Resource has been cached, so test resource is not re-fetched. | |
93 self.assertEqual('bob/bob0', file_system.ReadSingle('bob/bob0')) | |
94 self.assertTrue(fake_fs.CheckAndReset()) | |
95 | |
96 # Test if the Stat version is the same the resource is not re-fetched. | |
97 self._DeleteStatCacheItem('bob/bob0') | |
98 self.assertEqual('bob/bob0', file_system.ReadSingle('bob/bob0')) | |
99 self.assertTrue(fake_fs.CheckAndReset(stat_count=1)) | |
100 | |
101 # Test if there is a newer version, the resource is re-fetched. | |
102 self._DeleteStatCacheItem('bob/bob0') | |
103 fake_fs.stat_value += 1 | |
104 self.assertEqual('bob/bob0', file_system.ReadSingle('bob/bob0')) | |
105 self.assertTrue(fake_fs.CheckAndReset(read_count=1, stat_count=1)) | |
106 | |
107 # Test directory and subdirectory stats are cached. | |
108 self._DeleteStatCacheItem('bob/bob0') | |
109 self._DeleteReadCacheItem('bob/bob0') | |
110 self._DeleteStatCacheItem('bob/bob1') | |
111 self.assertEqual('bob/bob1', file_system.ReadSingle('bob/bob1')) | |
112 self.assertEqual('bob/bob0', file_system.ReadSingle('bob/bob0')) | |
113 self.assertTrue(fake_fs.CheckAndReset(read_count=2, stat_count=1)) | |
114 self.assertEqual('bob/bob1', file_system.ReadSingle('bob/bob1')) | |
115 self.assertTrue(fake_fs.CheckAndReset()) | |
116 | |
117 # Test a more recent parent directory doesn't force a refetch of children. | |
118 self._DeleteReadCacheItem('bob/bob0') | |
119 self._DeleteReadCacheItem('bob/bob1') | |
120 self.assertEqual('bob/bob1', file_system.ReadSingle('bob/bob1')) | |
121 self.assertEqual('bob/bob2', file_system.ReadSingle('bob/bob2')) | |
122 self.assertEqual('bob/bob3', file_system.ReadSingle('bob/bob3')) | |
123 self.assertTrue(fake_fs.CheckAndReset(read_count=3)) | |
124 self._SetStatCacheItem('bob/', 10) | |
125 self.assertEqual('bob/bob1', file_system.ReadSingle('bob/bob1')) | |
126 self.assertEqual('bob/bob2', file_system.ReadSingle('bob/bob2')) | |
127 self.assertEqual('bob/bob3', file_system.ReadSingle('bob/bob3')) | |
128 self.assertTrue(fake_fs.CheckAndReset()) | |
129 | |
130 self._DeleteStatCacheItem('bob/bob0') | |
131 self.assertEqual('bob/bob0', file_system.ReadSingle('bob/bob0')) | |
132 self.assertTrue(fake_fs.CheckAndReset(read_count=1, stat_count=1)) | |
133 self.assertEqual('bob/bob0', file_system.ReadSingle('bob/bob0')) | |
134 self.assertTrue(fake_fs.CheckAndReset()) | |
135 | |
136 if __name__ == '__main__': | |
137 unittest.main() | |
OLD | NEW |