repoman: add a simple unit test
authorZac Medico <zmedico@gentoo.org>
Fri, 26 Aug 2011 06:12:27 +0000 (23:12 -0700)
committerZac Medico <zmedico@gentoo.org>
Fri, 26 Aug 2011 06:12:27 +0000 (23:12 -0700)
bin/repoman
pym/portage/tests/repoman/__init__.py [new file with mode: 0644]
pym/portage/tests/repoman/test_simple.py [new file with mode: 0644]
pym/portage/tests/resolver/ResolverPlayground.py

index e0494d95e3361058384aa5f31d4e482366197baf..d9ecfc4693d51e581e97b2a1163ef29904ed31e2 100755 (executable)
@@ -96,7 +96,8 @@ os.umask(0o22)
 # behave incrementally.
 repoman_incrementals = tuple(x for x in \
        portage.const.INCREMENTALS if x != 'ACCEPT_KEYWORDS')
-repoman_settings = portage.config(local_config=False)
+eprefix = os.environ.get("__REPOMAN_TEST_EPREFIX")
+repoman_settings = portage.config(local_config=False, _eprefix=eprefix)
 repoman_settings.lock()
 
 if repoman_settings.get("NOCOLOR", "").lower() in ("yes", "true") or \
@@ -570,13 +571,13 @@ if options.mode == 'commit' and not options.pretend and not vcs:
        options.pretend = True
 
 # Ensure that PORTDIR_OVERLAY contains the repository corresponding to $PWD.
-repoman_settings = portage.config(local_config=False)
+repoman_settings = portage.config(local_config=False, _eprefix=eprefix)
 repoman_settings['PORTDIR_OVERLAY'] = "%s %s" % \
        (repoman_settings.get('PORTDIR_OVERLAY', ''), portdir_overlay)
 # We have to call the config constructor again so
 # that config.repositories is initialized correctly.
-repoman_settings = portage.config(local_config=False, env=dict(os.environ,
-       PORTDIR_OVERLAY=repoman_settings['PORTDIR_OVERLAY']))
+repoman_settings = portage.config(local_config=False, _eprefix=eprefix,
+       env=dict(os.environ, PORTDIR_OVERLAY=repoman_settings['PORTDIR_OVERLAY']))
 
 root = '/'
 trees = {
@@ -1887,7 +1888,7 @@ for x in scanlist:
                                                config_incrementals=repoman_incrementals,
                                                local_config=False,
                                                _unmatched_removal=options.unmatched_removal,
-                                               env=env)
+                                               env=env, _eprefix=eprefix)
                                        if options.without_mask:
                                                dep_settings._mask_manager = \
                                                        copy.deepcopy(dep_settings._mask_manager)
