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.
18 SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
19 BUILD_TOOLS_DIR = os.path.dirname(SCRIPT_DIR)
21 sys.path.append(BUILD_TOOLS_DIR)
23 import update_nacl_manifest
24 from update_nacl_manifest import CANARY_BUNDLE_NAME
27 HTTPS_BASE_URL = 'https://commondatastorage.googleapis.com' \
28 '/nativeclient_mirror/nacl/nacl_sdk/'
32 OS_ML = ('mac', 'linux')
33 OS_MW = ('mac', 'win')
34 OS_LW = ('linux', 'win')
35 OS_MLW = ('mac', 'linux', 'win')
37 POST_STABLE = 'post_stable'
44 def GetArchiveURL(basename, version):
45 return urlparse.urljoin(HTTPS_BASE_URL, posixpath.join(version, basename))
48 def GetPlatformArchiveUrl(host_os, version):
49 basename = 'naclsdk_%s.tar.bz2' % (host_os,)
50 return GetArchiveURL(basename, version)
53 def MakeGsUrl(rel_path):
54 return update_nacl_manifest.GS_BUCKET_PATH + rel_path
57 def GetPathFromGsUrl(url):
58 assert url.startswith(update_nacl_manifest.GS_BUCKET_PATH)
59 return url[len(update_nacl_manifest.GS_BUCKET_PATH):]
62 def GetPathFromHttpsUrl(url):
63 assert url.startswith(HTTPS_BASE_URL)
64 return url[len(HTTPS_BASE_URL):]
67 def MakeArchive(url, host_os):
68 archive = manifest_util.Archive(host_os)
70 # dummy values that won't succeed if we ever use them, but will pass
72 archive.checksum = {'sha1': 'foobar'}
77 def MakePlatformArchive(host_os, version):
78 return MakeArchive(GetPlatformArchiveUrl(host_os, version), host_os)
81 def MakeNonPlatformArchive(basename, version):
82 return MakeArchive(GetArchiveURL(basename, version), 'all')
85 def MakeNonPepperBundle(name, with_archives=False):
86 bundle = manifest_util.Bundle(name)
89 bundle.description = 'Dummy bundle'
90 bundle.recommended = 'yes'
91 bundle.stability = 'stable'
94 for host_os in OS_MLW:
95 archive = manifest_util.Archive(host_os)
96 archive.url = 'http://example.com'
97 archive.checksum = {'sha1': 'blah'}
99 bundle.AddArchive(archive)
103 def MakePepperBundle(major_version, revision=0, version=None, stability='dev'):
104 assert (version is None or
105 version.split('.')[0] == 'trunk' or
106 version.split('.')[0] == str(major_version))
107 if stability == CANARY:
108 bundle_name = CANARY_BUNDLE_NAME
110 bundle_name = 'pepper_' + str(major_version)
112 bundle = manifest_util.Bundle(bundle_name)
113 bundle.version = major_version
114 bundle.revision = revision
115 bundle.description = 'Chrome %s bundle, revision %s' % (major_version,
117 bundle.repath = 'pepper_' + str(major_version)
118 bundle.recommended = 'no'
119 bundle.stability = stability
124 def MakePlatformBundle(major_version, revision=0, version=None, host_oses=None,
126 bundle = MakePepperBundle(major_version, revision, version, stability)
129 for host_os in host_oses:
130 bundle.AddArchive(MakePlatformArchive(host_os, version))
135 class MakeManifest(manifest_util.SDKManifest):
136 def __init__(self, *args):
137 manifest_util.SDKManifest.__init__(self)
140 self.AddBundle(bundle)
142 def AddBundle(self, bundle):
143 self.MergeBundle(bundle, allow_existing=False)
146 class MakeHistory(object):
148 # used for a dummy timestamp
149 self.datetime = datetime.datetime.utcnow()
152 def Add(self, host_oses, channel, version):
153 for host_os in host_oses:
154 timestamp = self.datetime.strftime('%Y-%m-%d %H:%M:%S.%f')
155 self.history.append((host_os, channel, version, timestamp))
156 self.datetime += datetime.timedelta(0, -3600) # one hour earlier
157 self.datetime += datetime.timedelta(-1) # one day earlier
160 class MakeFiles(dict):
161 def AddOnlineManifest(self, manifest_string):
162 self['naclsdk_manifest2.json'] = manifest_string
164 def Add(self, bundle, add_archive_for_os=OS_MLW, add_json_for_os=OS_MLW):
165 for archive in bundle.GetArchives():
166 if not archive.host_os in add_archive_for_os:
169 self.AddArchive(bundle, archive, archive.host_os in add_json_for_os)
171 def AddArchive(self, bundle, archive, add_json=True):
172 path = GetPathFromHttpsUrl(archive.url)
173 self[path] = 'My Dummy archive'
176 # add .json manifest snippet, it should look like a normal Bundle, but
177 # only has one archive.
178 new_bundle = manifest_util.Bundle('')
179 new_bundle.CopyFrom(bundle)
180 del new_bundle.archives[:]
181 new_bundle.AddArchive(archive)
182 self[path + '.json'] = new_bundle.GetDataAsString()
185 class TestDelegate(update_nacl_manifest.Delegate):
186 def __init__(self, manifest, history, files, version_mapping):
187 self.manifest = manifest
188 self.history = history
190 self.version_mapping = version_mapping
192 self.called_gsutil_cp = False
193 self.called_sendmail = False
195 def GetRepoManifest(self):
198 def GetHistory(self):
201 def GetTrunkRevision(self, version):
202 return self.version_mapping[version]
204 def GsUtil_ls(self, url):
205 path = GetPathFromGsUrl(url)
207 for filename, _ in self.files.iteritems():
208 if filename.startswith(path):
209 result.append(MakeGsUrl(filename))
212 def GsUtil_cat(self, url):
213 path = GetPathFromGsUrl(url)
214 if path not in self.files:
215 raise subprocess.CalledProcessError(1, 'gsutil cat %s' % (url,))
216 return self.files[path]
218 def GsUtil_cp(self, src, dest, stdin=None):
219 self.called_gsutil_cp = True
220 dest_path = GetPathFromGsUrl(dest)
222 self.files[dest_path] = stdin
224 src_path = GetPathFromGsUrl(src)
225 if src_path not in self.files:
226 raise subprocess.CalledProcessError(1, 'gsutil cp %s %s' % (src, dest))
227 self.files[dest_path] = self.files[src_path]
229 def SendMail(self, subject, text):
230 self.called_sendmail = True
233 # Shorthand for premade bundles/versions
234 V18_0_1025_163 = '18.0.1025.163'
235 V18_0_1025_175 = '18.0.1025.175'
236 V18_0_1025_184 = '18.0.1025.184'
237 V19_0_1084_41 = '19.0.1084.41'
238 V19_0_1084_67 = '19.0.1084.67'
239 V21_0_1145_0 = '21.0.1145.0'
240 V21_0_1166_0 = '21.0.1166.0'
241 V26_0_1386_0 = '26.0.1386.0'
242 V26_0_1386_1 = '26.0.1386.1'
243 VTRUNK_140819 = 'trunk.140819'
244 B18_0_1025_163_MLW = MakePlatformBundle(18, 132135, V18_0_1025_163, OS_MLW)
245 B18_0_1025_184_MLW = MakePlatformBundle(18, 134900, V18_0_1025_184, OS_MLW)
246 B18_NONE = MakePlatformBundle(18)
247 B19_0_1084_41_MLW = MakePlatformBundle(19, 134854, V19_0_1084_41, OS_MLW)
248 B19_0_1084_67_MLW = MakePlatformBundle(19, 142000, V19_0_1084_67, OS_MLW)
249 B19_NONE = MakePlatformBundle(19)
250 BCANARY_NONE = MakePlatformBundle(0, stability=CANARY)
251 B21_0_1145_0_MLW = MakePlatformBundle(21, 138079, V21_0_1145_0, OS_MLW)
252 B21_0_1166_0_MW = MakePlatformBundle(21, 140819, V21_0_1166_0, OS_MW)
253 B26_NONE = MakePlatformBundle(26)
254 B26_0_1386_0_MLW = MakePlatformBundle(26, 177362, V26_0_1386_0, OS_MLW)
255 B26_0_1386_1_MLW = MakePlatformBundle(26, 177439, V26_0_1386_1, OS_MLW)
256 BTRUNK_140819_MLW = MakePlatformBundle(21, 140819, VTRUNK_140819, OS_MLW)
257 NON_PEPPER_BUNDLE_NOARCHIVES = MakeNonPepperBundle('foo')
258 NON_PEPPER_BUNDLE_ARCHIVES = MakeNonPepperBundle('bar', with_archives=True)
261 class TestUpdateManifest(unittest.TestCase):
263 self.history = MakeHistory()
264 self.files = MakeFiles()
265 self.version_mapping = {}
267 self.uploaded_manifest = None
269 # Ignore logging warnings, etc.
270 logging.getLogger('update_nacl_manifest').setLevel(logging.CRITICAL)
272 def _MakeDelegate(self):
273 self.delegate = TestDelegate(self.manifest, self.history.history,
274 self.files, self.version_mapping)
276 def _Run(self, host_oses, extra_archives=None, fixed_bundle_versions=None):
277 update_nacl_manifest.Run(self.delegate, host_oses, extra_archives,
278 fixed_bundle_versions)
280 def _HasUploadedManifest(self):
281 return 'naclsdk_manifest2.json' in self.files
283 def _ReadUploadedManifest(self):
284 self.uploaded_manifest = manifest_util.SDKManifest()
285 self.uploaded_manifest.LoadDataFromString(
286 self.files['naclsdk_manifest2.json'])
288 def _AssertUploadedManifestHasBundle(self, bundle, stability):
289 if stability == CANARY:
290 bundle_name = CANARY_BUNDLE_NAME
292 bundle_name = bundle.name
294 uploaded_manifest_bundle = self.uploaded_manifest.GetBundle(bundle_name)
295 # Bundles that we create in the test (and in the manifest snippets) have
296 # their stability set to "dev". update_nacl_manifest correctly updates it.
297 # So we have to force the stability of |bundle| so they compare equal.
298 test_bundle = copy.copy(bundle)
299 test_bundle.stability = stability
300 if stability == CANARY:
301 test_bundle.name = CANARY_BUNDLE_NAME
302 self.assertEqual(uploaded_manifest_bundle, test_bundle)
304 def _AddCsvHistory(self, history):
307 history_stream = cStringIO.StringIO(history)
308 self.history.history = [(platform, channel, version, date)
309 for platform, channel, version, date in csv.reader(history_stream)]
311 def testNoUpdateNeeded(self):
312 self.manifest = MakeManifest(B18_0_1025_163_MLW)
315 self.assertFalse(self._HasUploadedManifest())
317 # Add another bundle, make sure it still doesn't update
318 self.manifest.AddBundle(B19_0_1084_41_MLW)
320 self.assertFalse(self._HasUploadedManifest())
322 def testSimpleUpdate(self):
323 self.manifest = MakeManifest(B18_NONE)
324 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
325 self.files.Add(B18_0_1025_163_MLW)
328 self._ReadUploadedManifest()
329 self._AssertUploadedManifestHasBundle(B18_0_1025_163_MLW, BETA)
330 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
332 def testOnePlatformHasNewerRelease(self):
333 self.manifest = MakeManifest(B18_NONE)
334 self.history.Add(OS_M, BETA, V18_0_1025_175) # Mac has newer version
335 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
336 self.files.Add(B18_0_1025_163_MLW)
339 self._ReadUploadedManifest()
340 self._AssertUploadedManifestHasBundle(B18_0_1025_163_MLW, BETA)
341 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
343 def testMultipleMissingPlatformsInHistory(self):
344 self.manifest = MakeManifest(B18_NONE)
345 self.history.Add(OS_ML, BETA, V18_0_1025_184)
346 self.history.Add(OS_M, BETA, V18_0_1025_175)
347 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
348 self.files.Add(B18_0_1025_163_MLW)
351 self._ReadUploadedManifest()
352 self._AssertUploadedManifestHasBundle(B18_0_1025_163_MLW, BETA)
353 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
355 def testUpdateOnlyOneBundle(self):
356 self.manifest = MakeManifest(B18_NONE, B19_0_1084_41_MLW)
357 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
358 self.files.Add(B18_0_1025_163_MLW)
361 self._ReadUploadedManifest()
362 self._AssertUploadedManifestHasBundle(B18_0_1025_163_MLW, BETA)
363 self._AssertUploadedManifestHasBundle(B19_0_1084_41_MLW, DEV)
364 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 2)
366 def testUpdateTwoBundles(self):
367 self.manifest = MakeManifest(B18_NONE, B19_NONE)
368 self.history.Add(OS_MLW, DEV, V19_0_1084_41)
369 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
370 self.files.Add(B18_0_1025_163_MLW)
371 self.files.Add(B19_0_1084_41_MLW)
374 self._ReadUploadedManifest()
375 self._AssertUploadedManifestHasBundle(B18_0_1025_163_MLW, BETA)
376 self._AssertUploadedManifestHasBundle(B19_0_1084_41_MLW, DEV)
377 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 2)
379 def testUpdateWithMissingPlatformsInArchives(self):
380 self.manifest = MakeManifest(B18_NONE)
381 self.history.Add(OS_MLW, BETA, V18_0_1025_184)
382 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
383 self.files.Add(B18_0_1025_184_MLW, add_archive_for_os=OS_M)
384 self.files.Add(B18_0_1025_163_MLW)
387 self._ReadUploadedManifest()
388 self._AssertUploadedManifestHasBundle(B18_0_1025_163_MLW, BETA)
389 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
391 def testUpdateWithMissingManifestSnippets(self):
392 self.manifest = MakeManifest(B18_NONE)
393 self.history.Add(OS_MLW, BETA, V18_0_1025_184)
394 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
395 self.files.Add(B18_0_1025_184_MLW, add_json_for_os=OS_ML)
396 self.files.Add(B18_0_1025_163_MLW)
399 self._ReadUploadedManifest()
400 self._AssertUploadedManifestHasBundle(B18_0_1025_163_MLW, BETA)
401 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
403 def testRecommendedIsStable(self):
404 for channel in STABLE, BETA, DEV, CANARY:
406 bundle = copy.deepcopy(B18_NONE)
407 self.manifest = MakeManifest(bundle)
408 self.history.Add(OS_MLW, channel, V18_0_1025_163)
409 self.files.Add(B18_0_1025_163_MLW)
412 self._ReadUploadedManifest()
413 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
414 uploaded_bundle = self.uploaded_manifest.GetBundle('pepper_18')
415 if channel == STABLE:
416 self.assertEqual(uploaded_bundle.recommended, 'yes')
418 self.assertEqual(uploaded_bundle.recommended, 'no')
420 def testNoUpdateWithNonPepperBundle(self):
421 self.manifest = MakeManifest(NON_PEPPER_BUNDLE_NOARCHIVES,
425 self.assertFalse(self._HasUploadedManifest())
427 def testUpdateWithHistoryWithExtraneousPlatforms(self):
428 self.manifest = MakeManifest(B18_NONE)
429 self.history.Add(OS_ML, BETA, V18_0_1025_184)
430 self.history.Add(OS_CR, BETA, V18_0_1025_184)
431 self.history.Add(OS_CR, BETA, V18_0_1025_175)
432 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
433 self.files.Add(B18_0_1025_163_MLW)
436 self._ReadUploadedManifest()
437 self._AssertUploadedManifestHasBundle(B18_0_1025_163_MLW, BETA)
438 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
440 def testSnippetWithStringRevisionAndVersion(self):
441 # This test exists because some manifest snippets were uploaded with
442 # strings for their revisions and versions. I want to make sure the
443 # resulting manifest is still consistent with the old format.
444 self.manifest = MakeManifest(B18_NONE)
445 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
446 bundle_string_revision = MakePlatformBundle('18', '1234', V18_0_1025_163,
448 self.files.Add(bundle_string_revision)
451 self._ReadUploadedManifest()
452 uploaded_bundle = self.uploaded_manifest.GetBundle(
453 bundle_string_revision.name)
454 self.assertEqual(uploaded_bundle.revision, 1234)
455 self.assertEqual(uploaded_bundle.version, 18)
457 def testUpdateCanary(self):
458 # Note that the bundle in naclsdk_manifest2.json will be called
459 # CANARY_BUNDLE_NAME, whereas the bundle in the manifest "snippet" will be
460 # called "pepper_21".
461 canary_bundle = copy.deepcopy(BCANARY_NONE)
462 self.manifest = MakeManifest(canary_bundle)
463 self.history.Add(OS_MW, CANARY, V21_0_1145_0)
464 self.files.Add(B21_0_1145_0_MLW)
467 self._ReadUploadedManifest()
468 self._AssertUploadedManifestHasBundle(B21_0_1145_0_MLW, CANARY)
470 def testUpdateCanaryUseTrunkArchives(self):
471 canary_bundle = copy.deepcopy(BCANARY_NONE)
472 self.manifest = MakeManifest(canary_bundle)
473 self.history.Add(OS_MW, CANARY, V21_0_1166_0)
474 self.files.Add(B21_0_1166_0_MW)
475 self.files.Add(BTRUNK_140819_MLW)
476 self.version_mapping[V21_0_1166_0] = VTRUNK_140819
479 self._ReadUploadedManifest()
481 test_bundle = copy.deepcopy(B21_0_1166_0_MW)
482 test_bundle.AddArchive(BTRUNK_140819_MLW.GetArchive('linux'))
483 self._AssertUploadedManifestHasBundle(test_bundle, CANARY)
485 def testCanaryUseOnlyTrunkArchives(self):
486 self.manifest = MakeManifest(copy.deepcopy(BCANARY_NONE))
487 history = """win,canary,21.0.1163.0,2012-06-04 12:35:44.784446
488 mac,canary,21.0.1163.0,2012-06-04 11:54:09.433166"""
489 self._AddCsvHistory(history)
490 self.version_mapping['21.0.1163.0'] = 'trunk.140240'
491 my_bundle = MakePlatformBundle(21, 140240, '21.0.1163.0', OS_MLW)
492 self.files.Add(my_bundle)
495 self._ReadUploadedManifest()
496 self._AssertUploadedManifestHasBundle(my_bundle, CANARY)
498 def testCanaryShouldOnlyUseCanaryVersions(self):
499 canary_bundle = copy.deepcopy(BCANARY_NONE)
500 self.manifest = MakeManifest(canary_bundle)
501 self.history.Add(OS_MW, CANARY, V21_0_1166_0)
502 self.history.Add(OS_MW, BETA, V19_0_1084_41)
503 self.files.Add(B19_0_1084_41_MLW)
504 self.version_mapping[V21_0_1166_0] = VTRUNK_140819
506 self.assertRaises(Exception, self._Run, OS_MLW)
508 def testMissingCanaryFollowedByStableShouldWork(self):
509 history = """win,canary,21.0.1160.0,2012-06-01 19:44:35.936109
510 mac,canary,21.0.1160.0,2012-06-01 18:20:02.003123
511 mac,stable,19.0.1084.52,2012-06-01 17:59:21.559710
512 win,canary,21.0.1159.2,2012-06-01 02:31:43.877688
513 mac,stable,19.0.1084.53,2012-06-01 01:39:57.549149
514 win,canary,21.0.1158.0,2012-05-31 20:16:55.615236
515 win,canary,21.0.1157.0,2012-05-31 17:41:29.516013
516 mac,canary,21.0.1158.0,2012-05-31 17:41:27.591354
517 mac,beta,20.0.1132.21,2012-05-30 23:45:38.535586
518 linux,beta,20.0.1132.21,2012-05-30 23:45:37.025015
519 cf,beta,20.0.1132.21,2012-05-30 23:45:36.767529
520 win,beta,20.0.1132.21,2012-05-30 23:44:56.675123
521 win,canary,21.0.1156.1,2012-05-30 22:28:01.872056
522 mac,canary,21.0.1156.1,2012-05-30 21:20:29.920390
523 win,canary,21.0.1156.0,2012-05-30 12:46:48.046627
524 mac,canary,21.0.1156.0,2012-05-30 12:14:21.305090"""
525 self.manifest = MakeManifest(copy.deepcopy(BCANARY_NONE))
526 self._AddCsvHistory(history)
527 self.version_mapping = {
528 '21.0.1160.0': 'trunk.139984',
529 '21.0.1159.2': 'trunk.139890',
530 '21.0.1158.0': 'trunk.139740',
531 '21.0.1157.0': 'unknown',
532 '21.0.1156.1': 'trunk.139576',
533 '21.0.1156.0': 'trunk.139984'}
534 self.files.Add(MakePlatformBundle(21, 139890, '21.0.1159.2', OS_MLW))
535 self.files.Add(MakePlatformBundle(21, 0, '21.0.1157.1', ('linux', 'win')))
536 my_bundle = MakePlatformBundle(21, 139576, '21.0.1156.1', OS_MLW)
537 self.files.Add(my_bundle)
540 self._ReadUploadedManifest()
541 self._AssertUploadedManifestHasBundle(my_bundle, CANARY)
543 def testExtensionWorksAsBz2(self):
544 # Allow old bundles with just .bz2 extension to work
545 self.manifest = MakeManifest(B18_NONE)
546 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
547 bundle = copy.deepcopy(B18_0_1025_163_MLW)
548 archive_url = bundle.GetArchive('mac').url
549 bundle.GetArchive('mac').url = archive_url.replace('.tar', '')
550 self.files.Add(bundle)
553 self._ReadUploadedManifest()
554 self._AssertUploadedManifestHasBundle(bundle, BETA)
555 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
557 def testOnlyOneStableBundle(self):
558 # Make sure that any bundle that has an older version than STABLE is marked
559 # as POST_STABLE, even if the last version we found was BETA, DEV, etc.
560 for channel in STABLE, BETA, DEV, CANARY:
562 self.manifest = MakeManifest(B18_NONE, B19_NONE)
563 self.history.Add(OS_MLW, channel, V18_0_1025_163)
564 self.history.Add(OS_MLW, STABLE, V19_0_1084_41)
565 self.files.Add(B18_0_1025_163_MLW)
566 self.files.Add(B19_0_1084_41_MLW)
569 self._ReadUploadedManifest()
570 p18_bundle = self.uploaded_manifest.GetBundle(B18_NONE.name)
571 self.assertEqual(p18_bundle.stability, POST_STABLE)
572 self.assertEqual(p18_bundle.recommended, 'no')
573 p19_bundle = self.uploaded_manifest.GetBundle(B19_NONE.name)
574 self.assertEqual(p19_bundle.stability, STABLE)
575 self.assertEqual(p19_bundle.recommended, 'yes')
577 def testDontPushIfNoChange(self):
578 # Make an online manifest that already has this bundle.
579 online_manifest = MakeManifest(B18_0_1025_163_MLW)
580 self.files.AddOnlineManifest(online_manifest.GetDataAsString())
582 self.manifest = MakeManifest(B18_NONE)
583 self.history.Add(OS_MLW, DEV, V18_0_1025_163)
584 self.files.Add(B18_0_1025_163_MLW)
588 self.assertFalse(self.delegate.called_gsutil_cp)
590 def testDontPushIfRollback(self):
591 # Make an online manifest that has a newer bundle
592 online_manifest = MakeManifest(B18_0_1025_184_MLW)
593 self.files.AddOnlineManifest(online_manifest.GetDataAsString())
595 self.manifest = MakeManifest(B18_NONE)
596 self.history.Add(OS_MLW, DEV, V18_0_1025_163)
597 self.files.Add(B18_0_1025_163_MLW)
601 self.assertFalse(self.delegate.called_gsutil_cp)
603 def testRunWithFixedBundleVersions(self):
604 self.manifest = MakeManifest(B18_NONE)
605 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
606 self.files.Add(B18_0_1025_163_MLW)
607 self.files.Add(B18_0_1025_184_MLW)
610 self._Run(OS_MLW, None, [('pepper_18', '18.0.1025.184')])
611 self._ReadUploadedManifest()
612 self._AssertUploadedManifestHasBundle(B18_0_1025_184_MLW, BETA)
613 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
615 def testRunWithMissingFixedBundleVersions(self):
616 self.manifest = MakeManifest(B18_NONE)
617 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
618 self.files.Add(B18_0_1025_163_MLW)
621 self._Run(OS_MLW, None, [('pepper_18', '18.0.1025.184')])
622 # Nothing should be uploaded if the user gives a missing fixed version.
623 self.assertFalse(self.delegate.called_gsutil_cp)
625 def testDontIncludeRandomBundles(self):
626 self.manifest = MakeManifest(B26_NONE)
627 self.history.Add(OS_MLW, BETA, V26_0_1386_0)
628 self.files.Add(B26_0_1386_0_MLW)
630 some_other_bundle = MakePepperBundle(26, 1, V26_0_1386_0, BETA)
631 some_other_archive = MakeNonPlatformArchive('some_other.tar.bz2',
633 some_other_bundle.AddArchive(some_other_archive)
634 self.files.AddArchive(some_other_bundle, some_other_archive)
638 self._ReadUploadedManifest()
639 uploaded_bundle = self.uploaded_manifest.GetBundle('pepper_26')
640 self.assertEqual(1, len(uploaded_bundle.GetHostOSArchives()))
642 def testNaclportsBundle(self):
643 self.manifest = MakeManifest(B26_NONE)
644 self.history.Add(OS_MLW, BETA, V26_0_1386_0)
645 self.files.Add(B26_0_1386_0_MLW)
647 # NaclPorts "bundle".
648 naclports_bundle = MakePepperBundle(26, 1, V26_0_1386_0, BETA)
649 naclports_archive = MakeNonPlatformArchive('naclports.tar.bz2',
651 naclports_bundle.AddArchive(naclports_archive)
652 self.files.AddArchive(naclports_bundle, naclports_archive)
655 self._Run(OS_MLW, [('naclports.tar.bz2', '26.0.1386.0')])
656 self._ReadUploadedManifest()
658 uploaded_bundle = self.uploaded_manifest.GetBundle('pepper_26')
659 self.assertEqual(2, len(uploaded_bundle.GetHostOSArchives()))
661 def testKeepBundleOrder(self):
662 # This is a regression test: when a bundle is skipped (because it isn't
663 # newer than the online bundle), it was added to the end of the list.
665 # Make an online manifest that already has B18.
666 online_manifest = MakeManifest(B18_0_1025_163_MLW)
667 self.files.AddOnlineManifest(online_manifest.GetDataAsString())
669 self.manifest = MakeManifest(B18_NONE, B19_NONE)
670 self.history.Add(OS_MLW, STABLE, V18_0_1025_163)
671 self.history.Add(OS_MLW, STABLE, V19_0_1084_41)
672 self.files.Add(B18_0_1025_163_MLW)
673 self.files.Add(B19_0_1084_41_MLW)
677 self._ReadUploadedManifest()
679 # Bundle 18 should be before bundle 19.
680 bundles = self.uploaded_manifest.GetBundles()
681 self.assertEqual(2, len(bundles))
682 self.assertEqual('pepper_18', bundles[0].name)
683 self.assertEqual('pepper_19', bundles[1].name)
685 def testBundleWithoutHistoryUsesOnline(self):
686 online_manifest = MakeManifest(B18_0_1025_163_MLW)
687 self.files.AddOnlineManifest(online_manifest.GetDataAsString())
689 self.manifest = MakeManifest(B18_NONE)
692 # This should not raise.
694 self._ReadUploadedManifest()
696 # But it should have sent an email nagging the users to lock this bundle
698 self.assertTrue(self.delegate.called_sendmail)
700 uploaded_bundle = self.uploaded_manifest.GetBundle('pepper_18')
701 self.assertEqual(uploaded_bundle, B18_0_1025_163_MLW)
703 def testBundleWithoutHistoryOrOnlineRaises(self):
704 self.manifest = MakeManifest(B18_NONE)
706 self.assertRaises(update_nacl_manifest.UnknownLockedBundleException,
709 def testIgnoreLastDigitOnCanary(self):
710 # The final number in a canary build does not include any different
711 # changes, it is just a different experiment (e.g. using ASAN, or using
712 # aura). We should not compare these versions differently.
714 # Note that the version mapping will show that 31.0.1608.0 is different
715 # from 31.0.1608.1 -- this is because 31.0.1608.1 is built from the branch,
716 # not from trunk. Inspecting the branch would show that there are no
717 # changes (why would there be? No one has any reason to merge changes to a
719 self.manifest = MakeManifest(copy.deepcopy(BCANARY_NONE))
720 history = """win,canary,31.0.1608.1,2013-08-22 09:33:24.469760
721 mac,canary,31.0.1608.0,2013-08-22 07:18:09.762600"""
722 self._AddCsvHistory(history)
723 self.version_mapping['31.0.1608.1'] = 'trunk.218914'
724 self.version_mapping['31.0.1608.0'] = 'trunk.218872'
725 my_bundle = MakePlatformBundle(31, 218872, '31.0.1608.0', OS_MLW)
726 self.files.Add(my_bundle)
729 self._ReadUploadedManifest()
730 self._AssertUploadedManifestHasBundle(my_bundle, CANARY)
732 def testDontIgnoreLastDigitForNonCanary(self):
733 self.manifest = MakeManifest(B26_NONE)
734 self.history.Add(OS_M, BETA, V26_0_1386_1) # Only Mac
735 self.history.Add(OS_LW, BETA, V26_0_1386_0) # Only Linux, Windows.
736 self.files.Add(B26_0_1386_0_MLW)
739 # This raises because pepper_26 is not found in the history, and therefore
740 # "locked", but it also doesn't have an online version, therefore there is
741 # no good version number to upload.
743 # Basically we're asserting that 26.0.1386.1 != 26.0.1386.0, which would be
744 # true if it were canary.
745 self.assertRaises(update_nacl_manifest.UnknownLockedBundleException,
749 class TestUpdateVitals(unittest.TestCase):
751 f = tempfile.NamedTemporaryFile('w', prefix="test_update_nacl_manifest")
752 self.test_file = f.name
754 test_data = "Some test data"
755 self.sha1 = hashlib.sha1(test_data).hexdigest()
756 self.data_len = len(test_data)
757 with open(self.test_file, 'w') as f:
761 os.remove(self.test_file)
763 def testUpdateVitals(self):
764 archive = manifest_util.Archive(manifest_util.GetHostOS())
765 path = os.path.abspath(self.test_file)
766 if sys.platform == 'win32':
767 # On Windows, the path must start with three slashes, i.e.
768 # (file:///C:\whatever)
770 archive.url = 'file://' + path
772 bundle = MakePlatformBundle(18)
773 bundle.AddArchive(archive)
774 manifest = MakeManifest(bundle)
775 archive = manifest.GetBundles()[0]['archives'][0]
777 self.assertTrue('size' not in archive)
778 self.assertTrue('checksum' not in archive)
779 self.assertRaises(manifest_util.Error, manifest.Validate)
781 manifest.Validate(add_missing_info=True)
783 self.assertEqual(archive['size'], self.data_len)
784 self.assertEqual(archive['checksum']['sha1'], self.sha1)
787 class TestRealDelegate(unittest.TestCase):
789 self.delegate = update_nacl_manifest.RealDelegate()
791 def testGetTrunkRevision(self):
793 '21.0.1180.80': '151582',
794 '23.0.1271.89': '167132',
795 '24.0.1305.4': '164971',
797 for version, revision in revision_dict.iteritems():
798 self.assertEqual('trunk.%s' % revision,
799 self.delegate.GetTrunkRevision(version))
802 if __name__ == '__main__':
803 sys.exit(unittest.main())