summaryrefslogtreecommitdiffstats
path: root/chrome/common/extensions/docs/server2/compiled_file_system_test.py
blob: 6a99bfcddc63d14b54b17d4982f9adce17804725 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
#!/usr/bin/env python
# Copyright 2013 The Chromium Authors. All rights reserved.
# Use of this source code is governed by a BSD-style license that can be
# found in the LICENSE file.

import functools
import os

from appengine_wrappers import GetAppVersion
from compiled_file_system import CompiledFileSystem
from copy import deepcopy
from file_system import FileNotFoundError
from mock_file_system import MockFileSystem
from object_store_creator import ObjectStoreCreator
from test_file_system import TestFileSystem
from test_object_store import TestObjectStore
import unittest

_TEST_DATA = {
  '404.html': '404.html contents',
  'apps': {
    'a11y.html': 'a11y.html contents',
    'about_apps.html': 'about_apps.html contents',
    'fakedir': {
      'file.html': 'file.html contents'
    },
    'deepdir': {
      'deepfile.html': 'deepfile.html contents',
      'deeper': {
        'deepest.html': 'deepest.html contents',
      },
    }
  },
  'extensions': {
    'activeTab.html': 'activeTab.html contents',
    'alarms.html': 'alarms.html contents'
  }
}

identity = lambda _, x: x

def _GetTestCompiledFsCreator():
  '''Returns a function which creates CompiledFileSystem views of
  TestFileSystems backed by _TEST_DATA.
  '''
  return functools.partial(
      CompiledFileSystem.Factory(
          ObjectStoreCreator(start_empty=False,
                             store_type=TestObjectStore,
                             disable_wrappers=True),
      ).Create,
      TestFileSystem(deepcopy(_TEST_DATA)))