diff --git a/pym/portage/tests/repoman/__init__.py b/pym/portage/tests/repoman/__init__.py
new file mode 100644 (file)
index 0000000..532918b
--- /dev/null
@@ -0,0 +1,2 @@
+# Copyright 2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
diff --git a/pym/portage/tests/repoman/test_simple.py b/pym/portage/tests/repoman/test_simple.py
new file mode 100644 (file)
index 0000000..612ff8e
--- /dev/null
@@ -0,0 +1,163 @@
+# Copyright 2011 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+
+import shutil
+import subprocess
+import sys
+import time
+
+import portage
+from portage import os
+from portage import _unicode_decode
+from portage.const import PORTAGE_BASE_PATH, PORTAGE_BIN_PATH, PORTAGE_PYM_PATH
+from portage.process import find_binary
+from portage.tests import TestCase
+from portage.tests.resolver.ResolverPlayground import ResolverPlayground
+from portage.util import ensure_dirs
+
+class SimpleRepomanTestCase(TestCase):
+
+       def _must_skip(self):
+               xmllint = find_binary("xmllint")
+               if not xmllint:
+                       return "xmllint not found"
+
+               try:
+                       __import__("xml.etree.ElementTree")
+                       __import__("xml.parsers.expat").parsers.expat.ExpatError
+               except (AttributeError, ImportError):
+                       return "python is missing xml support"
+
+       def testSimple(self):
+
+               skip_reason = self._must_skip()
+               if skip_reason:
+                       self.portage_skip = skip_reason
+                       self.assertFalse(True, skip_reason)
+                       return
+
+               copyright_header = """# Copyright 1999-%s Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Header: $
+""" % time.gmtime().tm_year
+
+               profiles = (
+                       ("x86", "default/linux/x86/test_profile", "stable"),
+               )
+
+               ebuilds = {
+                       "dev-libs/A-1": {
+                               "COPYRIGHT_HEADER" : copyright_header,
+                               "DESCRIPTION" : "Desc goes here",
+                               "EAPI" : "4",
+                               "HOMEPAGE" : "http://example.com",
+                               "IUSE" : "flag",
+                               "KEYWORDS": "x86",
+                               "LICENSE": "GPL-2",
+                               "RDEPEND": "flag? ( dev-libs/B[flag] )",
+                       },
+                       "dev-libs/B-1": {
+                               "COPYRIGHT_HEADER" : copyright_header,
+                               "DESCRIPTION" : "Desc goes here",
+                               "EAPI" : "4",
+                               "HOMEPAGE" : "http://example.com",
+                               "IUSE" : "flag",
+                               "KEYWORDS": "x86",
+                               "LICENSE": "GPL-2",
+                       },
+               }
+               licenses = ["GPL-2"]
+               arch_list = ["x86"]
+               metadata_dtd = os.path.join(PORTAGE_BASE_PATH, "cnf/metadata.dtd")
+               metadata_xml_template = """<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE pkgmetadata SYSTEM "http://www.gentoo.org/dtd/metadata.dtd">
+<pkgmetadata>
+<herd>%(herd)s</herd>
+<maintainer>
+<email>maintainer-needed@gentoo.org</email>
+<description>Description of the maintainership</description>
+</maintainer>
+<longdescription>Long description of the package</longdescription>
+<use>
+%(flags)s
+</use>
+</pkgmetadata>
+"""
+
+               metadata_xml_files = (
+                       (
+                               "dev-libs/A",
+                               {
+                                       "herd" : "no-herd",
+                                       "flags" : "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
+                               },
+                       ),
+                       (
+                               "dev-libs/B",
+                               {
+                                       "herd" : "no-herd",
+                                       "flags" : "<flag name='flag'>Description of how USE='flag' affects this package</flag>",
+                               },
+                       ),
+               )
+
+               use_desc = (
+                       ("flag", "Description of how USE='flag' affects packages"),
+               )
+
+               playground = ResolverPlayground(ebuilds=ebuilds)
+               settings = playground.settings
+               eprefix = settings["EROOT"]
+               distdir = os.path.join(eprefix, "distdir")
+               portdir = settings["PORTDIR"]
+               profiles_dir = os.path.join(portdir, "profiles")
+               license_dir = os.path.join(portdir, "licenses")
+               env = os.environ.copy()
+               pythonpath = env.get("PYTHONPATH")
+               if pythonpath is not None and not pythonpath.strip():
+                       pythonpath = None
+               if pythonpath is None:
+                       pythonpath = ""
+               else:
+                       pythonpath = ":" + pythonpath
+               pythonpath = PORTAGE_PYM_PATH + pythonpath
+               env['PYTHONPATH'] = pythonpath
+               env.update({
+                       "__REPOMAN_TEST_EPREFIX" : eprefix,
+                       "DISTDIR" : distdir,
+                       "PORTDIR" : portdir,
+               })
+               dirs = [license_dir, profiles_dir, distdir]
+               try:
+                       for d in dirs:
+                               ensure_dirs(d)
+                       with open(os.path.join(profiles_dir, "profiles.desc"), 'w') as f:
+                               for x in profiles:
+                                       f.write("%s %s %s\n" % x)
+                       for x in licenses:
+                               open(os.path.join(license_dir, x), 'wb').close()
+                       with open(os.path.join(profiles_dir, "arch.list"), 'w') as f:
+                               for x in arch_list:
+                                       f.write("%s\n" % x)
+                       with open(os.path.join(profiles_dir, "use.desc"), 'w') as f:
+                               for k, v in use_desc:
+                                       f.write("%s - %s\n" % (k, v))
+                       for cp, xml_data in metadata_xml_files:
+                               with open(os.path.join(portdir, cp, "metadata.xml"), 'w') as f:
+                                       f.write(metadata_xml_template % xml_data)
+                       # repoman checks metadata.dtd for recent CTIME, so copy the file in
+                       # order to ensure that the CTIME is current
+                       shutil.copyfile(metadata_dtd, os.path.join(distdir, "metadata.dtd"))
+                       for cwd in ("", "dev-libs", "dev-libs/A", "dev-libs/B"):
+                               cwd = os.path.join(portdir, cwd)
+                               proc = subprocess.Popen([portage._python_interpreter, "-Wd",
+                                       os.path.join(PORTAGE_BIN_PATH, "repoman"), "full"],
+                                       cwd=cwd, env=env, stdout=subprocess.PIPE)
+                               output = proc.stdout.readlines()
+                               if proc.wait() != os.EX_OK:
+                                       for line in output:
+                                               sys.stderr.write(_unicode_decode(line))
+
+                               self.assertEqual(os.EX_OK, proc.returncode, "repoman failed")
+               finally:
+                       playground.cleanup()
index 6a8e3c18c75d15ddc9bb90dcd94c58ed68f01775..dd014140441e1672fe05af5c40b15781854e95ba 100644 (file)
@@ -106,11 +106,14 @@ class ResolverPlayground(object):
                                repo = "test_repo"
 
                        metadata = ebuilds[cpv].copy()
+                       copyright_header = metadata.pop("COPYRIGHT_HEADER", None)
+                       desc = metadata.pop("DESCRIPTION", None)
                        eapi = metadata.pop("EAPI", 0)
                        lic = metadata.pop("LICENSE", "")
                        properties = metadata.pop("PROPERTIES", "")
                        slot = metadata.pop("SLOT", 0)
                        keywords = metadata.pop("KEYWORDS", "x86")
+                       homepage = metadata.pop("HOMEPAGE", None)
                        iuse = metadata.pop("IUSE", "")
                        depend = metadata.pop("DEPEND", "")
                        rdepend = metadata.pop("RDEPEND", None)
@@ -129,7 +132,13 @@ class ResolverPlayground(object):
                                pass
 
                        f = open(ebuild_path, "w")
+                       if copyright_header is not None:
+                               f.write(copyright_header)
                        f.write('EAPI="' + str(eapi) + '"\n')
+                       if desc is not None:
+                               f.write('DESCRIPTION="%s"\n' % desc)
+                       if homepage is not None:
+                               f.write('HOMEPAGE="%s"\n' % homepage)
                        f.write('LICENSE="' + str(lic) + '"\n')
                        f.write('PROPERTIES="' + str(properties) + '"\n')
                        f.write('SLOT="' + str(slot) + '"\n')