| 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 |