OLD | NEW |
| (Empty) |
1 #!/usr/bin/env python | |
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. | |
5 | |
6 import unittest | |
7 | |
8 from app_yaml_helper import AppYamlHelper | |
9 from content_providers import IgnoreMissingContentProviders | |
10 from cron_servlet import CronServlet | |
11 from empty_dir_file_system import EmptyDirFileSystem | |
12 from environment import GetAppVersion | |
13 from extensions_paths import ( | |
14 APP_YAML, CONTENT_PROVIDERS, CHROME_EXTENSIONS, PUBLIC_TEMPLATES, SERVER2, | |
15 STATIC_DOCS) | |
16 from fake_fetchers import ConfigureFakeFetchers | |
17 from gcs_file_system_provider import CloudStorageFileSystemProvider | |
18 from github_file_system_provider import GithubFileSystemProvider | |
19 from host_file_system_provider import HostFileSystemProvider | |
20 from local_file_system import LocalFileSystem | |
21 from mock_file_system import MockFileSystem | |
22 from servlet import Request | |
23 from test_branch_utility import TestBranchUtility | |
24 from test_file_system import MoveTo, TestFileSystem | |
25 from test_util import EnableLogging, ReadFile | |
26 | |
27 | |
28 # NOTE(kalman): The ObjectStore created by the CronServlet is backed onto our | |
29 # fake AppEngine memcache/datastore, so the tests aren't isolated. Of course, | |
30 # if the host file systems have different identities, they will be, sort of. | |
31 class _TestDelegate(CronServlet.Delegate): | |
32 def __init__(self, create_file_system): | |
33 self.file_systems = [] | |
34 # A callback taking a commit and returning a file system. | |
35 self._create_file_system = create_file_system | |
36 self._app_version = GetAppVersion() | |
37 | |
38 def CreateBranchUtility(self, object_store_creator): | |
39 return TestBranchUtility.CreateWithCannedData() | |
40 | |
41 def CreateHostFileSystemProvider(self, | |
42 object_store_creator, | |
43 pinned_commit=None): | |
44 def constructor(branch=None, commit=None): | |
45 file_system = self._create_file_system(commit) | |
46 self.file_systems.append(file_system) | |
47 return file_system | |
48 return HostFileSystemProvider(object_store_creator, | |
49 pinned_commit=pinned_commit, | |
50 constructor_for_test=constructor) | |
51 | |
52 def CreateGithubFileSystemProvider(self, object_store_creator): | |
53 return GithubFileSystemProvider.ForEmpty() | |
54 | |
55 def CreateGCSFileSystemProvider(self, object_store_creator): | |
56 return CloudStorageFileSystemProvider.ForEmpty() | |
57 | |
58 def GetAppVersion(self): | |
59 return self._app_version | |
60 | |
61 # (non-Delegate method). | |
62 def SetAppVersion(self, app_version): | |
63 self._app_version = app_version | |
64 | |
65 class CronServletTest(unittest.TestCase): | |
66 @EnableLogging('info') | |
67 def testEverything(self): | |
68 # All these tests are dependent (see above comment) so lump everything in | |
69 # the one test. | |
70 delegate = _TestDelegate(lambda _: MockFileSystem(LocalFileSystem.Create())) | |
71 | |
72 # Test that the cron runs successfully. | |
73 response = CronServlet(Request.ForTest('trunk'), | |
74 delegate_for_test=delegate).Get() | |
75 self.assertEqual(200, response.status) | |
76 | |
77 # Save the file systems created, start with a fresh set for the next run. | |
78 first_run_file_systems = delegate.file_systems[:] | |
79 delegate.file_systems[:] = [] | |
80 | |
81 # When re-running, all file systems should be Stat()d the same number of | |
82 # times, but the second round shouldn't have been re-Read() since the | |
83 # Stats haven't changed. | |
84 response = CronServlet(Request.ForTest('trunk'), | |
85 delegate_for_test=delegate).Get() | |
86 self.assertEqual(200, response.status) | |
87 | |
88 self.assertEqual(len(first_run_file_systems), len(delegate.file_systems)) | |
89 for i, second_run_file_system in enumerate(delegate.file_systems): | |
90 self.assertTrue(*second_run_file_system.CheckAndReset( | |
91 read_count=0, | |
92 stat_count=first_run_file_systems[i].GetStatCount())) | |
93 | |
94 @IgnoreMissingContentProviders | |
95 def testSafeRevision(self): | |
96 test_data = { | |
97 'extensions': { | |
98 'browser': { | |
99 'api': {} | |
100 } | |
101 }, | |
102 'chrome': { | |
103 'browser': { | |
104 'extensions': { | |
105 'OWNERS': '', | |
106 'api': {} | |
107 } | |
108 }, | |
109 'common': { | |
110 'extensions': { | |
111 'api': { | |
112 '_api_features.json': '{}', | |
113 '_manifest_features.json': '{}', | |
114 '_permission_features.json': '{}', | |
115 }, | |
116 'docs': { | |
117 'examples': { | |
118 'examples.txt': 'examples.txt contents' | |
119 }, | |
120 'server2': { | |
121 'app.yaml': AppYamlHelper.GenerateAppYaml('2-0-8') | |
122 }, | |
123 'static': { | |
124 'static.txt': 'static.txt contents' | |
125 }, | |
126 'templates': { | |
127 'articles': { | |
128 'activeTab.html': 'activeTab.html contents' | |
129 }, | |
130 'intros': { | |
131 'browserAction.html': 'activeTab.html contents' | |
132 }, | |
133 'private': { | |
134 'table_of_contents.html': 'table_of_contents.html contents', | |
135 }, | |
136 'public': { | |
137 'apps': { | |
138 'storage.html': '<h1>storage.html</h1> contents' | |
139 }, | |
140 'extensions': { | |
141 'storage.html': '<h1>storage.html</h1> contents' | |
142 }, | |
143 }, | |
144 'json': { | |
145 'chrome_sidenav.json': '{}', | |
146 'content_providers.json': ReadFile(CONTENT_PROVIDERS), | |
147 'manifest.json': '{}', | |
148 'permissions.json': '{}', | |
149 'strings.json': '{}', | |
150 'whats_new.json': '{}', | |
151 }, | |
152 } | |
153 } | |
154 } | |
155 } | |
156 } | |
157 } | |
158 | |
159 updates = [] | |
160 | |
161 def app_yaml_update(version): | |
162 return MoveTo(SERVER2, { | |
163 'app.yaml': AppYamlHelper.GenerateAppYaml(version) | |
164 }) | |
165 def storage_html_update(update): | |
166 return MoveTo(PUBLIC_TEMPLATES, { | |
167 'apps': {'storage.html': update} | |
168 }) | |
169 def static_txt_update(update): | |
170 return MoveTo(STATIC_DOCS, { | |
171 'static.txt': update | |
172 }) | |
173 | |
174 storage_html_path = PUBLIC_TEMPLATES + 'apps/storage.html' | |
175 static_txt_path = STATIC_DOCS + 'static.txt' | |
176 | |
177 def create_file_system(commit=None): | |
178 '''Creates a MockFileSystem at |commit| by applying that many |updates| | |
179 to it. | |
180 ''' | |
181 mock_file_system = MockFileSystem(TestFileSystem(test_data)) | |
182 updates_for_commit = ( | |
183 updates if commit is None else updates[:int(commit)]) | |
184 for update in updates_for_commit: | |
185 mock_file_system.Update(update) | |
186 return mock_file_system | |
187 | |
188 delegate = _TestDelegate(create_file_system) | |
189 delegate.SetAppVersion('2-0-8') | |
190 | |
191 file_systems = delegate.file_systems | |
192 | |
193 # No updates applied yet. | |
194 CronServlet(Request.ForTest('trunk'), delegate_for_test=delegate).Get() | |
195 self.assertEqual(AppYamlHelper.GenerateAppYaml('2-0-8'), | |
196 file_systems[-1].ReadSingle(APP_YAML).Get()) | |
197 self.assertEqual('<h1>storage.html</h1> contents', | |
198 file_systems[-1].ReadSingle(storage_html_path).Get()) | |
199 | |
200 # Apply updates to storage.html. | |
201 updates.append(storage_html_update('interim contents')) | |
202 updates.append(storage_html_update('<h1>new</h1> contents')) | |
203 | |
204 CronServlet(Request.ForTest('trunk'), delegate_for_test=delegate).Get() | |
205 self.assertEqual(AppYamlHelper.GenerateAppYaml('2-0-8'), | |
206 file_systems[-1].ReadSingle(APP_YAML).Get()) | |
207 self.assertEqual('<h1>new</h1> contents', | |
208 file_systems[-1].ReadSingle(storage_html_path).Get()) | |
209 | |
210 # Apply several updates to storage.html and app.yaml. The file system | |
211 # should be pinned at the version before app.yaml changed. | |
212 updates.append(storage_html_update('<h1>stuck here</h1> contents')) | |
213 | |
214 double_update = storage_html_update('<h1>newer</h1> contents') | |
215 double_update.update(app_yaml_update('2-0-10')) | |
216 updates.append(double_update) | |
217 | |
218 updates.append(storage_html_update('never gonna reach here')) | |
219 | |
220 CronServlet(Request.ForTest('trunk'), delegate_for_test=delegate).Get() | |
221 self.assertEqual(AppYamlHelper.GenerateAppYaml('2-0-8'), | |
222 file_systems[-1].ReadSingle(APP_YAML).Get()) | |
223 self.assertEqual('<h1>stuck here</h1> contents', | |
224 file_systems[-1].ReadSingle(storage_html_path).Get()) | |
225 | |
226 # Further pushes to storage.html will keep it pinned. | |
227 updates.append(storage_html_update('<h1>y</h1> u not update!')) | |
228 | |
229 CronServlet(Request.ForTest('trunk'), delegate_for_test=delegate).Get() | |
230 self.assertEqual(AppYamlHelper.GenerateAppYaml('2-0-8'), | |
231 file_systems[-1].ReadSingle(APP_YAML).Get()) | |
232 self.assertEqual('<h1>stuck here</h1> contents', | |
233 file_systems[-1].ReadSingle(storage_html_path).Get()) | |
234 | |
235 # Likewise app.yaml. | |
236 updates.append(app_yaml_update('2-1-0')) | |
237 | |
238 CronServlet(Request.ForTest('trunk'), delegate_for_test=delegate).Get() | |
239 self.assertEqual(AppYamlHelper.GenerateAppYaml('2-0-8'), | |
240 file_systems[-1].ReadSingle(APP_YAML).Get()) | |
241 self.assertEqual('<h1>stuck here</h1> contents', | |
242 file_systems[-1].ReadSingle(storage_html_path).Get()) | |
243 | |
244 # And updates to other content won't happen either. | |
245 updates.append(static_txt_update('important content!')) | |
246 | |
247 CronServlet(Request.ForTest('trunk'), delegate_for_test=delegate).Get() | |
248 self.assertEqual(AppYamlHelper.GenerateAppYaml('2-0-8'), | |
249 file_systems[-1].ReadSingle(APP_YAML).Get()) | |
250 self.assertEqual('<h1>stuck here</h1> contents', | |
251 file_systems[-1].ReadSingle(storage_html_path).Get()) | |
252 self.assertEqual('static.txt contents', | |
253 file_systems[-1].ReadSingle(static_txt_path).Get()) | |
254 | |
255 # Lastly - when the app version changes, everything should no longer be | |
256 # pinned. | |
257 delegate.SetAppVersion('2-1-0') | |
258 CronServlet(Request.ForTest('trunk'), delegate_for_test=delegate).Get() | |
259 self.assertEqual(AppYamlHelper.GenerateAppYaml('2-1-0'), | |
260 file_systems[-1].ReadSingle(APP_YAML).Get()) | |
261 self.assertEqual('<h1>y</h1> u not update!', | |
262 file_systems[-1].ReadSingle(storage_html_path).Get()) | |
263 self.assertEqual('important content!', | |
264 file_systems[-1].ReadSingle(static_txt_path).Get()) | |
265 | |
266 | |
267 if __name__ == '__main__': | |
268 unittest.main() | |
OLD | NEW |