class CompiledFileSystemTest(unittest.TestCase):
  def testPopulateNamespace(self):
    def CheckNamespace(expected_file, expected_list, fs):
      self.assertEqual(expected_file, fs._file_object_store.namespace)
      self.assertEqual(expected_list, fs._list_object_store.namespace)
    compiled_fs_creator = _GetTestCompiledFsCreator()
    f = lambda x: x
    CheckNamespace(
        'class=CompiledFileSystem&'
            'category=CompiledFileSystemTest/TestFileSystem/file&'
            'app_version=%s' % GetAppVersion(),
        'class=CompiledFileSystem&'
            'category=CompiledFileSystemTest/TestFileSystem/list&'
            'app_version=%s' % GetAppVersion(),
        compiled_fs_creator(f, CompiledFileSystemTest))
    CheckNamespace(
        'class=CompiledFileSystem&'
            'category=CompiledFileSystemTest/TestFileSystem/foo/file&'
            'app_version=%s' % GetAppVersion(),
        'class=CompiledFileSystem&'
            'category=CompiledFileSystemTest/TestFileSystem/foo/list&'
            'app_version=%s' % GetAppVersion(),
        compiled_fs_creator(f, CompiledFileSystemTest, category='foo'))

  def testPopulateFromFile(self):
    def Sleepy(key, val):
      return '%s%s' % ('Z' * len(key), 'z' * len(val))
    compiled_fs = _GetTestCompiledFsCreator()(Sleepy, CompiledFileSystemTest)
    self.assertEqual('ZZZZZZZZzzzzzzzzzzzzzzzzz',
                     compiled_fs.GetFromFile('404.html').Get())
    self.assertEqual('ZZZZZZZZZZZZZZzzzzzzzzzzzzzzzzzz',
                     compiled_fs.GetFromFile('apps/a11y.html').Get())
    self.assertEqual('ZZZZZZZZZZZZZZZZZZZZZZzzzzzzzzzzzzzzzzzz',
                     compiled_fs.GetFromFile('apps/fakedir/file.html').Get())

  def testPopulateFromFileListing(self):
    def strip_ext(path, files):
      return [os.path.splitext(f)[0] for f in files]
    compiled_fs = _GetTestCompiledFsCreator()(strip_ext, CompiledFileSystemTest)
    expected_top_listing = [
      '404',
      'apps/a11y',
      'apps/about_apps',
      'apps/deepdir/deeper/deepest',
      'apps/deepdir/deepfile',
      'apps/fakedir/file',
      'extensions/activeTab',
      'extensions/alarms'
    ]
    self.assertEqual(expected_top_listing,
                     sorted(compiled_fs.GetFromFileListing('').Get()))
    expected_apps_listing = [
      'a11y',
      'about_apps',
      'deepdir/deeper/deepest',
      'deepdir/deepfile',
      'fakedir/file',
    ]
    self.assertEqual(expected_apps_listing,
                     sorted(compiled_fs.GetFromFileListing('apps/').Get()))
    self.assertEqual(['file',],
                     compiled_fs.GetFromFileListing('apps/fakedir/').Get())
    self.assertEqual(['deeper/deepest', 'deepfile'],
                     sorted(compiled_fs.GetFromFileListing(
                         'apps/deepdir/').Get()))
    self.assertEqual(['deepest'],
                     compiled_fs.GetFromFileListing(
                         'apps/deepdir/deeper/').Get())

  def testCaching(self):
    compiled_fs = _GetTestCompiledFsCreator()(identity, CompiledFileSystemTest)
    self.assertEqual('404.html contents',
                     compiled_fs.GetFromFile('404.html').Get())
    self.assertEqual(set(('file.html',)),
                     set(compiled_fs.GetFromFileListing('apps/fakedir/').Get()))

    compiled_fs._file_system._path_values['404.html'] = 'boom'
    compiled_fs._file_system._path_values['apps/fakedir/'] = [
        'file.html', 'boom.html']
    self.assertEqual('404.html contents',
                     compiled_fs.GetFromFile('404.html').Get())
    self.assertEqual(set(('file.html',)),
                     set(compiled_fs.GetFromFileListing('apps/fakedir/').Get()))

    compiled_fs._file_system.IncrementStat()
    self.assertEqual('boom', compiled_fs.GetFromFile('404.html').Get())
    self.assertEqual(set(('file.html', 'boom.html')),
                     set(compiled_fs.GetFromFileListing('apps/fakedir/').Get()))

  def testFailures(self):
    compiled_fs = _GetTestCompiledFsCreator()(identity, CompiledFileSystemTest)
    self.assertRaises(FileNotFoundError,
                      compiled_fs.GetFromFile('405.html').Get)
    # TODO(kalman): would be nice to test this fails since apps/ is a dir.
    compiled_fs.GetFromFile('apps')
    #self.assertRaises(SomeError, compiled_fs.GetFromFile, 'apps/')
    self.assertRaises(FileNotFoundError,
                      compiled_fs.GetFromFileListing('nodir/').Get)
    # TODO(kalman): likewise, not a FileNotFoundError.
    self.assertRaises(FileNotFoundError,
                      compiled_fs.GetFromFileListing('404.html/').Get)

  def testCorrectFutureBehaviour(self):
    # Tests that the underlying FileSystem's Read Future has had Get() called
    # on it before the Future is resolved, but the underlying Future isn't
    # resolved until Get is.
    mock_fs = MockFileSystem(TestFileSystem(_TEST_DATA))
    compiled_fs = CompiledFileSystem.Factory(
        ObjectStoreCreator.ForTest()).Create(
            mock_fs, lambda path, contents: contents, type(self))

    self.assertTrue(*mock_fs.CheckAndReset())
    future = compiled_fs.GetFromFile('404.html')
    self.assertTrue(*mock_fs.CheckAndReset(stat_count=1, read_count=1))
    future.Get()
    self.assertTrue(*mock_fs.CheckAndReset(read_resolve_count=1))

    future = compiled_fs.GetFromFileListing('apps/')
    # Current behaviour is to have read=2 and read_resolve=1 because the first
    # level is read eagerly, then all of the second is read (in parallel). If
    # it weren't eager (and it may be worth experimenting with that) then it'd
    # be read=1 and read_resolve=0.
    self.assertTrue(*mock_fs.CheckAndReset(stat_count=1,
                                           read_count=2,
                                           read_resolve_count=1))
    future.Get()
    # It's doing 1 more level 'deeper' (already read 'fakedir' and 'deepdir'
    # though not resolved), so that's 1 more read/resolve + the resolve from
    # the first read.
    self.assertTrue(*mock_fs.CheckAndReset(read_count=1, read_resolve_count=2))

    # Even though the directory is 1 layer deep the caller has no way of
    # determining that ahead of time (though perhaps the API could give some
    # kind of clue, if we really cared).
    future = compiled_fs.GetFromFileListing('extensions/')
    self.assertTrue(*mock_fs.CheckAndReset(stat_count=1,
                                           read_count=1,
                                           read_resolve_count=1))
    future.Get()
    self.assertTrue(*mock_fs.CheckAndReset())

    # Similar configuration to the 'apps/' case but deeper.
    future = compiled_fs.GetFromFileListing('')
    self.assertTrue(*mock_fs.CheckAndReset(stat_count=1,
                                           read_count=2,
                                           read_resolve_count=1))
    future.Get()
    self.assertTrue(*mock_fs.CheckAndReset(read_count=2, read_resolve_count=3))



if __name__ == '__main__':
  unittest.main()