Send a crash report when a hung process is detected.
[chromium-blink-merge.git] / native_client_sdk / src / build_tools / tests / update_nacl_manifest_test.py
blobcbbb13375738e432993d6c47a85dd55ebf3bcd55
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.
6 import copy
7 import datetime
8 import hashlib
9 import logging
10 import os
11 import posixpath
12 import subprocess
13 import sys
14 import tempfile
15 import unittest
16 import urlparse
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)
22 import manifest_util
23 import update_nacl_manifest
24 from update_nacl_manifest import CANARY_BUNDLE_NAME, BIONIC_CANARY_BUNDLE_NAME
27 HTTPS_BASE_URL = 'https://storage.googleapis.com' \
28 '/nativeclient_mirror/nacl/nacl_sdk/'
30 OS_CR = ('cros',)
31 OS_L = ('linux',)
32 OS_M = ('mac',)
33 OS_ML = ('mac', 'linux')
34 OS_MW = ('mac', 'win')
35 OS_LW = ('linux', 'win')
36 OS_MLW = ('mac', 'linux', 'win')
37 OS_ALL = ('all',)
38 POST_STABLE = 'post_stable'
39 STABLE = 'stable'
40 BETA = 'beta'
41 DEV = 'dev'
42 CANARY = 'canary'
45 def GetArchiveURL(basename, version):
46 return urlparse.urljoin(HTTPS_BASE_URL, posixpath.join(version, basename))
49 def GetPlatformArchiveUrl(host_os, version):
50 basename = 'naclsdk_%s.tar.bz2' % (host_os,)
51 return GetArchiveURL(basename, version)
54 def GetBionicArchiveUrl(version):
55 basename = 'naclsdk_bionic.tar.bz2'
56 return GetArchiveURL(basename, version)
59 def MakeGsUrl(rel_path):
60 return update_nacl_manifest.GS_BUCKET_PATH + rel_path
63 def GetPathFromGsUrl(url):
64 assert url.startswith(update_nacl_manifest.GS_BUCKET_PATH)
65 return url[len(update_nacl_manifest.GS_BUCKET_PATH):]
68 def GetPathFromHttpsUrl(url):
69 assert url.startswith(HTTPS_BASE_URL)
70 return url[len(HTTPS_BASE_URL):]
73 def MakeArchive(url, host_os):
74 archive = manifest_util.Archive(host_os)
75 archive.url = url
76 # dummy values that won't succeed if we ever use them, but will pass
77 # validation. :)
78 archive.checksum = {'sha1': 'foobar'}
79 archive.size = 1
80 return archive
83 def MakePlatformArchive(host_os, version):
84 return MakeArchive(GetPlatformArchiveUrl(host_os, version), host_os)
87 def MakeBionicArchive(host_os, version):
88 return MakeArchive(GetBionicArchiveUrl(version), host_os)
91 def MakeNonPlatformArchive(basename, version):
92 return MakeArchive(GetArchiveURL(basename, version), 'all')
95 def MakeNonPepperBundle(name, with_archives=False):
96 bundle = manifest_util.Bundle(name)
97 bundle.version = 1
98 bundle.revision = 1
99 bundle.description = 'Dummy bundle'
100 bundle.recommended = 'yes'
101 bundle.stability = 'stable'
103 if with_archives:
104 for host_os in OS_MLW:
105 archive = manifest_util.Archive(host_os)
106 archive.url = 'http://example.com'
107 archive.checksum = {'sha1': 'blah'}
108 archive.size = 2
109 bundle.AddArchive(archive)
110 return bundle
113 def MakePepperBundle(major_version, revision=0, version=None, stability='dev',
114 bundle_name=None):
115 assert (version is None or
116 version.split('.')[0] == 'trunk' or
117 version.split('.')[0] == str(major_version))
118 if not bundle_name:
119 bundle_name = 'pepper_' + str(major_version)
121 bundle = manifest_util.Bundle(bundle_name)
122 bundle.version = major_version
123 bundle.revision = revision
124 bundle.description = 'Chrome %s bundle, revision %s' % (major_version,
125 revision)
126 bundle.repath = 'pepper_' + str(major_version)
127 bundle.recommended = 'no'
128 bundle.stability = stability
130 return bundle
133 def MakePlatformBundle(major_version, revision=0, version=None, host_oses=None,
134 stability='dev'):
135 bundle = MakePepperBundle(major_version, revision, version, stability)
137 if host_oses:
138 for host_os in host_oses:
139 bundle.AddArchive(MakePlatformArchive(host_os, version))
141 return bundle
144 def MakeBionicBundle(major_version, revision=0, version=None, host_oses=None):
145 bundle = MakePepperBundle(major_version, revision, version, 'dev')
147 if host_oses:
148 for host_os in host_oses:
149 bundle.AddArchive(MakeBionicArchive(host_os, version))
151 return bundle
154 class MakeManifest(manifest_util.SDKManifest):
155 def __init__(self, *args):
156 manifest_util.SDKManifest.__init__(self)
158 for bundle in args:
159 self.AddBundle(bundle)
161 def AddBundle(self, bundle):
162 self.MergeBundle(bundle, allow_existing=False)
165 class MakeHistory(object):
166 def __init__(self):
167 # used for a dummy timestamp
168 self.datetime = datetime.datetime.utcnow()
169 self.history = []
171 def Add(self, host_oses, channel, version):
172 for host_os in host_oses:
173 timestamp = self.datetime.strftime('%Y-%m-%d %H:%M:%S.%f')
174 self.history.append((host_os, channel, version, timestamp))
175 self.datetime += datetime.timedelta(0, -3600) # one hour earlier
176 self.datetime += datetime.timedelta(-1) # one day earlier
179 class MakeFiles(dict):
180 def AddOnlineManifest(self, manifest_string):
181 self['naclsdk_manifest2.json'] = manifest_string
183 def Add(self, bundle, add_archive_for_os=OS_MLW, add_json_for_os=OS_MLW):
184 for archive in bundle.GetArchives():
185 if not archive.host_os in add_archive_for_os:
186 continue
188 self.AddArchive(bundle, archive, archive.host_os in add_json_for_os)
190 def AddArchive(self, bundle, archive, add_json=True):
191 path = GetPathFromHttpsUrl(archive.url)
192 self[path] = 'My Dummy archive'
194 if add_json:
195 # add .json manifest snippet, it should look like a normal Bundle, but
196 # only has one archive.
197 new_bundle = manifest_util.Bundle('')
198 new_bundle.CopyFrom(bundle)
199 del new_bundle.archives[:]
200 new_bundle.AddArchive(archive)
201 self[path + '.json'] = new_bundle.GetDataAsString()
204 class TestDelegate(update_nacl_manifest.Delegate):
205 def __init__(self, manifest, history, files):
206 self.manifest = manifest
207 self.history = history
208 self.files = files
209 self.dryrun = 0
210 self.called_gsutil_cp = False
211 self.called_sendmail = False
213 def GetRepoManifest(self):
214 return self.manifest
216 def GetHistory(self):
217 return self.history
219 def GsUtil_ls(self, url):
220 path = GetPathFromGsUrl(url)
221 result = []
222 for filename in self.files.iterkeys():
223 if not filename.startswith(path):
224 continue
226 # Find the first slash after the prefix (path).
227 # +1, because if the slash is directly after path, then we want to find
228 # the following slash anyway.
229 slash = filename.find('/', len(path) + 1)
231 if slash != -1:
232 filename = filename[:slash]
234 result.append(MakeGsUrl(filename))
236 # Remove dupes.
237 return list(set(result))
239 def GsUtil_cat(self, url):
240 path = GetPathFromGsUrl(url)
241 if path not in self.files:
242 raise subprocess.CalledProcessError(1, 'gsutil cat %s' % (url,))
243 return self.files[path]
245 def GsUtil_cp(self, src, dest, stdin=None):
246 self.called_gsutil_cp = True
247 dest_path = GetPathFromGsUrl(dest)
248 if src == '-':
249 self.files[dest_path] = stdin
250 else:
251 src_path = GetPathFromGsUrl(src)
252 if src_path not in self.files:
253 raise subprocess.CalledProcessError(1, 'gsutil cp %s %s' % (src, dest))
254 self.files[dest_path] = self.files[src_path]
256 def SendMail(self, subject, text):
257 self.called_sendmail = True
260 # Shorthand for premade bundles/versions
261 V18_0_1025_163 = '18.0.1025.163'
262 V18_0_1025_175 = '18.0.1025.175'
263 V18_0_1025_184 = '18.0.1025.184'
264 V19_0_1084_41 = '19.0.1084.41'
265 V19_0_1084_67 = '19.0.1084.67'
266 V21_0_1145_0 = '21.0.1145.0'
267 V21_0_1166_0 = '21.0.1166.0'
268 V26_0_1386_0 = '26.0.1386.0'
269 V26_0_1386_1 = '26.0.1386.1'
270 V37_0_2054_0 = '37.0.2054.0'
271 VTRUNK_140819 = 'trunk.140819'
272 VTRUNK_277776 = 'trunk.277776'
273 B18_0_1025_163_MLW = MakePlatformBundle(18, 132135, V18_0_1025_163, OS_MLW)
274 B18_0_1025_184_MLW = MakePlatformBundle(18, 134900, V18_0_1025_184, OS_MLW)
275 B18_NONE = MakePlatformBundle(18)
276 B19_0_1084_41_MLW = MakePlatformBundle(19, 134854, V19_0_1084_41, OS_MLW)
277 B19_0_1084_67_MLW = MakePlatformBundle(19, 142000, V19_0_1084_67, OS_MLW)
278 B19_NONE = MakePlatformBundle(19)
279 BCANARY_NONE = MakePepperBundle(0, stability=CANARY,
280 bundle_name=CANARY_BUNDLE_NAME)
281 B21_0_1145_0_MLW = MakePlatformBundle(21, 138079, V21_0_1145_0, OS_MLW)
282 B21_0_1166_0_MW = MakePlatformBundle(21, 140819, V21_0_1166_0, OS_MW)
283 B26_NONE = MakePlatformBundle(26)
284 B26_0_1386_0_MLW = MakePlatformBundle(26, 177362, V26_0_1386_0, OS_MLW)
285 B26_0_1386_1_MLW = MakePlatformBundle(26, 177439, V26_0_1386_1, OS_MLW)
286 BTRUNK_140819_MLW = MakePlatformBundle(21, 140819, VTRUNK_140819, OS_MLW)
287 BBIONIC_NONE = MakePepperBundle(0, stability=CANARY,
288 bundle_name=BIONIC_CANARY_BUNDLE_NAME)
289 BBIONIC_TRUNK_277776 = MakeBionicBundle(37, 277776, VTRUNK_277776, OS_L)
290 NON_PEPPER_BUNDLE_NOARCHIVES = MakeNonPepperBundle('foo')
291 NON_PEPPER_BUNDLE_ARCHIVES = MakeNonPepperBundle('bar', with_archives=True)
294 class TestUpdateManifest(unittest.TestCase):
295 def setUp(self):
296 self.history = MakeHistory()
297 self.files = MakeFiles()
298 self.version_mapping = {}
299 self.delegate = None
300 self.uploaded_manifest = None
301 self.manifest = None
303 logging.basicConfig(level=logging.CRITICAL)
304 # Uncomment the following line to enable more debugging info.
305 # logging.getLogger('update_nacl_manifest').setLevel(logging.INFO)
307 def _MakeDelegate(self):
308 self.delegate = TestDelegate(self.manifest, self.history.history,
309 self.files)
311 def _Run(self, host_oses, extra_archives=None, fixed_bundle_versions=None):
312 update_nacl_manifest.Run(self.delegate, host_oses, extra_archives,
313 fixed_bundle_versions)
315 def _HasUploadedManifest(self):
316 return 'naclsdk_manifest2.json' in self.files
318 def _ReadUploadedManifest(self):
319 self.uploaded_manifest = manifest_util.SDKManifest()
320 self.uploaded_manifest.LoadDataFromString(
321 self.files['naclsdk_manifest2.json'])
323 def _AssertUploadedManifestHasBundle(self, bundle, stability,
324 bundle_name=None):
325 if not bundle_name:
326 bundle_name = bundle.name
328 uploaded_manifest_bundle = self.uploaded_manifest.GetBundle(bundle_name)
329 # Bundles that we create in the test (and in the manifest snippets) have
330 # their stability set to "dev". update_nacl_manifest correctly updates it.
331 # So we have to force the stability of |bundle| so they compare equal.
332 test_bundle = copy.copy(bundle)
333 test_bundle.stability = stability
334 if bundle_name:
335 test_bundle.name = bundle_name
336 self.assertEqual(uploaded_manifest_bundle, test_bundle)
338 def _AddCsvHistory(self, history):
339 import csv
340 import cStringIO
341 history_stream = cStringIO.StringIO(history)
342 self.history.history = [(platform, channel, version, date)
343 for platform, channel, version, date in csv.reader(history_stream)]
345 def testNoUpdateNeeded(self):
346 self.manifest = MakeManifest(B18_0_1025_163_MLW)
347 self._MakeDelegate()
348 self._Run(OS_MLW)
349 self.assertFalse(self._HasUploadedManifest())
351 # Add another bundle, make sure it still doesn't update
352 self.manifest.AddBundle(B19_0_1084_41_MLW)
353 self._Run(OS_MLW)
354 self.assertFalse(self._HasUploadedManifest())
356 def testSimpleUpdate(self):
357 self.manifest = MakeManifest(B18_NONE)
358 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
359 self.files.Add(B18_0_1025_163_MLW)
360 self._MakeDelegate()
361 self._Run(OS_MLW)
362 self._ReadUploadedManifest()
363 self._AssertUploadedManifestHasBundle(B18_0_1025_163_MLW, BETA)
364 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
366 def testOnePlatformHasNewerRelease(self):
367 self.manifest = MakeManifest(B18_NONE)
368 self.history.Add(OS_M, BETA, V18_0_1025_175) # Mac has newer version
369 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
370 self.files.Add(B18_0_1025_163_MLW)
371 self._MakeDelegate()
372 self._Run(OS_MLW)
373 self._ReadUploadedManifest()
374 self._AssertUploadedManifestHasBundle(B18_0_1025_163_MLW, BETA)
375 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
377 def testMultipleMissingPlatformsInHistory(self):
378 self.manifest = MakeManifest(B18_NONE)
379 self.history.Add(OS_ML, BETA, V18_0_1025_184)
380 self.history.Add(OS_M, BETA, V18_0_1025_175)
381 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
382 self.files.Add(B18_0_1025_163_MLW)
383 self._MakeDelegate()
384 self._Run(OS_MLW)
385 self._ReadUploadedManifest()
386 self._AssertUploadedManifestHasBundle(B18_0_1025_163_MLW, BETA)
387 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
389 def testUpdateOnlyOneBundle(self):
390 self.manifest = MakeManifest(B18_NONE, B19_0_1084_41_MLW)
391 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
392 self.files.Add(B18_0_1025_163_MLW)
393 self._MakeDelegate()
394 self._Run(OS_MLW)
395 self._ReadUploadedManifest()
396 self._AssertUploadedManifestHasBundle(B18_0_1025_163_MLW, BETA)
397 self._AssertUploadedManifestHasBundle(B19_0_1084_41_MLW, DEV)
398 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 2)
400 def testUpdateTwoBundles(self):
401 self.manifest = MakeManifest(B18_NONE, B19_NONE)
402 self.history.Add(OS_MLW, DEV, V19_0_1084_41)
403 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
404 self.files.Add(B18_0_1025_163_MLW)
405 self.files.Add(B19_0_1084_41_MLW)
406 self._MakeDelegate()
407 self._Run(OS_MLW)
408 self._ReadUploadedManifest()
409 self._AssertUploadedManifestHasBundle(B18_0_1025_163_MLW, BETA)
410 self._AssertUploadedManifestHasBundle(B19_0_1084_41_MLW, DEV)
411 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 2)
413 def testUpdateWithMissingPlatformsInArchives(self):
414 self.manifest = MakeManifest(B18_NONE)
415 self.history.Add(OS_MLW, BETA, V18_0_1025_184)
416 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
417 self.files.Add(B18_0_1025_184_MLW, add_archive_for_os=OS_M)
418 self.files.Add(B18_0_1025_163_MLW)
419 self._MakeDelegate()
420 self._Run(OS_MLW)
421 self._ReadUploadedManifest()
422 self._AssertUploadedManifestHasBundle(B18_0_1025_163_MLW, BETA)
423 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
425 def testUpdateWithMissingManifestSnippets(self):
426 self.manifest = MakeManifest(B18_NONE)
427 self.history.Add(OS_MLW, BETA, V18_0_1025_184)
428 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
429 self.files.Add(B18_0_1025_184_MLW, add_json_for_os=OS_ML)
430 self.files.Add(B18_0_1025_163_MLW)
431 self._MakeDelegate()
432 self._Run(OS_MLW)
433 self._ReadUploadedManifest()
434 self._AssertUploadedManifestHasBundle(B18_0_1025_163_MLW, BETA)
435 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
437 def testRecommendedIsStable(self):
438 for channel in STABLE, BETA, DEV, CANARY:
439 self.setUp()
440 bundle = copy.deepcopy(B18_NONE)
441 self.manifest = MakeManifest(bundle)
442 self.history.Add(OS_MLW, channel, V18_0_1025_163)
443 self.files.Add(B18_0_1025_163_MLW)
444 self._MakeDelegate()
445 self._Run(OS_MLW)
446 self._ReadUploadedManifest()
447 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
448 uploaded_bundle = self.uploaded_manifest.GetBundle('pepper_18')
449 if channel == STABLE:
450 self.assertEqual(uploaded_bundle.recommended, 'yes')
451 else:
452 self.assertEqual(uploaded_bundle.recommended, 'no')
454 def testNoUpdateWithNonPepperBundle(self):
455 self.manifest = MakeManifest(NON_PEPPER_BUNDLE_NOARCHIVES,
456 B18_0_1025_163_MLW)
457 self._MakeDelegate()
458 self._Run(OS_MLW)
459 self.assertFalse(self._HasUploadedManifest())
461 def testUpdateWithHistoryWithExtraneousPlatforms(self):
462 self.manifest = MakeManifest(B18_NONE)
463 self.history.Add(OS_ML, BETA, V18_0_1025_184)
464 self.history.Add(OS_CR, BETA, V18_0_1025_184)
465 self.history.Add(OS_CR, BETA, V18_0_1025_175)
466 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
467 self.files.Add(B18_0_1025_163_MLW)
468 self._MakeDelegate()
469 self._Run(OS_MLW)
470 self._ReadUploadedManifest()
471 self._AssertUploadedManifestHasBundle(B18_0_1025_163_MLW, BETA)
472 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
474 def testSnippetWithStringRevisionAndVersion(self):
475 # This test exists because some manifest snippets were uploaded with
476 # strings for their revisions and versions. I want to make sure the
477 # resulting manifest is still consistent with the old format.
478 self.manifest = MakeManifest(B18_NONE)
479 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
480 bundle_string_revision = MakePlatformBundle('18', '1234', V18_0_1025_163,
481 OS_MLW)
482 self.files.Add(bundle_string_revision)
483 self._MakeDelegate()
484 self._Run(OS_MLW)
485 self._ReadUploadedManifest()
486 uploaded_bundle = self.uploaded_manifest.GetBundle(
487 bundle_string_revision.name)
488 self.assertEqual(uploaded_bundle.revision, 1234)
489 self.assertEqual(uploaded_bundle.version, 18)
491 def testUpdateCanary(self):
492 self.manifest = MakeManifest(copy.deepcopy(BCANARY_NONE))
493 self.files.Add(BTRUNK_140819_MLW)
494 self._MakeDelegate()
495 self._Run(OS_MLW)
496 self._ReadUploadedManifest()
497 self._AssertUploadedManifestHasBundle(BTRUNK_140819_MLW, CANARY,
498 bundle_name=CANARY_BUNDLE_NAME)
500 def testCanaryShouldOnlyUseCanaryVersions(self):
501 canary_bundle = copy.deepcopy(BCANARY_NONE)
502 self.manifest = MakeManifest(canary_bundle)
503 self.history.Add(OS_MW, CANARY, V21_0_1166_0)
504 self.history.Add(OS_MW, BETA, V19_0_1084_41)
505 self.files.Add(B19_0_1084_41_MLW)
506 self.version_mapping[V21_0_1166_0] = VTRUNK_140819
507 self._MakeDelegate()
508 self.assertRaises(Exception, self._Run, OS_MLW)
510 def testExtensionWorksAsBz2(self):
511 # Allow old bundles with just .bz2 extension to work
512 self.manifest = MakeManifest(B18_NONE)
513 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
514 bundle = copy.deepcopy(B18_0_1025_163_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)
524 def testOnlyOneStableBundle(self):
525 # Make sure that any bundle that has an older version than STABLE is marked
526 # as POST_STABLE, even if the last version we found was BETA, DEV, etc.
527 for channel in STABLE, BETA, DEV, CANARY:
528 self.setUp()
529 self.manifest = MakeManifest(B18_NONE, B19_NONE)
530 self.history.Add(OS_MLW, channel, V18_0_1025_163)
531 self.history.Add(OS_MLW, STABLE, V19_0_1084_41)
532 self.files.Add(B18_0_1025_163_MLW)
533 self.files.Add(B19_0_1084_41_MLW)
534 self._MakeDelegate()
535 self._Run(OS_MLW)
536 self._ReadUploadedManifest()
537 p18_bundle = self.uploaded_manifest.GetBundle(B18_NONE.name)
538 self.assertEqual(p18_bundle.stability, POST_STABLE)
539 self.assertEqual(p18_bundle.recommended, 'no')
540 p19_bundle = self.uploaded_manifest.GetBundle(B19_NONE.name)
541 self.assertEqual(p19_bundle.stability, STABLE)
542 self.assertEqual(p19_bundle.recommended, 'yes')
544 def testDontPushIfNoChange(self):
545 # Make an online manifest that already has this bundle.
546 online_manifest = MakeManifest(B18_0_1025_163_MLW)
547 self.files.AddOnlineManifest(online_manifest.GetDataAsString())
549 self.manifest = MakeManifest(B18_NONE)
550 self.history.Add(OS_MLW, DEV, V18_0_1025_163)
551 self.files.Add(B18_0_1025_163_MLW)
553 self._MakeDelegate()
554 self._Run(OS_MLW)
555 self.assertFalse(self.delegate.called_gsutil_cp)
557 def testDontPushIfRollback(self):
558 # Make an online manifest that has a newer bundle
559 online_manifest = MakeManifest(B18_0_1025_184_MLW)
560 self.files.AddOnlineManifest(online_manifest.GetDataAsString())
562 self.manifest = MakeManifest(B18_NONE)
563 self.history.Add(OS_MLW, DEV, V18_0_1025_163)
564 self.files.Add(B18_0_1025_163_MLW)
566 self._MakeDelegate()
567 self._Run(OS_MLW)
568 self.assertFalse(self.delegate.called_gsutil_cp)
570 def testRunWithFixedBundleVersions(self):
571 self.manifest = MakeManifest(B18_NONE)
572 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
573 self.files.Add(B18_0_1025_163_MLW)
574 self.files.Add(B18_0_1025_184_MLW)
576 self._MakeDelegate()
577 self._Run(OS_MLW, None, [('pepper_18', '18.0.1025.184')])
578 self._ReadUploadedManifest()
579 self._AssertUploadedManifestHasBundle(B18_0_1025_184_MLW, BETA)
580 self.assertEqual(len(self.uploaded_manifest.GetBundles()), 1)
582 def testRunWithMissingFixedBundleVersions(self):
583 self.manifest = MakeManifest(B18_NONE)
584 self.history.Add(OS_MLW, BETA, V18_0_1025_163)
585 self.files.Add(B18_0_1025_163_MLW)
587 self._MakeDelegate()
588 self._Run(OS_MLW, None, [('pepper_18', '18.0.1025.184')])
589 # Nothing should be uploaded if the user gives a missing fixed version.
590 self.assertFalse(self.delegate.called_gsutil_cp)
592 def testDontIncludeRandomBundles(self):
593 self.manifest = MakeManifest(B26_NONE)
594 self.history.Add(OS_MLW, BETA, V26_0_1386_0)
595 self.files.Add(B26_0_1386_0_MLW)
597 some_other_bundle = MakePepperBundle(26, 1, V26_0_1386_0, BETA)
598 some_other_archive = MakeNonPlatformArchive('some_other.tar.bz2',
599 V26_0_1386_0)
600 some_other_bundle.AddArchive(some_other_archive)
601 self.files.AddArchive(some_other_bundle, some_other_archive)
603 self._MakeDelegate()
604 self._Run(OS_MLW)
605 self._ReadUploadedManifest()
606 uploaded_bundle = self.uploaded_manifest.GetBundle('pepper_26')
607 self.assertEqual(1, len(uploaded_bundle.GetHostOSArchives()))
609 def testNaclportsBundle(self):
610 self.manifest = MakeManifest(B26_NONE)
611 self.history.Add(OS_MLW, BETA, V26_0_1386_0)
612 self.files.Add(B26_0_1386_0_MLW)
614 # NaclPorts "bundle".
615 naclports_bundle = MakePepperBundle(26, 1, V26_0_1386_0, BETA)
616 naclports_archive = MakeNonPlatformArchive('naclports.tar.bz2',
617 V26_0_1386_0)
618 naclports_bundle.AddArchive(naclports_archive)
619 self.files.AddArchive(naclports_bundle, naclports_archive)
621 self._MakeDelegate()
622 self._Run(OS_MLW, [('naclports.tar.bz2', '26.0.1386.0')])
623 self._ReadUploadedManifest()
625 uploaded_bundle = self.uploaded_manifest.GetBundle('pepper_26')
626 self.assertEqual(2, len(uploaded_bundle.GetHostOSArchives()))
628 def testKeepBundleOrder(self):
629 # This is a regression test: when a bundle is skipped (because it isn't
630 # newer than the online bundle), it was added to the end of the list.
632 # Make an online manifest that already has B18.
633 online_manifest = MakeManifest(B18_0_1025_163_MLW)
634 self.files.AddOnlineManifest(online_manifest.GetDataAsString())
636 self.manifest = MakeManifest(B18_NONE, B19_NONE)
637 self.history.Add(OS_MLW, STABLE, V18_0_1025_163)
638 self.history.Add(OS_MLW, STABLE, V19_0_1084_41)
639 self.files.Add(B18_0_1025_163_MLW)
640 self.files.Add(B19_0_1084_41_MLW)
642 self._MakeDelegate()
643 self._Run(OS_MLW)
644 self._ReadUploadedManifest()
646 # Bundle 18 should be before bundle 19.
647 bundles = self.uploaded_manifest.GetBundles()
648 self.assertEqual(2, len(bundles))
649 self.assertEqual('pepper_18', bundles[0].name)
650 self.assertEqual('pepper_19', bundles[1].name)
652 def testBundleWithoutHistoryUsesOnline(self):
653 online_manifest = MakeManifest(B18_0_1025_163_MLW)
654 self.files.AddOnlineManifest(online_manifest.GetDataAsString())
656 self.manifest = MakeManifest(B18_NONE)
658 self._MakeDelegate()
659 # This should not raise.
660 self._Run(OS_MLW)
661 self._ReadUploadedManifest()
663 # But it should have sent an email nagging the users to lock this bundle
664 # manually.
665 self.assertTrue(self.delegate.called_sendmail)
667 uploaded_bundle = self.uploaded_manifest.GetBundle('pepper_18')
668 self.assertEqual(uploaded_bundle, B18_0_1025_163_MLW)
670 def testBundleWithoutHistoryOrOnlineRaises(self):
671 self.manifest = MakeManifest(B18_NONE)
672 self._MakeDelegate()
673 self.assertRaises(update_nacl_manifest.UnknownLockedBundleException,
674 self._Run, OS_MLW)
676 def testUpdateBionic(self):
677 bionic_bundle = copy.deepcopy(BBIONIC_NONE)
678 self.manifest = MakeManifest(bionic_bundle)
679 self.history.Add(OS_MW, CANARY, V37_0_2054_0)
680 self.files.Add(BBIONIC_TRUNK_277776)
681 self.version_mapping[V37_0_2054_0] = VTRUNK_277776
682 self._MakeDelegate()
683 self._Run(OS_MLW)
684 self._ReadUploadedManifest()
685 self._AssertUploadedManifestHasBundle(BBIONIC_TRUNK_277776, CANARY,
686 bundle_name=BIONIC_CANARY_BUNDLE_NAME)
689 class TestUpdateVitals(unittest.TestCase):
690 def setUp(self):
691 f = tempfile.NamedTemporaryFile('w', prefix="test_update_nacl_manifest")
692 self.test_file = f.name
693 f.close()
694 test_data = "Some test data"
695 self.sha1 = hashlib.sha1(test_data).hexdigest()
696 self.data_len = len(test_data)
697 with open(self.test_file, 'w') as f:
698 f.write(test_data)
700 def tearDown(self):
701 os.remove(self.test_file)
703 def testUpdateVitals(self):
704 archive = manifest_util.Archive(manifest_util.GetHostOS())
705 path = os.path.abspath(self.test_file)
706 if sys.platform == 'win32':
707 # On Windows, the path must start with three slashes, i.e.
708 # (file:///C:\whatever)
709 path = '/' + path
710 archive.url = 'file://' + path
712 bundle = MakePlatformBundle(18)
713 bundle.AddArchive(archive)
714 manifest = MakeManifest(bundle)
715 archive = manifest.GetBundles()[0]['archives'][0]
717 self.assertTrue('size' not in archive)
718 self.assertTrue('checksum' not in archive)
719 self.assertRaises(manifest_util.Error, manifest.Validate)
721 manifest.Validate(add_missing_info=True)
723 self.assertEqual(archive['size'], self.data_len)
724 self.assertEqual(archive['checksum']['sha1'], self.sha1)
727 if __name__ == '__main__':
728 unittest.main()