2 # Copyright 2013 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.
9 from compiled_file_system
import Cache
, CompiledFileSystem
10 from copy
import deepcopy
11 from environment
import GetAppVersion
12 from file_system
import FileNotFoundError
13 from mock_file_system
import MockFileSystem
14 from object_store_creator
import ObjectStoreCreator
15 from test_file_system
import TestFileSystem
16 from test_object_store
import TestObjectStore
20 '404.html': '404.html contents',
22 'a11y.html': 'a11y.html contents',
23 'about_apps.html': 'about_apps.html contents',
25 'file.html': 'file.html contents'
28 'deepfile.html': 'deepfile.html contents',
30 'deepest.html': 'deepest.html contents',
35 'activeTab.html': 'activeTab.html contents',
36 'alarms.html': 'alarms.html contents'
40 identity
= lambda _
, x
: x
42 def _GetTestCompiledFsCreator():
43 '''Returns a function which creates CompiledFileSystem views of
44 TestFileSystems backed by _TEST_DATA.
46 return functools
.partial(
47 CompiledFileSystem
.Factory(
48 ObjectStoreCreator(start_empty
=False,
49 store_type
=TestObjectStore
,
50 disable_wrappers
=True),
52 TestFileSystem(deepcopy(_TEST_DATA
)))
54 class CompiledFileSystemTest(unittest
.TestCase
):
55 def testPopulateNamespace(self
):
56 def CheckNamespace(expected_file
, expected_list
, fs
):
57 self
.assertEqual(expected_file
, fs
._file
_object
_store
.namespace
)
58 self
.assertEqual(expected_list
, fs
._list
_object
_store
.namespace
)
59 compiled_fs_creator
= _GetTestCompiledFsCreator()
62 'class=CompiledFileSystem&'
63 'category=CompiledFileSystemTest/TestFileSystem/file&'
64 'app_version=%s' % GetAppVersion(),
65 'class=CompiledFileSystem&'
66 'category=CompiledFileSystemTest/TestFileSystem/list&'
67 'app_version=%s' % GetAppVersion(),
68 compiled_fs_creator(f
, CompiledFileSystemTest
))
70 'class=CompiledFileSystem&'
71 'category=CompiledFileSystemTest/TestFileSystem/foo/file&'
72 'app_version=%s' % GetAppVersion(),
73 'class=CompiledFileSystem&'
74 'category=CompiledFileSystemTest/TestFileSystem/foo/list&'
75 'app_version=%s' % GetAppVersion(),
76 compiled_fs_creator(f
, CompiledFileSystemTest
, category
='foo'))
78 def testPopulateFromFile(self
):
80 return '%s%s' % ('Z' * len(key
), 'z' * len(val
))
81 compiled_fs
= _GetTestCompiledFsCreator()(Sleepy
, CompiledFileSystemTest
)
82 self
.assertEqual('ZZZZZZZZzzzzzzzzzzzzzzzzz',
83 compiled_fs
.GetFromFile('404.html').Get())
84 self
.assertEqual('ZZZZZZZZZZZZZZzzzzzzzzzzzzzzzzzz',
85 compiled_fs
.GetFromFile('apps/a11y.html').Get())
86 self
.assertEqual('ZZZZZZZZZZZZZZZZZZZZZZzzzzzzzzzzzzzzzzzz',
87 compiled_fs
.GetFromFile('apps/fakedir/file.html').Get())
89 def testPopulateFromFileListing(self
):
90 def strip_ext(_
, files
):
91 return [os
.path
.splitext(f
)[0] for f
in files
]
92 compiled_fs
= _GetTestCompiledFsCreator()(strip_ext
, CompiledFileSystemTest
)
93 expected_top_listing
= [
97 'apps/deepdir/deeper/deepest',
98 'apps/deepdir/deepfile',
100 'extensions/activeTab',
103 self
.assertEqual(expected_top_listing
,
104 sorted(compiled_fs
.GetFromFileListing('').Get()))
105 expected_apps_listing
= [
108 'deepdir/deeper/deepest',
112 self
.assertEqual(expected_apps_listing
,
113 sorted(compiled_fs
.GetFromFileListing('apps/').Get()))
114 self
.assertEqual(['file',],
115 compiled_fs
.GetFromFileListing('apps/fakedir/').Get())
116 self
.assertEqual(['deeper/deepest', 'deepfile'],
117 sorted(compiled_fs
.GetFromFileListing(
118 'apps/deepdir/').Get()))
119 self
.assertEqual(['deepest'],
120 compiled_fs
.GetFromFileListing(
121 'apps/deepdir/deeper/').Get())
123 def testCaching(self
):
124 compiled_fs
= _GetTestCompiledFsCreator()(Cache(identity
),
125 CompiledFileSystemTest
)
126 self
.assertEqual('404.html contents',
127 compiled_fs
.GetFromFile('404.html').Get())
128 self
.assertEqual(set(('file.html',)),
129 set(compiled_fs
.GetFromFileListing('apps/fakedir/').Get()))
131 compiled_fs
._file
_system
._path
_values
['404.html'] = 'boom'
132 compiled_fs
._file
_system
._path
_values
['apps/fakedir/'] = [
133 'file.html', 'boom.html']
134 self
.assertEqual('404.html contents',
135 compiled_fs
.GetFromFile('404.html').Get())
136 self
.assertEqual(set(('file.html',)),
137 set(compiled_fs
.GetFromFileListing('apps/fakedir/').Get()))
139 compiled_fs
._file
_system
.IncrementStat()
140 self
.assertEqual('boom', compiled_fs
.GetFromFile('404.html').Get())
141 self
.assertEqual(set(('file.html', 'boom.html')),
142 set(compiled_fs
.GetFromFileListing('apps/fakedir/').Get()))
144 def testFailures(self
):
145 compiled_fs
= _GetTestCompiledFsCreator()(identity
, CompiledFileSystemTest
)
146 self
.assertRaises(FileNotFoundError
,
147 compiled_fs
.GetFromFile('405.html').Get
)
148 # TODO(kalman): would be nice to test this fails since apps/ is a dir.
149 compiled_fs
.GetFromFile('apps')
150 #self.assertRaises(SomeError, compiled_fs.GetFromFile, 'apps/')
151 self
.assertRaises(FileNotFoundError
,
152 compiled_fs
.GetFromFileListing('nodir/').Get
)
153 # TODO(kalman): likewise, not a FileNotFoundError.
154 self
.assertRaises(FileNotFoundError
,
155 compiled_fs
.GetFromFileListing('404.html/').Get
)
157 def testCorrectFutureBehaviour(self
):
158 # Tests that the underlying FileSystem's Read Future has had Get() called
159 # on it before the Future is resolved, but the underlying Future isn't
160 # resolved until Get is.
161 mock_fs
= MockFileSystem(TestFileSystem(_TEST_DATA
))
162 compiled_fs
= CompiledFileSystem
.Factory(
163 ObjectStoreCreator
.ForTest()).Create(
164 mock_fs
, lambda path
, contents
: contents
, type(self
))
166 self
.assertTrue(*mock_fs
.CheckAndReset())
167 future
= compiled_fs
.GetFromFile('404.html')
168 self
.assertTrue(*mock_fs
.CheckAndReset(stat_count
=1, read_count
=1))
170 self
.assertTrue(*mock_fs
.CheckAndReset(read_resolve_count
=1))
172 future
= compiled_fs
.GetFromFileListing('apps/')
173 # Current behaviour is to have read=2 and read_resolve=1 because the first
174 # level is read eagerly, then all of the second is read (in parallel). If
175 # it weren't eager (and it may be worth experimenting with that) then it'd
176 # be read=1 and read_resolve=0.
177 self
.assertTrue(*mock_fs
.CheckAndReset(stat_count
=1,
179 read_resolve_count
=1))
181 # It's doing 1 more level 'deeper' (already read 'fakedir' and 'deepdir'
182 # though not resolved), so that's 1 more read/resolve + the resolve from
184 self
.assertTrue(*mock_fs
.CheckAndReset(read_count
=1, read_resolve_count
=2))
186 # Even though the directory is 1 layer deep the caller has no way of
187 # determining that ahead of time (though perhaps the API could give some
188 # kind of clue, if we really cared).
189 future
= compiled_fs
.GetFromFileListing('extensions/')
190 self
.assertTrue(*mock_fs
.CheckAndReset(stat_count
=1,
192 read_resolve_count
=1))
194 self
.assertTrue(*mock_fs
.CheckAndReset())
196 # Similar configuration to the 'apps/' case but deeper.
197 future
= compiled_fs
.GetFromFileListing('')
198 self
.assertTrue(*mock_fs
.CheckAndReset(stat_count
=1,
200 read_resolve_count
=1))
202 self
.assertTrue(*mock_fs
.CheckAndReset(read_count
=2, read_resolve_count
=3))
204 def testSkipNotFound(self
):
205 mock_fs
= MockFileSystem(TestFileSystem(_TEST_DATA
))
206 compiled_fs
= CompiledFileSystem
.Factory(
207 ObjectStoreCreator
.ForTest()).Create(
208 mock_fs
, Cache(lambda path
, contents
: contents
), type(self
))
210 future
= compiled_fs
.GetFromFile('no_file', skip_not_found
=True)
211 # If the file doesn't exist, then the file system is not read.
212 self
.assertTrue(*mock_fs
.CheckAndReset(read_count
=1, stat_count
=1))
213 self
.assertEqual(None, future
.Get())
214 self
.assertTrue(*mock_fs
.CheckAndReset(read_resolve_count
=1))
215 future
= compiled_fs
.GetFromFile('no_file', skip_not_found
=True)
216 self
.assertTrue(*mock_fs
.CheckAndReset(stat_count
=1))
217 self
.assertEqual(None, future
.Get())
218 # The result for a non-existent file should still be cached.
219 self
.assertTrue(*mock_fs
.CheckAndReset())
220 future
= compiled_fs
.GetFromFile('no_file')
221 self
.assertRaises(FileNotFoundError
, future
.Get
)
224 if __name__
== '__main__':