2 # Copyright (c) 2012 The Chromium OS 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 """Unit tests for cros_portage_upgrade.py."""
8 from __future__ import print_function
20 sys.path.insert(0, os.path.join(os.path.dirname(os.path.realpath(__file__)),
22 from chromite.lib import cros_build_lib
23 from chromite.lib import cros_test_lib
24 from chromite.lib import osutils
25 from chromite.lib import upgrade_table as utable
26 from chromite.scripts import cros_portage_upgrade as cpu
27 from chromite.scripts import parallel_emerge
29 from portage.package.ebuild import config as portcfg # pylint: disable=F0401
31 # This no longer gets installed by portage. Stub it as None to avoid
33 #from portage.tests.resolver import ResolverPlayground as respgnd
36 # Enable color invariably. Since we rely on color for error/warn message
37 # recognition, leaving this to be decided based on stdout being a tty
38 # will make the tests fail/succeed based on how they are run.
39 # pylint: disable=W0102,W0212,E1120,E1101
40 cpu.oper._color._enabled = True
42 DEFAULT_PORTDIR = '/usr/portage'
44 # Configuration for generating a temporary valid ebuild hierarchy.
45 # ResolverPlayground sets up a default profile with ARCH=x86, so
46 # other architectures are irrelevant for now.
49 'dev-libs/A-1': {'RDEPEND': 'dev-libs/B'},
50 'dev-libs/A-2': {'RDEPEND': 'dev-libs/B'},
51 'dev-libs/B-1': {'RDEPEND': 'dev-libs/C'},
52 'dev-libs/B-2': {'RDEPEND': 'dev-libs/C'},
55 'dev-libs/D-1': {'RDEPEND': '!dev-libs/E'},
58 'dev-libs/E-2': {'RDEPEND': '!dev-libs/D'},
61 'dev-libs/F-1': {'SLOT': '1'},
62 'dev-libs/F-2': {'SLOT': '2'},
63 'dev-libs/F-2-r1': {'SLOT': '2',
64 'KEYWORDS': '~amd64 ~x86 ~arm',
70 'KEYWORDS': 'amd64 arm x86',
71 'RDEPEND': '=dev-libs/C-1',
76 'KEYWORDS': 'amd64 arm x86',
77 'RDEPEND': '=dev-libs/C-2',
80 'chromeos-base/flimflam-0.0.1-r228': {
83 'KEYWORDS': 'amd64 x86 arm',
84 'RDEPEND': '>=dev-libs/D-2',
86 'chromeos-base/flimflam-0.0.2-r123': {
89 'KEYWORDS': '~amd64 ~x86 ~arm',
90 'RDEPEND': '>=dev-libs/D-3',
92 'chromeos-base/libchrome-57098-r4': {
95 'KEYWORDS': 'amd64 x86 arm',
96 'RDEPEND': '>=dev-libs/E-2',
98 'chromeos-base/libcros-1': {
101 'KEYWORDS': 'amd64 x86 arm',
102 'RDEPEND': 'dev-libs/B dev-libs/C chromeos-base/flimflam',
104 'dev-libs/B dev-libs/C chromeos-base/flimflam chromeos-base/libchrome',
107 'virtual/libusb-0' : {
108 'EAPI': '2', 'SLOT': '0',
110 '|| ( >=dev-libs/libusb-0.1.12-r1:0 dev-libs/libusb-compat ' +
111 '>=sys-freebsd/freebsd-lib-8.0[usb] )'},
112 'virtual/libusb-1' : {
113 'EAPI':'2', 'SLOT': '1',
114 'RDEPEND': '>=dev-libs/libusb-1.0.4:1'},
115 'dev-libs/libusb-0.1.13' : {},
116 'dev-libs/libusb-1.0.5' : {'SLOT':'1'},
117 'dev-libs/libusb-compat-1' : {},
118 'sys-freebsd/freebsd-lib-8': {'IUSE': '+usb'},
120 'sys-fs/udev-164' : {'EAPI': '1', 'RDEPEND': 'virtual/libusb:0'},
122 'virtual/jre-1.5.0' : {
124 'RDEPEND': '|| ( =dev-java/sun-jre-bin-1.5.0* =virtual/jdk-1.5.0* )'},
125 'virtual/jre-1.5.0-r1' : {
127 'RDEPEND': '|| ( =dev-java/sun-jre-bin-1.5.0* =virtual/jdk-1.5.0* )'},
128 'virtual/jre-1.6.0' : {
130 'RDEPEND': '|| ( =dev-java/sun-jre-bin-1.6.0* =virtual/jdk-1.6.0* )'},
131 'virtual/jre-1.6.0-r1' : {
133 'RDEPEND': '|| ( =dev-java/sun-jre-bin-1.6.0* =virtual/jdk-1.6.0* )'},
134 'virtual/jdk-1.5.0' : {
136 'RDEPEND': '|| ( =dev-java/sun-jdk-1.5.0* dev-java/gcj-jdk )'},
137 'virtual/jdk-1.5.0-r1' : {
139 'RDEPEND': '|| ( =dev-java/sun-jdk-1.5.0* dev-java/gcj-jdk )'},
140 'virtual/jdk-1.6.0' : {
142 'RDEPEND': '|| ( =dev-java/icedtea-6* =dev-java/sun-jdk-1.6.0* )'},
143 'virtual/jdk-1.6.0-r1' : {
145 'RDEPEND': '|| ( =dev-java/icedtea-6* =dev-java/sun-jdk-1.6.0* )'},
146 'dev-java/gcj-jdk-4.5' : {},
147 'dev-java/gcj-jdk-4.5-r1' : {},
148 'dev-java/icedtea-6.1' : {},
149 'dev-java/icedtea-6.1-r1' : {},
150 'dev-java/sun-jdk-1.5' : {'SLOT': '1.5'},
151 'dev-java/sun-jdk-1.6' : {'SLOT': '1.6'},
152 'dev-java/sun-jre-bin-1.5' : {'SLOT': '1.5'},
153 'dev-java/sun-jre-bin-1.6' : {'SLOT': '1.6'},
155 'dev-java/ant-core-1.8' : {'DEPEND' : '>=virtual/jdk-1.4'},
156 'dev-db/hsqldb-1.8' : {'RDEPEND': '>=virtual/jre-1.6'},
171 'virtual/jre-1.5.0' : {
173 'RDEPEND': '|| ( =virtual/jdk-1.5.0* =dev-java/sun-jre-bin-1.5.0* )'},
174 'virtual/jre-1.6.0' : {
176 'RDEPEND': '|| ( =virtual/jdk-1.6.0* =dev-java/sun-jre-bin-1.6.0* )'},
177 'virtual/jdk-1.5.0' : {
179 'RDEPEND': '|| ( =dev-java/sun-jdk-1.5.0* dev-java/gcj-jdk )'},
180 'virtual/jdk-1.6.0' : {
182 'RDEPEND': '|| ( =dev-java/icedtea-6* =dev-java/sun-jdk-1.6.0* )'},
183 'dev-java/gcj-jdk-4.5' : {},
184 'dev-java/icedtea-6.1' : {},
186 'virtual/libusb-0' : {
187 'EAPI': '2', 'SLOT': '0',
189 '|| ( >=dev-libs/libusb-0.1.12-r1:0 dev-libs/libusb-compat ' +
190 '>=sys-freebsd/freebsd-lib-8.0[usb] )'},
193 # For verifying dependency graph results
194 GOLDEN_DEP_GRAPHS = {
195 'dev-libs/A-2': { 'needs': { 'dev-libs/B-2': 'runtime' },
197 'dev-libs/B-2': { 'needs': { 'dev-libs/C-2': 'runtime' } },
198 'dev-libs/C-2': { 'needs': { } },
199 'dev-libs/D-3': { 'needs': { } },
200 # TODO(mtennant): Bug in parallel_emerge deps graph makes blocker show up for
201 # E-3, rather than in just E-2 where it belongs. See crosbug.com/22190.
202 # To repeat bug, swap the commented status of next two lines.
203 #'dev-libs/E-3': { 'needs': { } },
204 'dev-libs/E-3': { 'needs': { 'dev-libs/D-3': 'blocker' } },
205 'chromeos-base/libcros-1': { 'needs': {
206 'dev-libs/B-2': 'runtime/buildtime',
207 'dev-libs/C-2': 'runtime/buildtime',
208 'chromeos-base/libchrome-57098-r4': 'buildtime',
209 'chromeos-base/flimflam-0.0.1-r228': 'runtime/buildtime'
211 'chromeos-base/flimflam-0.0.1-r228': { 'needs': {
212 'dev-libs/D-3': 'runtime'
214 'chromeos-base/libchrome-57098-r4': { 'needs': {
215 'dev-libs/E-3': 'runtime'
219 # For verifying dependency set results
221 'dev-libs/A': set(['dev-libs/A-2', 'dev-libs/B-2', 'dev-libs/C-2']),
222 'dev-libs/B': set(['dev-libs/B-2', 'dev-libs/C-2']),
223 'dev-libs/C': set(['dev-libs/C-2']),
224 'dev-libs/D': set(['dev-libs/D-3']),
225 'virtual/libusb': set(['virtual/libusb-1', 'dev-libs/libusb-1.0.5']),
226 'chromeos-base/libcros': set(['chromeos-base/libcros-1',
228 'chromeos-base/libchrome-57098-r4',
230 'chromeos-base/flimflam-0.0.1-r228',
237 def _GetGoldenDepsSet(pkg):
238 """Retrieve the golden dependency set for |pkg| from GOLDEN_DEP_SETS."""
239 return GOLDEN_DEP_SETS.get(pkg, None)
242 def _VerifyDepsGraph(deps_graph, pkgs):
244 if not _VerifyDepsGraphOnePkg(deps_graph, pkg):
250 def _VerifyDepsGraphOnePkg(deps_graph, pkg):
251 """Verfication function for Mox to validate deps graph for |pkg|."""
253 if deps_graph is None:
254 print('Error: no dependency graph passed into _GetPreOrderDepGraph')
257 if type(deps_graph) != dict:
258 print('Error: dependency graph is expected to be a dict. Instead:\n%r' %
264 golden_deps_set = _GetGoldenDepsSet(pkg)
265 if golden_deps_set == None:
266 print('Error: golden dependency list not configured for %s package' % pkg)
269 # Verify dependencies, by comparing them to GOLDEN_DEP_GRAPHS
271 golden_pkg_info = None
273 golden_pkg_info = GOLDEN_DEP_GRAPHS[p]
275 print('Error: golden dependency graph not configured for %s package' % p)
279 pkg_info = deps_graph[p]
280 for key in golden_pkg_info:
281 golden_value = golden_pkg_info[key]
282 value = pkg_info[key]
283 if not value == golden_value:
284 print('Error: while verifying "%s" value for %s package,'
285 ' expected:\n%r\nBut instead found:\n%r'
286 % (key, p, golden_value, value))
290 print('Error: dependency graph for %s is not as expected. Instead:\n%r' %
296 def _GenDepsGraphVerifier(pkgs):
297 """Generate a graph verification function for the given package."""
298 return lambda deps_graph: _VerifyDepsGraph(deps_graph, pkgs)
301 class ManifestLine(object):
302 """Class to represent a Manifest line."""
305 'type', # DIST, EBUILD, etc.
313 __attrlist__ = __slots__
315 def __init__(self, line=None, **kwargs):
316 """Parse |line| from manifest file."""
318 tokens = line.split()
319 self.type = tokens[0]
320 self.file = tokens[1]
321 self.size = tokens[2]
322 self.RMD160 = tokens[4]
323 self.SHA1 = tokens[6]
324 self.SHA256 = tokens[8]
326 assert tokens[3] == 'RMD160'
327 assert tokens[5] == 'SHA1'
328 assert tokens[7] == 'SHA256'
330 # Entries in kwargs are overwrites.
331 for attr in self.__attrlist__:
332 if attr in kwargs or not hasattr(self, attr):
333 setattr(self, attr, kwargs.get(attr))
336 return ('%s %s %s RMD160 %s SHA1 %s SHA256 %s' %
337 (self.type, self.file, self.size,
338 self.RMD160, self.SHA1, self.SHA256))
340 def __eq__(self, other):
341 """Equality support."""
343 if type(self) != type(other):
347 for attr in self.__attrlist__:
348 if getattr(self, attr, no_attr) != getattr(other, attr, no_attr):
353 def __ne__(self, other):
354 """Inequality for completeness."""
355 return not self == other
358 class RunCommandResult(object):
359 """Class to simulate result of cros_build_lib.RunCommand."""
360 __slots__ = ['returncode', 'output']
362 def __init__(self, returncode, output):
363 self.returncode = returncode
367 class PInfoTest(cros_test_lib.OutputTestCase):
368 """Tests for the PInfo class."""
371 pinfo = cpu.PInfo(category='SomeCat', user_arg='SomeArg')
373 self.assertEquals('SomeCat', pinfo.category)
374 self.assertEquals('SomeArg', pinfo.user_arg)
376 self.assertEquals(None, pinfo.cpv)
377 self.assertEquals(None, pinfo.overlay)
379 self.assertRaises(AttributeError, getattr, pinfo, 'foobar')
381 def testEqAndNe(self):
382 pinfo1 = cpu.PInfo(category='SomeCat', user_arg='SomeArg')
384 self.assertEquals(pinfo1, pinfo1)
385 self.assertTrue(pinfo1 == pinfo1)
386 self.assertFalse(pinfo1 != pinfo1)
388 pinfo2 = cpu.PInfo(category='SomeCat', user_arg='SomeArg')
390 self.assertEquals(pinfo1, pinfo2)
391 self.assertTrue(pinfo1 == pinfo2)
392 self.assertFalse(pinfo1 != pinfo2)
394 pinfo3 = cpu.PInfo(category='SomeCat', user_arg='SomeOtherArg')
396 self.assertNotEquals(pinfo1, pinfo3)
397 self.assertFalse(pinfo1 == pinfo3)
398 self.assertTrue(pinfo1 != pinfo3)
400 pinfo4 = cpu.PInfo(category='SomeCat', slot='SomeSlot')
402 self.assertNotEquals(pinfo1, pinfo4)
403 self.assertFalse(pinfo1 == pinfo4)
404 self.assertTrue(pinfo1 != pinfo4)
407 class CpuTestBase(cros_test_lib.MoxOutputTestCase):
408 """Base class for all test classes in this file."""
412 'playground_envvars',
416 self.playground = None
417 self.playground_envvars = None
420 self._TearDownPlayground()
422 def _SetUpPlayground(self, ebuilds=EBUILDS, installed=INSTALLED, world=WORLD,
424 """Prepare the temporary ebuild playground (ResolverPlayground).
426 This leverages test code in existing Portage modules to create an ebuild
427 hierarchy. This can be a little slow.
430 ebuilds: A list of hashes representing ebuild files in a portdir.
431 installed: A list of hashes representing ebuilds files already installed.
432 world: A list of lines to simulate in the world file.
433 active: True means that os.environ variables should be set
434 to point to the created playground, such that Portage tools
435 (such as emerge) can be run now using the playground as the active
436 PORTDIR. Also saves the playground as self._playground. If |active|
437 is False, then no os.environ variables are set and playground is
438 not saved (only returned).
441 Tuple (playground, envvars).
444 # TODO(mtennant): Support multiple overlays? This essentially
445 # creates just a default overlay.
446 # Also note that ResolverPlayground assumes ARCH=x86 for the
447 # default profile it creates.
448 playground = respgnd.ResolverPlayground(ebuilds=ebuilds,
452 # Set all envvars needed by parallel_emerge, since parallel_emerge
453 # normally does that when --board is given.
454 eroot = self._GetPlaygroundRoot(playground)
455 portdir = self._GetPlaygroundPortdir(playground)
456 envvars = {'PORTAGE_CONFIGROOT': eroot,
459 # See _GenPortageEnvvars for more info on this setting.
460 'PORTDIR_OVERLAY': portdir,
464 for envvar in envvars:
465 os.environ[envvar] = envvars[envvar]
467 self.playground = playground
468 self.playground_envvars = envvars
470 return (playground, envvars)
472 def _GetPlaygroundRoot(self, playground=None):
473 """Get the temp dir playground is using as ROOT."""
474 if playground is None:
475 playground = self.playground
477 eroot = playground.eroot
478 if eroot[-1:] == '/':
482 def _GetPlaygroundPortdir(self, playground=None):
483 """Get the temp portdir without playground."""
484 if playground is None:
485 playground = self.playground
487 eroot = self._GetPlaygroundRoot(playground)
488 portdir = '%s%s' % (eroot, DEFAULT_PORTDIR)
491 def _TearDownPlayground(self):
492 """Delete the temporary ebuild playground files."""
495 self.playground.cleanup()
497 # The clever tmp cleanup code in osutils.TempDirDecorator
498 # will take care of the cleanup before this point if it
499 # is used in the current test. Just move along.
502 self.playground = None
503 self.playground_envvars = None
505 def _MockUpgrader(self, cmdargs=None, **kwargs):
506 """Set up a mocked Upgrader object with the given args."""
507 upgrader_slot_defaults = {
508 '_curr_arch': DEFAULT_ARCH,
509 '_curr_board': 'some_board',
510 '_unstable_ok': False,
514 upgrader = self.mox.CreateMock(cpu.Upgrader)
516 # Initialize each attribute with default value.
517 for slot in cpu.Upgrader.__slots__:
518 value = upgrader_slot_defaults.get(slot, None)
519 upgrader.__setattr__(slot, value)
521 # Initialize with command line if given.
522 if cmdargs is not None:
523 parser = cpu._CreateParser()
524 options = parser.parse_args(cmdargs)
525 cpu.Upgrader.__init__(upgrader, options)
527 # Override Upgrader attributes if requested.
528 for slot in cpu.Upgrader.__slots__:
531 upgrader.__setattr__(slot, kwargs[slot])
536 @unittest.skip('relies on portage module not currently available')
537 class CopyUpstreamTest(CpuTestBase):
538 """Test Upgrader._CopyUpstreamPackage, _CopyUpstreamEclass, _CreateManifest"""
540 # This is a hack until crosbug.com/21965 is completed and upstreamed
541 # to Portage. Insert eclass simulation into tree.
542 def _AddEclassToPlayground(self, eclass, lines=None,
543 ebuilds=None, missing=False):
544 """Hack to insert an eclass into the playground source.
547 eclass: Name of eclass to create (without .eclass suffix). Will be
548 created as an empty file unless |lines| is specified.
549 lines: Lines of text to put into created eclass, if given.
550 ebuilds: List of ebuilds to put inherit line into. Should be path
551 to ebuild from playground portdir.
552 missing: If True, do not actually create the eclass file. Only makes
553 sense if |ebuilds| is non-empty, presumably to test inherit failure.
556 Full path to the eclass file, whether it was created or not.
558 portdir = self._GetPlaygroundPortdir()
559 eclass_path = os.path.join(portdir, 'eclass', '%s.eclass' % eclass)
561 # Create the eclass file
562 osutils.WriteFile(eclass_path, '\n'.join(lines if lines else []))
564 # Insert the inherit line into the ebuild file, if requested.
566 for ebuild in ebuilds:
567 ebuild_path = os.path.join(portdir, ebuild)
569 text = osutils.ReadFile(ebuild_path)
572 return match.group(1) + '\ninherit ' + eclass
573 text = re.sub(r'(EAPI.*)', repl, text)
575 osutils.WriteFile(ebuild_path, text)
577 # Remove the Manifest file
578 os.remove(os.path.join(os.path.dirname(ebuild_path), 'Manifest'))
580 # Recreate the Manifests using the ebuild utility.
581 cmd = ['ebuild', ebuild_path, 'manifest']
582 cros_build_lib.RunCommand(cmd, print_cmd=False, redirect_stdout=True,
583 combine_stdout_stderr=True)
585 # If requested, remove the eclass.
587 os.remove(eclass_path)
592 # _IdentifyNeededEclass
595 def _TestIdentifyNeededEclass(self, cpv, ebuild, eclass, create_eclass):
596 """Test Upgrader._IdentifyNeededEclass"""
598 self._SetUpPlayground()
599 portdir = self._GetPlaygroundPortdir()
600 mocked_upgrader = self._MockUpgrader(cmdargs=[],
601 _stable_repo=portdir,
603 self._AddEclassToPlayground(eclass,
605 missing=not create_eclass)
607 # Add test-specific mocks/stubs
610 envvars = cpu.Upgrader._GenPortageEnvvars(mocked_upgrader,
611 mocked_upgrader._curr_arch,
613 mocked_upgrader._GenPortageEnvvars(mocked_upgrader._curr_arch,
616 mocked_upgrader._GetBoardCmd('equery').AndReturn('equery')
620 with self.OutputCapturer():
621 result = cpu.Upgrader._IdentifyNeededEclass(mocked_upgrader, cpv)
626 def testIdentifyNeededEclassMissing(self):
627 result = self._TestIdentifyNeededEclass('dev-libs/A-2',
628 'dev-libs/A/A-2.ebuild',
631 self.assertEquals('inheritme.eclass', result)
633 def testIdentifyNeededEclassOK(self):
634 result = self._TestIdentifyNeededEclass('dev-libs/A-2',
635 'dev-libs/A/A-2.ebuild',
638 self.assertTrue(result is None)
641 # _CopyUpstreamEclass
644 @osutils.TempDirDecorator
645 def _TestCopyUpstreamEclass(self, eclass, do_copy,
646 local_copy_identical=None, error=None):
647 """Test Upgrader._CopyUpstreamEclass"""
649 self._SetUpPlayground()
650 upstream_portdir = self._GetPlaygroundPortdir()
651 portage_stable = self.tempdir
652 mocked_upgrader = self._MockUpgrader(_curr_board=None,
653 _upstream=upstream_portdir,
654 _stable_repo=portage_stable,
657 eclass_subpath = os.path.join('eclass', eclass + '.eclass')
658 eclass_path = os.path.join(portage_stable, eclass_subpath)
659 upstream_eclass_path = None
660 if do_copy or local_copy_identical:
661 lines = ['#Dummy eclass', '#Hi']
662 upstream_eclass_path = self._AddEclassToPlayground(eclass,
664 if local_copy_identical:
665 # Make it look like identical eclass already exists in portage-stable.
666 os.makedirs(os.path.dirname(eclass_path))
667 shutil.copy2(upstream_eclass_path, eclass_path)
668 elif local_copy_identical is not None:
669 # Make local copy some other gibberish.
670 os.makedirs(os.path.dirname(eclass_path))
671 osutils.WriteFile(eclass_path, 'garblety gook')
673 # Add test-specific mocks/stubs
677 mocked_upgrader._RunGit(mocked_upgrader._stable_repo,
678 ['add', eclass_subpath])
683 with self.OutputCapturer():
685 self.assertRaises(error, cpu.Upgrader._CopyUpstreamEclass,
686 mocked_upgrader, eclass + '.eclass')
688 result = cpu.Upgrader._CopyUpstreamEclass(mocked_upgrader,
693 self.assertTrue(result)
694 # Verify that eclass has been copied into portage-stable.
695 self.assertTrue(os.path.exists(eclass_path))
696 # Verify that eclass contents are correct.
697 self.assertTrue(filecmp.cmp(upstream_eclass_path, eclass_path))
700 self.assertFalse(result)
702 def testCopyUpstreamEclassCopyBecauseMissing(self):
703 self._TestCopyUpstreamEclass('inheritme',
706 def testCopyUpstreamEclassCopyBecauseDifferent(self):
707 self._TestCopyUpstreamEclass('inheritme',
709 local_copy_identical=False)
711 def testCopyUpstreamEclassNoCopyBecauseIdentical(self):
712 self._TestCopyUpstreamEclass('inheritme',
714 local_copy_identical=True)
716 def testCopyUpstreamEclassNoCopyBecauseUpstreamMissing(self):
717 self._TestCopyUpstreamEclass('inheritme',
722 # _CopyUpstreamPackage
725 @osutils.TempDirDecorator
726 def _TestCopyUpstreamPackage(self, catpkg, verrev, success,
727 existing_files, extra_upstream_files,
729 """Test Upgrader._CopyUpstreamPackage"""
731 upstream_cpv = '%s-%s' % (catpkg, verrev)
732 ebuild = '%s-%s.ebuild' % (catpkg.split('/')[-1], verrev)
734 self._SetUpPlayground()
735 upstream_portdir = self._GetPlaygroundPortdir()
737 # Simulate extra files in upsteam package dir.
738 if extra_upstream_files:
739 pkg_dir = os.path.join(upstream_portdir, catpkg)
740 if os.path.exists(pkg_dir):
741 for extra_file in extra_upstream_files:
742 open(os.path.join(pkg_dir, extra_file), 'w')
744 # Prepare dummy portage-stable dir, with extra previously
745 # existing files simulated if requested.
746 portage_stable = self.tempdir
748 pkg_dir = os.path.join(portage_stable, catpkg)
750 for existing_file in existing_files:
751 open(os.path.join(pkg_dir, existing_file), 'w')
754 mocked_upgrader = self._MockUpgrader(_curr_board=None,
755 _upstream=upstream_portdir,
756 _stable_repo=portage_stable,
761 def git_rm(*args, **_kwargs):
762 # Identify file that psuedo-git is to remove, then remove it.
763 # As with real "git rm", if the dir is then empty remove that.
764 # File to remove is last argument in git command (arg 1)
766 for f in args[1][2:]:
767 os.remove(os.path.join(dirpath, f))
769 os.rmdir(os.path.dirname(dirpath))
773 pkgdir = os.path.join(mocked_upgrader._stable_repo, catpkg)
776 rm_list = [os.path.join(catpkg, f) for f in existing_files]
778 # Accept files to remove in any order.
779 def rm_cmd_verifier(cmd):
780 cmd_args = cmd[2:] # Peel off 'rm -rf'.
781 return sorted(cmd_args) == sorted(rm_list)
783 mocked_upgrader._RunGit(mocked_upgrader._stable_repo,
784 mox.Func(rm_cmd_verifier),
786 ).WithSideEffects(git_rm)
788 mocked_upgrader._CreateManifest(os.path.join(upstream_portdir, catpkg),
790 mocked_upgrader._IdentifyNeededEclass(upstream_cpv).AndReturn(None)
795 with self.OutputCapturer():
797 self.assertRaises(error, cpu.Upgrader._CopyUpstreamPackage,
798 mocked_upgrader, upstream_cpv)
800 result = cpu.Upgrader._CopyUpstreamPackage(mocked_upgrader,
805 self.assertEquals(result, upstream_cpv)
807 # Verify that ebuild has been copied into portage-stable.
808 ebuild_path = os.path.join(portage_stable, catpkg, ebuild)
809 self.assertTrue(os.path.exists(ebuild_path),
810 msg='Missing expected ebuild after copy from upstream')
812 # Verify that any extra files upstream are also copied.
813 for extra_file in extra_upstream_files:
814 file_path = os.path.join(portage_stable, catpkg, extra_file)
815 msg = ('Missing expected extra file %s after copy from upstream' %
817 self.assertTrue(os.path.exists(file_path), msg=msg)
819 self.assertTrue(result is None)
821 def testCopyUpstreamPackageEmptyStable(self):
823 extra_upstream_files = []
824 self._TestCopyUpstreamPackage('dev-libs/D', '2', True,
826 extra_upstream_files)
828 def testCopyUpstreamPackageClutteredStable(self):
829 existing_files = ['foo', 'bar', 'foobar.ebuild', 'D-1.ebuild']
830 extra_upstream_files = []
831 self._TestCopyUpstreamPackage('dev-libs/D', '2', True,
833 extra_upstream_files)
835 def testCopyUpstreamPackageVersionNotAvailable(self):
836 """Should fail, dev-libs/D version 5 does not exist 'upstream'"""
838 extra_upstream_files = []
839 self._TestCopyUpstreamPackage('dev-libs/D', '5', False,
841 extra_upstream_files,
844 def testCopyUpstreamPackagePackageNotAvailable(self):
845 """Should fail, a-b-c/D does not exist 'upstream' in any version"""
847 extra_upstream_files = []
848 self._TestCopyUpstreamPackage('a-b-c/D', '5', False,
850 extra_upstream_files,
853 def testCopyUpstreamPackageExtraUpstreamFiles(self):
854 existing_files = ['foo', 'bar']
855 extra_upstream_files = ['keepme', 'andme']
856 self._TestCopyUpstreamPackage('dev-libs/F', '2-r1', True,
858 extra_upstream_files)
861 def _SetupManifestTest(self, ebuild,
862 upstream_mlines, current_mlines):
863 upstream_dir = tempfile.mkdtemp(dir=self.tempdir)
864 current_dir = tempfile.mkdtemp(dir=self.tempdir)
866 upstream_manifest = os.path.join(upstream_dir, 'Manifest')
867 current_manifest = os.path.join(current_dir, 'Manifest')
870 osutils.WriteFile(upstream_manifest,
871 '\n'.join(str(x) for x in upstream_mlines) + '\n')
874 osutils.WriteFile(current_manifest,
875 '\n'.join(str(x) for x in current_mlines) + '\n')
877 ebuild_path = os.path.join(current_dir, ebuild)
879 # Add test-specific mocks/stubs
880 self.mox.StubOutWithMock(cros_build_lib, 'RunCommand')
882 # Prepare test replay script.
883 run_result = RunCommandResult(returncode=0, output='')
884 cros_build_lib.RunCommand(['ebuild', ebuild_path, 'manifest'],
885 error_code_ok=True, print_cmd=False,
886 redirect_stdout=True, combine_stdout_stderr=True
887 ).AndReturn(run_result)
890 return (upstream_dir, current_dir)
892 def _AssertManifestContents(self, manifest_path, expected_manifest_lines):
894 with open(manifest_path, 'r') as f:
896 manifest_lines.append(ManifestLine(line))
898 msg = ('Manifest contents not as expected. Expected:\n%s\n'
900 ('\n'.join([str(ml) for ml in expected_manifest_lines]),
901 '\n'.join([str(ml) for ml in manifest_lines])))
902 self.assertTrue(manifest_lines == expected_manifest_lines, msg=msg)
903 self.assertFalse(manifest_lines != expected_manifest_lines, msg=msg)
905 @osutils.TempDirDecorator
906 def testCreateManifestNew(self):
907 """Test case with upstream but no current Manifest."""
909 mocked_upgrader = self._MockUpgrader()
911 ebuild = 'some-pkg.ebuild'
912 upst_mlines = [ManifestLine(type='DIST',
919 ManifestLine(type='EBUILD',
927 upstream_dir, current_dir = self._SetupManifestTest(ebuild,
930 upstream_manifest = os.path.join(upstream_dir, 'Manifest')
931 current_manifest = os.path.join(current_dir, 'Manifest')
933 # Run test verification.
934 self.assertFalse(os.path.exists(current_manifest))
935 cpu.Upgrader._CreateManifest(mocked_upgrader,
936 upstream_dir, current_dir, ebuild)
938 self.assertTrue(filecmp.cmp(upstream_manifest, current_manifest))
940 @osutils.TempDirDecorator
941 def testCreateManifestMerge(self):
942 """Test case with upstream but no current Manifest."""
944 mocked_upgrader = self._MockUpgrader()
946 ebuild = 'some-pkg.ebuild'
947 curr_mlines = [ManifestLine(type='DIST',
954 ManifestLine(type='DIST',
961 ManifestLine(type='EBUILD',
969 upst_mlines = [ManifestLine(type='DIST',
976 # This file is different from current manifest.
977 # It should be picked up by _CreateManifest.
978 ManifestLine(type='DIST',
985 ManifestLine(type='EBUILD',
994 upstream_dir, current_dir = self._SetupManifestTest(ebuild,
998 current_manifest = os.path.join(current_dir, 'Manifest')
1000 # Run test verification.
1001 self.assertTrue(os.path.exists(current_manifest))
1002 cpu.Upgrader._CreateManifest(mocked_upgrader,
1003 upstream_dir, current_dir, ebuild)
1004 self.mox.VerifyAll()
1006 expected_mlines = curr_mlines + upst_mlines[1:2]
1007 self._AssertManifestContents(current_manifest, expected_mlines)
1010 class GetPackageUpgradeStateTest(CpuTestBase):
1011 """Test Upgrader._GetPackageUpgradeState"""
1013 def _TestGetPackageUpgradeState(self, pinfo,
1018 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs)
1020 # Add test-specific mocks/stubs
1023 mocked_upgrader._FindUpstreamCPV(pinfo.cpv, unstable_ok=True,
1024 ).AndReturn(exists_upstream)
1025 self.mox.ReplayAll()
1028 result = cpu.Upgrader._GetPackageUpgradeState(mocked_upgrader, pinfo)
1029 self.mox.VerifyAll()
1033 def testGetPackageUpgradeStateLocalOnly(self):
1034 pinfo = cpu.PInfo(cpv='foo/bar-2',
1035 overlay='chromiumos-overlay',
1036 cpv_cmp_upstream=None,
1037 latest_upstream_cpv=None,
1039 result = self._TestGetPackageUpgradeState(pinfo, exists_upstream=False)
1040 self.assertEquals(result, utable.UpgradeTable.STATE_LOCAL_ONLY)
1042 def testGetPackageUpgradeStateUnknown(self):
1043 pinfo = cpu.PInfo(cpv='foo/bar-2',
1045 cpv_cmp_upstream=None,
1046 latest_upstream_cpv=None,
1048 result = self._TestGetPackageUpgradeState(pinfo, exists_upstream=False)
1049 self.assertEquals(result, utable.UpgradeTable.STATE_UNKNOWN)
1051 def testGetPackageUpgradeStateUpgradeAndDuplicated(self):
1052 pinfo = cpu.PInfo(cpv='foo/bar-2',
1053 overlay='chromiumos-overlay',
1054 cpv_cmp_upstream=1, # outdated
1055 latest_upstream_cpv='not important',
1057 result = self._TestGetPackageUpgradeState(pinfo, exists_upstream=True)
1058 self.assertEquals(result,
1059 utable.UpgradeTable.STATE_NEEDS_UPGRADE_AND_DUPLICATED)
1061 def testGetPackageUpgradeStateUpgradeAndPatched(self):
1062 pinfo = cpu.PInfo(cpv='foo/bar-2',
1063 overlay='chromiumos-overlay',
1064 cpv_cmp_upstream=1, # outdated
1065 latest_upstream_cpv='not important',
1067 result = self._TestGetPackageUpgradeState(pinfo, exists_upstream=False)
1068 self.assertEquals(result,
1069 utable.UpgradeTable.STATE_NEEDS_UPGRADE_AND_PATCHED)
1071 def testGetPackageUpgradeStateUpgrade(self):
1072 pinfo = cpu.PInfo(cpv='foo/bar-2',
1073 overlay='portage-stable',
1074 cpv_cmp_upstream=1, # outdated
1075 latest_upstream_cpv='not important',
1077 result = self._TestGetPackageUpgradeState(pinfo, exists_upstream=False)
1078 self.assertEquals(result, utable.UpgradeTable.STATE_NEEDS_UPGRADE)
1080 def testGetPackageUpgradeStateDuplicated(self):
1081 pinfo = cpu.PInfo(cpv='foo/bar-2',
1082 overlay='chromiumos-overlay',
1083 cpv_cmp_upstream=0, # current
1084 latest_upstream_cpv='not important',
1086 result = self._TestGetPackageUpgradeState(pinfo, exists_upstream=True)
1087 self.assertEquals(result, utable.UpgradeTable.STATE_DUPLICATED)
1089 def testGetPackageUpgradeStatePatched(self):
1090 pinfo = cpu.PInfo(cpv='foo/bar-2',
1091 overlay='chromiumos-overlay',
1092 cpv_cmp_upstream=0, # current
1093 latest_upstream_cpv='not important',
1095 result = self._TestGetPackageUpgradeState(pinfo, exists_upstream=False)
1096 self.assertEquals(result, utable.UpgradeTable.STATE_PATCHED)
1098 def testGetPackageUpgradeStateCurrent(self):
1099 pinfo = cpu.PInfo(cpv='foo/bar-2',
1100 overlay='portage-stable',
1101 cpv_cmp_upstream=0, # current
1102 latest_upstream_cpv='not important',
1104 result = self._TestGetPackageUpgradeState(pinfo, exists_upstream=False)
1105 self.assertEquals(result, utable.UpgradeTable.STATE_CURRENT)
1108 @unittest.skip('relies on portage module not currently available')
1109 class EmergeableTest(CpuTestBase):
1110 """Test Upgrader._AreEmergeable."""
1112 def _TestAreEmergeable(self, cpvlist, expect,
1113 debug=False, world=WORLD):
1114 """Test the Upgrader._AreEmergeable method.
1116 |cpvlist| is passed to _AreEmergeable.
1117 |expect| is boolean, expected return value of _AreEmergeable
1118 |debug| requests that emerge output in _AreEmergeable be shown.
1119 |world| is list of lines to override default world contents.
1122 cmdargs = ['--upgrade'] + cpvlist
1123 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs)
1124 self._SetUpPlayground(world=world)
1126 # Add test-specific mocks/stubs
1129 envvars = cpu.Upgrader._GenPortageEnvvars(mocked_upgrader,
1130 mocked_upgrader._curr_arch,
1132 mocked_upgrader._GenPortageEnvvars(mocked_upgrader._curr_arch,
1133 unstable_ok=False).AndReturn(envvars)
1134 mocked_upgrader._GetBoardCmd('emerge').AndReturn('emerge')
1135 self.mox.ReplayAll()
1138 result = cpu.Upgrader._AreEmergeable(mocked_upgrader, cpvlist)
1139 self.mox.VerifyAll()
1141 (code, _cmd, output) = result
1142 if debug or code != expect:
1143 print('\nTest ended with success==%r (expected==%r)' % (code, expect))
1144 print('Emerge output:\n%s' % output)
1146 self.assertEquals(code, expect)
1148 def testAreEmergeableOnePkg(self):
1149 """Should pass, one cpv target."""
1150 cpvlist = ['dev-libs/A-1']
1151 return self._TestAreEmergeable(cpvlist, True)
1153 def testAreEmergeableTwoPkgs(self):
1154 """Should pass, two cpv targets."""
1155 cpvlist = ['dev-libs/A-1', 'dev-libs/B-1']
1156 return self._TestAreEmergeable(cpvlist, True)
1158 def testAreEmergeableOnePkgTwoVersions(self):
1159 """Should fail, targets two versions of same package."""
1160 cpvlist = ['dev-libs/A-1', 'dev-libs/A-2']
1161 return self._TestAreEmergeable(cpvlist, False)
1163 def testAreEmergeableStableFlimFlam(self):
1164 """Should pass, target stable version of pkg."""
1165 cpvlist = ['chromeos-base/flimflam-0.0.1-r228']
1166 return self._TestAreEmergeable(cpvlist, True)
1168 def testAreEmergeableUnstableFlimFlam(self):
1169 """Should fail, target unstable version of pkg."""
1170 cpvlist = ['chromeos-base/flimflam-0.0.2-r123']
1171 return self._TestAreEmergeable(cpvlist, False)
1173 def testAreEmergeableBlockedPackages(self):
1174 """Should fail, targets have blocking deps on each other."""
1175 cpvlist = ['dev-libs/D-1', 'dev-libs/E-2']
1176 return self._TestAreEmergeable(cpvlist, False)
1178 def testAreEmergeableBlockedByInstalledPkg(self):
1179 """Should fail because of installed D-1 pkg."""
1180 cpvlist = ['dev-libs/E-2']
1181 return self._TestAreEmergeable(cpvlist, False)
1183 def testAreEmergeableNotBlockedByInstalledPkgNotInWorld(self):
1184 """Should pass because installed D-1 pkg not in world."""
1185 cpvlist = ['dev-libs/E-2']
1186 return self._TestAreEmergeable(cpvlist, True, world=[])
1188 def testAreEmergeableSamePkgDiffSlots(self):
1189 """Should pass, same package but different slots."""
1190 cpvlist = ['dev-libs/F-1', 'dev-libs/F-2']
1191 return self._TestAreEmergeable(cpvlist, True)
1193 def testAreEmergeableTwoPackagesIncompatibleDeps(self):
1194 """Should fail, targets depend on two versions of same pkg."""
1195 cpvlist = ['dev-apps/X-1', 'dev-apps/Y-2']
1196 return self._TestAreEmergeable(cpvlist, False)
1199 class CPVUtilTest(CpuTestBase):
1200 """Test various CPV utilities in Upgrader"""
1202 def _TestCmpCpv(self, cpv1, cpv2):
1203 """Test Upgrader._CmpCpv"""
1204 # Add test-specific mocks/stubs
1207 self.mox.ReplayAll()
1210 result = cpu.Upgrader._CmpCpv(cpv1, cpv2)
1211 self.mox.VerifyAll()
1215 def testCmpCpv(self):
1217 equal = [('foo/bar-1', 'foo/bar-1'),
1218 ('a-b-c/x-y-z-1.2.3-r1', 'a-b-c/x-y-z-1.2.3-r1'),
1219 ('foo/bar-1', 'foo/bar-1-r0'),
1222 for (cpv1, cpv2) in equal:
1223 self.assertEqual(0, self._TestCmpCpv(cpv1, cpv2))
1225 lessthan = [(None, 'foo/bar-1'),
1226 ('foo/bar-1', 'foo/bar-2'),
1227 ('foo/bar-1', 'foo/bar-1-r1'),
1228 ('foo/bar-1-r1', 'foo/bar-1-r2'),
1229 ('foo/bar-1.2.3', 'foo/bar-1.2.4'),
1230 ('foo/bar-5a', 'foo/bar-5b'),
1232 for (cpv1, cpv2) in lessthan:
1233 self.assertTrue(self._TestCmpCpv(cpv1, cpv2) < 0)
1234 self.assertTrue(self._TestCmpCpv(cpv2, cpv1) > 0)
1236 not_comparable = [('foo/bar-1', 'bar/foo-1'),
1238 for (cpv1, cpv2) in not_comparable:
1239 self.assertEquals(None, self._TestCmpCpv(cpv1, cpv2))
1241 def _TestGetCatPkgFromCpv(self, cpv):
1242 """Test Upgrader._GetCatPkgFromCpv"""
1243 # Add test-specific mocks/stubs
1246 self.mox.ReplayAll()
1249 result = cpu.Upgrader._GetCatPkgFromCpv(cpv)
1250 self.mox.VerifyAll()
1254 def testGetCatPkgFromCpv(self):
1255 # (input, output) tuples
1256 data = [('foo/bar-1', 'foo/bar'),
1257 ('a-b-c/x-y-z-1', 'a-b-c/x-y-z'),
1258 ('a-b-c/x-y-z-1.2.3-r3', 'a-b-c/x-y-z'),
1263 for (cpv, catpn) in data:
1264 result = self._TestGetCatPkgFromCpv(cpv)
1265 self.assertEquals(catpn, result)
1267 def _TestGetVerRevFromCpv(self, cpv):
1268 """Test Upgrader._GetVerRevFromCpv"""
1269 # Add test-specific mocks/stubs
1272 self.mox.ReplayAll()
1275 result = cpu.Upgrader._GetVerRevFromCpv(cpv)
1276 self.mox.VerifyAll()
1280 def testGetVerRevFromCpv(self):
1281 # (input, output) tuples
1282 data = [('foo/bar-1', '1'),
1283 ('a-b-c/x-y-z-1', '1'),
1284 ('a-b-c/x-y-z-1.2.3-r3', '1.2.3-r3'),
1285 ('foo/bar-3.222-r0', '3.222'),
1290 for (cpv, verrev) in data:
1291 result = self._TestGetVerRevFromCpv(cpv)
1292 self.assertEquals(verrev, result)
1294 def _TestGetEbuildPathFromCpv(self, cpv):
1295 """Test Upgrader._GetEbuildPathFromCpv"""
1296 # Add test-specific mocks/stubs
1299 self.mox.ReplayAll()
1302 result = cpu.Upgrader._GetEbuildPathFromCpv(cpv)
1303 self.mox.VerifyAll()
1307 def testGetEbuildPathFromCpv(self):
1308 # (input, output) tuples
1309 data = [('foo/bar-1', 'foo/bar/bar-1.ebuild'),
1310 ('a-b-c/x-y-z-1', 'a-b-c/x-y-z/x-y-z-1.ebuild'),
1311 ('a-b-c/x-y-z-1.2.3-r3', 'a-b-c/x-y-z/x-y-z-1.2.3-r3.ebuild'),
1312 ('foo/bar-3.222-r0', 'foo/bar/bar-3.222-r0.ebuild'),
1315 for (cpv, verrev) in data:
1316 result = self._TestGetEbuildPathFromCpv(cpv)
1317 self.assertEquals(verrev, result)
1320 class PortageStableTest(CpuTestBase):
1321 """Test Upgrader methods _SaveStatusOnStableRepo, _CheckStableRepoOnBranch"""
1323 STATUS_MIX = {'path1/file1': 'M',
1324 'path1/path2/file2': 'A',
1328 'unknown/file': '??',
1330 STATUS_UNKNOWN = {'foo/bar': '??',
1336 # _CheckStableRepoOnBranch
1339 def _TestCheckStableRepoOnBranch(self, run_result, expect_err):
1340 """Test Upgrader._CheckStableRepoOnBranch"""
1342 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs)
1344 # Add test-specific mocks/stubs
1347 mocked_upgrader._RunGit(mocked_upgrader._stable_repo,
1348 ['branch'], redirect_stdout=True,
1349 ).AndReturn(run_result)
1350 self.mox.ReplayAll()
1354 cpu.Upgrader._CheckStableRepoOnBranch(mocked_upgrader)
1355 self.assertFalse(expect_err, 'Expected RuntimeError, but none raised.')
1356 except RuntimeError as ex:
1357 self.assertTrue(expect_err, 'Unexpected RuntimeError: %s' % str(ex))
1358 self.mox.VerifyAll()
1360 def testCheckStableRepoOnBranchNoBranch(self):
1361 """Should fail due to 'git branch' saying 'no branch'"""
1362 output = '* (no branch)\n somebranch\n otherbranch\n'
1363 run_result = RunCommandResult(returncode=0, output=output)
1364 self._TestCheckStableRepoOnBranch(run_result, True)
1366 def testCheckStableRepoOnBranchOK1(self):
1367 """Should pass as 'git branch' indicates a branch"""
1368 output = '* somebranch\n otherbranch\n'
1369 run_result = RunCommandResult(returncode=0, output=output)
1370 self._TestCheckStableRepoOnBranch(run_result, False)
1372 def testCheckStableRepoOnBranchOK2(self):
1373 """Should pass as 'git branch' indicates a branch"""
1374 output = ' somebranch\n* otherbranch\n'
1375 run_result = RunCommandResult(returncode=0, output=output)
1376 self._TestCheckStableRepoOnBranch(run_result, False)
1378 def testCheckStableRepoOnBranchFail(self):
1379 """Should fail as 'git branch' failed"""
1380 output = 'does not matter'
1381 run_result = RunCommandResult(returncode=1, output=output)
1382 self._TestCheckStableRepoOnBranch(run_result, True)
1385 # _SaveStatusOnStableRepo
1388 def _TestSaveStatusOnStableRepo(self, run_result):
1389 """Test Upgrader._SaveStatusOnStableRepo"""
1391 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs)
1393 # Add test-specific mocks/stubs
1396 mocked_upgrader._RunGit(mocked_upgrader._stable_repo,
1397 ['status', '-s'], redirect_stdout=True,
1398 ).AndReturn(run_result)
1399 self.mox.ReplayAll()
1402 cpu.Upgrader._SaveStatusOnStableRepo(mocked_upgrader)
1403 self.mox.VerifyAll()
1405 self.assertFalse(mocked_upgrader._stable_repo_stashed)
1406 return mocked_upgrader._stable_repo_status
1408 def testSaveStatusOnStableRepoFailed(self):
1409 """Test case where 'git status -s' fails, should raise RuntimeError"""
1410 run_result = RunCommandResult(returncode=1,
1413 self.assertRaises(RuntimeError,
1414 self._TestSaveStatusOnStableRepo,
1417 def testSaveStatusOnStableRepoAllKinds(self):
1418 """Test where 'git status -s' returns all status kinds"""
1419 status_lines = ['%2s %s' % (v, k) for (k, v) in self.STATUS_MIX.items()]
1420 status_output = '\n'.join(status_lines)
1421 run_result = RunCommandResult(returncode=0,
1422 output=status_output)
1423 status = self._TestSaveStatusOnStableRepo(run_result)
1424 self.assertEqual(status, self.STATUS_MIX)
1426 def testSaveStatusOnStableRepoRename(self):
1427 """Test where 'git status -s' shows a file rename"""
1430 status_lines = [' R %s --> %s' % (old, new)]
1431 status_output = '\n'.join(status_lines)
1432 run_result = RunCommandResult(returncode=0,
1433 output=status_output)
1434 status = self._TestSaveStatusOnStableRepo(run_result)
1435 self.assertEqual(status, {old: 'D', new: 'A'})
1437 def testSaveStatusOnStableRepoEmpty(self):
1438 """Test empty response from 'git status -s'"""
1439 run_result = RunCommandResult(returncode=0,
1441 status = self._TestSaveStatusOnStableRepo(run_result)
1442 self.assertEqual(status, {})
1448 def _TestAnyChangesStaged(self, status_dict):
1449 """Test Upgrader._AnyChangesStaged"""
1450 mocked_upgrader = self._MockUpgrader(_stable_repo_status=status_dict)
1452 # Add test-specific mocks/stubs
1455 self.mox.ReplayAll()
1458 result = cpu.Upgrader._AnyChangesStaged(mocked_upgrader)
1459 self.mox.VerifyAll()
1463 def testAnyChangesStagedMix(self):
1464 """Should return True"""
1465 self.assertTrue(self._TestAnyChangesStaged(self.STATUS_MIX),
1466 'Failed to notice files with changed status.')
1468 def testAnyChangesStagedUnknown(self):
1469 """Should return False, only files with '??' status"""
1470 self.assertFalse(self._TestAnyChangesStaged(self.STATUS_UNKNOWN),
1471 'Should not consider files with "??" status.')
1473 def testAnyChangesStagedEmpty(self):
1474 """Should return False, no file statuses"""
1475 self.assertFalse(self._TestAnyChangesStaged(self.STATUS_EMPTY),
1476 'No files should mean no changes staged.')
1482 def testStashChanges(self):
1483 """Test Upgrader._StashChanges"""
1484 mocked_upgrader = self._MockUpgrader(cmdargs=[],
1485 _stable_repo_stashed=False)
1486 self.assertFalse(mocked_upgrader._stable_repo_stashed)
1488 # Add test-specific mocks/stubs
1491 mocked_upgrader._RunGit(mocked_upgrader._stable_repo,
1493 redirect_stdout=True,
1494 combine_stdout_stderr=True)
1495 self.mox.ReplayAll()
1498 cpu.Upgrader._StashChanges(mocked_upgrader)
1499 self.mox.VerifyAll()
1501 self.assertTrue(mocked_upgrader._stable_repo_stashed)
1504 # _UnstashAnyChanges
1507 def _TestUnstashAnyChanges(self, stashed):
1508 """Test Upgrader._UnstashAnyChanges"""
1509 mocked_upgrader = self._MockUpgrader(cmdargs=[],
1510 _stable_repo_stashed=stashed)
1511 self.assertEqual(stashed, mocked_upgrader._stable_repo_stashed)
1513 # Add test-specific mocks/stubs
1517 mocked_upgrader._RunGit(mocked_upgrader._stable_repo,
1518 ['stash', 'pop', '--index'],
1519 redirect_stdout=True,
1520 combine_stdout_stderr=True)
1521 self.mox.ReplayAll()
1524 cpu.Upgrader._UnstashAnyChanges(mocked_upgrader)
1525 self.mox.VerifyAll()
1527 self.assertFalse(mocked_upgrader._stable_repo_stashed)
1529 def testUnstashAnyChanges(self):
1530 self._TestUnstashAnyChanges(True)
1531 self._TestUnstashAnyChanges(False)
1534 # _DropAnyStashedChanges
1537 def _TestDropAnyStashedChanges(self, stashed):
1538 """Test Upgrader._DropAnyStashedChanges"""
1539 mocked_upgrader = self._MockUpgrader(cmdargs=[],
1540 _stable_repo_stashed=stashed)
1541 self.assertEqual(stashed, mocked_upgrader._stable_repo_stashed)
1543 # Add test-specific mocks/stubs
1547 mocked_upgrader._RunGit(mocked_upgrader._stable_repo,
1549 redirect_stdout=True,
1550 combine_stdout_stderr=True)
1551 self.mox.ReplayAll()
1554 cpu.Upgrader._DropAnyStashedChanges(mocked_upgrader)
1555 self.mox.VerifyAll()
1557 self.assertFalse(mocked_upgrader._stable_repo_stashed)
1559 def testDropAnyStashedChanges(self):
1560 self._TestDropAnyStashedChanges(True)
1561 self._TestDropAnyStashedChanges(False)
1564 class UtilityTest(CpuTestBase):
1565 """Test several Upgrader methods.
1567 Test these Upgrader methods: _SplitEBuildPath, _GenPortageEnvvars
1574 def _TestIsInUpgradeMode(self, cmdargs):
1575 """Test Upgrader._IsInUpgradeMode. Pretty simple."""
1576 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs)
1578 # Add test-specific mocks/stubs
1581 self.mox.ReplayAll()
1584 result = cpu.Upgrader._IsInUpgradeMode(mocked_upgrader)
1585 self.mox.VerifyAll()
1589 def testIsInUpgradeModeNoOpts(self):
1590 """Should not be in upgrade mode with no options."""
1591 result = self._TestIsInUpgradeMode([])
1592 self.assertFalse(result)
1594 def testIsInUpgradeModeUpgrade(self):
1595 """Should be in upgrade mode with --upgrade."""
1596 result = self._TestIsInUpgradeMode(['--upgrade'])
1597 self.assertTrue(result)
1599 def testIsInUpgradeModeUpgradeDeep(self):
1600 """Should be in upgrade mode with --upgrade-deep."""
1601 result = self._TestIsInUpgradeMode(['--upgrade-deep'])
1602 self.assertTrue(result)
1608 def _TestGetBoardCmd(self, cmd, board):
1609 """Test Upgrader._GetBoardCmd."""
1610 mocked_upgrader = self._MockUpgrader(_curr_board=board)
1613 self.mox.ReplayAll()
1616 result = cpu.Upgrader._GetBoardCmd(mocked_upgrader, cmd)
1617 self.mox.VerifyAll()
1621 def testGetBoardCmdKnownCmds(self):
1623 for cmd in ['emerge', 'equery', 'portageq']:
1624 result = self._TestGetBoardCmd(cmd, cpu.Upgrader.HOST_BOARD)
1625 self.assertEquals(result, cmd)
1626 result = self._TestGetBoardCmd(cmd, board)
1627 self.assertEquals(result, '%s-%s' % (cmd, board))
1629 def testGetBoardCmdUnknownCmd(self):
1632 result = self._TestGetBoardCmd(cmd, cpu.Upgrader.HOST_BOARD)
1633 self.assertEquals(result, cmd)
1634 result = self._TestGetBoardCmd(cmd, board)
1635 self.assertEquals(result, cmd)
1638 # _GenPortageEnvvars testing
1641 def _TestGenPortageEnvvars(self, arch, unstable_ok,
1642 portdir=None, portage_configroot=None):
1643 """Testing the behavior of the Upgrader._GenPortageEnvvars method."""
1644 mocked_upgrader = self._MockUpgrader()
1647 self.mox.ReplayAll()
1650 result = cpu.Upgrader._GenPortageEnvvars(mocked_upgrader,
1652 portdir, portage_configroot)
1653 self.mox.VerifyAll()
1657 keyw = arch + ' ~' + arch
1659 self.assertEquals(result['ACCEPT_KEYWORDS'], keyw)
1661 self.assertFalse('PORTDIR' in result)
1663 self.assertEquals(result['PORTDIR'], portdir)
1664 if portage_configroot is None:
1665 self.assertFalse('PORTAGE_CONFIGROOT' in result)
1667 self.assertEquals(result['PORTAGE_CONFIGROOT'], portage_configroot)
1669 def testGenPortageEnvvars1(self):
1670 self._TestGenPortageEnvvars('arm', False)
1672 def testGenPortageEnvvars2(self):
1673 self._TestGenPortageEnvvars('x86', True)
1675 def testGenPortageEnvvars3(self):
1676 self._TestGenPortageEnvvars('x86', True,
1678 portage_configroot='/bar/foo')
1681 # _SplitEBuildPath testing
1684 def _TestSplitEBuildPath(self, ebuild_path, golden_result):
1685 """Test the behavior of the Upgrader._SplitEBuildPath method."""
1686 mocked_upgrader = self._MockUpgrader()
1689 self.mox.ReplayAll()
1692 result = cpu.Upgrader._SplitEBuildPath(mocked_upgrader,
1694 self.assertEquals(result, golden_result)
1695 self.mox.VerifyAll()
1697 def testSplitEBuildPath1(self):
1698 self._TestSplitEBuildPath('/foo/bar/portage/dev-libs/A/A-2.ebuild',
1699 ('portage', 'dev-libs', 'A', 'A-2'))
1701 def testSplitEBuildPath2(self):
1702 self._TestSplitEBuildPath('/foo/ooo/ccc/ppp/ppp-1.2.3-r123.ebuild',
1703 ('ooo', 'ccc', 'ppp', 'ppp-1.2.3-r123'))
1706 @unittest.skip('relies on portage module not currently available')
1707 class TreeInspectTest(CpuTestBase):
1708 """Test Upgrader methods: _FindCurrentCPV, _FindUpstreamCPV"""
1710 def _GenerateTestInput(self, category, pkg_name, ver_rev,
1711 path_prefix=DEFAULT_PORTDIR):
1712 """Return tuple (ebuild_path, cpv, cp)."""
1716 ebuild_path = '%s/%s/%s/%s-%s.ebuild' % (path_prefix,
1719 cpv = '%s/%s-%s' % (category, pkg_name, ver_rev)
1720 cp = '%s/%s' % (category, pkg_name)
1721 return (ebuild_path, cpv, cp)
1724 # _FindUpstreamCPV testing
1727 def _TestFindUpstreamCPV(self, pkg_arg, ebuild_expect, unstable_ok=False):
1728 """Test Upgrader._FindUpstreamCPV
1730 This points _FindUpstreamCPV at the ResolverPlayground as if it is
1734 self._SetUpPlayground()
1735 eroot = self._GetPlaygroundRoot()
1736 mocked_upgrader = self._MockUpgrader(_curr_board=None,
1740 # Add test-specific mocks/stubs
1743 envvars = cpu.Upgrader._GenPortageEnvvars(mocked_upgrader,
1744 mocked_upgrader._curr_arch,
1747 portage_configroot=eroot)
1748 portage_configroot = mocked_upgrader._emptydir
1749 mocked_upgrader._GenPortageEnvvars(mocked_upgrader._curr_arch,
1751 portdir=mocked_upgrader._upstream,
1752 portage_configroot=portage_configroot,
1753 ).AndReturn(envvars)
1756 ebuild_path = eroot + ebuild_expect
1757 split_path = cpu.Upgrader._SplitEBuildPath(mocked_upgrader, ebuild_path)
1758 mocked_upgrader._SplitEBuildPath(ebuild_path).AndReturn(split_path)
1759 self.mox.ReplayAll()
1762 result = cpu.Upgrader._FindUpstreamCPV(mocked_upgrader, pkg_arg,
1764 self.mox.VerifyAll()
1765 self.assertTrue(bool(ebuild_expect) == bool(result))
1769 def testFindUpstreamA2(self):
1770 (ebuild, cpv, cp) = self._GenerateTestInput(category='dev-libs',
1773 result = self._TestFindUpstreamCPV(cp, ebuild)
1774 self.assertEquals(result, cpv)
1776 def testFindUpstreamAAA(self):
1777 (ebuild, cpv, cp) = self._GenerateTestInput(category='dev-apps',
1780 result = self._TestFindUpstreamCPV(cp, ebuild)
1781 self.assertEquals(result, cpv)
1783 def testFindUpstreamF(self):
1784 (ebuild, cpv, cp) = self._GenerateTestInput(category='dev-libs',
1787 result = self._TestFindUpstreamCPV(cp, ebuild)
1788 self.assertEquals(result, cpv)
1790 def testFindUpstreamFlimflam(self):
1791 """Should find 0.0.1-r228 because more recent flimflam unstable."""
1792 (ebuild, cpv, cp) = self._GenerateTestInput(category='chromeos-base',
1793 pkg_name='flimflam',
1794 ver_rev='0.0.1-r228')
1795 result = self._TestFindUpstreamCPV(cp, ebuild)
1796 self.assertEquals(result, cpv)
1798 def testFindUpstreamFlimflamUnstable(self):
1799 """Should find 0.0.2-r123 because of unstable_ok."""
1800 (ebuild, cpv, cp) = self._GenerateTestInput(category='chromeos-base',
1801 pkg_name='flimflam',
1802 ver_rev='0.0.2-r123')
1803 result = self._TestFindUpstreamCPV(cp, ebuild, unstable_ok=True)
1804 self.assertEquals(result, cpv)
1807 # _FindCurrentCPV testing
1810 def _TestFindCurrentCPV(self, pkg_arg, ebuild_expect):
1811 """Test Upgrader._FindCurrentCPV
1813 This test points Upgrader._FindCurrentCPV to the ResolverPlayground
1814 tree as if it is the local source.
1817 mocked_upgrader = self._MockUpgrader(_curr_board=None)
1818 self._SetUpPlayground()
1819 eroot = self._GetPlaygroundRoot()
1821 # Add test-specific mocks/stubs
1824 envvars = cpu.Upgrader._GenPortageEnvvars(mocked_upgrader,
1825 mocked_upgrader._curr_arch,
1827 mocked_upgrader._GenPortageEnvvars(mocked_upgrader._curr_arch,
1828 unstable_ok=False).AndReturn(envvars)
1829 mocked_upgrader._GetBoardCmd('equery').AndReturn('equery')
1832 ebuild_path = eroot + ebuild_expect
1833 split_path = cpu.Upgrader._SplitEBuildPath(mocked_upgrader, ebuild_path)
1834 mocked_upgrader._SplitEBuildPath(ebuild_path).AndReturn(split_path)
1836 self.mox.ReplayAll()
1839 result = cpu.Upgrader._FindCurrentCPV(mocked_upgrader, pkg_arg)
1840 self.mox.VerifyAll()
1844 def testFindCurrentA(self):
1845 """Should find dev-libs/A-2."""
1846 (ebuild, cpv, cp) = self._GenerateTestInput(category='dev-libs',
1849 result = self._TestFindCurrentCPV(cp, ebuild)
1850 self.assertEquals(result, cpv)
1852 def testFindCurrentAAA(self):
1853 """Should find None, because dev-libs/AAA does not exist in tree."""
1854 (ebuild, cpv, cp) = self._GenerateTestInput(category='dev-libs',
1857 result = self._TestFindCurrentCPV(cp, ebuild)
1858 self.assertEquals(result, cpv)
1860 def testFindCurrentF(self):
1861 """Should find dev-libs/F-2."""
1862 (ebuild, cpv, cp) = self._GenerateTestInput(category='dev-libs',
1865 result = self._TestFindCurrentCPV(cp, ebuild)
1866 self.assertEquals(result, cpv)
1868 def testFindCurrentFlimflam(self):
1869 """Should find 0.0.1-r228 because more recent flimflam unstable."""
1870 (ebuild, cpv, cp) = self._GenerateTestInput(category='chromeos-base',
1871 pkg_name='flimflam',
1872 ver_rev='0.0.1-r228')
1873 result = self._TestFindCurrentCPV(cp, ebuild)
1874 self.assertEquals(result, cpv)
1877 class RunBoardTest(CpuTestBase):
1878 """Test Upgrader.RunBoard,PrepareToRun,RunCompleted."""
1880 def testRunCompletedSpecified(self):
1881 cmdargs = ['--upstream=/some/dir']
1882 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
1883 _emptydir='empty-dir',
1886 # Add test-specific mocks/stubs
1887 self.mox.StubOutWithMock(osutils, 'RmDir')
1890 osutils.RmDir('empty-dir', ignore_missing=True)
1891 self.mox.ReplayAll()
1894 with self.OutputCapturer():
1895 cpu.Upgrader.RunCompleted(mocked_upgrader)
1896 self.mox.VerifyAll()
1898 def testRunCompletedRemoveCache(self):
1899 cmdargs = ['--no-upstream-cache']
1900 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
1901 _emptydir='empty-dir',
1904 # Add test-specific mocks/stubs
1905 self.mox.StubOutWithMock(osutils, 'RmDir')
1906 self.mox.StubOutWithMock(osutils, 'SafeUnlink')
1909 osutils.RmDir(mocked_upgrader._upstream, ignore_missing=True)
1910 osutils.SafeUnlink('%s-README' % mocked_upgrader._upstream)
1911 osutils.RmDir('empty-dir', ignore_missing=True)
1912 self.mox.ReplayAll()
1915 with self.OutputCapturer():
1916 cpu.Upgrader.RunCompleted(mocked_upgrader)
1917 self.mox.VerifyAll()
1919 def testRunCompletedKeepCache(self):
1921 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
1922 _emptydir='empty-dir',
1925 # Add test-specific mocks/stubs
1926 self.mox.StubOutWithMock(osutils, 'RmDir')
1929 osutils.RmDir('empty-dir', ignore_missing=True)
1930 self.mox.ReplayAll()
1933 with self.OutputCapturer():
1934 cpu.Upgrader.RunCompleted(mocked_upgrader)
1935 self.mox.VerifyAll()
1937 def testPrepareToRunUpstreamRepoExists(self):
1939 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
1942 # Add test-specific mocks/stubs
1943 self.mox.StubOutWithMock(os.path, 'exists')
1944 self.mox.StubOutWithMock(osutils, 'RmDir')
1947 os.path.exists('/tmp/portage/.git/shallow').AndReturn(False)
1948 osutils.RmDir('/tmp/portage', ignore_missing=True)
1949 os.path.exists('/tmp/portage').AndReturn(True)
1950 mocked_upgrader._RunGit(
1951 '/tmp/portage', ['remote', 'set-url', 'origin',
1952 cpu.Upgrader.PORTAGE_GIT_URL])
1953 mocked_upgrader._RunGit(
1954 '/tmp/portage', ['remote', 'update'])
1955 mocked_upgrader._RunGit(
1956 '/tmp/portage', ['checkout', 'origin/gentoo'],
1957 combine_stdout_stderr=True, redirect_stdout=True)
1958 self.mox.ReplayAll()
1961 with self.OutputCapturer():
1962 cpu.Upgrader.PrepareToRun(mocked_upgrader)
1963 self.mox.VerifyAll()
1965 @osutils.TempDirDecorator
1966 def testPrepareToRunUpstreamRepoNew(self):
1968 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
1969 _upstream=self.tempdir,
1972 # Add test-specific mocks/stubs
1973 self.mox.StubOutWithMock(os.path, 'dirname')
1974 self.mox.StubOutWithMock(os.path, 'basename')
1975 self.mox.StubOutWithMock(tempfile, 'mkdtemp')
1979 root = os.path.dirname(mocked_upgrader._upstream).AndReturn('root')
1980 name = os.path.basename(mocked_upgrader._upstream).AndReturn('name')
1981 os.path.basename('origin/gentoo').AndReturn('gentoo')
1982 mocked_upgrader._RunGit(root,
1983 ['clone', '--branch', 'gentoo', '--depth', '1',
1984 cpu.Upgrader.PORTAGE_GIT_URL, name])
1985 self.mox.ReplayAll()
1989 with self.OutputCapturer():
1990 cpu.Upgrader.PrepareToRun(mocked_upgrader)
1991 self.mox.VerifyAll()
1993 self.mox.UnsetStubs()
1995 readme_path = self.tempdir + '-README'
1996 self.assertTrue(os.path.exists(readme_path))
1997 os.remove(readme_path)
1999 def _TestRunBoard(self, pinfolist, upgrade=False, staged_changes=False):
2000 """Test Upgrader.RunBoard."""
2002 targetlist = [pinfo.user_arg for pinfo in pinfolist]
2003 upstream_only_pinfolist = [pinfo for pinfo in pinfolist if not pinfo.cpv]
2005 cmdargs = targetlist
2007 cmdargs = ['--upgrade'] + cmdargs
2008 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
2010 board = 'runboard_testboard'
2012 # Add test-specific mocks/stubs
2013 self.mox.StubOutWithMock(cpu.Upgrader, '_FindBoardArch')
2016 mocked_upgrader._SaveStatusOnStableRepo()
2017 mocked_upgrader._LoadStableRepoCategories()
2018 cpu.Upgrader._FindBoardArch(board).AndReturn('x86')
2019 upgrade_mode = cpu.Upgrader._IsInUpgradeMode(mocked_upgrader)
2020 mocked_upgrader._IsInUpgradeMode().AndReturn(upgrade_mode)
2021 mocked_upgrader._AnyChangesStaged().AndReturn(staged_changes)
2022 if (staged_changes):
2023 mocked_upgrader._StashChanges()
2025 mocked_upgrader._ResolveAndVerifyArgs(targetlist,
2026 upgrade_mode).AndReturn(pinfolist)
2028 mocked_upgrader._FinalizeUpstreamPInfolist(pinfolist).AndReturn([])
2030 mocked_upgrader._GetCurrentVersions(pinfolist).AndReturn(pinfolist)
2031 mocked_upgrader._FinalizeLocalPInfolist(pinfolist).AndReturn([])
2034 mocked_upgrader._FinalizeUpstreamPInfolist(
2035 upstream_only_pinfolist).AndReturn([])
2037 mocked_upgrader._UnstashAnyChanges()
2038 mocked_upgrader._UpgradePackages([])
2040 mocked_upgrader._DropAnyStashedChanges()
2042 self.mox.ReplayAll()
2045 with self.OutputCapturer():
2046 cpu.Upgrader.RunBoard(mocked_upgrader, board)
2047 self.mox.VerifyAll()
2049 def testRunBoard1(self):
2050 target_pinfolist = [cpu.PInfo(user_arg='dev-libs/A',
2052 upstream_cpv='dev-libs/A-2',
2055 return self._TestRunBoard(target_pinfolist)
2057 def testRunBoard2(self):
2058 target_pinfolist = [cpu.PInfo(user_arg='dev-libs/A',
2060 upstream_cpv='dev-libs/A-2',
2063 return self._TestRunBoard(target_pinfolist, upgrade=True)
2065 def testRunBoard3(self):
2066 target_pinfolist = [cpu.PInfo(user_arg='dev-libs/A',
2068 upstream_cpv='dev-libs/A-2',
2071 return self._TestRunBoard(target_pinfolist, upgrade=True,
2072 staged_changes=True)
2074 def testRunBoardUpstreamOnlyStatusMode(self):
2075 """Status mode with package that is only upstream should error."""
2077 pinfolist = [cpu.PInfo(user_arg='dev-libs/M',
2079 upstream_cpv='dev-libs/M-2',
2083 targetlist = [pinfo.user_arg for pinfo in pinfolist]
2085 mocked_upgrader = self._MockUpgrader(cmdargs=['dev-libs/M'],
2087 board = 'runboard_testboard'
2089 # Add test-specific mocks/stubs
2090 self.mox.StubOutWithMock(cpu.Upgrader, '_FindBoardArch')
2093 mocked_upgrader._SaveStatusOnStableRepo()
2094 mocked_upgrader._LoadStableRepoCategories()
2095 cpu.Upgrader._FindBoardArch(board).AndReturn('x86')
2096 upgrade_mode = cpu.Upgrader._IsInUpgradeMode(mocked_upgrader)
2097 mocked_upgrader._IsInUpgradeMode().AndReturn(upgrade_mode)
2098 mocked_upgrader._AnyChangesStaged().AndReturn(False)
2100 mocked_upgrader._ResolveAndVerifyArgs(targetlist,
2101 upgrade_mode).AndReturn(pinfolist)
2102 mocked_upgrader._DropAnyStashedChanges()
2103 self.mox.ReplayAll()
2106 with self.OutputCapturer():
2107 self.assertRaises(RuntimeError,
2108 cpu.Upgrader.RunBoard,
2109 mocked_upgrader, board)
2110 self.mox.VerifyAll()
2113 class GiveEmergeResultsTest(CpuTestBase):
2114 """Test Upgrader._GiveEmergeResults"""
2116 def _TestGiveEmergeResultsOK(self, pinfolist, ok, error=None):
2118 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs)
2120 # Add test-specific mocks/stubs
2123 mocked_upgrader._AreEmergeable(mox.IgnoreArg(),
2124 ).AndReturn((ok, None, None))
2125 self.mox.ReplayAll()
2129 with self.OutputCapturer():
2131 self.assertRaises(error, cpu.Upgrader._GiveEmergeResults,
2132 mocked_upgrader, pinfolist)
2134 result = cpu.Upgrader._GiveEmergeResults(mocked_upgrader, pinfolist)
2135 self.mox.VerifyAll()
2139 def testGiveEmergeResultsUnmaskedOK(self):
2140 pinfolist = [cpu.PInfo(upgraded_cpv='abc/def-4', upgraded_unmasked=True),
2141 cpu.PInfo(upgraded_cpv='bcd/efg-8', upgraded_unmasked=True),
2143 self._TestGiveEmergeResultsOK(pinfolist, True)
2145 def testGiveEmergeResultsUnmaskedNotOK(self):
2146 pinfolist = [cpu.PInfo(upgraded_cpv='abc/def-4', upgraded_unmasked=True),
2147 cpu.PInfo(upgraded_cpv='bcd/efg-8', upgraded_unmasked=True),
2149 self._TestGiveEmergeResultsOK(pinfolist, False, error=RuntimeError)
2151 def _TestGiveEmergeResultsMasked(self, pinfolist, ok, masked_cpvs,
2154 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs)
2156 # Add test-specific mocks/stubs
2159 emergeable_tuple = (ok, 'some-cmd', 'some-output')
2160 mocked_upgrader._AreEmergeable(mox.IgnoreArg(),
2161 ).AndReturn(emergeable_tuple)
2163 for cpv in masked_cpvs:
2164 mocked_upgrader._GiveMaskedError(cpv, 'some-output').InAnyOrder()
2165 self.mox.ReplayAll()
2169 with self.OutputCapturer():
2171 self.assertRaises(error, cpu.Upgrader._GiveEmergeResults,
2172 mocked_upgrader, pinfolist)
2174 result = cpu.Upgrader._GiveEmergeResults(mocked_upgrader, pinfolist)
2175 self.mox.VerifyAll()
2179 def testGiveEmergeResultsMaskedOK(self):
2180 pinfolist = [cpu.PInfo(upgraded_cpv='abc/def-4', upgraded_unmasked=False),
2181 cpu.PInfo(upgraded_cpv='bcd/efg-8', upgraded_unmasked=False),
2183 masked_cpvs = ['abc/def-4', 'bcd/efg-8']
2184 self._TestGiveEmergeResultsMasked(pinfolist, True, masked_cpvs,
2187 def testGiveEmergeResultsMaskedNotOK(self):
2188 pinfolist = [cpu.PInfo(upgraded_cpv='abc/def-4', upgraded_unmasked=False),
2189 cpu.PInfo(upgraded_cpv='bcd/efg-8', upgraded_unmasked=False),
2191 masked_cpvs = ['abc/def-4', 'bcd/efg-8']
2192 self._TestGiveEmergeResultsMasked(pinfolist, False, masked_cpvs,
2196 class CheckStagedUpgradesTest(CpuTestBase):
2197 """Test Upgrader._CheckStagedUpgrades"""
2199 def testCheckStagedUpgradesTwoStaged(self):
2202 ebuild1 = 'a/b/foo/bar/bar-1.ebuild'
2203 ebuild2 = 'x/y/bar/foo/foo-3.ebuild'
2204 repo_status = {ebuild1: 'A',
2205 'a/b/foo/garbage': 'A',
2209 pinfolist = [cpu.PInfo(package='foo/bar'),
2210 cpu.PInfo(package='bar/foo'),
2213 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
2214 _stable_repo_status=repo_status)
2216 # Add test-specific mocks/stubs
2219 for ebuild in [ebuild1, ebuild2]:
2220 split = cpu.Upgrader._SplitEBuildPath(mocked_upgrader, ebuild)
2221 mocked_upgrader._SplitEBuildPath(ebuild).InAnyOrder().AndReturn(split)
2223 self.mox.ReplayAll()
2226 cpu.Upgrader._CheckStagedUpgrades(mocked_upgrader, pinfolist)
2227 self.mox.VerifyAll()
2229 def testCheckStagedUpgradesTwoStagedOneUnexpected(self):
2232 ebuild1 = 'a/b/foo/bar/bar-1.ebuild'
2233 ebuild2 = 'x/y/bar/foo/foo-3.ebuild'
2234 repo_status = {ebuild1: 'A',
2235 'a/b/foo/garbage': 'A',
2239 # Without foo/bar in the pinfolist it should complain about that
2240 # package having staged changes.
2241 pinfolist = [cpu.PInfo(package='bar/foo')]
2243 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
2244 _stable_repo_status=repo_status)
2246 # Add test-specific mocks/stubs
2249 for ebuild in [ebuild1, ebuild2]:
2250 split = cpu.Upgrader._SplitEBuildPath(mocked_upgrader, ebuild)
2251 mocked_upgrader._SplitEBuildPath(ebuild).InAnyOrder().AndReturn(split)
2253 self.mox.ReplayAll()
2256 self.assertRaises(RuntimeError, cpu.Upgrader._CheckStagedUpgrades,
2257 mocked_upgrader, pinfolist)
2258 self.mox.VerifyAll()
2260 def testCheckStagedUpgradesNoneStaged(self):
2263 pinfolist = [cpu.PInfo(package='foo/bar-1'),
2264 cpu.PInfo(package='bar/foo-3'),
2267 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
2268 _stable_repo_status=None)
2270 # Add test-specific mocks/stubs
2273 self.mox.ReplayAll()
2276 cpu.Upgrader._CheckStagedUpgrades(mocked_upgrader, pinfolist)
2277 self.mox.VerifyAll()
2280 class UpgradePackagesTest(CpuTestBase):
2281 """Test Upgrader._UpgradePackages"""
2283 def _TestUpgradePackages(self, pinfolist, upgrade):
2286 cmdargs.append('--upgrade')
2287 table = utable.UpgradeTable('some-arch')
2288 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
2291 # Add test-specific mocks/stubs
2294 upgrades_this_run = False
2295 for pinfo in pinfolist:
2296 pkg_result = bool(pinfo.upgraded_cpv)
2297 mocked_upgrader._UpgradePackage(pinfo).InAnyOrder('up'
2298 ).AndReturn(pkg_result)
2300 upgrades_this_run = True
2302 for pinfo in pinfolist:
2303 if pinfo.upgraded_cpv:
2304 mocked_upgrader._VerifyPackageUpgrade(pinfo).InAnyOrder('ver')
2305 mocked_upgrader._PackageReport(pinfo).InAnyOrder('ver')
2307 if upgrades_this_run:
2308 mocked_upgrader._GiveEmergeResults(pinfolist)
2310 upgrade_mode = cpu.Upgrader._IsInUpgradeMode(mocked_upgrader)
2311 mocked_upgrader._IsInUpgradeMode().AndReturn(upgrade_mode)
2313 mocked_upgrader._CheckStagedUpgrades(pinfolist)
2314 self.mox.ReplayAll()
2317 cpu.Upgrader._UpgradePackages(mocked_upgrader, pinfolist)
2318 self.mox.VerifyAll()
2320 def testUpgradePackagesUpgradeModeWithUpgrades(self):
2321 pinfolist = [cpu.PInfo(upgraded_cpv='abc/def-4'),
2322 cpu.PInfo(upgraded_cpv='bcd/efg-8'),
2323 cpu.PInfo(upgraded_cpv=None),
2324 cpu.PInfo(upgraded_cpv=None)
2326 self._TestUpgradePackages(pinfolist, True)
2328 def testUpgradePackagesUpgradeModeNoUpgrades(self):
2329 pinfolist = [cpu.PInfo(upgraded_cpv=None),
2330 cpu.PInfo(upgraded_cpv=None),
2332 self._TestUpgradePackages(pinfolist, True)
2334 def testUpgradePackagesStatusModeNoUpgrades(self):
2335 pinfolist = [cpu.PInfo(upgraded_cpv=None),
2336 cpu.PInfo(upgraded_cpv=None),
2338 self._TestUpgradePackages(pinfolist, False)
2341 class CategoriesRoundtripTest(cros_test_lib.MoxOutputTestCase):
2342 """Tests for full "round trip" runs."""
2344 @osutils.TempDirDecorator
2345 def _TestCategoriesRoundtrip(self, categories):
2346 stable_repo = self.tempdir
2347 cat_file = cpu.Upgrader.CATEGORIES_FILE
2348 profiles_dir = os.path.join(stable_repo, os.path.dirname(cat_file))
2350 self.mox.StubOutWithMock(cpu.Upgrader, '_RunGit')
2352 # Prepare replay script.
2353 cpu.Upgrader._RunGit(stable_repo, ['add', cat_file])
2354 self.mox.ReplayAll()
2356 options = cros_test_lib.EasyAttr(srcroot='foobar', upstream=None,
2358 upgrader = cpu.Upgrader(options=options)
2359 upgrader._stable_repo = stable_repo
2360 os.makedirs(profiles_dir)
2362 # Verification phase. Write then load categories.
2363 upgrader._stable_repo_categories = set(categories)
2364 upgrader._WriteStableRepoCategories()
2365 upgrader._stable_repo_categories = None
2366 upgrader._LoadStableRepoCategories()
2367 self.mox.VerifyAll()
2368 self.assertEquals(sorted(categories),
2369 sorted(upgrader._stable_repo_categories))
2372 categories = ['alpha-omega', 'omega-beta', 'beta-chi']
2373 self._TestCategoriesRoundtrip(categories)
2377 self._TestCategoriesRoundtrip(categories)
2380 categories = ['virtual', 'happy-days', 'virtually-there']
2381 self._TestCategoriesRoundtrip(categories)
2384 class UpgradePackageTest(CpuTestBase):
2385 """Test Upgrader._UpgradePackage"""
2387 def _TestUpgradePackage(self, pinfo, upstream_cpv, upstream_cmp,
2388 stable_up, latest_up,
2389 upgrade_requested, upgrade_staged,
2390 unstable_ok, force):
2393 cmdargs.append('--unstable-ok')
2395 cmdargs.append('--force')
2396 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs)
2398 # Add test-specific mocks/stubs
2399 self.mox.StubOutWithMock(cros_build_lib, 'RunCommand')
2402 mocked_upgrader._FindUpstreamCPV(pinfo.package).AndReturn(stable_up)
2403 mocked_upgrader._FindUpstreamCPV(pinfo.package,
2404 unstable_ok=True).AndReturn(latest_up)
2406 mocked_upgrader._PkgUpgradeRequested(pinfo).AndReturn(upgrade_requested)
2407 if upgrade_requested:
2408 mocked_upgrader._PkgUpgradeStaged(upstream_cpv
2409 ).AndReturn(upgrade_staged)
2410 if (not upgrade_staged and
2411 (upstream_cmp > 0 or (upstream_cmp == 0 and force))):
2412 mocked_upgrader._CopyUpstreamPackage(upstream_cpv
2413 ).AndReturn(upstream_cpv)
2414 upgrade_staged = True
2418 mocked_upgrader._SetUpgradedMaskBits(pinfo)
2419 ebuild_path = cpu.Upgrader._GetEbuildPathFromCpv(upstream_cpv)
2420 ebuild_path = os.path.join(mocked_upgrader._stable_repo,
2422 mocked_upgrader._StabilizeEbuild(ebuild_path)
2423 mocked_upgrader._RunGit(mocked_upgrader._stable_repo,
2424 ['add', pinfo.package])
2425 mocked_upgrader._UpdateCategories(pinfo)
2426 cache_files = 'metadata/md5-cache/%s-[0-9]*' % pinfo.package
2427 mocked_upgrader._RunGit(mocked_upgrader._stable_repo, ['rm',
2428 '--ignore-unmatch', '-q', '-f', cache_files])
2429 cmd = ['egencache', '--update', '--repo=portage-stable',
2431 run_result = RunCommandResult(returncode=0, output=None)
2432 cros_build_lib.RunCommand(cmd, print_cmd=False,
2433 redirect_stdout=True,
2434 combine_stdout_stderr=True).AndReturn(
2436 mocked_upgrader._RunGit(mocked_upgrader._stable_repo,
2437 ['add', cache_files])
2438 self.mox.ReplayAll()
2441 with self.OutputCapturer():
2442 result = cpu.Upgrader._UpgradePackage(mocked_upgrader, pinfo)
2443 self.mox.VerifyAll()
2446 self.assertEquals(upstream_cpv, pinfo.upstream_cpv)
2448 if upgrade_requested and (upstream_cpv != pinfo.cpv or force):
2449 self.assertEquals(upstream_cpv, pinfo.upgraded_cpv)
2451 self.assertTrue(pinfo.upgraded_cpv is None)
2453 self.assertTrue(pinfo.upstream_cpv is None)
2454 self.assertTrue(pinfo.upgraded_cpv is None)
2455 self.assertEquals(stable_up, pinfo.stable_upstream_cpv)
2456 self.assertEquals(latest_up, pinfo.latest_upstream_cpv)
2460 # Dimensions to vary:
2461 # 1) Upgrade for this package requested or not
2462 # 2) Upgrade can be stable or not
2463 # 3) Specific version to upgrade to specified
2464 # 4) Upgrade already staged or not
2465 # 5) Upgrade needed or not (current)
2467 def testUpgradePackageOutdatedRequestedStable(self):
2468 pinfo = cpu.PInfo(cpv='foo/bar-2',
2472 result = self._TestUpgradePackage(pinfo,
2473 upstream_cpv='foo/bar-3',
2474 upstream_cmp=1, # outdated
2475 stable_up='foo/bar-3',
2476 latest_up='foo/bar-5',
2477 upgrade_requested=True,
2478 upgrade_staged=False,
2482 self.assertTrue(result)
2484 def testUpgradePackageOutdatedRequestedUnstable(self):
2485 pinfo = cpu.PInfo(cpv='foo/bar-2',
2489 result = self._TestUpgradePackage(pinfo,
2490 upstream_cpv='foo/bar-5',
2491 upstream_cmp=1, # outdated
2492 stable_up='foo/bar-3',
2493 latest_up='foo/bar-5',
2494 upgrade_requested=True,
2495 upgrade_staged=False,
2499 self.assertTrue(result)
2501 def testUpgradePackageOutdatedRequestedStableSpecified(self):
2502 pinfo = cpu.PInfo(cpv='foo/bar-2',
2504 upstream_cpv='foo/bar-4',
2506 result = self._TestUpgradePackage(pinfo,
2507 upstream_cpv='foo/bar-4',
2508 upstream_cmp=1, # outdated
2509 stable_up='foo/bar-3',
2510 latest_up='foo/bar-5',
2511 upgrade_requested=True,
2512 upgrade_staged=False,
2513 unstable_ok=False, # not important
2516 self.assertTrue(result)
2518 def testUpgradePackageCurrentRequestedStable(self):
2519 pinfo = cpu.PInfo(cpv='foo/bar-3',
2523 result = self._TestUpgradePackage(pinfo,
2524 upstream_cpv='foo/bar-3',
2525 upstream_cmp=0, # current
2526 stable_up='foo/bar-3',
2527 latest_up='foo/bar-5',
2528 upgrade_requested=True,
2529 upgrade_staged=False,
2533 self.assertFalse(result)
2535 def testUpgradePackageCurrentRequestedStableForce(self):
2536 pinfo = cpu.PInfo(cpv='foo/bar-3',
2538 upstream_cpv='foo/bar-3',
2540 result = self._TestUpgradePackage(pinfo,
2541 upstream_cpv='foo/bar-3',
2542 upstream_cmp=0, # current
2543 stable_up='foo/bar-3',
2544 latest_up='foo/bar-5',
2545 upgrade_requested=True,
2546 upgrade_staged=False,
2550 self.assertTrue(result)
2552 def testUpgradePackageOutdatedStable(self):
2553 pinfo = cpu.PInfo(cpv='foo/bar-2',
2557 result = self._TestUpgradePackage(pinfo,
2558 upstream_cpv='foo/bar-3',
2559 upstream_cmp=1, # outdated
2560 stable_up='foo/bar-3',
2561 latest_up='foo/bar-5',
2562 upgrade_requested=False,
2563 upgrade_staged=False,
2567 self.assertFalse(result)
2569 def testUpgradePackageOutdatedRequestedStableStaged(self):
2570 pinfo = cpu.PInfo(cpv='foo/bar-2',
2574 result = self._TestUpgradePackage(pinfo,
2575 upstream_cpv='foo/bar-3',
2576 upstream_cmp=1, # outdated
2577 stable_up='foo/bar-3',
2578 latest_up='foo/bar-5',
2579 upgrade_requested=True,
2580 upgrade_staged=True,
2584 self.assertTrue(result)
2586 def testUpgradePackageOutdatedRequestedUnstableStaged(self):
2587 pinfo = cpu.PInfo(cpv='foo/bar-2',
2589 upstream_cpv='foo/bar-5',
2591 result = self._TestUpgradePackage(pinfo,
2592 upstream_cpv='foo/bar-5',
2593 upstream_cmp=1, # outdated
2594 stable_up='foo/bar-3',
2595 latest_up='foo/bar-5',
2596 upgrade_requested=True,
2597 upgrade_staged=True,
2601 self.assertTrue(result)
2604 class VerifyPackageTest(CpuTestBase):
2605 """Tests for _VerifyPackageUpgrade()."""
2607 def _TestVerifyPackageUpgrade(self, pinfo):
2609 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs)
2610 was_overwrite = pinfo.cpv_cmp_upstream == 0
2612 # Add test-specific mocks/stubs
2615 mocked_upgrader._VerifyEbuildOverlay(pinfo.upgraded_cpv,
2618 self.mox.ReplayAll()
2621 cpu.Upgrader._VerifyPackageUpgrade(mocked_upgrader, pinfo)
2622 self.mox.VerifyAll()
2624 def testVerifyPackageUpgrade(self):
2625 pinfo = cpu.PInfo(upgraded_cpv='foo/bar-3')
2627 for cpv_cmp_upstream in (0, 1):
2628 pinfo.cpv_cmp_upstream = cpv_cmp_upstream
2629 self._TestVerifyPackageUpgrade(pinfo)
2631 def _TestVerifyEbuildOverlay(self, cpv, overlay, ebuild_path, was_overwrite):
2632 """Test Upgrader._VerifyEbuildOverlay"""
2634 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
2635 _curr_arch=DEFAULT_ARCH,
2638 # Add test-specific mocks/stubs
2639 self.mox.StubOutWithMock(cros_build_lib, 'RunCommand')
2642 envvars = cpu.Upgrader._GenPortageEnvvars(mocked_upgrader,
2643 mocked_upgrader._curr_arch,
2645 mocked_upgrader._GenPortageEnvvars(mocked_upgrader._curr_arch,
2646 unstable_ok=False).AndReturn(envvars)
2647 mocked_upgrader._GetBoardCmd('equery').AndReturn('equery')
2648 run_result = RunCommandResult(returncode=0,
2650 cros_build_lib.RunCommand(['equery', '-C', 'which', '--include-masked',
2651 cpv], error_code_ok=True,
2652 extra_env=envvars, print_cmd=False,
2653 redirect_stdout=True, combine_stdout_stderr=True,
2654 ).AndReturn(run_result)
2655 split_ebuild = cpu.Upgrader._SplitEBuildPath(mocked_upgrader, ebuild_path)
2656 mocked_upgrader._SplitEBuildPath(ebuild_path).AndReturn(split_ebuild)
2657 self.mox.ReplayAll()
2660 cpu.Upgrader._VerifyEbuildOverlay(mocked_upgrader, cpv,
2661 overlay, was_overwrite)
2662 self.mox.VerifyAll()
2664 def testVerifyEbuildOverlayGood(self):
2666 overlay = 'some-overlay'
2667 good_path = '/some/path/%s/foo/bar/bar-2.ebuild' % overlay
2669 self._TestVerifyEbuildOverlay(cpv, overlay, good_path, False)
2671 def testVerifyEbuildOverlayEvilNonOverwrite(self):
2673 overlay = 'some-overlay'
2674 evil_path = '/some/path/spam/foo/bar/bar-2.ebuild'
2676 self.assertRaises(RuntimeError,
2677 self._TestVerifyEbuildOverlay,
2678 cpv, overlay, evil_path, False)
2680 def testVerifyEbuildOverlayEvilOverwrite(self):
2682 overlay = 'some-overlay'
2683 evil_path = '/some/path/spam/foo/bar/bar-2.ebuild'
2685 self.assertRaises(RuntimeError,
2686 self._TestVerifyEbuildOverlay,
2687 cpv, overlay, evil_path, True)
2689 def _TestSetUpgradedMaskBits(self, pinfo, output):
2690 cpv = pinfo.upgraded_cpv
2692 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
2693 _curr_arch=DEFAULT_ARCH,
2696 # Add test-specific mocks/stubs
2697 self.mox.StubOutWithMock(cros_build_lib, 'RunCommand')
2700 mocked_upgrader._GenPortageEnvvars(mocked_upgrader._curr_arch,
2701 unstable_ok=False).AndReturn('envvars')
2702 mocked_upgrader._GetBoardCmd('equery').AndReturn('equery')
2703 run_result = RunCommandResult(returncode=0,
2705 cros_build_lib.RunCommand(['equery', '-qCN', 'list', '-F',
2706 '$mask|$cpv:$slot', '-op', cpv],
2708 extra_env='envvars', print_cmd=False,
2709 redirect_stdout=True, combine_stdout_stderr=True,
2710 ).AndReturn(run_result)
2711 self.mox.ReplayAll()
2714 cpu.Upgrader._SetUpgradedMaskBits(mocked_upgrader, pinfo)
2715 self.mox.VerifyAll()
2717 def testGetMaskBitsUnmaskedStable(self):
2718 output = ' |foo/bar-2.7.0:0'
2719 pinfo = cpu.PInfo(upgraded_cpv='foo/bar-2.7.0')
2720 self._TestSetUpgradedMaskBits(pinfo, output)
2721 self.assertTrue(pinfo.upgraded_unmasked)
2723 def testGetMaskBitsUnmaskedUnstable(self):
2724 output = ' ~|foo/bar-2.7.3:0'
2725 pinfo = cpu.PInfo(upgraded_cpv='foo/bar-2.7.3')
2726 self._TestSetUpgradedMaskBits(pinfo, output)
2727 self.assertTrue(pinfo.upgraded_unmasked)
2729 def testGetMaskBitsMaskedStable(self):
2730 output = 'M |foo/bar-2.7.4:0'
2731 pinfo = cpu.PInfo(upgraded_cpv='foo/bar-2.7.4')
2732 self._TestSetUpgradedMaskBits(pinfo, output)
2733 self.assertFalse(pinfo.upgraded_unmasked)
2735 def testGetMaskBitsMaskedUnstable(self):
2736 output = 'M~|foo/bar-2.7.4-r1:0'
2737 pinfo = cpu.PInfo(upgraded_cpv='foo/bar-2.7.4-r1')
2738 self._TestSetUpgradedMaskBits(pinfo, output)
2739 self.assertFalse(pinfo.upgraded_unmasked)
2742 class CommitTest(CpuTestBase):
2743 """Test various commit-related Upgrader methods"""
2746 # _ExtractUpgradedPkgs
2749 def _TestExtractUpgradedPkgs(self, upgrade_lines):
2750 """Test Upgrader._ExtractUpgradedPkgs"""
2751 mocked_upgrader = self._MockUpgrader()
2754 self.mox.ReplayAll()
2757 with self.OutputCapturer():
2758 result = cpu.Upgrader._ExtractUpgradedPkgs(mocked_upgrader, upgrade_lines)
2759 self.mox.VerifyAll()
2763 def testExtractUpgradedPkgs(self):
2764 upgrade_lines = ['Upgraded abc/efg to version 1.2.3 on amd64, arm, x86',
2765 'Upgraded xyz/uvw to version 1.2.3 on amd64',
2766 'Upgraded xyz/uvw to version 3.2.1 on arm, x86',
2767 'Upgraded mno/pqr to version 12345 on x86',
2769 result = self._TestExtractUpgradedPkgs(upgrade_lines)
2770 self.assertEquals(result, ['efg', 'pqr', 'uvw'])
2773 # _AmendCommitMessage
2776 def _TestAmendCommitMessage(self, new_upgrade_lines,
2777 old_upgrade_lines, remaining_lines,
2779 """Test Upgrader._AmendCommitMessage"""
2780 mocked_upgrader = self._MockUpgrader()
2782 gold_lines = new_upgrade_lines + old_upgrade_lines
2783 def all_lines_verifier(lines):
2784 return gold_lines == lines
2786 # Add test-specific mocks/stubs
2789 git_result = RunCommandResult(returncode=0,
2791 mocked_upgrader._RunGit(mocked_upgrader._stable_repo,
2792 mox.IgnoreArg(), redirect_stdout=True,
2793 ).AndReturn(git_result)
2794 mocked_upgrader._CreateCommitMessage(mox.Func(all_lines_verifier),
2796 self.mox.ReplayAll()
2799 with self.OutputCapturer():
2800 cpu.Upgrader._AmendCommitMessage(mocked_upgrader,
2802 self.mox.VerifyAll()
2804 def testOldAndNew(self):
2805 new_upgrade_lines = ['Upgraded abc/efg to version 1.2.3 on amd64, arm, x86',
2806 'Upgraded mno/pqr to version 4.5-r1 on x86',
2808 old_upgrade_lines = ['Upgraded xyz/uvw to version 3.2.1 on arm, x86',
2809 'Upgraded mno/pqr to version 12345 on x86',
2811 remaining_lines = ['Extraneous extra comments in commit body.',
2813 'BUG=chromium-os:12345',
2814 'TEST=test everything',
2817 git_show_output = ('\n'.join(old_upgrade_lines) + '\n'
2819 + '\n'.join(remaining_lines))
2820 self._TestAmendCommitMessage(new_upgrade_lines, old_upgrade_lines,
2821 remaining_lines, git_show_output)
2823 def testOldOnly(self):
2824 old_upgrade_lines = ['Upgraded xyz/uvw to version 3.2.1 on arm, x86',
2825 'Upgraded mno/pqr to version 12345 on x86',
2827 git_show_output = ('\n'.join(old_upgrade_lines))
2828 self._TestAmendCommitMessage([], old_upgrade_lines, [], git_show_output)
2830 def testNewOnly(self):
2831 new_upgrade_lines = ['Upgraded abc/efg to version 1.2.3 on amd64, arm, x86',
2832 'Upgraded mno/pqr to version 4.5-r1 on x86',
2834 git_show_output = ''
2835 self._TestAmendCommitMessage(new_upgrade_lines, [], [], git_show_output)
2837 def testOldEditedAndNew(self):
2838 new_upgrade_lines = ['Upgraded abc/efg to version 1.2.3 on amd64, arm, x86',
2839 'Upgraded mno/pqr to version 4.5-r1 on x86',
2841 old_upgrade_lines = ['So I upgraded xyz/uvw to version 3.2.1 on arm, x86',
2842 'Then I Upgraded mno/pqr to version 12345 on x86',
2844 remaining_lines = ['Extraneous extra comments in commit body.',
2846 'BUG=chromium-os:12345',
2847 'TEST=test everything',
2850 git_show_output = ('\n'.join(old_upgrade_lines) + '\n'
2852 + '\n'.join(remaining_lines))
2854 # In this test, it should not recognize the existing old_upgrade_lines
2855 # as a previous commit message from this script. So it should give a
2856 # warning and push those lines to the end (grouped with remaining_lines).
2857 remaining_lines = old_upgrade_lines + [''] + remaining_lines
2858 self._TestAmendCommitMessage(new_upgrade_lines, [],
2859 remaining_lines, git_show_output)
2862 # _CreateCommitMessage
2865 def _TestCreateCommitMessage(self, upgrade_lines):
2866 """Test Upgrader._CreateCommitMessage"""
2867 mocked_upgrader = self._MockUpgrader()
2869 # Add test-specific mocks/stubs
2872 upgrade_pkgs = cpu.Upgrader._ExtractUpgradedPkgs(mocked_upgrader,
2874 mocked_upgrader._ExtractUpgradedPkgs(upgrade_lines).AndReturn(upgrade_pkgs)
2875 self.mox.ReplayAll()
2878 with self.OutputCapturer():
2879 result = cpu.Upgrader._CreateCommitMessage(mocked_upgrader, upgrade_lines)
2880 self.mox.VerifyAll()
2882 self.assertTrue(': upgraded package' in result or
2883 'Upgraded the following' in result)
2886 def testCreateCommitMessageOnePkg(self):
2887 upgrade_lines = ['Upgraded abc/efg to version 1.2.3 on amd64, arm, x86',
2889 result = self._TestCreateCommitMessage(upgrade_lines)
2891 # Commit message should have:
2892 # -- Summary that mentions 'efg' and ends in "package" (singular)
2893 # -- Body corresponding to upgrade_lines
2894 # -- BUG= line (with space after '=' to invalidate it)
2895 # -- TEST= line (with space after '=' to invalidate it)
2896 body = r'\n'.join([re.sub(r'\s+', r'\s', line) for line in upgrade_lines])
2897 regexp = re.compile(r'''^efg:\supgraded\spackage\sto\supstream\n # Summary
2901 ^BUG=\s.+\n # BUG line
2902 ^TEST=\s # TEST line
2904 re.VERBOSE | re.MULTILINE)
2905 self.assertTrue(regexp.search(result))
2907 def testCreateCommitMessageThreePkgs(self):
2908 upgrade_lines = ['Upgraded abc/efg to version 1.2.3 on amd64, arm, x86',
2909 'Upgraded xyz/uvw to version 1.2.3 on amd64',
2910 'Upgraded xyz/uvw to version 3.2.1 on arm, x86',
2911 'Upgraded mno/pqr to version 12345 on x86',
2913 result = self._TestCreateCommitMessage(upgrade_lines)
2915 # Commit message should have:
2916 # -- Summary that mentions 'efg, pqr, uvw' and ends in "packages" (plural)
2917 # -- Body corresponding to upgrade_lines
2918 # -- BUG= line (with space after '=' to invalidate it)
2919 # -- TEST= line (with space after '=' to invalidate it)
2920 body = r'\n'.join([re.sub(r'\s+', r'\s', line) for line in upgrade_lines])
2921 regexp = re.compile(r'''^efg,\spqr,\suvw:\supgraded\spackages.*\n # Summary
2925 ^BUG=\s.+\n # BUG line
2926 ^TEST=\s # TEST line
2928 re.VERBOSE | re.MULTILINE)
2929 self.assertTrue(regexp.search(result))
2931 def testCreateCommitMessageTenPkgs(self):
2932 upgrade_lines = ['Upgraded abc/efg to version 1.2.3 on amd64, arm, x86',
2933 'Upgraded bcd/fgh to version 1.2.3 on amd64',
2934 'Upgraded cde/ghi to version 3.2.1 on arm, x86',
2935 'Upgraded def/hij to version 12345 on x86',
2936 'Upgraded efg/ijk to version 1.2.3 on amd64',
2937 'Upgraded fgh/jkl to version 3.2.1 on arm, x86',
2938 'Upgraded ghi/klm to version 12345 on x86',
2939 'Upgraded hij/lmn to version 1.2.3 on amd64',
2940 'Upgraded ijk/mno to version 3.2.1 on arm, x86',
2941 'Upgraded jkl/nop to version 12345 on x86',
2943 result = self._TestCreateCommitMessage(upgrade_lines)
2945 # Commit message should have:
2946 # -- Summary that mentions '10' and ends in "packages" (plural)
2947 # -- Body corresponding to upgrade_lines
2948 # -- BUG= line (with space after '=' to invalidate it)
2949 # -- TEST= line (with space after '=' to invalidate it)
2950 body = r'\n'.join([re.sub(r'\s+', r'\s', line) for line in upgrade_lines])
2951 regexp = re.compile(r'''^Upgraded\s.*10.*\spackages\n # Summary
2955 ^BUG=\s.+\n # BUG line
2956 ^TEST=\s # TEST line
2958 re.VERBOSE | re.MULTILINE)
2959 self.assertTrue(regexp.search(result))
2962 @unittest.skip('relies on portage module not currently available')
2963 class GetCurrentVersionsTest(CpuTestBase):
2964 """Test Upgrader._GetCurrentVersions"""
2966 def _TestGetCurrentVersionsLocalCpv(self, target_pinfolist):
2968 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
2970 self._SetUpPlayground()
2972 # Add test-specific mocks/stubs
2973 self.mox.StubOutWithMock(cpu.Upgrader, '_GetPreOrderDepGraph')
2976 packages = [pinfo.package for pinfo in target_pinfolist]
2977 targets = ['=' + pinfo.cpv for pinfo in target_pinfolist]
2978 pm_argv = cpu.Upgrader._GenParallelEmergeArgv(mocked_upgrader, targets)
2979 pm_argv.append('--root-deps')
2980 verifier = _GenDepsGraphVerifier(packages)
2981 mocked_upgrader._GenParallelEmergeArgv(targets).AndReturn(pm_argv)
2982 mocked_upgrader._SetPortTree(mox.IsA(portcfg.config), mox.IsA(dict))
2983 cpu.Upgrader._GetPreOrderDepGraph(mox.Func(verifier)).AndReturn([])
2984 self.mox.ReplayAll()
2987 result = cpu.Upgrader._GetCurrentVersions(mocked_upgrader, target_pinfolist)
2988 self.mox.VerifyAll()
2992 def testGetCurrentVersionsTwoPkgs(self):
2993 target_pinfolist = [cpu.PInfo(package='dev-libs/A', cpv='dev-libs/A-2'),
2994 cpu.PInfo(package='dev-libs/D', cpv='dev-libs/D-3'),
2996 self._TestGetCurrentVersionsLocalCpv(target_pinfolist)
2998 def testGetCurrentVersionsOnePkgB(self):
2999 target_pinfolist = [cpu.PInfo(package='dev-libs/B', cpv='dev-libs/B-2'),
3001 self._TestGetCurrentVersionsLocalCpv(target_pinfolist)
3003 def testGetCurrentVersionsOnePkgLibcros(self):
3004 target_pinfolist = [cpu.PInfo(package='chromeos-base/libcros',
3005 cpv='chromeos-base/libcros-1',
3008 self._TestGetCurrentVersionsLocalCpv(target_pinfolist)
3010 def _TestGetCurrentVersionsPackageOnly(self, target_pinfolist):
3012 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
3014 self._SetUpPlayground()
3016 # Add test-specific mocks/stubs
3017 self.mox.StubOutWithMock(cpu.Upgrader, '_GetPreOrderDepGraph')
3020 packages = [pinfo.package for pinfo in target_pinfolist]
3021 pm_argv = cpu.Upgrader._GenParallelEmergeArgv(mocked_upgrader, packages)
3022 pm_argv.append('--root-deps')
3023 mocked_upgrader._GenParallelEmergeArgv(packages).AndReturn(pm_argv)
3024 mocked_upgrader._SetPortTree(mox.IsA(portcfg.config), mox.IsA(dict))
3025 cpu.Upgrader._GetPreOrderDepGraph(mox.IgnoreArg()).AndReturn([])
3026 self.mox.ReplayAll()
3029 result = cpu.Upgrader._GetCurrentVersions(mocked_upgrader, target_pinfolist)
3030 self.mox.VerifyAll()
3034 def testGetCurrentVersionsWorld(self):
3035 target_pinfolist = [cpu.PInfo(package='world', cpv='world'),
3037 self._TestGetCurrentVersionsPackageOnly(target_pinfolist)
3039 def testGetCurrentVersionsLocalOnlyB(self):
3040 target_pinfolist = [cpu.PInfo(package='dev-libs/B', cpv=None),
3042 self._TestGetCurrentVersionsPackageOnly(target_pinfolist)
3045 class ResolveAndVerifyArgsTest(CpuTestBase):
3046 """Test Upgrader._ResolveAndVerifyArgs"""
3048 def _TestResolveAndVerifyArgsWorld(self, upgrade_mode):
3051 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
3054 # Add test-specific mocks/stubs
3057 self.mox.ReplayAll()
3060 with self.OutputCapturer():
3061 result = cpu.Upgrader._ResolveAndVerifyArgs(mocked_upgrader, args,
3062 upgrade_mode=upgrade_mode)
3063 self.mox.VerifyAll()
3065 self.assertEquals(result, [cpu.PInfo(user_arg='world',
3067 package_name='world',
3072 def testResolveAndVerifyArgsWorldUpgradeMode(self):
3073 self._TestResolveAndVerifyArgsWorld(True)
3075 def testResolveAndVerifyArgsWorldStatusMode(self):
3076 self._TestResolveAndVerifyArgsWorld(False)
3078 def _TestResolveAndVerifyArgsNonWorld(self, pinfolist, cmdargs=[],
3079 error=None, error_checker=None):
3080 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
3082 upgrade_mode = cpu.Upgrader._IsInUpgradeMode(mocked_upgrader)
3084 # Add test-specific mocks/stubs
3088 for pinfo in pinfolist:
3089 arg = pinfo.user_arg
3090 local_cpv = pinfo.cpv
3091 upstream_cpv = pinfo.upstream_cpv
3094 catpkg = cpu.Upgrader._GetCatPkgFromCpv(arg)
3095 local_arg = catpkg if catpkg else arg
3097 mocked_upgrader._FindCurrentCPV(local_arg).AndReturn(local_cpv)
3098 mocked_upgrader._FindUpstreamCPV(arg, mocked_upgrader._unstable_ok,
3099 ).AndReturn(upstream_cpv)
3101 if not upstream_cpv and upgrade_mode:
3102 # Real method raises an exception here.
3103 if not mocked_upgrader._unstable_ok:
3104 mocked_upgrader._FindUpstreamCPV(arg, True).AndReturn(arg)
3107 any_cpv = local_cpv if local_cpv else upstream_cpv
3109 mocked_upgrader._FillPInfoFromCPV(mox.IsA(cpu.PInfo), any_cpv)
3111 self.mox.ReplayAll()
3115 with self.OutputCapturer():
3117 exc = self.AssertRaisesAndReturn(error,
3118 cpu.Upgrader._ResolveAndVerifyArgs,
3119 mocked_upgrader, args, upgrade_mode)
3121 check = error_checker(exc)
3122 self.assertTrue(check[0], msg=check[1])
3124 result = cpu.Upgrader._ResolveAndVerifyArgs(mocked_upgrader, args,
3126 self.mox.VerifyAll()
3130 def testResolveAndVerifyArgsNonWorldUpgrade(self):
3131 pinfolist = [cpu.PInfo(user_arg='dev-libs/B',
3133 upstream_cpv='dev-libs/B-2',
3136 cmdargs = ['--upgrade', '--unstable-ok']
3137 result = self._TestResolveAndVerifyArgsNonWorld(pinfolist, cmdargs)
3138 self.assertEquals(result, pinfolist)
3140 def testResolveAndVerifyArgsNonWorldUpgradeSpecificVer(self):
3141 pinfolist = [cpu.PInfo(user_arg='dev-libs/B-2',
3143 upstream_cpv='dev-libs/B-2',
3146 cmdargs = ['--upgrade', '--unstable-ok']
3147 result = self._TestResolveAndVerifyArgsNonWorld(pinfolist, cmdargs)
3148 self.assertEquals(result, pinfolist)
3150 def testResolveAndVerifyArgsNonWorldUpgradeSpecificVerNotFoundStable(self):
3151 pinfolist = [cpu.PInfo(user_arg='dev-libs/B-2',
3155 cmdargs = ['--upgrade']
3157 def _error_checker(exception):
3158 # RuntimeError text should mention 'is unstable'.
3159 text = str(exception)
3160 phrase = 'is unstable'
3161 msg = 'No mention of "%s" in error message: %s' % (phrase, text)
3162 return (0 <= text.find(phrase), msg)
3164 self._TestResolveAndVerifyArgsNonWorld(pinfolist, cmdargs,
3166 error_checker=_error_checker)
3168 def testResolveAndVerifyArgsNonWorldUpgradeSpecificVerNotFoundUnstable(self):
3169 pinfolist = [cpu.PInfo(user_arg='dev-libs/B-2',
3173 cmdargs = ['--upgrade', '--unstable-ok']
3175 def _error_checker(exception):
3176 # RuntimeError text should start with 'Unable to find'.
3177 text = str(exception)
3178 phrase = 'Unable to find'
3179 msg = 'Error message expected to start with "%s": %s' % (phrase, text)
3180 return (text.startswith(phrase), msg)
3182 self._TestResolveAndVerifyArgsNonWorld(pinfolist, cmdargs,
3184 error_checker=_error_checker)
3186 def testResolveAndVerifyArgsNonWorldLocalOny(self):
3187 pinfolist = [cpu.PInfo(user_arg='dev-libs/B',
3191 cmdargs = ['--upgrade', '--unstable-ok']
3193 def _error_checker(exception):
3194 # RuntimeError text should start with 'Unable to find'.
3195 text = str(exception)
3196 phrase = 'Unable to find'
3197 msg = 'Error message expected to start with "%s": %s' % (phrase, text)
3198 return (text.startswith(phrase), msg)
3200 self._TestResolveAndVerifyArgsNonWorld(pinfolist, cmdargs,
3202 error_checker=_error_checker)
3204 def testResolveAndVerifyArgsNonWorldUpstreamOnly(self):
3205 pinfolist = [cpu.PInfo(user_arg='dev-libs/B',
3206 upstream_cpv='dev-libs/B-2',
3209 cmdargs = ['--upgrade', '--unstable-ok']
3210 result = self._TestResolveAndVerifyArgsNonWorld(pinfolist, cmdargs)
3211 self.assertEquals(result, pinfolist)
3213 def testResolveAndVerifyArgsNonWorldNeither(self):
3214 pinfolist = [cpu.PInfo(user_arg='dev-libs/B'),
3216 cmdargs = ['--upgrade', '--unstable-ok']
3217 self._TestResolveAndVerifyArgsNonWorld(pinfolist, cmdargs,
3220 def testResolveAndVerifyArgsNonWorldStatusSpecificVer(self):
3221 """Exception because specific cpv arg not allowed without --ugprade."""
3222 cmdargs = ['--unstable-ok']
3223 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
3225 upgrade_mode = cpu.Upgrader._IsInUpgradeMode(mocked_upgrader)
3227 # Add test-specific mocks/stubs
3230 self.mox.ReplayAll()
3233 self.assertRaises(RuntimeError,
3234 cpu.Upgrader._ResolveAndVerifyArgs,
3236 ['dev-libs/B-2'], upgrade_mode)
3237 self.mox.VerifyAll()
3240 class StabilizeEbuildTest(CpuTestBase):
3241 """Tests for _StabilizeEbuild()."""
3243 PREFIX_LINES = ['Garbletygook nonsense unimportant',
3244 'Some other nonsense with KEYWORDS mention',
3246 POSTFIX_LINES = ['Some mention of KEYWORDS in a line',
3247 'And other nonsense',
3250 def _TestStabilizeEbuild(self, ebuild_path, arch):
3252 mocked_upgrader = self._MockUpgrader(cmdargs=[],
3255 # These are the steps of the replay script.
3256 self.mox.ReplayAll()
3258 # This is the verification phase.
3259 with self.OutputCapturer():
3260 cpu.Upgrader._StabilizeEbuild(mocked_upgrader, ebuild_path)
3261 self.mox.VerifyAll()
3263 def _AssertEqualsExcludingComments(self, lines1, lines2):
3264 lines1 = [ln for ln in lines1 if not ln.startswith('#')]
3265 lines2 = [ln for ln in lines2 if not ln.startswith('#')]
3267 self.assertEquals(lines1, lines2)
3269 def _TestStabilizeEbuildWrapper(self, ebuild_path, arch,
3270 keyword_line, gold_keyword_line):
3271 if not isinstance(keyword_line, list):
3272 keyword_line = [keyword_line]
3273 if not isinstance(gold_keyword_line, list):
3274 gold_keyword_line = [gold_keyword_line]
3276 input_content = self.PREFIX_LINES + keyword_line + self.POSTFIX_LINES
3277 gold_content = self.PREFIX_LINES + gold_keyword_line + self.POSTFIX_LINES
3279 # Write contents to ebuild_path before test.
3280 osutils.WriteFile(ebuild_path, '\n'.join(input_content))
3282 self._TestStabilizeEbuild(ebuild_path, arch)
3284 # Read content back after test.
3285 content_lines = osutils.ReadFile(ebuild_path).splitlines()
3287 self._AssertEqualsExcludingComments(gold_content, content_lines)
3289 @osutils.TempFileDecorator
3290 def testNothingToDo(self):
3292 keyword_line = 'KEYWORDS="amd64 arm mips x86"'
3293 gold_keyword_line = 'KEYWORDS="*"'
3294 self._TestStabilizeEbuildWrapper(self.tempfile, arch,
3295 keyword_line, gold_keyword_line)
3297 @osutils.TempFileDecorator
3298 def testNothingToDoFbsd(self):
3300 keyword_line = 'KEYWORDS="amd64 arm ~mips x86 ~x86-fbsd"'
3301 gold_keyword_line = 'KEYWORDS="*"'
3302 self._TestStabilizeEbuildWrapper(self.tempfile, arch,
3303 keyword_line, gold_keyword_line)
3305 @osutils.TempFileDecorator
3306 def testSimpleMiddleOfLine(self):
3308 keyword_line = 'KEYWORDS="amd64 ~arm ~mips x86"'
3309 gold_keyword_line = 'KEYWORDS="*"'
3310 self._TestStabilizeEbuildWrapper(self.tempfile, arch,
3311 keyword_line, gold_keyword_line)
3313 @osutils.TempFileDecorator
3314 def testSimpleMiddleOfLineSpacePrefix(self):
3316 keyword_line = ' KEYWORDS="amd64 ~arm ~mips x86"'
3317 gold_keyword_line = ' KEYWORDS="*"'
3318 self._TestStabilizeEbuildWrapper(self.tempfile, arch,
3319 keyword_line, gold_keyword_line)
3321 @osutils.TempFileDecorator
3322 def testSimpleStartOfLine(self):
3324 keyword_line = 'KEYWORDS="~arm amd64 ~mips x86"'
3325 gold_keyword_line = 'KEYWORDS="*"'
3326 self._TestStabilizeEbuildWrapper(self.tempfile, arch,
3327 keyword_line, gold_keyword_line)
3329 @osutils.TempFileDecorator
3330 def testSimpleEndOfLine(self):
3332 keyword_line = 'KEYWORDS="amd64 ~mips x86 ~arm"'
3333 gold_keyword_line = 'KEYWORDS="*"'
3334 self._TestStabilizeEbuildWrapper(self.tempfile, arch,
3335 keyword_line, gold_keyword_line)
3337 @osutils.TempFileDecorator
3338 def testPreFbsd(self):
3340 keyword_line = 'KEYWORDS="amd64 ~arm ~mips ~x86 ~x86-fbsd"'
3341 gold_keyword_line = 'KEYWORDS="*"'
3342 self._TestStabilizeEbuildWrapper(self.tempfile, arch,
3343 keyword_line, gold_keyword_line)
3345 @osutils.TempFileDecorator
3346 def testPostFbsd(self):
3348 keyword_line = 'KEYWORDS="amd64 ~arm ~mips ~x86-fbsd ~x86"'
3349 gold_keyword_line = 'KEYWORDS="*"'
3350 self._TestStabilizeEbuildWrapper(self.tempfile, arch,
3351 keyword_line, gold_keyword_line)
3353 @osutils.TempFileDecorator
3354 def testMultilineKeywordsMiddle(self):
3356 keyword_lines = ['KEYWORDS="amd64',
3361 gold_keyword_lines = ['KEYWORDS="*"',]
3362 self._TestStabilizeEbuildWrapper(self.tempfile, arch,
3363 keyword_lines, gold_keyword_lines)
3365 @osutils.TempFileDecorator
3366 def testMultilineKeywordsStart(self):
3368 keyword_lines = ['KEYWORDS="~amd64',
3373 gold_keyword_lines = ['KEYWORDS="*"',]
3374 self._TestStabilizeEbuildWrapper(self.tempfile, arch,
3375 keyword_lines, gold_keyword_lines)
3377 @osutils.TempFileDecorator
3378 def testMultilineKeywordsEnd(self):
3380 keyword_lines = ['KEYWORDS="amd64',
3385 gold_keyword_lines = ['KEYWORDS="*"',]
3386 self._TestStabilizeEbuildWrapper(self.tempfile, arch,
3387 keyword_lines, gold_keyword_lines)
3389 @osutils.TempFileDecorator
3390 def testMultipleKeywordLinesOneChange(self):
3392 keyword_lines = ['KEYWORDS="amd64 arm mips x86"',
3393 'KEYWORDS="~amd64 ~arm ~mips ~x86"',
3395 gold_keyword_lines = ['KEYWORDS="*"',] * 2
3396 self._TestStabilizeEbuildWrapper(self.tempfile, arch,
3397 keyword_lines, gold_keyword_lines)
3399 @osutils.TempFileDecorator
3400 def testMultipleKeywordLinesMultipleChanges(self):
3402 keyword_lines = ['KEYWORDS="amd64 ~arm mips x86"',
3403 'KEYWORDS="~amd64 ~arm ~mips ~x86"',
3405 gold_keyword_lines = ['KEYWORDS="*"',] * 2
3406 self._TestStabilizeEbuildWrapper(self.tempfile, arch,
3407 keyword_lines, gold_keyword_lines)
3409 @osutils.TempFileDecorator
3410 def testMultipleKeywordLinesMultipleChangesSpacePrefix(self):
3412 keyword_lines = [' KEYWORDS="amd64 ~arm mips x86"',
3413 ' KEYWORDS="~amd64 ~arm ~mips ~x86"',
3415 gold_keyword_lines = [' KEYWORDS="*"',] * 2
3416 self._TestStabilizeEbuildWrapper(self.tempfile, arch,
3417 keyword_lines, gold_keyword_lines)
3420 @unittest.skip('relies on portage module not currently available')
3421 class GetPreOrderDepGraphTest(CpuTestBase):
3422 """Test the Upgrader class from cros_portage_upgrade."""
3425 # _GetPreOrderDepGraph testing (defunct - to be replaced)
3428 def _TestGetPreOrderDepGraph(self, pkg):
3429 """Test the behavior of the Upgrader._GetPreOrderDepGraph method."""
3432 mocked_upgrader = self._MockUpgrader(cmdargs=cmdargs,
3434 self._SetUpPlayground()
3437 self.mox.ReplayAll()
3440 pm_argv = cpu.Upgrader._GenParallelEmergeArgv(mocked_upgrader, [pkg])
3441 pm_argv.append('--root-deps')
3442 deps = parallel_emerge.DepGraphGenerator()
3443 deps.Initialize(pm_argv)
3444 deps_tree, deps_info = deps.GenDependencyTree()
3445 deps_graph = deps.GenDependencyGraph(deps_tree, deps_info)
3447 deps_list = cpu.Upgrader._GetPreOrderDepGraph(deps_graph)
3448 golden_deps_set = _GetGoldenDepsSet(pkg)
3449 self.assertEquals(set(deps_list), golden_deps_set)
3450 self.mox.VerifyAll()
3452 def testGetPreOrderDepGraphDevLibsA(self):
3453 return self._TestGetPreOrderDepGraph('dev-libs/A')
3455 def testGetPreOrderDepGraphDevLibsC(self):
3456 return self._TestGetPreOrderDepGraph('dev-libs/C')
3458 def testGetPreOrderDepGraphVirtualLibusb(self):
3459 return self._TestGetPreOrderDepGraph('virtual/libusb')
3461 def testGetPreOrderDepGraphCrosbaseLibcros(self):
3462 return self._TestGetPreOrderDepGraph('chromeos-base/libcros')
3465 class MainTest(CpuTestBase):
3466 """Test argument handling at the main method level."""
3468 def _AssertCPUMain(self, args, expect_zero):
3469 """Run cpu.main() and assert exit value is expected.
3471 If |expect_zero| is True, assert exit value = 0. If False,
3472 assert exit value != 0.
3476 except exceptions.SystemExit as e:
3478 self.assertEquals(e.args[0], 0,
3479 msg='expected call to main() to exit cleanly, '
3480 'but it exited with code %d' % e.args[0])
3482 self.assertNotEquals(e.args[0], 0,
3483 msg='expected call to main() to exit with '
3484 'failure code, but exited with code 0 instead.')
3487 """Test that --help is functioning"""
3489 with self.OutputCapturer() as output:
3490 # Running with --help should exit with code==0
3492 cpu.main(['--help'])
3493 except exceptions.SystemExit as e:
3494 self.assertEquals(e.args[0], 0)
3496 # Verify that a message beginning with "Usage: " was printed
3497 stdout = output.GetStdout()
3498 self.assertTrue(stdout.startswith('usage: '))
3500 def testMissingBoard(self):
3501 """Test that running without --board exits with an error."""
3502 with self.OutputCapturer():
3503 # Running without --board should exit with code!=0
3506 except exceptions.SystemExit as e:
3507 self.assertNotEquals(e.args[0], 0)
3509 # Verify that an error message was printed.
3510 self.AssertOutputEndsInError()
3512 def testBoardWithoutPackage(self):
3513 """Test that running without a package argument exits with an error."""
3514 with self.OutputCapturer():
3515 # Running without a package should exit with code!=0
3516 self._AssertCPUMain(['--board=any-board'], expect_zero=False)
3518 # Verify that an error message was printed.
3519 self.AssertOutputEndsInError()
3521 def testHostWithoutPackage(self):
3522 """Test that running without a package argument exits with an error."""
3523 with self.OutputCapturer():
3524 # Running without a package should exit with code!=0
3525 self._AssertCPUMain(['--host'], expect_zero=False)
3527 # Verify that an error message was printed.
3528 self.AssertOutputEndsInError()
3530 def testUpgradeAndUpgradeDeep(self):
3531 """Running with --upgrade and --upgrade-deep exits with an error."""
3532 with self.OutputCapturer():
3533 # Expect exit with code!=0
3534 self._AssertCPUMain(['--host', '--upgrade', '--upgrade-deep',
3535 'any-package'], expect_zero=False)
3537 # Verify that an error message was printed.
3538 self.AssertOutputEndsInError()
3540 def testForceWithoutUpgrade(self):
3541 """Running with --force requires --upgrade or --upgrade-deep."""
3542 with self.OutputCapturer():
3543 # Expect exit with code!=0
3544 self._AssertCPUMain(['--host', '--force', 'any-package'],
3547 # Verify that an error message was printed.
3548 self.AssertOutputEndsInError()
3550 def testFlowStatusReportOneBoard(self):
3551 """Test main flow for basic one-board status report."""
3553 self.mox.StubOutWithMock(cpu.Upgrader, 'PreRunChecks')
3554 self.mox.StubOutWithMock(cpu, '_BoardIsSetUp')
3555 self.mox.StubOutWithMock(cpu.Upgrader, 'PrepareToRun')
3556 self.mox.StubOutWithMock(cpu.Upgrader, 'RunBoard')
3557 self.mox.StubOutWithMock(cpu.Upgrader, 'RunCompleted')
3558 self.mox.StubOutWithMock(cpu.Upgrader, 'WriteTableFiles')
3560 cpu.Upgrader.PreRunChecks()
3561 cpu._BoardIsSetUp('any-board').AndReturn(True)
3562 cpu.Upgrader.PrepareToRun()
3563 cpu.Upgrader.RunBoard('any-board')
3564 cpu.Upgrader.RunCompleted()
3565 cpu.Upgrader.WriteTableFiles(csv='/dev/null')
3566 self.mox.ReplayAll()
3568 with self.OutputCapturer():
3569 self._AssertCPUMain(['--board=any-board', '--to-csv=/dev/null',
3570 'any-package'], expect_zero=True)
3571 self.mox.VerifyAll()
3573 def testFlowStatusReportOneBoardNotSetUp(self):
3574 """Test main flow for basic one-board status report."""
3575 self.mox.StubOutWithMock(cpu.Upgrader, 'PreRunChecks')
3576 self.mox.StubOutWithMock(cpu, '_BoardIsSetUp')
3578 cpu.Upgrader.PreRunChecks()
3579 cpu._BoardIsSetUp('any-board').AndReturn(False)
3580 self.mox.ReplayAll()
3582 # Running with a package not set up should exit with code!=0
3583 with self.OutputCapturer():
3584 self._AssertCPUMain(['--board=any-board', '--to-csv=/dev/null',
3585 'any-package'], expect_zero=False)
3586 self.mox.VerifyAll()
3588 # Verify that an error message was printed.
3589 self.AssertOutputEndsInError()
3591 def testFlowStatusReportTwoBoards(self):
3592 """Test main flow for two-board status report."""
3593 self.mox.StubOutWithMock(cpu.Upgrader, 'PreRunChecks')
3594 self.mox.StubOutWithMock(cpu, '_BoardIsSetUp')
3595 self.mox.StubOutWithMock(cpu.Upgrader, 'PrepareToRun')
3596 self.mox.StubOutWithMock(cpu.Upgrader, 'RunBoard')
3597 self.mox.StubOutWithMock(cpu.Upgrader, 'RunCompleted')
3598 self.mox.StubOutWithMock(cpu.Upgrader, 'WriteTableFiles')
3600 cpu.Upgrader.PreRunChecks()
3601 cpu._BoardIsSetUp('board1').AndReturn(True)
3602 cpu._BoardIsSetUp('board2').AndReturn(True)
3603 cpu.Upgrader.PrepareToRun()
3604 cpu.Upgrader.RunBoard('board1')
3605 cpu.Upgrader.RunBoard('board2')
3606 cpu.Upgrader.RunCompleted()
3607 cpu.Upgrader.WriteTableFiles(csv=None)
3608 self.mox.ReplayAll()
3610 with self.OutputCapturer():
3611 self._AssertCPUMain(['--board=board1:board2', 'any-package'],
3613 self.mox.VerifyAll()
3615 def testFlowUpgradeOneBoard(self):
3616 """Test main flow for basic one-board upgrade."""
3617 self.mox.StubOutWithMock(cpu.Upgrader, 'PreRunChecks')
3618 self.mox.StubOutWithMock(cpu.Upgrader, 'CheckBoardList')
3619 self.mox.StubOutWithMock(cpu, '_BoardIsSetUp')
3620 self.mox.StubOutWithMock(cpu.Upgrader, 'PrepareToRun')
3621 self.mox.StubOutWithMock(cpu.Upgrader, 'RunBoard')
3622 self.mox.StubOutWithMock(cpu.Upgrader, 'RunCompleted')
3623 self.mox.StubOutWithMock(cpu.Upgrader, 'WriteTableFiles')
3625 cpu.Upgrader.PreRunChecks()
3626 cpu.Upgrader.CheckBoardList(['any-board'])
3627 cpu._BoardIsSetUp('any-board').AndReturn(True)
3628 cpu.Upgrader.PrepareToRun()
3629 cpu.Upgrader.RunBoard('any-board')
3630 cpu.Upgrader.RunCompleted()
3631 cpu.Upgrader.WriteTableFiles(csv=None)
3632 self.mox.ReplayAll()
3634 with self.OutputCapturer():
3635 self._AssertCPUMain(['--upgrade', '--board=any-board', 'any-package'],
3637 self.mox.VerifyAll()
3639 def testFlowUpgradeTwoBoards(self):
3640 """Test main flow for two-board upgrade."""
3641 self.mox.StubOutWithMock(cpu.Upgrader, 'PreRunChecks')
3642 self.mox.StubOutWithMock(cpu.Upgrader, 'CheckBoardList')
3643 self.mox.StubOutWithMock(cpu, '_BoardIsSetUp')
3644 self.mox.StubOutWithMock(cpu.Upgrader, 'PrepareToRun')
3645 self.mox.StubOutWithMock(cpu.Upgrader, 'RunBoard')
3646 self.mox.StubOutWithMock(cpu.Upgrader, 'RunCompleted')
3647 self.mox.StubOutWithMock(cpu.Upgrader, 'WriteTableFiles')
3649 cpu.Upgrader.PreRunChecks()
3650 cpu.Upgrader.CheckBoardList(['board1', 'board2'])
3651 cpu._BoardIsSetUp('board1').AndReturn(True)
3652 cpu._BoardIsSetUp('board2').AndReturn(True)
3653 cpu.Upgrader.PrepareToRun()
3654 cpu.Upgrader.RunBoard('board1')
3655 cpu.Upgrader.RunBoard('board2')
3656 cpu.Upgrader.RunCompleted()
3657 cpu.Upgrader.WriteTableFiles(csv='/dev/null')
3658 self.mox.ReplayAll()
3660 with self.OutputCapturer():
3661 self._AssertCPUMain(['--upgrade', '--board=board1:board2',
3662 '--to-csv=/dev/null', 'any-package'],
3664 self.mox.VerifyAll()
3666 def testFlowUpgradeTwoBoardsAndHost(self):
3667 """Test main flow for two-board and host upgrade."""
3668 self.mox.StubOutWithMock(cpu.Upgrader, 'PreRunChecks')
3669 self.mox.StubOutWithMock(cpu.Upgrader, 'CheckBoardList')
3670 self.mox.StubOutWithMock(cpu, '_BoardIsSetUp')
3671 self.mox.StubOutWithMock(cpu.Upgrader, 'PrepareToRun')
3672 self.mox.StubOutWithMock(cpu.Upgrader, 'RunBoard')
3673 self.mox.StubOutWithMock(cpu.Upgrader, 'RunCompleted')
3674 self.mox.StubOutWithMock(cpu.Upgrader, 'WriteTableFiles')
3676 cpu.Upgrader.PreRunChecks()
3677 cpu.Upgrader.CheckBoardList(['board1', 'board2'])
3678 cpu._BoardIsSetUp('board1').AndReturn(True)
3679 cpu._BoardIsSetUp('board2').AndReturn(True)
3680 cpu.Upgrader.PrepareToRun()
3681 cpu.Upgrader.RunBoard(cpu.Upgrader.HOST_BOARD)
3682 cpu.Upgrader.RunBoard('board1')
3683 cpu.Upgrader.RunBoard('board2')
3684 cpu.Upgrader.RunCompleted()
3685 cpu.Upgrader.WriteTableFiles(csv='/dev/null')
3686 self.mox.ReplayAll()
3688 with self.OutputCapturer():
3689 self._AssertCPUMain(['--upgrade', '--host', '--board=board1:host:board2',
3690 '--to-csv=/dev/null', 'any-package'], expect_zero=True)
3691 self.mox.VerifyAll()
3693 if __name__ == '__main__':
3694 cros_test_lib.main()