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

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

Issue 82433002: Docserver: Further refactoring to the new GithubFileSystem to make it update (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 7 years, 1 month 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 #!/usr/bin/env python 1 #!/usr/bin/env python
2 # Copyright 2013 The Chromium Authors. All rights reserved. 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 3 # Use of this source code is governed by a BSD-style license that can be
4 # found in the LICENSE file. 4 # found in the LICENSE file.
5 5
6 import json 6 import json
7 from copy import deepcopy
7 from cStringIO import StringIO 8 from cStringIO import StringIO
8 from functools import partial 9 from functools import partial
9 from hashlib import sha1 10 from hashlib import sha1
10 from random import random 11 from random import random
11 import unittest 12 import unittest
12 from zipfile import ZipFile 13 from zipfile import ZipFile
13 14
14 from caching_file_system import CachingFileSystem 15 from caching_file_system import CachingFileSystem
15 from file_system import FileNotFoundError, StatInfo 16 from file_system import FileNotFoundError, StatInfo
16 from fake_url_fetcher import FakeURLFSFetcher, MockURLFetcher 17 from fake_url_fetcher import FakeURLFSFetcher, MockURLFetcher
17 from local_file_system import LocalFileSystem 18 from local_file_system import LocalFileSystem
18 from new_github_file_system import GithubFileSystem 19 from new_github_file_system import GithubFileSystem
19 from object_store_creator import ObjectStoreCreator 20 from object_store_creator import ObjectStoreCreator
20 from test_file_system import TestFileSystem 21 from test_file_system import TestFileSystem
21 from test_util import EnableLogging 22 from test_util import EnableLogging
22 23
23 24
24 def _GenerateFakeHash(): 25 class _TestBundle(object):
25 '''Generates a fake SHA1 hash. 26 '''Bundles test file data with a GithubFileSystem and test utilites. Create
27 GithubFileSystems via |CreateGfs()|, the Fetcher it uses as |fetcher|,
28 randomly mutate its contents via |Mutate()|, and access the underlying zip
29 data via |files|.
26 ''' 30 '''
27 return sha1(str(random())).hexdigest() 31
32 def __init__(self):
33 self.files = {
34 'zipfile/': '',
35 'zipfile/hello.txt': 'world',
36 'zipfile/readme': 'test zip',
37 'zipfile/dir/file1': 'contents',
38 'zipfile/dir/file2': 'more contents'
39 }
40 self._test_files = {
41 'test_owner': {
42 'changing-repo': {
43 'commits': {
44 'HEAD': self._MakeShaJson(self._GenerateHash())
45 },
46 'zipball': self._ZipFromFiles(self.files)
47 }
48 }
49 }
28 50
29 51
30 def _ZipFromFiles(file_dict): 52 def CreateGfsAndFetcher(self):
31 string = StringIO() 53 fetchers = []
32 zipfile = ZipFile(string, 'w') 54 def create_mock_url_fetcher(base_path):
33 for filename, contents in file_dict.iteritems(): 55 assert not fetchers
34 zipfile.writestr(filename, contents) 56 fetchers.append(MockURLFetcher(
35 zipfile.close() 57 FakeURLFSFetcher(TestFileSystem(self._test_files), base_path)))
58 return fetchers[-1]
36 59
37 return string.getvalue() 60 # Constructing |gfs| will create a fetcher.
61 gfs = GithubFileSystem.ForTest(
62 'changing-repo', create_mock_url_fetcher, path='')
63 assert len(fetchers) == 1
64 return gfs, fetchers[0]
65
66 def Mutate(self):
67 fake_version = self._GenerateHash()
68 fake_data = self._GenerateHash()
69 self.files['zipfile/hello.txt'] = fake_data
70 self.files['zipfile/new-file'] = fake_data
71 self.files['zipfile/dir/file1'] = fake_data
72 self._test_files['test_owner']['changing-repo']['zipball'] = (
73 self._ZipFromFiles(self.files))
74 self._test_files['test_owner']['changing-repo']['commits']['HEAD'] = (
75 self._MakeShaJson(fake_version))
76 return fake_version, fake_data
77
78 def _GenerateHash(self):
79 '''Generates an arbitrary SHA1 hash.
80 '''
81 return sha1(str(random())).hexdigest()
82
83 def _MakeShaJson(self, hash_value):
84 commit_json = json.loads(deepcopy(LocalFileSystem('').ReadSingle(
85 'test_data/github_file_system/test_owner/repo/commits/HEAD').Get()))
86 commit_json['sha'] = hash_value
87 return json.dumps(commit_json)
88
89 def _ZipFromFiles(self, file_dict):
90 string = StringIO()
91 zipfile = ZipFile(string, 'w')
92 for filename, contents in file_dict.iteritems():
93 zipfile.writestr(filename, contents)
94 zipfile.close()
95 return string.getvalue()
38 96
39 97
40 class TestGithubFileSystem(unittest.TestCase): 98 class TestGithubFileSystem(unittest.TestCase):
41 def setUp(self): 99 def setUp(self):
42 self._gfs = GithubFileSystem.ForTest( 100 self._gfs = GithubFileSystem.ForTest(
43 'repo', partial(FakeURLFSFetcher, LocalFileSystem(''))) 101 'repo', partial(FakeURLFSFetcher, LocalFileSystem('')))
44 # Start and finish the repository load. 102 # Start and finish the repository load.
45 self._cgfs = CachingFileSystem(self._gfs, ObjectStoreCreator.ForTest()) 103 self._cgfs = CachingFileSystem(self._gfs, ObjectStoreCreator.ForTest())
46 104
47 def testReadDirectory(self): 105 def testReadDirectory(self):
(...skipping 25 matching lines...) Expand all
73 'src/': sorted(['hello.notpy', '__init__.notpy']), 131 'src/': sorted(['hello.notpy', '__init__.notpy']),
74 '': sorted(['requirements.txt', '.gitignore', 'README.md', 'src/']) 132 '': sorted(['requirements.txt', '.gitignore', 'README.md', 'src/'])
75 } 133 }
76 134
77 read = self._gfs.Read(['', 'src/']).Get() 135 read = self._gfs.Read(['', 'src/']).Get()
78 self.assertEqual(expected['src/'], sorted(read['src/'])) 136 self.assertEqual(expected['src/'], sorted(read['src/']))
79 self.assertEqual(expected[''], sorted(read[''])) 137 self.assertEqual(expected[''], sorted(read['']))
80 138
81 def testStat(self): 139 def testStat(self):
82 # This is the hash value from the zip on disk. 140 # This is the hash value from the zip on disk.
83 real_hash = '7becb9f554dec76bd0fc12c1d32dbaff1d134a4d' 141 real_hash = 'c36fc23688a9ec9e264d3182905dc0151bfff7d7'
84 142
85 self._gfs.Refresh().Get() 143 self._gfs.Refresh().Get()
86 dir_stat = StatInfo(real_hash, { 144 dir_stat = StatInfo(real_hash, {
87 'hello.notpy': StatInfo(real_hash), 145 'hello.notpy': StatInfo(real_hash),
88 '__init__.notpy': StatInfo(real_hash) 146 '__init__.notpy': StatInfo(real_hash)
89 }) 147 })
90 148
91 self.assertEqual(StatInfo(real_hash), self._gfs.Stat('README.md')) 149 self.assertEqual(StatInfo(real_hash), self._gfs.Stat('README.md'))
92 self.assertEqual(StatInfo(real_hash), self._gfs.Stat('src/hello.notpy')) 150 self.assertEqual(StatInfo(real_hash), self._gfs.Stat('src/hello.notpy'))
93 self.assertEqual(dir_stat, self._gfs.Stat('src/')) 151 self.assertEqual(dir_stat, self._gfs.Stat('src/'))
(...skipping 23 matching lines...) Expand all
117 initial_cgfs_read_two, 175 initial_cgfs_read_two,
118 self._cgfs.Read(['README.md', 'requirements.txt']).Get()) 176 self._cgfs.Read(['README.md', 'requirements.txt']).Get())
119 177
120 def testWithoutRefresh(self): 178 def testWithoutRefresh(self):
121 # Without refreshing it will still read the content from blobstore, and it 179 # Without refreshing it will still read the content from blobstore, and it
122 # does this via the magic of the FakeURLFSFetcher. 180 # does this via the magic of the FakeURLFSFetcher.
123 self.assertEqual(['__init__.notpy', 'hello.notpy'], 181 self.assertEqual(['__init__.notpy', 'hello.notpy'],
124 sorted(self._gfs.ReadSingle('src/').Get())) 182 sorted(self._gfs.ReadSingle('src/').Get()))
125 183
126 def testRefresh(self): 184 def testRefresh(self):
127 def make_sha_json(hash_value): 185 test_bundle = _TestBundle()
128 from copy import deepcopy 186 gfs, fetcher = test_bundle.CreateGfsAndFetcher()
129 commit_json = json.loads(deepcopy(LocalFileSystem('').ReadSingle(
130 'test_data/github_file_system/test_owner/repo/commits/HEAD').Get()))
131 commit_json['commit']['tree']['sha'] = hash_value
132 return json.dumps(commit_json)
133
134 files = {
135 'zipfile/': '',
136 'zipfile/hello.txt': 'world',
137 'zipfile/readme': 'test zip',
138 'zipfile/dir/file1': 'contents',
139 'zipfile/dir/file2': 'more contents'
140 }
141
142 string = _ZipFromFiles(files)
143
144 test_files = {
145 'test_owner': {
146 'changing-repo': {
147 'commits': {
148 'HEAD': make_sha_json(_GenerateFakeHash())
149 },
150 'zipball': string
151 }
152 }
153 }
154
155 def mutate_file_data():
156 fake_hash = _GenerateFakeHash()
157 files['zipfile/hello.txt'] = fake_hash
158 files['zipfile/new-file'] = fake_hash
159 files['zipfile/dir/file1'] = fake_hash
160 test_files['test_owner']['changing-repo']['zipball'] = _ZipFromFiles(
161 files)
162 test_files['test_owner']['changing-repo']['commits']['HEAD'] = (
163 make_sha_json(fake_hash))
164 return fake_hash, fake_hash
165
166 test_file_system = TestFileSystem(test_files)
167 fetchers = []
168 def create_mock_url_fetcher(base_path):
169 fetchers.append(
170 MockURLFetcher(FakeURLFSFetcher(test_file_system, base_path)))
171 return fetchers[-1]
172 gfs = GithubFileSystem.ForTest(
173 'changing-repo', create_mock_url_fetcher, path='')
174 fetcher = fetchers[0]
175 187
176 # It shouldn't fetch until Refresh does so; then it will do 2, one for the 188 # It shouldn't fetch until Refresh does so; then it will do 2, one for the
177 # stat, and another for the read. 189 # stat, and another for the read.
178 self.assertTrue(*fetcher.CheckAndReset()) 190 self.assertTrue(*fetcher.CheckAndReset())
179 gfs.Refresh().Get() 191 gfs.Refresh().Get()
180 self.assertTrue(*fetcher.CheckAndReset(fetch_count=1, 192 self.assertTrue(*fetcher.CheckAndReset(fetch_count=1,
181 fetch_async_count=1, 193 fetch_async_count=1,
182 fetch_resolve_count=1)) 194 fetch_resolve_count=1))
183 195
184 # Refreshing again will stat but not fetch. 196 # Refresh is just an alias for Read('').
185 gfs.Refresh().Get() 197 gfs.Refresh().Get()
186 self.assertTrue(*fetcher.CheckAndReset(fetch_count=1)) 198 self.assertTrue(*fetcher.CheckAndReset())
187 199
188 initial_dir_read = sorted(gfs.ReadSingle('').Get()) 200 initial_dir_read = sorted(gfs.ReadSingle('').Get())
189 initial_file_read = gfs.ReadSingle('dir/file1').Get() 201 initial_file_read = gfs.ReadSingle('dir/file1').Get()
190 202
191 version, data = mutate_file_data() 203 version, data = test_bundle.Mutate()
192 204
193 # Check that changes have not effected the file system yet. 205 # Check that changes have not effected the file system yet.
194 self.assertEqual(initial_dir_read, sorted(gfs.ReadSingle('').Get())) 206 self.assertEqual(initial_dir_read, sorted(gfs.ReadSingle('').Get()))
195 self.assertEqual(initial_file_read, gfs.ReadSingle('dir/file1').Get()) 207 self.assertEqual(initial_file_read, gfs.ReadSingle('dir/file1').Get())
196 self.assertNotEqual(StatInfo(version), gfs.Stat('')) 208 self.assertNotEqual(StatInfo(version), gfs.Stat(''))
197 209
210 gfs, fetcher = test_bundle.CreateGfsAndFetcher()
198 gfs.Refresh().Get() 211 gfs.Refresh().Get()
199 self.assertTrue(*fetcher.CheckAndReset(fetch_count=1, 212 self.assertTrue(*fetcher.CheckAndReset(fetch_count=1,
200 fetch_async_count=1, 213 fetch_async_count=1,
201 fetch_resolve_count=1)) 214 fetch_resolve_count=1))
202 215
203 # Check that the changes have affected the file system. 216 # Check that the changes have affected the file system.
204 self.assertEqual(data, gfs.ReadSingle('new-file').Get()) 217 self.assertEqual(data, gfs.ReadSingle('new-file').Get())
205 self.assertEqual(files['zipfile/dir/file1'], 218 self.assertEqual(test_bundle.files['zipfile/dir/file1'],
206 gfs.ReadSingle('dir/file1').Get()) 219 gfs.ReadSingle('dir/file1').Get())
207 self.assertEqual(StatInfo(version), gfs.Stat('new-file')) 220 self.assertEqual(StatInfo(version), gfs.Stat('new-file'))
208 221
209 # Regression test: ensure that reading the data after it's been mutated, 222 # Regression test: ensure that reading the data after it's been mutated,
210 # but before Refresh() has been realised, still returns the correct data. 223 # but before Refresh() has been realised, still returns the correct data.
211 version, data = mutate_file_data() 224 gfs, fetcher = test_bundle.CreateGfsAndFetcher()
225 version, data = test_bundle.Mutate()
212 226
213 refresh_future = gfs.Refresh() 227 refresh_future = gfs.Refresh()
214 self.assertTrue(*fetcher.CheckAndReset(fetch_count=1, fetch_async_count=1)) 228 self.assertTrue(*fetcher.CheckAndReset(fetch_count=1, fetch_async_count=1))
215 229
216 self.assertEqual(data, gfs.ReadSingle('new-file').Get()) 230 self.assertEqual(data, gfs.ReadSingle('new-file').Get())
217 self.assertEqual(files['zipfile/dir/file1'], 231 self.assertEqual(test_bundle.files['zipfile/dir/file1'],
218 gfs.ReadSingle('dir/file1').Get()) 232 gfs.ReadSingle('dir/file1').Get())
219 self.assertEqual(StatInfo(version), gfs.Stat('new-file')) 233 self.assertEqual(StatInfo(version), gfs.Stat('new-file'))
220 234
221 refresh_future.Get() 235 refresh_future.Get()
222 self.assertTrue(*fetcher.CheckAndReset(fetch_resolve_count=1)) 236 self.assertTrue(*fetcher.CheckAndReset(fetch_resolve_count=1))
223 237
238 def testGetThenRefreshOnStartup(self):
239 # Regression test: Test that calling Get() but never resolving the future,
240 # then Refresh()ing the data, causes the data to be refreshed.
241 test_bundle = _TestBundle()
242 gfs, fetcher = test_bundle.CreateGfsAndFetcher()
243 self.assertTrue(*fetcher.CheckAndReset())
244
245 # Get a predictable version.
246 version, data = test_bundle.Mutate()
247
248 read_future = gfs.ReadSingle('hello.txt')
249 # Fetch for the Stat(), async-fetch for the Read().
250 self.assertTrue(*fetcher.CheckAndReset(fetch_count=1, fetch_async_count=1))
251
252 refresh_future = gfs.Refresh()
253 self.assertTrue(*fetcher.CheckAndReset())
254
255 self.assertEqual(data, read_future.Get())
256 self.assertTrue(*fetcher.CheckAndReset(fetch_resolve_count=1))
257 self.assertEqual(StatInfo(version), gfs.Stat('hello.txt'))
258 self.assertTrue(*fetcher.CheckAndReset())
259
260 # The fetch will already have been resolved, so resolving the Refresh won't
261 # affect anything.
262 refresh_future.Get()
263 self.assertTrue(*fetcher.CheckAndReset())
264
265 # Read data should not have changed.
266 self.assertEqual(data, gfs.ReadSingle('hello.txt').Get())
267 self.assertEqual(StatInfo(version), gfs.Stat('hello.txt'))
268 self.assertTrue(*fetcher.CheckAndReset())
269
224 270
225 if __name__ == '__main__': 271 if __name__ == '__main__':
226 unittest.main() 272 unittest.main()
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698