- add sources.
[platform/framework/web/crosswalk.git] / src / chrome / common / extensions / docs / server2 / caching_file_system_test.py
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 from caching_file_system import CachingFileSystem
11 from file_system import FileSystem, StatInfo
12 from future import Future
13 from local_file_system import LocalFileSystem
14 from mock_file_system import MockFileSystem
15 from object_store_creator import ObjectStoreCreator
16 from test_file_system import TestFileSystem
17 from test_object_store import TestObjectStore
18
19 def _CreateLocalFs():
20   return LocalFileSystem(
21       os.path.join(sys.path[0], 'test_data', 'file_system'))
22
23 class CachingFileSystemTest(unittest.TestCase):
24   def setUp(self):
25     # Use this to make sure that every time _CreateCachingFileSystem is called
26     # the underlying object store data is the same, within each test.
27     self._object_store_dbs = {}
28
29   def _CreateCachingFileSystem(self, fs, start_empty=False):
30     def store_type_constructor(namespace, start_empty=False):
31       '''Returns an ObjectStore backed onto test-lifetime-persistent objects
32       in |_object_store_dbs|.
33       '''
34       if namespace not in self._object_store_dbs:
35         self._object_store_dbs[namespace] = {}
36       db = self._object_store_dbs[namespace]
37       if start_empty:
38         db.clear()
39       return TestObjectStore(namespace, init=db)
40     object_store_creator = ObjectStoreCreator(start_empty=start_empty,
41                                               store_type=store_type_constructor)
42     return CachingFileSystem(fs, object_store_creator)
43
44   def testReadFiles(self):
45     file_system = self._CreateCachingFileSystem(
46         _CreateLocalFs(), start_empty=False)
47     expected = {
48       './test1.txt': 'test1\n',
49       './test2.txt': 'test2\n',
50       './test3.txt': 'test3\n',
51     }
52     self.assertEqual(
53         expected,
54         file_system.Read(['./test1.txt', './test2.txt', './test3.txt']).Get())
55
56   def testListDir(self):
57     file_system = self._CreateCachingFileSystem(
58         _CreateLocalFs(), start_empty=False)
59     expected = ['dir/'] + ['file%d.html' % i for i in range(7)]
60     file_system._read_object_store.Set(
61         'list/',
62         (expected, file_system.Stat('list/').version))
63     self.assertEqual(expected, sorted(file_system.ReadSingle('list/').Get()))
64
65     expected.remove('file0.html')
66     file_system._read_object_store.Set(
67         'list/',
68         (expected, file_system.Stat('list/').version))
69     self.assertEqual(expected, sorted(file_system.ReadSingle('list/').Get()))
70
71   def testCaching(self):
72     test_fs = TestFileSystem({
73       'bob': {
74         'bob0': 'bob/bob0 contents',
75         'bob1': 'bob/bob1 contents',
76         'bob2': 'bob/bob2 contents',
77         'bob3': 'bob/bob3 contents',
78       }
79     })
80     mock_fs = MockFileSystem(test_fs)
81     def create_empty_caching_fs():
82       return self._CreateCachingFileSystem(mock_fs, start_empty=True)
83
84     file_system = create_empty_caching_fs()
85
86     # The stat/read should happen before resolving the Future, and resolving
87     # the future shouldn't do any additional work.
88     get_future = file_system.ReadSingle('bob/bob0')
89     self.assertTrue(*mock_fs.CheckAndReset(read_count=1, stat_count=1))
90     self.assertEqual('bob/bob0 contents', get_future.Get())
91     self.assertTrue(*mock_fs.CheckAndReset(read_resolve_count=1))
92
93     # Resource has been cached, so test resource is not re-fetched.
94     self.assertEqual('bob/bob0 contents',
95                      file_system.ReadSingle('bob/bob0').Get())
96     self.assertTrue(*mock_fs.CheckAndReset())
97
98     # Test if the Stat version is the same the resource is not re-fetched.
99     file_system = create_empty_caching_fs()
100     self.assertEqual('bob/bob0 contents',
101                      file_system.ReadSingle('bob/bob0').Get())
102     self.assertTrue(*mock_fs.CheckAndReset(stat_count=1))
103
104     # Test if there is a newer version, the resource is re-fetched.
105     file_system = create_empty_caching_fs()
106     test_fs.IncrementStat();
107     future = file_system.ReadSingle('bob/bob0')
108     self.assertTrue(*mock_fs.CheckAndReset(read_count=1, stat_count=1))
109     self.assertEqual('bob/bob0 contents', future.Get())
110     self.assertTrue(*mock_fs.CheckAndReset(read_resolve_count=1))
111
112     # Test directory and subdirectory stats are cached.
113     file_system = create_empty_caching_fs()
114     file_system._stat_object_store.Del('bob/bob0')
115     file_system._read_object_store.Del('bob/bob0')
116     file_system._stat_object_store.Del('bob/bob1')
117     test_fs.IncrementStat();
118     futures = (file_system.ReadSingle('bob/bob1'),
119                file_system.ReadSingle('bob/bob0'))
120     self.assertTrue(*mock_fs.CheckAndReset(read_count=2, stat_count=1))
121     self.assertEqual(('bob/bob1 contents', 'bob/bob0 contents'),
122                      tuple(future.Get() for future in futures))
123     self.assertTrue(*mock_fs.CheckAndReset(read_resolve_count=2))
124     self.assertEqual('bob/bob1 contents',
125                      file_system.ReadSingle('bob/bob1').Get())
126     self.assertTrue(*mock_fs.CheckAndReset())
127
128     # Test a more recent parent directory doesn't force a refetch of children.
129     file_system = create_empty_caching_fs()
130     file_system._read_object_store.Del('bob/bob0')
131     file_system._read_object_store.Del('bob/bob1')
132     futures = (file_system.ReadSingle('bob/bob1'),
133                file_system.ReadSingle('bob/bob2'),
134                file_system.ReadSingle('bob/bob3'))
135     self.assertTrue(*mock_fs.CheckAndReset(read_count=3, stat_count=1))
136     self.assertEqual(
137         ('bob/bob1 contents', 'bob/bob2 contents', 'bob/bob3 contents'),
138         tuple(future.Get() for future in futures))
139     self.assertTrue(*mock_fs.CheckAndReset(read_resolve_count=3))
140
141     test_fs.IncrementStat(path='bob/')
142     file_system = create_empty_caching_fs()
143     self.assertEqual('bob/bob1 contents',
144                      file_system.ReadSingle('bob/bob1').Get())
145     self.assertEqual('bob/bob2 contents',
146                      file_system.ReadSingle('bob/bob2').Get())
147     self.assertEqual('bob/bob3 contents',
148                      file_system.ReadSingle('bob/bob3').Get())
149     self.assertTrue(*mock_fs.CheckAndReset(stat_count=1))
150
151     file_system = create_empty_caching_fs()
152     file_system._stat_object_store.Del('bob/bob0')
153     future = file_system.ReadSingle('bob/bob0')
154     self.assertTrue(*mock_fs.CheckAndReset(read_count=1, stat_count=1))
155     self.assertEqual('bob/bob0 contents', future.Get())
156     self.assertTrue(*mock_fs.CheckAndReset(read_resolve_count=1))
157     self.assertEqual('bob/bob0 contents',
158                      file_system.ReadSingle('bob/bob0').Get())
159     self.assertTrue(*mock_fs.CheckAndReset())
160
161   def testCachedStat(self):
162     test_fs = TestFileSystem({
163       'bob': {
164         'bob0': 'bob/bob0 contents',
165         'bob1': 'bob/bob1 contents'
166       }
167     })
168     mock_fs = MockFileSystem(test_fs)
169
170     file_system = self._CreateCachingFileSystem(mock_fs, start_empty=False)
171
172     self.assertEqual(StatInfo('0'), file_system.Stat('bob/bob0'))
173     self.assertTrue(*mock_fs.CheckAndReset(stat_count=1))
174     self.assertEqual(StatInfo('0'), file_system.Stat('bob/bob0'))
175     self.assertTrue(*mock_fs.CheckAndReset())
176
177     # Caching happens on a directory basis, so reading other files from that
178     # directory won't result in a stat.
179     self.assertEqual(StatInfo('0'), file_system.Stat('bob/bob1'))
180     self.assertEqual(
181         StatInfo('0', child_versions={'bob0': '0', 'bob1': '0'}),
182         file_system.Stat('bob/'))
183     self.assertTrue(*mock_fs.CheckAndReset())
184
185     # Even though the stat is bumped, the object store still has it cached so
186     # this won't update.
187     test_fs.IncrementStat()
188     self.assertEqual(StatInfo('0'), file_system.Stat('bob/bob0'))
189     self.assertEqual(StatInfo('0'), file_system.Stat('bob/bob1'))
190     self.assertEqual(
191         StatInfo('0', child_versions={'bob0': '0', 'bob1': '0'}),
192         file_system.Stat('bob/'))
193     self.assertTrue(*mock_fs.CheckAndReset())
194
195   def testFreshStat(self):
196     test_fs = TestFileSystem({
197       'bob': {
198         'bob0': 'bob/bob0 contents',
199         'bob1': 'bob/bob1 contents'
200       }
201     })
202     mock_fs = MockFileSystem(test_fs)
203
204     def run_expecting_stat(stat):
205       def run():
206         file_system = self._CreateCachingFileSystem(mock_fs, start_empty=True)
207         self.assertEqual(
208             StatInfo(stat, child_versions={'bob0': stat, 'bob1': stat}),
209             file_system.Stat('bob/'))
210         self.assertTrue(*mock_fs.CheckAndReset(stat_count=1))
211         self.assertEqual(StatInfo(stat), file_system.Stat('bob/bob0'))
212         self.assertEqual(StatInfo(stat), file_system.Stat('bob/bob0'))
213         self.assertTrue(*mock_fs.CheckAndReset())
214       run()
215       run()
216
217     run_expecting_stat('0')
218     test_fs.IncrementStat()
219     run_expecting_stat('1')
220
221 if __name__ == '__main__':
222   unittest.main()