| OLD | NEW |
| (Empty) |
| 1 #!/usr/bin/env python | |
| 2 # Copyright (c) 2012 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 copy | |
| 7 import datetime | |
| 8 import hashlib | |
| 9 import os | |
| 10 import posixpath | |
| 11 import subprocess | |
| 12 import sys | |
| 13 import tempfile | |
| 14 import unittest | |
| 15 import urlparse | |
| 16 | |
| 17 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__)) | |
| 18 BUILD_TOOLS_DIR = os.path.dirname(SCRIPT_DIR) | |
| 19 | |
| 20 sys.path.append(BUILD_TOOLS_DIR) | |
| 21 import manifest_util | |
| 22 import update_nacl_manifest | |
| 23 from update_nacl_manifest import CANARY_BUNDLE_NAME | |
| 24 | |
| 25 | |
| 26 HTTPS_BASE_URL = 'https://commondatastorage.googleapis.com' \ | |
| 27 '/nativeclient_mirror/nacl/nacl_sdk/' | |
| 28 | |
| 29 OS_CR = ('cros',) | |
| 30 OS_M = ('mac',) | |
| 31 OS_ML = ('mac', 'linux') | |
| 32 OS_MW = ('mac', 'win') | |
| 33 OS_MLW = ('mac', 'linux', 'win') | |
| 34 POST_STABLE = 'post_stable' | |
| 35 STABLE = 'stable' | |
| 36 BETA = 'beta' | |
| 37 DEV = 'dev' | |
| 38 CANARY = 'canary' | |
| 39 | |
| 40 | |
| 41 def GetArchiveUrl(host_os, version): | |
| 42 basename = 'naclsdk_%s.tar.bz2' % (host_os,) | |
| 43 return urlparse.urljoin(HTTPS_BASE_URL, posixpath.join(version, basename)) | |
| 44 | |
| 45 | |
| 46 def MakeGsUrl(rel_path): | |
| 47 return update_nacl_manifest.GS_BUCKET_PATH + rel_path | |
| 48 | |
| 49 | |
| 50 def GetPathFromGsUrl(url): | |
| 51 assert url.startswith(update_nacl_manifest.GS_BUCKET_PATH) | |
| 52 return url[len(update_nacl_manifest.GS_BUCKET_PATH):] | |
| 53 | |
| 54 | |
| 55 def GetPathFromHttpsUrl(url): | |
| 56 assert url.startswith(HTTPS_BASE_URL) | |
| 57 return url[len(HTTPS_BASE_URL):] | |
| 58 | |
| 59 | |
| 60 def MakeArchive(host_os, version): | |
| 61 archive = manifest_util.Archive(host_os) | |
| 62 archive.url = GetArchiveUrl(host_os, version) | |
| 63 # dummy values that won't succeed if we ever use them, but will pass | |
| 64 # validation. :) | |
| 65 archive.checksum = {'sha1': 'foobar'} | |
| 66 archive.size = 1 | |
| 67 return archive | |
| 68 | |
| 69 | |
| 70 def MakeNonPepperBundle(name, with_archives=False): | |
| 71 bundle = manifest_util.Bundle(name) | |
| 72 bundle.version = 1 | |
| 73 bundle.revision = 1 | |
| 74 bundle.description = 'Dummy bundle' | |
| 75 bundle.recommended = 'yes' | |
| 76 bundle.stability = 'stable' | |
| 77 | |
| 78 if with_archives: | |
| 79 for host_os in OS_MLW: | |
| 80 archive = manifest_util.Archive(host_os) | |
| 81 archive.url = 'http://example.com' | |
| 82 archive.checksum = {'sha1': 'blah'} | |
| 83 archive.size = 2 | |
| 84 bundle.AddArchive(archive) | |
| 85 return bundle | |
| 86 | |
| 87 | |
| 88 def MakeBundle(major_version, revision=0, version=None, host_oses=None, | |
| 89 stability='dev'): | |
| 90 assert (version is None or | |
| 91 version.split('.')[0] == 'trunk' or | |
| 92 version.split('.')[0] == str(major_version)) | |
| 93 if stability == CANARY: | |
| 94 bundle_name = CANARY_BUNDLE_NAME | |
| 95 else: | |
| 96 bundle_name = 'pepper_' + str(major_version) | |
| 97 | |
| 98 bundle = manifest_util.Bundle(bundle_name) | |
| 99 bundle.version = major_version | |
| 100 bundle.revision = revision | |
| 101 bundle.description = 'Chrome %s bundle, revision %s' % (major_version, | |
| 102 revision) | |
| 103 bundle.repath = 'pepper_' + str(major_version) | |
| 104 bundle.recommended = 'no' | |
| 105 bundle.stability = stability | |
| 106 | |
| 107 if host_oses: | |
| 108 for host_os in host_oses: | |
| 109 bundle.AddArchive(MakeArchive(host_os, version)) | |
| 110 return bundle | |
| 111 | |
| 112 | |
| 113 class MakeManifest(manifest_util.SDKManifest): | |
| 114 def __init__(self, *args): | |
| 115 manifest_util.SDKManifest.__init__(self) | |
| 116 | |
| 117 for bundle in args: | |
| 118 self.AddBundle(bundle) | |
| 119 | |
| 120 def AddBundle(self, bundle): | |
| 121 self.MergeBundle(bundle, allow_existing=False) | |
| 122 | |
| 123 | |
| 124 class MakeHistory(object): | |
| 125 def __init__(self): | |
| 126 # used for a dummy timestamp | |
| 127 self.datetime = datetime.datetime.utcnow() | |
| 128 self.history = [] | |
| 129 | |
| 130 def Add(self, host_oses, channel, version): | |
| 131 for host_os in host_oses: | |
| 132 timestamp = self.datetime.strftime('%Y-%m-%d %H:%M:%S.%f') | |
| 133 self.history.append((host_os, channel, version, timestamp)) | |
| 134 self.datetime += datetime.timedelta(0, -3600) # one hour earlier | |
| 135 self.datetime += datetime.timedelta(-1) # one day earlier | |
| 136 | |
| 137 | |
| 138 class MakeFiles(dict): | |
| 139 def AddOnlineManifest(self, manifest_string): | |
| 140 self['naclsdk_manifest2.json'] = manifest_string | |
| 141 | |
| 142 def Add(self, bundle, add_archive_for_os=OS_MLW, add_json_for_os=OS_MLW): | |
| 143 for archive in bundle.GetArchives(): | |
| 144 if not archive.host_os in add_archive_for_os: | |
| 145 continue | |
| 146 | |
| 147 # add a dummy file for each archive | |
| 148 path = GetPathFromHttpsUrl(archive.url) | |
| 149 self[path] = 'My Dummy Archive' | |
| 150 | |
| 151 if archive.host_os in add_json_for_os: | |
| 152 # add .json manifest snippet, it should look like a normal Bundle, but | |
| 153 # only has one archive. | |
| 154 new_bundle = manifest_util.Bundle('') | |
| 155 new_bundle.CopyFrom(bundle) | |
| 156 del new_bundle.archives[:] | |
| 157 new_bundle.AddArchive(archive) | |
| 158 self[path + '.json'] = new_bundle.GetDataAsString() | |
| 159 | |
| 160 | |
| 161 class TestDelegate(update_nacl_manifest.Delegate): | |
| 162 def __init__(self, manifest, history, files, version_mapping): | |
| 163 self.manifest = manifest | |
| 164 self.history = history | |
| 165 self.files = files | |
| 166 self.version_mapping = version_mapping | |
| 167 self.dryrun = 0 | |
| 168 self.called_gsutil_cp = False | |
| 169 | |
| 170 def GetRepoManifest(self): | |
| 171 return self.manifest | |
| 172 | |
| 173 def GetHistory(self): | |
| 174 return self.history | |
| 175 | |
| 176 def GetTrunkRevision(self, version): | |
| 177 return self.version_mapping[version] | |
| 178 | |
| 179 def GsUtil_ls(self, url): | |
| 180 path = GetPathFromGsUrl(url) | |
| 181 result = [] | |
| 182 for filename, _ in self.files.iteritems(): | |
| 183 if filename.startswith(path): | |
| 184 result.append(MakeGsUrl(filename)) | |
| 185 return result | |
| 186 | |
| 187 def GsUtil_cat(self, url): | |
| 188 path = GetPathFromGsUrl(url) | |
| 189 if path not in self.files: | |
| 190 raise subprocess.CalledProcessError(1, 'gsutil cat %s' % (url,)) | |
| 191 return self.files[path] | |
| 192 | |
| 193 def GsUtil_cp(self, src, dest, stdin=None): | |
| 194 self.called_gsutil_cp = True | |
| 195 dest_path = GetPathFromGsUrl(dest) | |
| 196 if src == '-': | |
| 197 self.files[dest_path] = stdin | |
| 198 else: | |
| 199 src_path = GetPathFromGsUrl(src) | |
| 200 if src_path not in self.files: | |
| 201 raise subprocess.CalledProcessError(1, 'gsutil cp %s %s' % (src, dest)) | |
| 202 self.files[dest_path] = self.files[src_path] | |
| 203 | |
| 204 def Print(self, *args): | |
| 205 # eat all informational messages | |
| 206 pass | |
| 207 | |
| 208 | |
| 209 # Shorthand for premade bundles/versions | |
| 210 V18_0_1025_163 = '18.0.1025.163' | |
| 211 V18_0_1025_175 = '18.0.1025.175' | |
| 212 V18_0_1025_184 = '18.0.1025.184' | |
| 213 V19_0_1084_41 = '19.0.1084.41' | |
| 214 V19_0_1084_67 = '19.0.1084.67' | |
| 215 V21_0_1145_0 = '21.0.1145.0' | |
| 216 V21_0_1166_0 = '21.0.1166.0' | |
| 217 VTRUNK_138079 = 'trunk.138079' | |
| 218 B18_0_1025_163_R1_MLW = MakeBundle(18, 1, V18_0_1025_163, OS_MLW) | |
| 219 B18_0_1025_184_R1_MLW = MakeBundle(18, 1, V18_0_1025_184, OS_MLW) | |
| 220 B18_R1_NONE = MakeBundle(18) | |
| 221 B19_0_1084_41_R1_MLW = MakeBundle(19, 1, V19_0_1084_41, OS_MLW) | |
| 222 B19_0_1084_67_R1_MLW = MakeBundle(19, 1, V19_0_1084_67, OS_MLW) | |
| 223 B19_R1_NONE = MakeBundle(19) | |
| 224 BCANARY_R1_NONE = MakeBundle(0, stability=CANARY) | |
| 225 B21_0_1145_0_R1_MLW = MakeBundle(21, 1, V21_0_1145_0, OS_MLW) | |
| 226 B21_0_1166_0_R1_MW = MakeBundle(21, 1, V21_0_1166_0, OS_MW) | |
| 227 BTRUNK_138079_R1_MLW = MakeBundle(21, 1, VTRUNK_138079, OS_MLW) | |
| 228 NON_PEPPER_BUNDLE_NOARCHIVES = MakeNonPepperBundle('foo') | |
| 229 NON_PEPPER_BUNDLE_ARCHIVES = MakeNonPepperBundle('bar', with_archives=True) | |
| 230 | |
| 231 | |
| 232 class TestUpdateManifest(unittest.TestCase): | |
| 233 def setUp(self): | |
| 234 self.history = MakeHistory() | |
| 235 self.files = MakeFiles() | |
| 236 self.version_mapping = {} | |
| 237 self.delegate = None | |
| 238 self.uploaded_manifest = None | |
| 239 self.manifest = None | |
| 240 | |
| 241 def _MakeDelegate(self): | |
| 242 self.delegate = TestDelegate(self.manifest, self.history.history, | |
| 243 self.files, self.version_mapping) | |
| 244 | |
| 245 def _Run(self, host_oses, fixed_bundle_versions=None): | |
| 246 update_nacl_manifest.Run(self.delegate, host_oses, fixed_bundle_versions) | |
| 247 | |
| 248 def _HasUploadedManifest(self): | |
| 249 return 'naclsdk_manifest2.json' in self.files | |
| 250 | |
| 251 def _ReadUploadedManifest(self): | |
| 252 self.uploaded_manifest = manifest_util.SDKManifest() | |
| 253 self.uploaded_manifest.LoadDataFromString( | |
| 254 self.files['naclsdk_manifest2.json']) | |
| 255 | |
| 256 def _AssertUploadedManifestHasBundle(self, bundle, stability): | |
| 257 if stability == CANARY: | |
| 258 bundle_name = CANARY_BUNDLE_NAME | |
| 259 else: | |
| 260 bundle_name = bundle.name | |
| 261 | |
| 262 uploaded_manifest_bundle = self.uploaded_manifest.GetBundle(bundle_name) | |
| 263 # Bundles that we create in the test (and in the manifest snippets) have | |
| 264 # their stability set to "dev". update_nacl_manifest correctly updates it. | |
| 265 # So we have to force the stability of |bundle| so they compare equal. | |
| 266 test_bundle = copy.copy(bundle) | |
| 267 test_bundle.stability = stability | |
| 268 if stability == CANARY: | |
| 269 test_bundle.name = CANARY_BUNDLE_NAME | |
| 270 self.assertEqual(uploaded_manifest_bundle, test_bundle) | |
| 271 | |
| 272 def _AddCsvHistory(self, history): | |
| 273 import csv | |
| 274 import cStringIO | |
| 275 history_stream = cStringIO.StringIO(history) | |
| 276 self.history.history = [(platform, channel, version, date) | |
| 277 for platform, channel, version, date in csv.reader(history_stream)] | |
| 278 | |
| 279 def testNoUpdateNeeded(self): | |
| 280 self.manifest = MakeManifest(B18_0_1025_163_R1_MLW) | |
| 281 self._MakeDelegate() | |
| 282 self._Run(OS_MLW) | |
| 283 self.assertFalse(self._HasUploadedManifest()) | |
| 284 | |
| 285 # Add another bundle, make sure it still doesn't update | |
| 286 self.manifest.AddBundle(B19_0_1084_41_R1_MLW) | |
| 287 self._Run(OS_MLW) | |
| 288 self.assertFalse(self._HasUploadedManifest()) | |
| 289 | |
| 290 def testSimpleUpdate(self): | |
| 291 self.manifest = MakeManifest(B18_R1_NONE) | |
| 292 self.history.Add(OS_MLW, BETA, V18_0_1025_163) | |
| 293 self.files.Add(B18_0_1025_163_R1_MLW) | |
| 294 self._MakeDelegate() | |
| 295 self._Run(OS_MLW) | |
| 296 self._ReadUploadedManifest() | |
| 297 self._AssertUploadedManifestHasBundle(B18_0_1025_163_R1_MLW, BETA) | |
| 298 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1) | |
| 299 | |
| 300 def testOnePlatformHasNewerRelease(self): | |
| 301 self.manifest = MakeManifest(B18_R1_NONE) | |
| 302 self.history.Add(OS_M, BETA, V18_0_1025_175) # Mac has newer version | |
| 303 self.history.Add(OS_MLW, BETA, V18_0_1025_163) | |
| 304 self.files.Add(B18_0_1025_163_R1_MLW) | |
| 305 self._MakeDelegate() | |
| 306 self._Run(OS_MLW) | |
| 307 self._ReadUploadedManifest() | |
| 308 self._AssertUploadedManifestHasBundle(B18_0_1025_163_R1_MLW, BETA) | |
| 309 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1) | |
| 310 | |
| 311 def testMultipleMissingPlatformsInHistory(self): | |
| 312 self.manifest = MakeManifest(B18_R1_NONE) | |
| 313 self.history.Add(OS_ML, BETA, V18_0_1025_184) | |
| 314 self.history.Add(OS_M, BETA, V18_0_1025_175) | |
| 315 self.history.Add(OS_MLW, BETA, V18_0_1025_163) | |
| 316 self.files.Add(B18_0_1025_163_R1_MLW) | |
| 317 self._MakeDelegate() | |
| 318 self._Run(OS_MLW) | |
| 319 self._ReadUploadedManifest() | |
| 320 self._AssertUploadedManifestHasBundle(B18_0_1025_163_R1_MLW, BETA) | |
| 321 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1) | |
| 322 | |
| 323 def testUpdateOnlyOneBundle(self): | |
| 324 self.manifest = MakeManifest(B18_R1_NONE, B19_0_1084_41_R1_MLW) | |
| 325 self.history.Add(OS_MLW, BETA, V18_0_1025_163) | |
| 326 self.files.Add(B18_0_1025_163_R1_MLW) | |
| 327 self._MakeDelegate() | |
| 328 self._Run(OS_MLW) | |
| 329 self._ReadUploadedManifest() | |
| 330 self._AssertUploadedManifestHasBundle(B18_0_1025_163_R1_MLW, BETA) | |
| 331 self._AssertUploadedManifestHasBundle(B19_0_1084_41_R1_MLW, DEV) | |
| 332 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 2) | |
| 333 | |
| 334 def testUpdateTwoBundles(self): | |
| 335 self.manifest = MakeManifest(B18_R1_NONE, B19_R1_NONE) | |
| 336 self.history.Add(OS_MLW, DEV, V19_0_1084_41) | |
| 337 self.history.Add(OS_MLW, BETA, V18_0_1025_163) | |
| 338 self.files.Add(B18_0_1025_163_R1_MLW) | |
| 339 self.files.Add(B19_0_1084_41_R1_MLW) | |
| 340 self._MakeDelegate() | |
| 341 self._Run(OS_MLW) | |
| 342 self._ReadUploadedManifest() | |
| 343 self._AssertUploadedManifestHasBundle(B18_0_1025_163_R1_MLW, BETA) | |
| 344 self._AssertUploadedManifestHasBundle(B19_0_1084_41_R1_MLW, DEV) | |
| 345 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 2) | |
| 346 | |
| 347 def testUpdateWithMissingPlatformsInArchives(self): | |
| 348 self.manifest = MakeManifest(B18_R1_NONE) | |
| 349 self.history.Add(OS_MLW, BETA, V18_0_1025_184) | |
| 350 self.history.Add(OS_MLW, BETA, V18_0_1025_163) | |
| 351 self.files.Add(B18_0_1025_184_R1_MLW, add_archive_for_os=OS_M) | |
| 352 self.files.Add(B18_0_1025_163_R1_MLW) | |
| 353 self._MakeDelegate() | |
| 354 self._Run(OS_MLW) | |
| 355 self._ReadUploadedManifest() | |
| 356 self._AssertUploadedManifestHasBundle(B18_0_1025_163_R1_MLW, BETA) | |
| 357 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1) | |
| 358 | |
| 359 def testUpdateWithMissingManifestSnippets(self): | |
| 360 self.manifest = MakeManifest(B18_R1_NONE) | |
| 361 self.history.Add(OS_MLW, BETA, V18_0_1025_184) | |
| 362 self.history.Add(OS_MLW, BETA, V18_0_1025_163) | |
| 363 self.files.Add(B18_0_1025_184_R1_MLW, add_json_for_os=OS_ML) | |
| 364 self.files.Add(B18_0_1025_163_R1_MLW) | |
| 365 self._MakeDelegate() | |
| 366 self._Run(OS_MLW) | |
| 367 self._ReadUploadedManifest() | |
| 368 self._AssertUploadedManifestHasBundle(B18_0_1025_163_R1_MLW, BETA) | |
| 369 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1) | |
| 370 | |
| 371 def testRecommendedIsStable(self): | |
| 372 for channel in STABLE, BETA, DEV, CANARY: | |
| 373 self.setUp() | |
| 374 bundle = copy.deepcopy(B18_R1_NONE) | |
| 375 self.manifest = MakeManifest(bundle) | |
| 376 self.history.Add(OS_MLW, channel, V18_0_1025_163) | |
| 377 self.files.Add(B18_0_1025_163_R1_MLW) | |
| 378 self._MakeDelegate() | |
| 379 self._Run(OS_MLW) | |
| 380 self._ReadUploadedManifest() | |
| 381 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1) | |
| 382 uploaded_bundle = self.uploaded_manifest.GetBundle('pepper_18') | |
| 383 if channel == STABLE: | |
| 384 self.assertEqual(uploaded_bundle.recommended, 'yes') | |
| 385 else: | |
| 386 self.assertEqual(uploaded_bundle.recommended, 'no') | |
| 387 | |
| 388 def testNoUpdateWithNonPepperBundle(self): | |
| 389 self.manifest = MakeManifest(NON_PEPPER_BUNDLE_NOARCHIVES, | |
| 390 B18_0_1025_163_R1_MLW) | |
| 391 self._MakeDelegate() | |
| 392 self._Run(OS_MLW) | |
| 393 self.assertFalse(self._HasUploadedManifest()) | |
| 394 | |
| 395 def testUpdateWithHistoryWithExtraneousPlatforms(self): | |
| 396 self.manifest = MakeManifest(B18_R1_NONE) | |
| 397 self.history.Add(OS_ML, BETA, V18_0_1025_184) | |
| 398 self.history.Add(OS_CR, BETA, V18_0_1025_184) | |
| 399 self.history.Add(OS_CR, BETA, V18_0_1025_175) | |
| 400 self.history.Add(OS_MLW, BETA, V18_0_1025_163) | |
| 401 self.files.Add(B18_0_1025_163_R1_MLW) | |
| 402 self._MakeDelegate() | |
| 403 self._Run(OS_MLW) | |
| 404 self._ReadUploadedManifest() | |
| 405 self._AssertUploadedManifestHasBundle(B18_0_1025_163_R1_MLW, BETA) | |
| 406 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1) | |
| 407 | |
| 408 def testSnippetWithStringRevisionAndVersion(self): | |
| 409 # This test exists because some manifest snippets were uploaded with | |
| 410 # strings for their revisions and versions. I want to make sure the | |
| 411 # resulting manifest is still consistent with the old format. | |
| 412 self.manifest = MakeManifest(B18_R1_NONE) | |
| 413 self.history.Add(OS_MLW, BETA, V18_0_1025_163) | |
| 414 bundle_string_revision = MakeBundle('18', '1234', V18_0_1025_163, OS_MLW) | |
| 415 self.files.Add(bundle_string_revision) | |
| 416 self._MakeDelegate() | |
| 417 self._Run(OS_MLW) | |
| 418 self._ReadUploadedManifest() | |
| 419 uploaded_bundle = self.uploaded_manifest.GetBundle( | |
| 420 bundle_string_revision.name) | |
| 421 self.assertEqual(uploaded_bundle.revision, 1234) | |
| 422 self.assertEqual(uploaded_bundle.version, 18) | |
| 423 | |
| 424 def testUpdateCanary(self): | |
| 425 # Note that the bundle in naclsdk_manifest2.json will be called | |
| 426 # CANARY_BUNDLE_NAME, whereas the bundle in the manifest "snippet" will be | |
| 427 # called "pepper_21". | |
| 428 canary_bundle = copy.deepcopy(BCANARY_R1_NONE) | |
| 429 self.manifest = MakeManifest(canary_bundle) | |
| 430 self.history.Add(OS_MW, CANARY, V21_0_1145_0) | |
| 431 self.files.Add(B21_0_1145_0_R1_MLW) | |
| 432 self._MakeDelegate() | |
| 433 self._Run(OS_MLW) | |
| 434 self._ReadUploadedManifest() | |
| 435 self._AssertUploadedManifestHasBundle(B21_0_1145_0_R1_MLW, CANARY) | |
| 436 | |
| 437 def testUpdateCanaryUseTrunkArchives(self): | |
| 438 canary_bundle = copy.deepcopy(BCANARY_R1_NONE) | |
| 439 self.manifest = MakeManifest(canary_bundle) | |
| 440 self.history.Add(OS_MW, CANARY, V21_0_1166_0) | |
| 441 self.files.Add(B21_0_1166_0_R1_MW) | |
| 442 self.files.Add(BTRUNK_138079_R1_MLW) | |
| 443 self.version_mapping[V21_0_1166_0] = VTRUNK_138079 | |
| 444 self._MakeDelegate() | |
| 445 self._Run(OS_MLW) | |
| 446 self._ReadUploadedManifest() | |
| 447 | |
| 448 test_bundle = copy.deepcopy(B21_0_1166_0_R1_MW) | |
| 449 test_bundle.AddArchive(BTRUNK_138079_R1_MLW.GetArchive('linux')) | |
| 450 self._AssertUploadedManifestHasBundle(test_bundle, CANARY) | |
| 451 | |
| 452 def testCanaryUseOnlyTrunkArchives(self): | |
| 453 self.manifest = MakeManifest(copy.deepcopy(BCANARY_R1_NONE)) | |
| 454 history = """win,canary,21.0.1163.0,2012-06-04 12:35:44.784446 | |
| 455 mac,canary,21.0.1163.0,2012-06-04 11:54:09.433166""" | |
| 456 self._AddCsvHistory(history) | |
| 457 self.version_mapping['21.0.1163.0'] = 'trunk.140240' | |
| 458 my_bundle = MakeBundle(21, 140240, '21.0.1163.0', OS_MLW) | |
| 459 self.files.Add(my_bundle) | |
| 460 self._MakeDelegate() | |
| 461 self._Run(OS_MLW) | |
| 462 self._ReadUploadedManifest() | |
| 463 self._AssertUploadedManifestHasBundle(my_bundle, CANARY) | |
| 464 | |
| 465 def testCanaryShouldOnlyUseCanaryVersions(self): | |
| 466 canary_bundle = copy.deepcopy(BCANARY_R1_NONE) | |
| 467 self.manifest = MakeManifest(canary_bundle) | |
| 468 self.history.Add(OS_MW, CANARY, V21_0_1166_0) | |
| 469 self.history.Add(OS_MW, BETA, V19_0_1084_41) | |
| 470 self.files.Add(B19_0_1084_41_R1_MLW) | |
| 471 self.version_mapping[V21_0_1166_0] = VTRUNK_138079 | |
| 472 self._MakeDelegate() | |
| 473 self.assertRaises(Exception, self._Run, OS_MLW) | |
| 474 | |
| 475 def testMissingCanaryFollowedByStableShouldWork(self): | |
| 476 history = """win,canary,21.0.1160.0,2012-06-01 19:44:35.936109 | |
| 477 mac,canary,21.0.1160.0,2012-06-01 18:20:02.003123 | |
| 478 mac,stable,19.0.1084.52,2012-06-01 17:59:21.559710 | |
| 479 win,canary,21.0.1159.2,2012-06-01 02:31:43.877688 | |
| 480 mac,stable,19.0.1084.53,2012-06-01 01:39:57.549149 | |
| 481 win,canary,21.0.1158.0,2012-05-31 20:16:55.615236 | |
| 482 win,canary,21.0.1157.0,2012-05-31 17:41:29.516013 | |
| 483 mac,canary,21.0.1158.0,2012-05-31 17:41:27.591354 | |
| 484 mac,beta,20.0.1132.21,2012-05-30 23:45:38.535586 | |
| 485 linux,beta,20.0.1132.21,2012-05-30 23:45:37.025015 | |
| 486 cf,beta,20.0.1132.21,2012-05-30 23:45:36.767529 | |
| 487 win,beta,20.0.1132.21,2012-05-30 23:44:56.675123 | |
| 488 win,canary,21.0.1156.1,2012-05-30 22:28:01.872056 | |
| 489 mac,canary,21.0.1156.1,2012-05-30 21:20:29.920390 | |
| 490 win,canary,21.0.1156.0,2012-05-30 12:46:48.046627 | |
| 491 mac,canary,21.0.1156.0,2012-05-30 12:14:21.305090""" | |
| 492 self.manifest = MakeManifest(copy.deepcopy(BCANARY_R1_NONE)) | |
| 493 self._AddCsvHistory(history) | |
| 494 self.version_mapping = { | |
| 495 '21.0.1160.0': 'trunk.139984', | |
| 496 '21.0.1159.2': 'trunk.139890', | |
| 497 '21.0.1158.0': 'trunk.139740', | |
| 498 '21.0.1157.0': 'unknown', | |
| 499 '21.0.1156.1': 'trunk.139576', | |
| 500 '21.0.1156.0': 'trunk.139984'} | |
| 501 self.files.Add(MakeBundle(21, 139890, '21.0.1159.2', OS_MLW)) | |
| 502 self.files.Add(MakeBundle(21, 0, '21.0.1157.1', ('linux', 'win'))) | |
| 503 my_bundle = MakeBundle(21, 139576, '21.0.1156.1', OS_MLW) | |
| 504 self.files.Add(my_bundle) | |
| 505 self._MakeDelegate() | |
| 506 self._Run(OS_MLW) | |
| 507 self._ReadUploadedManifest() | |
| 508 self._AssertUploadedManifestHasBundle(my_bundle, CANARY) | |
| 509 | |
| 510 def testExtensionWorksAsBz2(self): | |
| 511 # Allow old bundles with just .bz2 extension to work | |
| 512 self.manifest = MakeManifest(B18_R1_NONE) | |
| 513 self.history.Add(OS_MLW, BETA, V18_0_1025_163) | |
| 514 bundle = copy.deepcopy(B18_0_1025_163_R1_MLW) | |
| 515 archive_url = bundle.GetArchive('mac').url | |
| 516 bundle.GetArchive('mac').url = archive_url.replace('.tar', '') | |
| 517 self.files.Add(bundle) | |
| 518 self._MakeDelegate() | |
| 519 self._Run(OS_MLW) | |
| 520 self._ReadUploadedManifest() | |
| 521 self._AssertUploadedManifestHasBundle(bundle, BETA) | |
| 522 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1) | |
| 523 | |
| 524 def testOnlyOneStableBundle(self): | |
| 525 self.manifest = MakeManifest(B18_R1_NONE, B19_R1_NONE) | |
| 526 self.history.Add(OS_MLW, STABLE, V18_0_1025_163) | |
| 527 self.history.Add(OS_MLW, STABLE, V19_0_1084_41) | |
| 528 self.files.Add(B18_0_1025_163_R1_MLW) | |
| 529 self.files.Add(B19_0_1084_41_R1_MLW) | |
| 530 self._MakeDelegate() | |
| 531 self._Run(OS_MLW) | |
| 532 self._ReadUploadedManifest() | |
| 533 p18_bundle = self.uploaded_manifest.GetBundle(B18_R1_NONE.name) | |
| 534 self.assertEqual(p18_bundle.stability, POST_STABLE) | |
| 535 p19_bundle = self.uploaded_manifest.GetBundle(B19_R1_NONE.name) | |
| 536 self.assertEqual(p19_bundle.stability, STABLE) | |
| 537 | |
| 538 def testDontPushIfNoChange(self): | |
| 539 # Make an online manifest that already has this bundle. | |
| 540 online_manifest = MakeManifest(B18_0_1025_163_R1_MLW) | |
| 541 self.files.AddOnlineManifest(online_manifest.GetDataAsString()) | |
| 542 | |
| 543 self.manifest = MakeManifest(B18_R1_NONE) | |
| 544 self.history.Add(OS_MLW, DEV, V18_0_1025_163) | |
| 545 self.files.Add(B18_0_1025_163_R1_MLW) | |
| 546 | |
| 547 self._MakeDelegate() | |
| 548 self._Run(OS_MLW) | |
| 549 self.assertFalse(self.delegate.called_gsutil_cp) | |
| 550 | |
| 551 def testDontPushIfRollback(self): | |
| 552 # Make an online manifest that has a newer bundle | |
| 553 online_manifest = MakeManifest(B18_0_1025_184_R1_MLW) | |
| 554 self.files.AddOnlineManifest(online_manifest.GetDataAsString()) | |
| 555 | |
| 556 self.manifest = MakeManifest(B18_R1_NONE) | |
| 557 self.history.Add(OS_MLW, DEV, V18_0_1025_163) | |
| 558 self.files.Add(B18_0_1025_163_R1_MLW) | |
| 559 | |
| 560 self._MakeDelegate() | |
| 561 self._Run(OS_MLW) | |
| 562 self.assertFalse(self.delegate.called_gsutil_cp) | |
| 563 | |
| 564 def testRunWithFixedBundleVersions(self): | |
| 565 self.manifest = MakeManifest(B18_R1_NONE) | |
| 566 self.history.Add(OS_MLW, BETA, V18_0_1025_163) | |
| 567 self.files.Add(B18_0_1025_163_R1_MLW) | |
| 568 self.files.Add(B18_0_1025_184_R1_MLW) | |
| 569 | |
| 570 self._MakeDelegate() | |
| 571 self._Run(OS_MLW, [('pepper_18', '18.0.1025.184')]) | |
| 572 self._ReadUploadedManifest() | |
| 573 self._AssertUploadedManifestHasBundle(B18_0_1025_184_R1_MLW, BETA) | |
| 574 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1) | |
| 575 | |
| 576 def testRunWithMissingFixedBundleVersions(self): | |
| 577 self.manifest = MakeManifest(B18_R1_NONE) | |
| 578 self.history.Add(OS_MLW, BETA, V18_0_1025_163) | |
| 579 self.files.Add(B18_0_1025_163_R1_MLW) | |
| 580 | |
| 581 self._MakeDelegate() | |
| 582 self._Run(OS_MLW, [('pepper_18', '18.0.1025.184')]) | |
| 583 # Nothing should be uploaded if the user gives a missing fixed version. | |
| 584 self.assertFalse(self.delegate.called_gsutil_cp) | |
| 585 | |
| 586 | |
| 587 class TestUpdateVitals(unittest.TestCase): | |
| 588 def setUp(self): | |
| 589 f = tempfile.NamedTemporaryFile('w', prefix="test_update_nacl_manifest") | |
| 590 self.test_file = f.name | |
| 591 f.close() | |
| 592 test_data = "Some test data" | |
| 593 self.sha1 = hashlib.sha1(test_data).hexdigest() | |
| 594 self.data_len = len(test_data) | |
| 595 with open(self.test_file, 'w') as f: | |
| 596 f.write(test_data) | |
| 597 | |
| 598 def tearDown(self): | |
| 599 os.remove(self.test_file) | |
| 600 | |
| 601 def testUpdateVitals(self): | |
| 602 archive = manifest_util.Archive(manifest_util.GetHostOS()) | |
| 603 path = os.path.abspath(self.test_file) | |
| 604 if sys.platform == 'win32': | |
| 605 # On Windows, the path must start with three slashes, i.e. | |
| 606 # (file:///C:\whatever) | |
| 607 path = '/' + path | |
| 608 archive.url = 'file://' + path | |
| 609 | |
| 610 bundle = MakeBundle(18) | |
| 611 bundle.AddArchive(archive) | |
| 612 manifest = MakeManifest(bundle) | |
| 613 archive = manifest.GetBundles()[0]['archives'][0] | |
| 614 | |
| 615 self.assertTrue('size' not in archive) | |
| 616 self.assertTrue('checksum' not in archive) | |
| 617 self.assertRaises(manifest_util.Error, manifest.Validate) | |
| 618 | |
| 619 manifest.Validate(add_missing_info=True) | |
| 620 | |
| 621 self.assertEqual(archive['size'], self.data_len) | |
| 622 self.assertEqual(archive['checksum']['sha1'], self.sha1) | |
| 623 | |
| 624 | |
| 625 class TestRealDelegate(unittest.TestCase): | |
| 626 def setUp(self): | |
| 627 self.delegate = update_nacl_manifest.RealDelegate() | |
| 628 | |
| 629 def testGetTrunkRevision(self): | |
| 630 revision_dict = { | |
| 631 '21.0.1180.80': '151582', | |
| 632 '23.0.1271.89': '167132', | |
| 633 '24.0.1305.4': '164971', | |
| 634 } | |
| 635 for version, revision in revision_dict.iteritems(): | |
| 636 self.assertEqual('trunk.%s' % revision, | |
| 637 self.delegate.GetTrunkRevision(version)) | |
| 638 | |
| 639 | |
| 640 if __name__ == '__main__': | |
| 641 sys.exit(unittest.main()) | |
| OLD | NEW |