PageRenderTime 56ms CodeModel.GetById 9ms RepoModel.GetById 0ms app.codeStats 1ms

/chrome/common/extensions/docs/server2/caching_file_system_test.py

https://gitlab.com/jonnialva90/iridium-browser
Python | 297 lines | 240 code | 31 blank | 26 comment | 6 complexity | c3892740a4009d56aecee1358d0e3e45 MD5 | raw file
  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. import os
  6. import sys
  7. import unittest
  8. from caching_file_system import CachingFileSystem
  9. from extensions_paths import SERVER2
  10. from file_system import FileNotFoundError, StatInfo
  11. from local_file_system import LocalFileSystem
  12. from mock_file_system import MockFileSystem
  13. from object_store_creator import ObjectStoreCreator
  14. from test_file_system import TestFileSystem
  15. from test_object_store import TestObjectStore
  16. def _CreateLocalFs():
  17. return LocalFileSystem.Create(SERVER2, 'test_data', 'file_system/')
  18. class CachingFileSystemTest(unittest.TestCase):
  19. def setUp(self):
  20. # Use this to make sure that every time _CreateCachingFileSystem is called
  21. # the underlying object store data is the same, within each test.
  22. self._object_store_dbs = {}
  23. def _CreateCachingFileSystem(self, fs, start_empty=False):
  24. def store_type_constructor(namespace, start_empty=False):
  25. '''Returns an ObjectStore backed onto test-lifetime-persistent objects
  26. in |_object_store_dbs|.
  27. '''
  28. if namespace not in self._object_store_dbs:
  29. self._object_store_dbs[namespace] = {}
  30. db = self._object_store_dbs[namespace]
  31. if start_empty:
  32. db.clear()
  33. return TestObjectStore(namespace, init=db)
  34. object_store_creator = ObjectStoreCreator(start_empty=start_empty,
  35. store_type=store_type_constructor)
  36. return CachingFileSystem(fs, object_store_creator)
  37. def testReadFiles(self):
  38. file_system = self._CreateCachingFileSystem(
  39. _CreateLocalFs(), start_empty=False)
  40. expected = {
  41. './test1.txt': 'test1\n',
  42. './test2.txt': 'test2\n',
  43. './test3.txt': 'test3\n',
  44. }
  45. self.assertEqual(
  46. expected,
  47. file_system.Read(['./test1.txt', './test2.txt', './test3.txt']).Get())
  48. def testListDir(self):
  49. file_system = self._CreateCachingFileSystem(
  50. _CreateLocalFs(), start_empty=False)
  51. expected = ['dir/'] + ['file%d.html' % i for i in range(7)]
  52. file_system._read_cache.Set(
  53. 'list/',
  54. (expected, file_system.Stat('list/').version))
  55. self.assertEqual(expected, sorted(file_system.ReadSingle('list/').Get()))
  56. expected.remove('file0.html')
  57. file_system._read_cache.Set(
  58. 'list/',
  59. (expected, file_system.Stat('list/').version))
  60. self.assertEqual(expected, sorted(file_system.ReadSingle('list/').Get()))
  61. def testCaching(self):
  62. test_fs = TestFileSystem({
  63. 'bob': {
  64. 'bob0': 'bob/bob0 contents',
  65. 'bob1': 'bob/bob1 contents',
  66. 'bob2': 'bob/bob2 contents',
  67. 'bob3': 'bob/bob3 contents',
  68. }
  69. })
  70. mock_fs = MockFileSystem(test_fs)
  71. def create_empty_caching_fs():
  72. return self._CreateCachingFileSystem(mock_fs, start_empty=True)
  73. file_system = create_empty_caching_fs()
  74. # The stat/read should happen before resolving the Future, and resolving
  75. # the future shouldn't do any additional work.
  76. get_future = file_system.ReadSingle('bob/bob0')
  77. self.assertTrue(*mock_fs.CheckAndReset(read_count=1))
  78. self.assertEqual('bob/bob0 contents', get_future.Get())
  79. self.assertTrue(*mock_fs.CheckAndReset(read_resolve_count=1, stat_count=1))
  80. # Resource has been cached, so test resource is not re-fetched.
  81. self.assertEqual('bob/bob0 contents',
  82. file_system.ReadSingle('bob/bob0').Get())
  83. self.assertTrue(*mock_fs.CheckAndReset())
  84. # Test if the Stat version is the same the resource is not re-fetched.
  85. file_system = create_empty_caching_fs()
  86. self.assertEqual('bob/bob0 contents',
  87. file_system.ReadSingle('bob/bob0').Get())
  88. self.assertTrue(*mock_fs.CheckAndReset(stat_count=1))
  89. # Test if there is a newer version, the resource is re-fetched.
  90. file_system = create_empty_caching_fs()
  91. test_fs.IncrementStat();
  92. future = file_system.ReadSingle('bob/bob0')
  93. self.assertTrue(*mock_fs.CheckAndReset(read_count=1, stat_count=1))
  94. self.assertEqual('bob/bob0 contents', future.Get())
  95. self.assertTrue(*mock_fs.CheckAndReset(read_resolve_count=1))
  96. # Test directory and subdirectory stats are cached.
  97. file_system = create_empty_caching_fs()
  98. file_system._stat_cache.Del('bob/bob0')
  99. file_system._read_cache.Del('bob/bob0')
  100. file_system._stat_cache.Del('bob/bob1')
  101. test_fs.IncrementStat();
  102. futures = (file_system.ReadSingle('bob/bob1'),
  103. file_system.ReadSingle('bob/bob0'))
  104. self.assertTrue(*mock_fs.CheckAndReset(read_count=2))
  105. self.assertEqual(('bob/bob1 contents', 'bob/bob0 contents'),
  106. tuple(future.Get() for future in futures))
  107. self.assertTrue(*mock_fs.CheckAndReset(read_resolve_count=2, stat_count=1))
  108. self.assertEqual('bob/bob1 contents',
  109. file_system.ReadSingle('bob/bob1').Get())
  110. self.assertTrue(*mock_fs.CheckAndReset())
  111. # Test a more recent parent directory doesn't force a refetch of children.
  112. file_system = create_empty_caching_fs()
  113. file_system._read_cache.Del('bob/bob0')
  114. file_system._read_cache.Del('bob/bob1')
  115. futures = (file_system.ReadSingle('bob/bob1'),
  116. file_system.ReadSingle('bob/bob2'),
  117. file_system.ReadSingle('bob/bob3'))
  118. self.assertTrue(*mock_fs.CheckAndReset(read_count=3))
  119. self.assertEqual(
  120. ('bob/bob1 contents', 'bob/bob2 contents', 'bob/bob3 contents'),
  121. tuple(future.Get() for future in futures))
  122. self.assertTrue(*mock_fs.CheckAndReset(read_resolve_count=3, stat_count=1))
  123. test_fs.IncrementStat(path='bob/bob0')
  124. file_system = create_empty_caching_fs()
  125. self.assertEqual('bob/bob1 contents',
  126. file_system.ReadSingle('bob/bob1').Get())
  127. self.assertEqual('bob/bob2 contents',
  128. file_system.ReadSingle('bob/bob2').Get())
  129. self.assertEqual('bob/bob3 contents',
  130. file_system.ReadSingle('bob/bob3').Get())
  131. self.assertTrue(*mock_fs.CheckAndReset(stat_count=1))
  132. file_system = create_empty_caching_fs()
  133. file_system._stat_cache.Del('bob/bob0')
  134. future = file_system.ReadSingle('bob/bob0')
  135. self.assertTrue(*mock_fs.CheckAndReset(read_count=1))
  136. self.assertEqual('bob/bob0 contents', future.Get())
  137. self.assertTrue(*mock_fs.CheckAndReset(read_resolve_count=1, stat_count=1))
  138. self.assertEqual('bob/bob0 contents',
  139. file_system.ReadSingle('bob/bob0').Get())
  140. self.assertTrue(*mock_fs.CheckAndReset())
  141. # Test skip_not_found caching behavior.
  142. file_system = create_empty_caching_fs()
  143. future = file_system.ReadSingle('bob/no_file', skip_not_found=True)
  144. self.assertTrue(*mock_fs.CheckAndReset(read_count=1))
  145. self.assertEqual(None, future.Get())
  146. self.assertTrue(*mock_fs.CheckAndReset(read_resolve_count=1, stat_count=1))
  147. future = file_system.ReadSingle('bob/no_file', skip_not_found=True)
  148. # There shouldn't be another read/stat from the file system;
  149. # we know the file is not there.
  150. self.assertTrue(*mock_fs.CheckAndReset())
  151. future = file_system.ReadSingle('bob/no_file')
  152. self.assertTrue(*mock_fs.CheckAndReset(read_count=1))
  153. # Even though we cached information about non-existent files,
  154. # trying to read one without specifiying skip_not_found should
  155. # still raise an error.
  156. self.assertRaises(FileNotFoundError, future.Get)
  157. def testCachedStat(self):
  158. test_fs = TestFileSystem({
  159. 'bob': {
  160. 'bob0': 'bob/bob0 contents',
  161. 'bob1': 'bob/bob1 contents'
  162. }
  163. })
  164. mock_fs = MockFileSystem(test_fs)
  165. file_system = self._CreateCachingFileSystem(mock_fs, start_empty=False)
  166. self.assertEqual(StatInfo('0'), file_system.Stat('bob/bob0'))
  167. self.assertTrue(*mock_fs.CheckAndReset(stat_count=1))
  168. self.assertEqual(StatInfo('0'), file_system.Stat('bob/bob0'))
  169. self.assertTrue(*mock_fs.CheckAndReset())
  170. # Caching happens on a directory basis, so reading other files from that
  171. # directory won't result in a stat.
  172. self.assertEqual(StatInfo('0'), file_system.Stat('bob/bob1'))
  173. self.assertEqual(
  174. StatInfo('0', child_versions={'bob0': '0', 'bob1': '0'}),
  175. file_system.Stat('bob/'))
  176. self.assertTrue(*mock_fs.CheckAndReset())
  177. # Even though the stat is bumped, the object store still has it cached so
  178. # this won't update.
  179. test_fs.IncrementStat()
  180. self.assertEqual(StatInfo('0'), file_system.Stat('bob/bob0'))
  181. self.assertEqual(StatInfo('0'), file_system.Stat('bob/bob1'))
  182. self.assertEqual(
  183. StatInfo('0', child_versions={'bob0': '0', 'bob1': '0'}),
  184. file_system.Stat('bob/'))
  185. self.assertTrue(*mock_fs.CheckAndReset())
  186. def testFreshStat(self):
  187. test_fs = TestFileSystem({
  188. 'bob': {
  189. 'bob0': 'bob/bob0 contents',
  190. 'bob1': 'bob/bob1 contents'
  191. }
  192. })
  193. mock_fs = MockFileSystem(test_fs)
  194. def run_expecting_stat(stat):
  195. def run():
  196. file_system = self._CreateCachingFileSystem(mock_fs, start_empty=True)
  197. self.assertEqual(
  198. StatInfo(stat, child_versions={'bob0': stat, 'bob1': stat}),
  199. file_system.Stat('bob/'))
  200. self.assertTrue(*mock_fs.CheckAndReset(stat_count=1))
  201. self.assertEqual(StatInfo(stat), file_system.Stat('bob/bob0'))
  202. self.assertEqual(StatInfo(stat), file_system.Stat('bob/bob0'))
  203. self.assertTrue(*mock_fs.CheckAndReset())
  204. run()
  205. run()
  206. run_expecting_stat('0')
  207. test_fs.IncrementStat()
  208. run_expecting_stat('1')
  209. def testSkipNotFound(self):
  210. caching_fs = self._CreateCachingFileSystem(TestFileSystem({
  211. 'bob': {
  212. 'bob0': 'bob/bob0 contents',
  213. 'bob1': 'bob/bob1 contents'
  214. }
  215. }))
  216. def read_skip_not_found(paths):
  217. return caching_fs.Read(paths, skip_not_found=True).Get()
  218. self.assertEqual({}, read_skip_not_found(('grub',)))
  219. self.assertEqual({}, read_skip_not_found(('bob/bob2',)))
  220. self.assertEqual({
  221. 'bob/bob0': 'bob/bob0 contents',
  222. }, read_skip_not_found(('bob/bob0', 'bob/bob2')))
  223. def testWalkCaching(self):
  224. test_fs = TestFileSystem({
  225. 'root': {
  226. 'file1': 'file1',
  227. 'file2': 'file2',
  228. 'dir1': {
  229. 'dir1_file1': 'dir1_file1',
  230. 'dir2': {},
  231. 'dir3': {
  232. 'dir3_file1': 'dir3_file1',
  233. 'dir3_file2': 'dir3_file2'
  234. }
  235. }
  236. }
  237. })
  238. mock_fs = MockFileSystem(test_fs)
  239. file_system = self._CreateCachingFileSystem(mock_fs, start_empty=True)
  240. for walkinfo in file_system.Walk(''):
  241. pass
  242. self.assertTrue(*mock_fs.CheckAndReset(
  243. read_resolve_count=5, read_count=5, stat_count=5))
  244. all_dirs, all_files = [], []
  245. for root, dirs, files in file_system.Walk(''):
  246. all_dirs.extend(dirs)
  247. all_files.extend(files)
  248. self.assertEqual(sorted(['root/', 'dir1/', 'dir2/', 'dir3/']),
  249. sorted(all_dirs))
  250. self.assertEqual(
  251. sorted(['file1', 'file2', 'dir1_file1', 'dir3_file1', 'dir3_file2']),
  252. sorted(all_files))
  253. # All data should be cached.
  254. self.assertTrue(*mock_fs.CheckAndReset())
  255. # Starting from a different root should still pull cached data.
  256. for walkinfo in file_system.Walk('root/dir1/'):
  257. pass
  258. self.assertTrue(*mock_fs.CheckAndReset())
  259. # TODO(ahernandez): Test with a new instance CachingFileSystem so a
  260. # different object store is utilized.
  261. if __name__ == '__main__':
  262. unittest.main()