Index: chrome/common/extensions/docs/server2/new_github_file_system_test.py |
diff --git a/chrome/common/extensions/docs/server2/new_github_file_system_test.py b/chrome/common/extensions/docs/server2/new_github_file_system_test.py |
index f6c3c5dd60af6f0efdf43cbe8c1c7823c380ba57..3f0ae42237b347793a2173712ffe524f05d04908 100755 |
--- a/chrome/common/extensions/docs/server2/new_github_file_system_test.py |
+++ b/chrome/common/extensions/docs/server2/new_github_file_system_test.py |
@@ -4,6 +4,7 @@ |
# found in the LICENSE file. |
import json |
+from copy import deepcopy |
from cStringIO import StringIO |
from functools import partial |
from hashlib import sha1 |
@@ -21,20 +22,77 @@ from test_file_system import TestFileSystem |
from test_util import EnableLogging |
-def _GenerateFakeHash(): |
- '''Generates a fake SHA1 hash. |
+class _TestBundle(object): |
+ '''Bundles test file data with a GithubFileSystem and test utilites. Create |
+ GithubFileSystems via |CreateGfs()|, the Fetcher it uses as |fetcher|, |
+ randomly mutate its contents via |Mutate()|, and access the underlying zip |
+ data via |files|. |
''' |
- return sha1(str(random())).hexdigest() |
+ def __init__(self): |
+ self.files = { |
+ 'zipfile/': '', |
+ 'zipfile/hello.txt': 'world', |
+ 'zipfile/readme': 'test zip', |
+ 'zipfile/dir/file1': 'contents', |
+ 'zipfile/dir/file2': 'more contents' |
+ } |
+ self._test_files = { |
+ 'test_owner': { |
+ 'changing-repo': { |
+ 'commits': { |
+ 'HEAD': self._MakeShaJson(self._GenerateHash()) |
+ }, |
+ 'zipball': self._ZipFromFiles(self.files) |
+ } |
+ } |
+ } |
-def _ZipFromFiles(file_dict): |
- string = StringIO() |
- zipfile = ZipFile(string, 'w') |
- for filename, contents in file_dict.iteritems(): |
- zipfile.writestr(filename, contents) |
- zipfile.close() |
- return string.getvalue() |
+ def CreateGfsAndFetcher(self): |
+ fetchers = [] |
+ def create_mock_url_fetcher(base_path): |
+ assert not fetchers |
+ fetchers.append(MockURLFetcher( |
+ FakeURLFSFetcher(TestFileSystem(self._test_files), base_path))) |
+ return fetchers[-1] |
+ |
+ # Constructing |gfs| will create a fetcher. |
+ gfs = GithubFileSystem.ForTest( |
+ 'changing-repo', create_mock_url_fetcher, path='') |
+ assert len(fetchers) == 1 |
+ return gfs, fetchers[0] |
+ |
+ def Mutate(self): |
+ fake_version = self._GenerateHash() |
+ fake_data = self._GenerateHash() |
+ self.files['zipfile/hello.txt'] = fake_data |
+ self.files['zipfile/new-file'] = fake_data |
+ self.files['zipfile/dir/file1'] = fake_data |
+ self._test_files['test_owner']['changing-repo']['zipball'] = ( |
+ self._ZipFromFiles(self.files)) |
+ self._test_files['test_owner']['changing-repo']['commits']['HEAD'] = ( |
+ self._MakeShaJson(fake_version)) |
+ return fake_version, fake_data |
+ |
+ def _GenerateHash(self): |
+ '''Generates an arbitrary SHA1 hash. |
+ ''' |
+ return sha1(str(random())).hexdigest() |
+ |
+ def _MakeShaJson(self, hash_value): |
+ commit_json = json.loads(deepcopy(LocalFileSystem('').ReadSingle( |
+ 'test_data/github_file_system/test_owner/repo/commits/HEAD').Get())) |
+ commit_json['sha'] = hash_value |
+ return json.dumps(commit_json) |
+ |
+ def _ZipFromFiles(self, file_dict): |
+ string = StringIO() |
+ zipfile = ZipFile(string, 'w') |
+ for filename, contents in file_dict.iteritems(): |
+ zipfile.writestr(filename, contents) |
+ zipfile.close() |
+ return string.getvalue() |
class TestGithubFileSystem(unittest.TestCase): |
@@ -80,7 +138,7 @@ class TestGithubFileSystem(unittest.TestCase): |
def testStat(self): |
# This is the hash value from the zip on disk. |
- real_hash = '7becb9f554dec76bd0fc12c1d32dbaff1d134a4d' |
+ real_hash = 'c36fc23688a9ec9e264d3182905dc0151bfff7d7' |
self._gfs.Refresh().Get() |
dir_stat = StatInfo(real_hash, { |
@@ -124,54 +182,8 @@ class TestGithubFileSystem(unittest.TestCase): |
sorted(self._gfs.ReadSingle('src/').Get())) |
def testRefresh(self): |
- def make_sha_json(hash_value): |
- from copy import deepcopy |
- commit_json = json.loads(deepcopy(LocalFileSystem('').ReadSingle( |
- 'test_data/github_file_system/test_owner/repo/commits/HEAD').Get())) |
- commit_json['commit']['tree']['sha'] = hash_value |
- return json.dumps(commit_json) |
- |
- files = { |
- 'zipfile/': '', |
- 'zipfile/hello.txt': 'world', |
- 'zipfile/readme': 'test zip', |
- 'zipfile/dir/file1': 'contents', |
- 'zipfile/dir/file2': 'more contents' |
- } |
- |
- string = _ZipFromFiles(files) |
- |
- test_files = { |
- 'test_owner': { |
- 'changing-repo': { |
- 'commits': { |
- 'HEAD': make_sha_json(_GenerateFakeHash()) |
- }, |
- 'zipball': string |
- } |
- } |
- } |
- |
- def mutate_file_data(): |
- fake_hash = _GenerateFakeHash() |
- files['zipfile/hello.txt'] = fake_hash |
- files['zipfile/new-file'] = fake_hash |
- files['zipfile/dir/file1'] = fake_hash |
- test_files['test_owner']['changing-repo']['zipball'] = _ZipFromFiles( |
- files) |
- test_files['test_owner']['changing-repo']['commits']['HEAD'] = ( |
- make_sha_json(fake_hash)) |
- return fake_hash, fake_hash |
- |
- test_file_system = TestFileSystem(test_files) |
- fetchers = [] |
- def create_mock_url_fetcher(base_path): |
- fetchers.append( |
- MockURLFetcher(FakeURLFSFetcher(test_file_system, base_path))) |
- return fetchers[-1] |
- gfs = GithubFileSystem.ForTest( |
- 'changing-repo', create_mock_url_fetcher, path='') |
- fetcher = fetchers[0] |
+ test_bundle = _TestBundle() |
+ gfs, fetcher = test_bundle.CreateGfsAndFetcher() |
# It shouldn't fetch until Refresh does so; then it will do 2, one for the |
# stat, and another for the read. |
@@ -181,20 +193,21 @@ class TestGithubFileSystem(unittest.TestCase): |
fetch_async_count=1, |
fetch_resolve_count=1)) |
- # Refreshing again will stat but not fetch. |
+ # Refresh is just an alias for Read(''). |
gfs.Refresh().Get() |
- self.assertTrue(*fetcher.CheckAndReset(fetch_count=1)) |
+ self.assertTrue(*fetcher.CheckAndReset()) |
initial_dir_read = sorted(gfs.ReadSingle('').Get()) |
initial_file_read = gfs.ReadSingle('dir/file1').Get() |
- version, data = mutate_file_data() |
+ version, data = test_bundle.Mutate() |
# Check that changes have not effected the file system yet. |
self.assertEqual(initial_dir_read, sorted(gfs.ReadSingle('').Get())) |
self.assertEqual(initial_file_read, gfs.ReadSingle('dir/file1').Get()) |
self.assertNotEqual(StatInfo(version), gfs.Stat('')) |
+ gfs, fetcher = test_bundle.CreateGfsAndFetcher() |
gfs.Refresh().Get() |
self.assertTrue(*fetcher.CheckAndReset(fetch_count=1, |
fetch_async_count=1, |
@@ -202,25 +215,58 @@ class TestGithubFileSystem(unittest.TestCase): |
# Check that the changes have affected the file system. |
self.assertEqual(data, gfs.ReadSingle('new-file').Get()) |
- self.assertEqual(files['zipfile/dir/file1'], |
+ self.assertEqual(test_bundle.files['zipfile/dir/file1'], |
gfs.ReadSingle('dir/file1').Get()) |
self.assertEqual(StatInfo(version), gfs.Stat('new-file')) |
# Regression test: ensure that reading the data after it's been mutated, |
# but before Refresh() has been realised, still returns the correct data. |
- version, data = mutate_file_data() |
+ gfs, fetcher = test_bundle.CreateGfsAndFetcher() |
+ version, data = test_bundle.Mutate() |
refresh_future = gfs.Refresh() |
self.assertTrue(*fetcher.CheckAndReset(fetch_count=1, fetch_async_count=1)) |
self.assertEqual(data, gfs.ReadSingle('new-file').Get()) |
- self.assertEqual(files['zipfile/dir/file1'], |
+ self.assertEqual(test_bundle.files['zipfile/dir/file1'], |
gfs.ReadSingle('dir/file1').Get()) |
self.assertEqual(StatInfo(version), gfs.Stat('new-file')) |
refresh_future.Get() |
self.assertTrue(*fetcher.CheckAndReset(fetch_resolve_count=1)) |
+ def testGetThenRefreshOnStartup(self): |
+ # Regression test: Test that calling Get() but never resolving the future, |
+ # then Refresh()ing the data, causes the data to be refreshed. |
+ test_bundle = _TestBundle() |
+ gfs, fetcher = test_bundle.CreateGfsAndFetcher() |
+ self.assertTrue(*fetcher.CheckAndReset()) |
+ |
+ # Get a predictable version. |
+ version, data = test_bundle.Mutate() |
+ |
+ read_future = gfs.ReadSingle('hello.txt') |
+ # Fetch for the Stat(), async-fetch for the Read(). |
+ self.assertTrue(*fetcher.CheckAndReset(fetch_count=1, fetch_async_count=1)) |
+ |
+ refresh_future = gfs.Refresh() |
+ self.assertTrue(*fetcher.CheckAndReset()) |
+ |
+ self.assertEqual(data, read_future.Get()) |
+ self.assertTrue(*fetcher.CheckAndReset(fetch_resolve_count=1)) |
+ self.assertEqual(StatInfo(version), gfs.Stat('hello.txt')) |
+ self.assertTrue(*fetcher.CheckAndReset()) |
+ |
+ # The fetch will already have been resolved, so resolving the Refresh won't |
+ # affect anything. |
+ refresh_future.Get() |
+ self.assertTrue(*fetcher.CheckAndReset()) |
+ |
+ # Read data should not have changed. |
+ self.assertEqual(data, gfs.ReadSingle('hello.txt').Get()) |
+ self.assertEqual(StatInfo(version), gfs.Stat('hello.txt')) |
+ self.assertTrue(*fetcher.CheckAndReset()) |
+ |
if __name__ == '__main__': |
unittest.main() |