Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(146)

Side by Side Diff: chrome/common/extensions/docs/server2/mock_file_system.py

Issue 151883009: Docserver: Make MockFileSystem not iterate over the entire file system as part (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: yoz and then some Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
OLDNEW
1 # Copyright 2013 The Chromium Authors. All rights reserved. 1 # Copyright 2013 The Chromium Authors. All rights reserved.
2 # Use of this source code is governed by a BSD-style license that can be 2 # Use of this source code is governed by a BSD-style license that can be
3 # found in the LICENSE file. 3 # found in the LICENSE file.
4 4
5 import posixpath
6
5 from file_system import FileSystem, FileNotFoundError 7 from file_system import FileSystem, FileNotFoundError
6 from future import Gettable, Future 8 from future import Gettable, Future
7 from test_file_system import TestFileSystem 9 from test_file_system import _List, _StatTracker, TestFileSystem
10 from path_util import IsDirectory
11
8 12
9 class MockFileSystem(FileSystem): 13 class MockFileSystem(FileSystem):
10 '''Wraps FileSystems to add a selection of mock behaviour: 14 '''Wraps FileSystems to add a selection of mock behaviour:
11
12 - asserting how often Stat/Read calls are being made to it. 15 - asserting how often Stat/Read calls are being made to it.
13 - primitive changes/versioning via applying object "diffs", mapping paths to 16 - primitive changes/versioning via applying object "diffs", mapping paths to
14 new content (similar to how TestFileSystem works). 17 new content (similar to how TestFileSystem works).
15 ''' 18 '''
16 def __init__(self, file_system): 19 def __init__(self, file_system):
17 self._file_system = file_system 20 self._file_system = file_system
18 # Updates are modelled are stored as TestFileSystems because they've 21 # Updates are stored as TestFileSystems because it already implements a
19 # implemented a bunch of logic to interpret paths into dictionaries. 22 # bunch of logic to intepret paths into dictionaries.
20 self._updates = [] 23 self._updates = []
24 self._stat_tracker = _StatTracker()
21 self._read_count = 0 25 self._read_count = 0
22 self._read_resolve_count = 0 26 self._read_resolve_count = 0
23 self._stat_count = 0 27 self._stat_count = 0
24 28
25 @staticmethod 29 @staticmethod
26 def Create(file_system, updates): 30 def Create(file_system, updates):
27 mock_file_system = MockFileSystem(file_system) 31 mock_file_system = MockFileSystem(file_system)
28 for update in updates: 32 for update in updates:
29 mock_file_system.Update(update) 33 mock_file_system.Update(update)
30 return mock_file_system 34 return mock_file_system
31 35
32 # 36 #
33 # FileSystem implementation. 37 # FileSystem implementation.
34 # 38 #
35 39
36 def Read(self, paths): 40 def Read(self, paths):
37 '''Reads |paths| from |_file_system|, then applies the most recent update 41 '''Reads |paths| from |_file_system|, then applies the most recent update
38 from |_updates|, if any. 42 from |_updates|, if any.
39 ''' 43 '''
40 self._read_count += 1 44 self._read_count += 1
41 future_result = self._file_system.Read(paths) 45 future_result = self._file_system.Read(paths)
42 def resolve(): 46 def resolve():
43 self._read_resolve_count += 1 47 self._read_resolve_count += 1
44 result = future_result.Get() 48 result = future_result.Get()
45 for path in result.iterkeys(): 49 for path in result.iterkeys():
46 _, update = self._GetMostRecentUpdate(path) 50 update = self._GetMostRecentUpdate(path)
47 if update is not None: 51 if update is not None:
48 result[path] = update 52 result[path] = update
49 return result 53 return result
50 return Future(delegate=Gettable(resolve)) 54 return Future(delegate=Gettable(resolve))
51 55
52 def Refresh(self): 56 def Refresh(self):
53 return self._file_system.Refresh() 57 return self._file_system.Refresh()
54 58
55 def _GetMostRecentUpdate(self, path): 59 def _GetMostRecentUpdate(self, path):
56 for revision, update in reversed(list(enumerate(self._updates))): 60 '''Returns the latest update for the file at |path|, or None if |path|
61 has never been updated.
62 '''
63 for update in reversed(self._updates):
57 try: 64 try:
58 return (revision + 1, update.ReadSingle(path).Get()) 65 return update.ReadSingle(path).Get()
59 except FileNotFoundError: 66 except FileNotFoundError:
60 pass 67 pass
61 return (0, None) 68 return None
62 69
63 def Stat(self, path): 70 def Stat(self, path):
64 self._stat_count += 1 71 self._stat_count += 1
65 return self._StatImpl(path)
66 72
67 def _StatImpl(self, path): 73 # This only supports numeric stat values since we need to add to it. In
68 result = self._file_system.Stat(path) 74 # reality the logic here could just be to randomly mutate the stat values
69 result.version = self._UpdateStat(result.version, path) 75 # every time there's an Update but that's less meaningful for testing.
70 child_versions = result.child_versions 76 def stradd(a, b):
71 if child_versions is not None: 77 return str(int(a) + b)
72 for child_path in child_versions.iterkeys():
73 child_versions[child_path] = self._UpdateStat(
74 child_versions[child_path],
75 '%s%s' % (path, child_path))
76 return result
77 78
78 def _UpdateStat(self, version, path): 79 stat = self._file_system.Stat(path)
79 if not path.endswith('/'): 80 stat.version = stradd(stat.version, self._stat_tracker.GetVersion(path))
80 return str(int(version) + self._GetMostRecentUpdate(path)[0]) 81 if stat.child_versions:
81 # Bleh, it's a directory, need to recursively search all the children. 82 for child_path, child_version in stat.child_versions.iteritems():
82 child_paths = self._file_system.ReadSingle(path).Get() 83 stat.child_versions[child_path] = stradd(
83 if not child_paths: 84 stat.child_versions[child_path],
84 return version 85 self._stat_tracker.GetVersion(posixpath.join(path, child_path)))
85 return str(max([int(version)] + 86
86 [int(self._StatImpl('%s%s' % (path, child_path)).version) 87 return stat
87 for child_path in child_paths]))
88 88
89 def GetIdentity(self): 89 def GetIdentity(self):
90 return self._file_system.GetIdentity() 90 return self._file_system.GetIdentity()
91 91
92 def __str__(self): 92 def __str__(self):
93 return repr(self) 93 return repr(self)
94 94
95 def __repr__(self): 95 def __repr__(self):
96 return 'MockFileSystem(read_count=%s, stat_count=%s, updates=%s)' % ( 96 return 'MockFileSystem(read_count=%s, stat_count=%s, updates=%s)' % (
97 self._read_count, self._stat_count, len(self._updates)) 97 self._read_count, self._stat_count, len(self._updates))
(...skipping 21 matching lines...) Expand all
119 finally: 119 finally:
120 self.Reset() 120 self.Reset()
121 121
122 def Reset(self): 122 def Reset(self):
123 self._read_count = 0 123 self._read_count = 0
124 self._read_resolve_count = 0 124 self._read_resolve_count = 0
125 self._stat_count = 0 125 self._stat_count = 0
126 126
127 def Update(self, update): 127 def Update(self, update):
128 self._updates.append(TestFileSystem(update)) 128 self._updates.append(TestFileSystem(update))
129 for path in _List(update).iterkeys():
130 # Any files (not directories) which changed are now at the version
131 # derived from |_updates|.
132 if not IsDirectory(path):
133 self._stat_tracker.SetVersion(path, len(self._updates))
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698