from itertools import permutations
import shutil
+import sys
import tempfile
import portage
from portage import os
from _emerge.depgraph import backtrack_depgraph
from _emerge.RootConfig import RootConfig
+if sys.hexversion >= 0x3000000:
+ basestring = str
+
class ResolverPlayground(object):
"""
This class helps to create the necessary files on disk and
def __init__(self, request, **kwargs):
self.all_permutations = kwargs.pop("all_permutations", False)
self.ignore_mergelist_order = kwargs.pop("ignore_mergelist_order", False)
+ self.ambigous_merge_order = kwargs.pop("ambigous_merge_order", False)
self.check_repo_names = kwargs.pop("check_repo_names", False)
if self.all_permutations:
got = new_got
if expected:
new_expected = []
- for cpv in expected:
- a = Atom("="+cpv, allow_repo=True)
- new_expected.append(a.cpv)
+ for obj in expected:
+ if isinstance(obj, basestring):
+ a = Atom("="+obj, allow_repo=True)
+ new_expected.append(a.cpv)
+ continue
+ new_expected.append(set())
+ for cpv in obj:
+ a = Atom("="+cpv, allow_repo=True)
+ new_expected[-1].add(a.cpv)
expected = new_expected
if self.ignore_mergelist_order and got is not None:
got = set(got)
expected = set(expected)
+
+ if self.ambigous_merge_order and got:
+ expected_stack = list(reversed(expected))
+ got_stack = list(reversed(got))
+ new_expected = []
+ while got_stack and expected_stack:
+ got_token = got_stack.pop()
+ expected_obj = expected_stack.pop()
+ if isinstance(expected_obj, basestring):
+ new_expected.append(got_token)
+ continue
+ expected_obj = set(expected_obj)
+ try:
+ expected_obj.remove(got_token)
+ except KeyError:
+ # result doesn't match, so stop early
+ break
+ new_expected.append(got_token)
+ match = True
+ while got_stack and expected_obj:
+ got_token = got_stack.pop()
+ try:
+ expected_obj.remove(got_token)
+ except KeyError:
+ match = False
+ break
+ new_expected.append(got_token)
+ if not match:
+ # result doesn't match, so stop early
+ break
+ expected = new_expected
+
elif key in ("unstable_keywords", "needed_p_mask_changes") and expected is not None:
expected = set(expected)
--- /dev/null
+# Copyright 2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+from portage.tests import TestCase
+from portage.tests.resolver.ResolverPlayground import (ResolverPlayground,
+ ResolverPlaygroundTestCase)
+
+class MergeOrderTestCase(TestCase):
+
+ def testMergeOrder(self):
+ ebuilds = {
+ "app-misc/circ-runtime-a-1": {
+ "RDEPEND": "app-misc/circ-runtime-b",
+ },
+ "app-misc/circ-runtime-b-1": {
+ "RDEPEND": "app-misc/circ-runtime-a",
+ },
+ "app-misc/some-app-a-1": {
+ "RDEPEND": "app-misc/circ-runtime-a app-misc/circ-runtime-b",
+ },
+ }
+
+ installed = {
+ }
+
+ test_cases = (
+ ResolverPlaygroundTestCase(
+ ["app-misc/some-app-a"],
+ success = True,
+ ambigous_merge_order = True,
+ mergelist = [("app-misc/circ-runtime-a-1", "app-misc/circ-runtime-b-1"), "app-misc/some-app-a-1"]),
+ ResolverPlaygroundTestCase(
+ ["app-misc/some-app-a"],
+ success = True,
+ ambigous_merge_order = True,
+ mergelist = [("app-misc/circ-runtime-b-1", "app-misc/circ-runtime-a-1"), "app-misc/some-app-a-1"]),
+ )
+
+ playground = ResolverPlayground(ebuilds=ebuilds, installed=installed)
+ try:
+ for test_case in test_cases:
+ playground.run_TestCase(test_case)
+ self.assertEqual(test_case.test_success, True, test_case.fail_msg)
+ finally:
+ playground.cleanup()