[csw-devel] SF.net SVN: gar:[9343] csw/mgar/gar/v2

wahwah at users.sourceforge.net wahwah at users.sourceforge.net
Tue Mar 23 23:32:23 CET 2010


Revision: 9343
          http://gar.svn.sourceforge.net/gar/?rev=9343&view=rev
Author:   wahwah
Date:     2010-03-23 22:32:23 +0000 (Tue, 23 Mar 2010)

Log Message:
-----------
mGAR v2: checkpkg, a rewrite of the library checking functions (fixing some problems), removing a lot of obsolete test data, adding a check for runpaths.

Modified Paths:
--------------
    csw/mgar/gar/v2/bin/analyze_module_results.py
    csw/mgar/gar/v2/bin/checkpkg
    csw/mgar/gar/v2/lib/python/checkpkg.py
    csw/mgar/gar/v2/lib/python/checkpkg_test.py
    csw/mgar/gar/v2/lib/python/opencsw.py
    csw/mgar/gar/v2/lib/python/package_checks.py
    csw/mgar/gar/v2/lib/python/package_checks_test.py

Added Paths:
-----------
    csw/mgar/gar/v2/lib/python/dependency_checks.py
    csw/mgar/gar/v2/lib/python/testdata/checkpkg_pkgs_data_minimal.py
    csw/mgar/gar/v2/lib/python/testdata/dump_output_3.py

Removed Paths:
-------------
    csw/mgar/gar/v2/lib/python/testdata/checkpkg_test_data_CSWlibpq_84.py
    csw/mgar/gar/v2/lib/python/testdata/checkpkg_test_data_CSWmysql51.py
    csw/mgar/gar/v2/lib/python/testdata/checkpkg_test_data_CSWmysql51client.py
    csw/mgar/gar/v2/lib/python/testdata/checkpkg_test_data_CSWmysql51devel.py
    csw/mgar/gar/v2/lib/python/testdata/checkpkg_test_data_CSWmysql51rt.py
    csw/mgar/gar/v2/lib/python/testdata/checkpkg_test_data_CSWmysql5client_8x.py
    csw/mgar/gar/v2/lib/python/testdata/checkpkg_test_data_CSWpostfix.py

Modified: csw/mgar/gar/v2/bin/analyze_module_results.py
===================================================================
--- csw/mgar/gar/v2/bin/analyze_module_results.py	2010-03-23 17:37:18 UTC (rev 9342)
+++ csw/mgar/gar/v2/bin/analyze_module_results.py	2010-03-23 22:32:23 UTC (rev 9343)
@@ -1,6 +1,7 @@
 #!/opt/csw/bin/python2.6
 # $Id$
 
+import operator
 import optparse
 import os
 import sys
@@ -28,7 +29,7 @@
   for file_name in files:
     full_path = os.path.join(options.extractdir, file_name)
     error_tags.extend(checkpkg.ErrorTagsFromFile(full_path))
-  overrides = reduce(lambda x, y: x + y, overrides_list)
+  overrides = reduce(operator.add, overrides_list)
   (tags_after_overrides,
    unapplied_overrides) = checkpkg.ApplyOverrides(error_tags, overrides)
   exit_code = bool(tags_after_overrides)

Modified: csw/mgar/gar/v2/bin/checkpkg
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg	2010-03-23 17:37:18 UTC (rev 9342)
+++ csw/mgar/gar/v2/bin/checkpkg	2010-03-23 22:32:23 UTC (rev 9343)
@@ -113,16 +113,19 @@
 #  - Use an pre-cached (from a catalog file?) list of md5 sums
 #  - Don't use the data from /var/sadm/install/contents
 SAVE_TAGS=0
+SAVED_TAGS_FILE=error-tags.txt
 display_help=0
 SKIP_STATS_COLLECTION=0
 MD5_SUMS_CATALOG_FILE=""
 
-while getopts hsdNM: opt; do
+while getopts hsdNM:o: opt; do
 	case "${opt}" in
 	  s)
       SAVE_TAGS=1
-      SAVED_TAGS_FILE=error-tags.txt
       ;;
+    o)
+      SAVED_TAGS_FILE="${OPTARG}"
+      ;;
     d)
       DEBUG=1
       ;;

Modified: csw/mgar/gar/v2/lib/python/checkpkg.py
===================================================================
--- csw/mgar/gar/v2/lib/python/checkpkg.py	2010-03-23 17:37:18 UTC (rev 9342)
+++ csw/mgar/gar/v2/lib/python/checkpkg.py	2010-03-23 22:32:23 UTC (rev 9343)
@@ -8,10 +8,12 @@
 import errno
 import itertools
 import logging
+import operator
 import optparse
 import os
 import os.path
 import re
+import pprint
 import socket
 import sqlite3
 import subprocess
@@ -22,7 +24,7 @@
 import package_checks
 
 DB_SCHEMA_VERSION = 2L
-PACKAGE_STATS_VERSION = 3L
+PACKAGE_STATS_VERSION = 4L
 SYSTEM_PKGMAP = "/var/sadm/install/contents"
 WS_RE = re.compile(r"\s+")
 NEEDED_SONAMES = "needed sonames"
@@ -47,7 +49,14 @@
     ("/opt/csw/lib/i386", ["/opt/csw/lib"]),
 )
 INSTALL_CONTENTS_AVG_LINE_LENGTH = 102.09710677919261
+SYS_DEFAULT_RUNPATH = [
+    "/usr/lib/$ISALIST",
+    "/usr/lib",
+    "/lib/$ISALIST",
+    "/lib",
+]
 
+
 # This shared library is present on Solaris 10 on amd64, but it's missing on
 # Solaris 8 on i386.  It's okay if it's missing.
 ALLOWED_ORPHAN_SONAMES = set([u"libm.so.2"])
@@ -62,24 +71,22 @@
 # $pkgname:
 #end if
 #if $missing_deps
-# SUGGESTION: you may want to add some or all of the following as depends:
-#    (Feel free to ignore SUNW or SPRO packages)
-#for $pkg in $sorted($missing_deps)
+# SUGGESTION: you may want to add some or all of the following as dependencies:
+#for $pkg, $reasons in $sorted($missing_deps)
+# $pkg, reasons:
+#for $reason in $reasons
+# - $reason
+#end for
 RUNTIME_DEP_PKGS_$pkgname += $pkg
 #end for
 #end if
 #if $surplus_deps
-# The following dependencies might be unnecessary:
+# If you don't know of any reasons to include these dependencies, you might
+# remove them:
 #for $pkg in $sorted($surplus_deps)
 # ? $pkg
 #end for
 #end if
-#if $orphan_sonames
-# The following required sonames would not be found at runtime:
-#for $soname in $sorted($orphan_sonames)
-# ! $soname
-#end for
-#end if
 """
 
 SCREEN_ERROR_REPORT_TMPL = u"""#if $errors and $debug
@@ -355,6 +362,25 @@
     self.cache[filename] = lines
     return lines
 
+  def _InferPackagesFromPkgmapLine(self, line):
+    """A stub of a function, to be enhanced."""
+    line = line.strip()
+    parts = re.split(WS_RE, line)
+    return [parts[-1]]
+
+  def GetPathsAndPkgnamesByBasename(self, filename):
+    """Returns paths and packages by basename.
+
+    e.g.
+    {"/opt/csw/lib": ["CSWfoo", "CSWbar"],
+     "/opt/csw/1/lib": ["CSWfoomore"]}
+    """
+    lines = self.GetPkgmapLineByBasename(filename)
+    # Infer packages
+    for file_path in lines:
+      lines[file_path] = self._InferPackagesFromPkgmapLine(lines[file_path])
+    return lines
+
   def GetDatabaseMtime(self):
     if not self.cache_mtime:
       sql = """
@@ -447,134 +473,6 @@
     return dict(x[0:2] for x in c)
 
 
-def SharedObjectDependencies(pkgname,
-                             binaries_by_pkgname,
-                             needed_sonames_by_binary,
-                             pkgs_by_soname,
-                             filenames_by_soname,
-                             pkg_by_any_filename):
-  """This is one of the more obscure and more important pieces of code.
-
-  I tried to make it simpler, but given that the operations here involve
-  whole sets of packages, it's not easy to simplify.
-  """
-  so_dependencies = set()
-  orphan_sonames = set()
-  self_provided = set()
-  for binary in binaries_by_pkgname[pkgname]:
-    needed_sonames = needed_sonames_by_binary[binary][NEEDED_SONAMES]
-    for soname in needed_sonames:
-      if soname in filenames_by_soname:
-        filename = filenames_by_soname[soname]
-        pkg = pkg_by_any_filename[filename]
-        self_provided.add(soname)
-        so_dependencies.add(pkg)
-      elif soname in pkgs_by_soname:
-        so_dependencies.add(pkgs_by_soname[soname])
-      else:
-        orphan_sonames.add(soname)
-  return so_dependencies, self_provided, orphan_sonames
-
-
-def GuessDepsByFilename(pkgname, pkg_by_any_filename):
-  """Guesses dependencies based on filename regexes.
-
-  This function is still inefficient.  It should be getting better data
-  structures to work with.
-  """
-  guessed_deps = set()
-  patterns = [(re.compile(x), y) for x, y in DEPENDENCY_FILENAME_REGEXES]
-  filenames = []
-  # First, find the filenames of interest.
-  for filename, file_pkgname in pkg_by_any_filename.iteritems():
-    if file_pkgname == pkgname:
-      filenames.append(filename)
-  for regex, dep_pkgname in patterns:
-    for filename in filenames:
-      if regex.match(filename):
-        guessed_deps.add(dep_pkgname)
-  return guessed_deps
-
-
-def GuessDepsByPkgname(pkgname, pkg_by_any_filename):
-  # More guessed dependencies: If one package is a substring of another, it
-  # might be a hint. For example, CSWmysql51test should depend on CSWmysql51.
-  # However, the rt (runtime) packages should not want to depend on the main
-  # package.
-  guessed_deps = set()
-  all_other_pkgs = set(pkg_by_any_filename.values())
-  for other_pkg in all_other_pkgs:
-    other_pkg = unicode(other_pkg)
-    if pkgname == other_pkg:
-      continue
-    if pkgname.startswith(other_pkg):
-      endings = ["devel", "test", "bench", "dev"]
-      for ending in endings:
-        if pkgname.endswith(ending):
-          guessed_deps.add(other_pkg)
-  return guessed_deps
-
-
-def AnalyzeDependencies(pkgname,
-                        declared_dependencies,
-                        binaries_by_pkgname,
-                        needed_sonames_by_binary,
-                        pkgs_by_soname,
-                        filenames_by_soname,
-                        pkg_by_any_filename):
-  """Gathers and merges dependency results from other functions.
-
-  declared_dependencies: Dependencies that the package in question claims to
-                         have.
-
-  binaries_by_pkgname: A dictionary mapping pkgnames (CSWfoo) to binary names
-                       (without paths)
-
-  needed_sonames_by_binary: A dictionary mapping binary file name to
-                            a dictionary containing: "needed sonames",
-                            "soname", "rpath". Based on examining the binary
-                            files within the packages.
-
-  pkgs_by_soname: A dictionary mapping sonames to pkgnames, based on the
-                  contents of the system wide pkgmap
-                  (/var/sadm/install/contents)
-
-  filenames_by_soname: A dictionary mapping shared library sonames to filenames,
-                       based on files within packages
-
-  pkg_by_any_filename: Mapping from file names to packages names, based on the
-                       contents of the packages under examination.
-  """
-  declared_dependencies_set = set(declared_dependencies)
-
-  so_dependencies, self_provided, orphan_sonames = SharedObjectDependencies(
-      pkgname,
-      binaries_by_pkgname,
-      needed_sonames_by_binary,
-      pkgs_by_soname,
-      filenames_by_soname,
-      pkg_by_any_filename)
-  auto_dependencies = reduce(lambda x, y: x.union(y),
-      [
-        so_dependencies,
-        GuessDepsByFilename(pkgname, pkg_by_any_filename),
-        GuessDepsByPkgname(pkgname, pkg_by_any_filename),
-      ])
-  missing_deps = auto_dependencies.difference(declared_dependencies_set)
-  # Don't report itself as a suggested dependency.
-  missing_deps = missing_deps.difference(set([pkgname]))
-  missing_deps = missing_deps.difference(set(DO_NOT_REPORT_MISSING))
-  for re_str in DO_NOT_REPORT_MISSING_RE:
-    padded_re = "^%s$" % re_str
-    missing_deps = filter(lambda x: not re.match(padded_re, x),
-                          missing_deps)
-  missing_deps = set(missing_deps)
-  surplus_deps = declared_dependencies_set.difference(auto_dependencies)
-  surplus_deps = surplus_deps.difference(DO_NOT_REPORT_SURPLUS)
-  orphan_sonames = orphan_sonames.difference(ALLOWED_ORPHAN_SONAMES)
-  return missing_deps, surplus_deps, orphan_sonames
-
-
 def ExpandRunpath(runpath, isalist):
   # Emulating $ISALIST expansion
   if '$ISALIST' in runpath:
@@ -618,71 +516,45 @@
   return runpath
 
 
-def GetLinesBySoname(runpath_data_by_soname,
-                     needed_sonames,
-                     runpath_by_needed_soname, isalist):
-  """Works out which system pkgmap lines correspond to given sonames."""
-  lines_by_soname = {}
-  for soname in needed_sonames:
-    # This is the critical part of the algorithm: it iterates over the
-    # runpath and finds the first matching one.
-    runpath_found = False
-    for runpath in runpath_by_needed_soname[soname]:
-      runpath = SanitizeRunpath(runpath)
-      runpath_list = ExpandRunpath(runpath, isalist)
-      runpath_list = Emulate64BitSymlinks(runpath_list)
-      # Emulating the install time symlinks, for instance, if the prototype contains
-      # /opt/csw/lib/i386/foo.so.0 and /opt/csw/lib/i386 is a symlink to ".",
-      # the shared library ends up in /opt/csw/lib/foo.so.0 and should be
-      # findable even when RPATH does not contain $ISALIST.
-      soname_runpath_data = runpath_data_by_soname[soname]
-      new_soname_runpath_data = {}
-      for p in soname_runpath_data:
-        expanded_p_list = Emulate64BitSymlinks([p])
-        for expanded_p in expanded_p_list:
-          new_soname_runpath_data[expanded_p] = soname_runpath_data[p]
-      soname_runpath_data = new_soname_runpath_data
+def ResolveSoname(runpath, soname, isalist, path_list):
+  """Emulates ldd behavior, minimal implementation.
 
-      logging.debug("%s: will be looking for %s in %s" %
-                    (soname, runpath_list, soname_runpath_data.keys()))
-      for runpath_expanded in runpath_list:
-        if runpath_expanded in soname_runpath_data:
-          lines_by_soname[soname] = soname_runpath_data[runpath_expanded]
-          runpath_found = True
-          # This break only goes out of the inner loop,
-          # need another one below to finish the outer loop.
-          break
-      if runpath_found:
-        break
-  return lines_by_soname
+  runpath: e.g. ["/opt/csw/lib/$ISALIST", "/usr/lib"]
+  soname: e.g. "libfoo.so.1"
+  isalist: e.g. ["sparcv9", "sparcv8"]
+  path_list: A list of paths where the soname is present, e.g.
+             ["/opt/csw/lib", "/opt/csw/lib/sparcv9"]
 
-
-def BuildIndexesBySoname(needed_sonames_by_binary):
-  """Builds data structures indexed by soname.
-
-  Building indexes
-  {"foo.so": ["/opt/csw/lib/gcc4", "/opt/csw/lib", ...],
-   ...
-  }
+  The function returns the one path.
   """
-  needed_sonames = set()
-  binaries_by_soname = {}
-  runpath_by_needed_soname = {}
-  for binary_name, data in needed_sonames_by_binary.iteritems():
-    for soname in data[NEEDED_SONAMES]:
-      needed_sonames.add(soname)
-      if soname not in runpath_by_needed_soname:
-        runpath_by_needed_soname[soname] = []
-      runpath_by_needed_soname[soname].extend(data[RUNPATH])
-      if soname not in binaries_by_soname:
-        binaries_by_soname[soname] = set()
-      binaries_by_soname[soname].add(binary_name)
-  return needed_sonames, binaries_by_soname, runpath_by_needed_soname
+  runpath = SanitizeRunpath(runpath)
+  runpath_list = ExpandRunpath(runpath, isalist)
+  runpath_list = Emulate64BitSymlinks(runpath_list)
+  # Emulating the install time symlinks, for instance, if the prototype contains
+  # /opt/csw/lib/i386/foo.so.0 and /opt/csw/lib/i386 is a symlink to ".",
+  # the shared library ends up in /opt/csw/lib/foo.so.0 and should be
+  # findable even when RPATH does not contain $ISALIST.
+  original_paths_by_expanded_paths = {}
+  for p in path_list:
+    expanded_p_list = Emulate64BitSymlinks([p])
+    # We can't just expand and return; we need to return one of the paths given
+    # in the path_list.
+    for expanded_p in expanded_p_list:
+      original_paths_by_expanded_paths[expanded_p] = p
+  logging.debug("%s: looking for %s in %s",
+      soname, runpath_list, original_paths_by_expanded_paths.keys())
+  for runpath_expanded in runpath_list:
+    if runpath_expanded in original_paths_by_expanded_paths:
+      logging.debug("Found %s",
+                    original_paths_by_expanded_paths[runpath_expanded])
+      return original_paths_by_expanded_paths[runpath_expanded]
 
 
 def ParseDumpOutput(dump_output):
   binary_data = {RUNPATH: [],
                  NEEDED_SONAMES: []}
+  runpath = []
+  rpath = []
   for line in dump_output.splitlines():
     fields = re.split(WS_RE, line)
     # TODO: Make it a unit test
@@ -692,14 +564,18 @@
     if fields[1] == "NEEDED":
       binary_data[NEEDED_SONAMES].append(fields[2])
     elif fields[1] == "RUNPATH":
-      binary_data[RUNPATH].extend(fields[2].split(":"))
+      runpath.extend(fields[2].split(":"))
+    elif fields[1] == "RPATH":
+      rpath.extend(fields[2].split(":"))
     elif fields[1] == "SONAME":
       binary_data[SONAME] = fields[2]
-  # Adding the default runtime path search option.
-  binary_data[RUNPATH].append("/usr/lib/$ISALIST")
-  binary_data[RUNPATH].append("/usr/lib")
-  binary_data[RUNPATH].append("/lib/$ISALIST")
-  binary_data[RUNPATH].append("/lib")
+  if runpath:
+    binary_data[RUNPATH].extend(runpath)
+  elif rpath:
+    binary_data[RUNPATH].extend(rpath)
+  binary_data["RUNPATH RPATH the same"] = (runpath == rpath)
+  binary_data["RPATH set"] = bool(rpath)
+  binary_data["RUNPATH set"] = bool(runpath)
   return binary_data
 
 
@@ -810,11 +686,8 @@
     return (exit_code, screen_report, tags_report)
 
 
-class Flyweight(object):
-  pass
-
 class CheckInterfaceBase(object):
-  """Base class for check proxies.
+  """Proxies interaction with checking functions.
 
   It wraps access to the /var/sadm/install/contents cache.
   """
@@ -827,8 +700,13 @@
 
   def GetPkgmapLineByBasename(self, basename):
     """Proxies calls to self.system_pkgmap."""
+    logging.warning("GetPkgmapLineByBasename(%s): deprecated function", basename)
     return self.system_pkgmap.GetPkgmapLineByBasename(basename)
 
+  def GetPathsAndPkgnamesByBasename(self, basename):
+    """Proxies calls to self.system_pkgmap."""
+    return self.system_pkgmap.GetPathsAndPkgnamesByBasename(basename)
+
   def GetInstalledPackages(self):
     return self.system_pkgmap.GetInstalledPackages()
 

Modified: csw/mgar/gar/v2/lib/python/checkpkg_test.py
===================================================================
--- csw/mgar/gar/v2/lib/python/checkpkg_test.py	2010-03-23 17:37:18 UTC (rev 9342)
+++ csw/mgar/gar/v2/lib/python/checkpkg_test.py	2010-03-23 22:32:23 UTC (rev 9343)
@@ -7,30 +7,18 @@
 import difflib
 import checkpkg
 import opencsw
-import testdata.checkpkg_test_data_CSWmysql51rt as d1
-import testdata.checkpkg_test_data_CSWmysql51client as d2
-import testdata.checkpkg_test_data_CSWmysql51 as d3
-import testdata.checkpkg_test_data_CSWmysql51devel as d4
-import testdata.checkpkg_test_data_CSWlibpq_84 as d5
-import testdata.checkpkg_test_data_CSWmysql5client_8x as d6
-import testdata.checkpkg_test_data_CSWpostfix as d7
 import testdata.dump_output_1 as dump_1
 import testdata.dump_output_2 as dump_2
+import testdata.dump_output_3 as dump_3
 
 """A set of unit tests for the library checking code.
 
 A bunch of lines to test in the interactive Python shell.
 
 import sys
-sys.path.append("gar/bin/checkpkg.d")
+sys.path.append("lib/python")
 import checkpkg
-import testdata.checkpkg_test_data_CSWmysql5client_8x as d6
 
-checkpkg.SharedObjectDependencies("CSWmysql5client",
-d6.DATA_BINARIES_BY_PKGNAME, d6.DATA_NEEDED_SONAMES_BY_BINARY,
-d6.DATA_PKGS_BY_FILENAME, d6.DATA_FILENAMES_BY_SONAME,
-d6.DATA_PKG_BY_ANY_FILENAME)
-
 sqlite3 ~/.checkpkg/var-sadm-install-contents-cache-build8x
 SELECT * FROM systempkgmap WHERE basename = 'libncursesw.so.5';
 """
@@ -44,263 +32,6 @@
 \tlibXext.so.0 (SUNW_1.1) =>\t (version not found)
 """
 
-class DependenciesUnitTest_1(unittest.TestCase):
-
-  def setUp(self):
-    (self.missing_deps,
-     self.surplus_deps,
-     self.orphan_sonames) = checkpkg.AnalyzeDependencies(
-        d1.DATA_PKGNAME,
-        d1.DATA_DECLARED_DEPENDENCIES,
-        d1.DATA_BINARIES_BY_PKGNAME,
-        d1.DATA_NEEDED_SONAMES_BY_BINARY,
-        d1.DATA_PKGS_BY_FILENAME,
-        d1.DATA_FILENAMES_BY_SONAME,
-        d1.DATA_PKG_BY_ANY_FILENAME,
-    )
-
-  def testSurplusDeps(self):
-    self.assertEquals(set([]), self.surplus_deps)
-
-  def testOrphanSonames(self):
-    self.assertEquals(set([]), self.orphan_sonames)
-
-  def testMissingDeps(self):
-    expected = set([])
-    self.assertEquals(expected, self.missing_deps)
-
-
-class DependenciesUnitTest_2(unittest.TestCase):
-
-  def setUp(self):
-    (self.missing_deps,
-     self.surplus_deps,
-     self.orphan_sonames) = checkpkg.AnalyzeDependencies(
-        d2.DATA_PKGNAME,
-        d2.DATA_DECLARED_DEPENDENCIES,
-        d2.DATA_BINARIES_BY_PKGNAME,
-        d2.DATA_NEEDED_SONAMES_BY_BINARY,
-        d2.DATA_PKGS_BY_FILENAME,
-        d2.DATA_FILENAMES_BY_SONAME,
-        d2.DATA_PKG_BY_ANY_FILENAME,
-    )
-
-  def testSurplusDeps(self):
-    self.assertEquals(set([]), self.surplus_deps)
-
-  def testOrphanSonames(self):
-    self.assertEquals(set([]), self.orphan_sonames)
-
-  def testMissingDeps(self):
-    expected = set([])
-    self.assertEquals(expected, self.missing_deps)
-
-
-class DependenciesUnitTest_3(unittest.TestCase):
-
-  def setUp(self):
-    (self.missing_deps,
-     self.surplus_deps,
-     self.orphan_sonames) = checkpkg.AnalyzeDependencies(
-        d3.DATA_PKGNAME,
-        d3.DATA_DECLARED_DEPENDENCIES,
-        d3.DATA_BINARIES_BY_PKGNAME,
-        d3.DATA_NEEDED_SONAMES_BY_BINARY,
-        d3.DATA_PKGS_BY_FILENAME,
-        d3.DATA_FILENAMES_BY_SONAME,
-        d3.DATA_PKG_BY_ANY_FILENAME,
-    )
-
-  def testSurplusDeps(self):
-    self.assertEquals(set([u'CSWmysql51client']), self.surplus_deps)
-
-  def testOrphanSonames(self):
-    self.assertEquals(set([]), self.orphan_sonames)
-
-  def testMissingDeps(self):
-    expected = set(['CSWmysql51rt'])
-    self.assertEquals(expected, self.missing_deps)
-
-
-class DependenciesUnitTest_4(unittest.TestCase):
-
-  def setUp(self):
-    (self.missing_deps,
-     self.surplus_deps,
-     self.orphan_sonames) = checkpkg.AnalyzeDependencies(
-        d4.DATA_PKGNAME,
-        d4.DATA_DECLARED_DEPENDENCIES,
-        d4.DATA_BINARIES_BY_PKGNAME,
-        d4.DATA_NEEDED_SONAMES_BY_BINARY,
-        d4.DATA_PKGS_BY_FILENAME,
-        d4.DATA_FILENAMES_BY_SONAME,
-        d4.DATA_PKG_BY_ANY_FILENAME,
-    )
-
-  def testSurplusDeps(self):
-    self.assertEquals(set([]), self.surplus_deps)
-
-  def testOrphanSonames(self):
-    self.assertEquals(set([]), self.orphan_sonames)
-
-  def testMissingDeps(self):
-    expected = set([])
-    self.assertEquals(expected, self.missing_deps)
-
-
-class DependenciesUnitTest_5(unittest.TestCase):
-
-  def setUp(self):
-    (self.missing_deps,
-     self.surplus_deps,
-     self.orphan_sonames) = checkpkg.AnalyzeDependencies(
-        d5.DATA_PKGNAME,
-        d5.DATA_DECLARED_DEPENDENCIES,
-        d5.DATA_BINARIES_BY_PKGNAME,
-        d5.DATA_NEEDED_SONAMES_BY_BINARY,
-        d5.DATA_PKGS_BY_FILENAME,
-        d5.DATA_FILENAMES_BY_SONAME,
-        d5.DATA_PKG_BY_ANY_FILENAME,
-    )
-
-  def testSurplusDeps(self):
-    self.assertEquals(set([]), self.surplus_deps)
-
-  def testOrphanSonames(self):
-    self.assertEquals(set([]), self.orphan_sonames)
-
-  def testMissingDeps(self):
-    # This tends to report itself...
-    expected = set([])
-    self.assertEquals(expected, self.missing_deps)
-
-
-class DependenciesUnitTest_6(unittest.TestCase):
-
-  def setUp(self):
-    (self.missing_deps,
-     self.surplus_deps,
-     self.orphan_sonames) = checkpkg.AnalyzeDependencies(
-        d6.DATA_PKGNAME,
-        d6.DATA_DECLARED_DEPENDENCIES,
-        d6.DATA_BINARIES_BY_PKGNAME,
-        d6.DATA_NEEDED_SONAMES_BY_BINARY,
-        d6.DATA_PKGS_BY_FILENAME,
-        d6.DATA_FILENAMES_BY_SONAME,
-        d6.DATA_PKG_BY_ANY_FILENAME,
-    )
-
-  def testSurplusDeps(self):
-    self.assertEquals(set([]), self.surplus_deps)
-
-  def testOrphanSonames(self):
-    self.assertEquals(set([]), self.orphan_sonames)
-
-  def testMissingDeps(self):
-    expected = set([])
-    self.assertEquals(expected, self.missing_deps)
-
-
-class DependenciesUnitTest_7(unittest.TestCase):
-
-  def setUp(self):
-    (self.missing_deps,
-     self.surplus_deps,
-     self.orphan_sonames) = checkpkg.AnalyzeDependencies(
-        d7.DATA_PKGNAME,
-        d7.DATA_DECLARED_DEPENDENCIES,
-        d7.DATA_BINARIES_BY_PKGNAME,
-        d7.DATA_NEEDED_SONAMES_BY_BINARY,
-        d7.DATA_PKGS_BY_FILENAME,
-        d7.DATA_FILENAMES_BY_SONAME,
-        d7.DATA_PKG_BY_ANY_FILENAME,
-    )
-
-  def testSurplusDeps(self):
-    self.assertEquals(set([]), self.surplus_deps)
-
-  def testOrphanSonames(self):
-    self.assertEquals(set([]), self.orphan_sonames)
-
-  def testMissingDeps(self):
-    expected = set([])
-    self.assertEquals(expected, self.missing_deps)
-
-
-class GuessDepsUnitTest(unittest.TestCase):
-
-  def testGuessDepsByFilename1(self):
-    expected = set([u"CSWpython"])
-    pkgname = u"CSWfoo"
-    pkg_by_filename = {
-        "/opt/csw/bin/bar": u"CSWfoo",
-        "/opt/csw/lib/python/site-packages/foo.py": u"CSWfoo",
-    }
-    self.assertEqual(expected,
-                     checkpkg.GuessDepsByFilename(pkgname, pkg_by_filename))
-
-  def testGuessDepsByFilename2(self):
-    expected = set([])
-    pkgname = u"CSWfoo"
-    pkg_by_filename = {
-        "/opt/csw/bin/bar": u"CSWfoo",
-        "/opt/csw/lib/python/site-packages/foo.py": u"CSWbar",
-    }
-    self.assertEqual(expected,
-                     checkpkg.GuessDepsByFilename(pkgname, pkg_by_filename))
-
-  def testGuessDepsByFilename3(self):
-    expected = set([])
-    pkgname = u"CSWfoo"
-    pkg_by_filename = {
-        "/opt/csw/bin/bar": u"CSWfoo",
-        "/opt/csw/lib/foo.so.1": u"CSWfoo",
-    }
-    self.assertEqual(expected,
-                     checkpkg.GuessDepsByFilename(pkgname, pkg_by_filename))
-
-  def testGuessDepsByPkgname1(self):
-    expected = set([u"CSWfoo"])
-    pkgname = u"CSWfoo-devel"
-    pkg_by_filename = {
-        "/opt/csw/bin/bar": u"CSWfoo",
-        "/opt/csw/bin/barfoo": u"CSWfoobar",
-        "/opt/csw/lib/python/site-packages/foo.py": u"CSWfoo",
-    }
-    self.assertEqual(expected,
-                     checkpkg.GuessDepsByPkgname(pkgname, pkg_by_filename))
-
-  def testGuessDepsByPkgname2(self):
-    expected = set([])
-    pkgname = u"CSWzfoo-devel"
-    pkg_by_filename = {
-        "/opt/csw/bin/bar": u"CSWfoo",
-        "/opt/csw/bin/barfoo": u"CSWfoobar",
-        "/opt/csw/lib/python/site-packages/foo.py": u"CSWfoo",
-    }
-    self.assertEqual(expected,
-                     checkpkg.GuessDepsByPkgname(pkgname, pkg_by_filename))
-
-  def testGuessDepsByPkgname3(self):
-    self.assertEqual(set([u"CSWmysql51"]),
-                     checkpkg.GuessDepsByPkgname(u"CSWmysql51devel",
-                                                 d4.DATA_PKG_BY_ANY_FILENAME))
-
-  def testGuessDepsByPkgname4(self):
-    data1 = set(['CSWmysql51', 'CSWmysql51rt', 'CSWmysql51test',
-                 'CSWmysql51client', 'CSWmysql51bench', 'CSWmysql51devel'])
-    data2 = dict(((x, x) for x in data1))
-    self.assertEqual(set([u"CSWmysql51"]),
-                     checkpkg.GuessDepsByPkgname(u"CSWmysql51devel", data2))
-
-  def testGuessDepsByPkgname4(self):
-    data1 = set(['CSWmysql51', 'CSWmysql51rt', 'CSWmysql51test',
-                 'CSWmysql51client', 'CSWmysql51bench', 'CSWmysql51devel'])
-    data2 = dict(((x, x) for x in data1))
-    self.assertEqual(set([]),
-                     checkpkg.GuessDepsByPkgname(u"CSWmysql51rt", data2))
-
-
 class GetLinesBySonameUnitTest(unittest.TestCase):
 
   def setUp(self):
@@ -378,157 +109,6 @@
     self.assertFalse(not_expected in result,
                      "%s is in %s" % (not_expected, result))
 
-  def testGetLinesBySoname(self):
-    expected = {'foo.so.1': '/opt/csw/lib/isa-value-1/foo.so.1 foo'}
-    runpath_data_by_soname = {
-        "foo.so.1": {
-          "/opt/csw/lib/isa-value-1": "/opt/csw/lib/isa-value-1/foo.so.1 foo",
-          "/usr/lib":                 "/usr/lib/foo.so.1 foo"},
-    }
-    needed_sonames = set(["foo.so.1"])
-    runpath_by_needed_soname = {"foo.so.1": ["/opt/csw/lib/$ISALIST", "/usr/lib"]}
-    isalist = ["isa-value-1", "isa-value-2"]
-    result = checkpkg.GetLinesBySoname(runpath_data_by_soname, needed_sonames,
-                                       runpath_by_needed_soname, isalist)
-    self.assertEqual(expected, result)
-
-  def testGetLinesBySoname_3(self):
-    expected = {'foo.so.1': '/opt/csw/lib/isa-value-1/foo.so.1 foo'}
-    runpath_data_by_soname = {
-        "foo.so.1": {
-          "/opt/csw/lib/isa-value-1": "/opt/csw/lib/isa-value-1/foo.so.1 foo",
-          "/opt/csw/lib":             "/opt/csw/lib/foo.so.1 foo",
-          "/usr/lib":                 "/usr/lib/foo.so.1 foo",
-        }
-    }
-    needed_sonames = set(["foo.so.1"])
-    runpath_by_needed_soname = {
-        "foo.so.1": ["/opt/csw/lib/$ISALIST", "/usr/lib"]}
-    isalist = ["isa-value-1", "isa-value-2"]
-    result = checkpkg.GetLinesBySoname(runpath_data_by_soname, needed_sonames,
-                                       runpath_by_needed_soname, isalist)
-    self.assertEqual(expected, result)
-
-  def testGetLinesBySoname_4(self):
-    """A more complex test, four ISAs."""
-    expected = {'foo.so.1': '/opt/csw/lib/isa-value-1/foo.so.1 foo'}
-    runpath_data_by_soname = {
-        "foo.so.1": {
-          "/opt/csw/lib/isa-value-1":
-              "/opt/csw/lib/isa-value-1/foo.so.1 foo",
-          "/opt/csw/mysql5/lib/isa-value-2":
-              "/opt/csw/mysql5/lib/isa-value-2/foo.so.1 foo",
-          "/opt/csw/mysql5/lib/isa-value-1":
-              "/opt/csw/mysql5/lib/isa-value-1/foo.so.1 foo",
-          "/opt/csw/lib":
-              "/opt/csw/lib/foo.so.1 foo",
-          "/usr/lib":
-              "/usr/lib/foo.so.1 foo"
-        }
-    }
-    needed_sonames = set(["foo.so.1"])
-    runpath_by_needed_soname = {
-        "foo.so.1": ["/opt/csw/mysql5/lib/$ISALIST/mysql",
-                     "/opt/csw/lib/$ISALIST",
-                     "/usr/lib"]}
-    isalist = ["isa-value-1", "isa-value-2"]
-    result = checkpkg.GetLinesBySoname(
-        runpath_data_by_soname, needed_sonames, runpath_by_needed_soname, isalist)
-    self.pkgmap_mocker.VerifyAll()
-    self.assertEqual(expected, result)
-
-  def testGetLinesBySoname_5(self):
-    """Based on CSWmysql5client on build8x (5)."""
-    soname = u'libm.so.1'
-    expected = {u'libm.so.1': u'/usr/lib/libm.so.1 f none 0755 root bin '
-                              u'99844 3884 1050525375 SUNWlibms\n'}
-    runpath_data_by_soname = d6.DATA_PKGMAP_CACHE
-    (needed_sonames,
-     binaries_by_soname,
-     runpath_by_needed_soname) = checkpkg.BuildIndexesBySoname(
-         d6.DATA_NEEDED_SONAMES_BY_BINARY)
-    result = checkpkg.GetLinesBySoname(
-        runpath_data_by_soname,
-        set([soname]),
-        runpath_by_needed_soname,
-        d6.DATA_ISALIST)
-    self.assertEqual(expected, result)
-
-  def testGetLinesBySoname_6(self):
-    """Based on CSWmysql5client on build8x (6)."""
-    soname = u'libz.so.1'
-    expected = {
-        u'libz.so.1': u'/opt/csw/lib/pentium_pro+mmx/libz.so.1=libz.so.1.2.3 '
-        u's none CSWzlib\n'}
-    runpath_data_by_soname = d6.DATA_PKGMAP_CACHE
-    (needed_sonames,
-     binaries_by_soname,
-     runpath_by_needed_soname) = checkpkg.BuildIndexesBySoname(
-         d6.DATA_NEEDED_SONAMES_BY_BINARY)
-    result = checkpkg.GetLinesBySoname(
-        runpath_data_by_soname,
-        set([soname]),
-        runpath_by_needed_soname,
-        d6.DATA_ISALIST)
-    self.assertEqual(expected, result)
-
-  def testGetLinesBySoname_7(self):
-    """A test for 64-bit symlink expansion."""
-    soname = u'libncursesw.so.5'
-    # To test the 64-bit symlink expansion
-    expected = {
-        u'libncursesw.so.5':
-          u'/opt/csw/lib/amd64/libncursesw.so.5=libncursesw.so.5.7 '
-          u's none CSWncurses\n'}
-    runpath_data_by_soname = d6.DATA_PKGMAP_CACHE
-    (needed_sonames,
-     binaries_by_soname,
-     runpath_by_needed_soname) = checkpkg.BuildIndexesBySoname(
-         d6.DATA_NEEDED_SONAMES_BY_BINARY)
-    # The original data did not have amd64 in the isalist.
-    isalist = ['amd64', 'pentium_pro+mmx', 'pentium_pro', 'pentium+mmx',
-               'pentium', 'i486', 'i386', 'i86']
-    result = checkpkg.GetLinesBySoname(
-        runpath_data_by_soname,
-        set([soname]),
-        runpath_by_needed_soname,
-        isalist)
-    self.assertEqual(expected, result)
-
-  def testGetLinesBySoname_8(self):
-    expected = {'foo.so.1': '/opt/csw/postgresql/lib/foo.so.1 foo'}
-    runpath_data_by_soname = {
-        "foo.so.1": {
-          "/opt/csw/postgresql/lib": "/opt/csw/postgresql/lib/foo.so.1 foo",
-        }
-    }
-    needed_sonames = set(["foo.so.1"])
-    runpath_by_needed_soname = {
-        "foo.so.1": ["/opt/csw/postgresql/lib/", "/usr/lib"]}
-    isalist = ["isa-value-1", "isa-value-2"]
-    result = checkpkg.GetLinesBySoname(
-        runpath_data_by_soname, needed_sonames, runpath_by_needed_soname, isalist)
-    self.assertEqual(expected, result)
-
-  def testGetLinesBySoname_9(self):
-    """Emulation of binaries installed into /opt/csw/lib/i386.
-
-    The problem is that /opt/csw/lib/i386 is a symlink and the binaries
-    end up in /opt/csw/lib instead.
-    """
-    expected = {'foo.so.0': '/opt/csw/lib/i386/foo.so.0 foo'}
-    runpath_data_by_soname = {
-        "foo.so.0": {
-          "/opt/csw/lib/i386": "/opt/csw/lib/i386/foo.so.0 foo",
-        }
-    }
-    needed_sonames = set(["foo.so.0"])
-    runpath_by_needed_soname = {"foo.so.0": ["/opt/csw/lib", "/usr/lib"]}
-    isalist = ["isa-value-1", "isa-value-2"]
-    result = checkpkg.GetLinesBySoname(
-        runpath_data_by_soname, needed_sonames, runpath_by_needed_soname, isalist)
-    self.assertEqual(expected, result)
-
   def testSanitizeRunpath_1(self):
     self.assertEqual("/opt/csw/lib",
                      checkpkg.SanitizeRunpath("/opt/csw/lib/"))
@@ -543,17 +123,9 @@
 
   def test_1(self):
     expected = {
-        'soname': 'libmysqlclient.so.15',
-        'runpath': ['/opt/csw/lib/$ISALIST',
-                    '/opt/csw/lib',
-                    '/opt/csw/mysql5/lib/$ISALIST',
-                    '/opt/csw/mysql5/lib',
-                    '/opt/csw/mysql5/lib/$ISALIST/mysql',
-                    # These four are artificially appended
-                    '/usr/lib/$ISALIST',
-                    '/usr/lib',
-                    '/lib/$ISALIST',
-                    '/lib'],
+        'RPATH set': True,
+        'RUNPATH RPATH the same': True,
+        'RUNPATH set': True,
         'needed sonames': ['librt.so.1',
                            'libresolv.so.2',
                            'libc.so.1',
@@ -561,57 +133,50 @@
                            'libsocket.so.1',
                            'libnsl.so.1',
                            'libm.so.1',
-                           'libz.so.1']}
+                           'libz.so.1'],
+        'runpath': ['/opt/csw/lib/$ISALIST',
+                    '/opt/csw/lib',
+                    '/opt/csw/mysql5/lib/$ISALIST',
+                    '/opt/csw/mysql5/lib',
+                    '/opt/csw/mysql5/lib/$ISALIST/mysql'],
+        'soname': 'libmysqlclient.so.15',
+    }
     self.assertEqual(expected,
                      checkpkg.ParseDumpOutput(dump_1.DATA_DUMP_OUTPUT))
 
-  def test_2(self):
-    expected_runpath = ['/usr/lib/$ISALIST', '/usr/lib', '/lib/$ISALIST',
-                        '/lib']
+  def testEmpty(self):
+    expected_runpath = []
     self.assertEqual(
         expected_runpath,
         checkpkg.ParseDumpOutput(dump_2.DATA_DUMP_OUTPUT)["runpath"])
 
+  def testRpathOnly(self):
+    expected = {
+        'RPATH set': True,
+        'RUNPATH RPATH the same': False,
+        'RUNPATH set': False,
+        'needed sonames': ['librt.so.1',
+                           'libresolv.so.2',
+                           'libc.so.1',
+                           'libgen.so.1',
+                           'libsocket.so.1',
+                           'libnsl.so.1',
+                           'libm.so.1',
+                           'libz.so.1'],
+        'runpath': ['/opt/csw/lib/$ISALIST',
+                    '/opt/csw/lib',
+                    '/opt/csw/mysql5/lib/$ISALIST',
+                    '/opt/csw/mysql5/lib',
+                    '/opt/csw/mysql5/lib/$ISALIST/mysql'],
+        'soname': 'libmysqlclient.so.15',
+    }
+    self.assertEqual(
+        expected,
+        checkpkg.ParseDumpOutput(dump_3.DATA_DUMP_OUTPUT))
 
-class FormatDepsReportUnitTest(unittest.TestCase):
 
-  def AssertTextEqual(self, text1, text2):
-    difference = "\n".join(difflib.context_diff(text2.splitlines(), text1.splitlines()))
-    self.assertEqual(text1, text2, difference)
-
-  def testAll(self):
-    missing_deps = set([u'SUNWgss', u'*SUNWlxsl'])
-    surplus_deps = set(['CSWsudo', 'CSWlibxslt'])
-    orphan_sonames = set([u'libm.so.2'])
-    testdata = ("CSWfoo", missing_deps, surplus_deps, orphan_sonames)
-    checker = opencsw.DirectoryFormatPackage("/tmp/nonexistent/CSWfoo")
-    expected = u"""# CSWfoo:
-# SUGGESTION: you may want to add some or all of the following as depends:
-#    (Feel free to ignore SUNW or SPRO packages)
-RUNTIME_DEP_PKGS_CSWfoo += *SUNWlxsl
-RUNTIME_DEP_PKGS_CSWfoo += SUNWgss
-# The following dependencies might be unnecessary:
-# ? CSWlibxslt
-# ? CSWsudo
-# The following required sonames would not be found at runtime:
-# ! libm.so.2
-"""
-    result = checkpkg.FormatDepsReport(*testdata)
-    self.AssertTextEqual(result, expected)
-
-  def testNone(self):
-    missing_deps = set([])
-    surplus_deps = set([])
-    orphan_sonames = set([])
-    testdata = ("CSWfoo", missing_deps, surplus_deps, orphan_sonames)
-    checker = opencsw.DirectoryFormatPackage("/tmp/nonexistent/CSWfoo")
-    expected = u""
-    result = checkpkg.FormatDepsReport(*testdata)
-    self.AssertTextEqual(result, expected)
-
-
 class CheckpkgTagsUnitTest(unittest.TestCase):
-  
+
   def test_1(self):
     m = checkpkg.CheckpkgManager2("testname", "/tmp", ["CSWfoo"])
     tags = {

Added: csw/mgar/gar/v2/lib/python/dependency_checks.py
===================================================================
--- csw/mgar/gar/v2/lib/python/dependency_checks.py	                        (rev 0)
+++ csw/mgar/gar/v2/lib/python/dependency_checks.py	2010-03-23 22:32:23 UTC (rev 9343)
@@ -0,0 +1,64 @@
+# $Id$
+
+import checkpkg
+import re
+
+def Libraries(pkg_data, error_mgr, logger, path_and_pkg_by_soname):
+  pkgname = pkg_data["basic_stats"]["pkgname"]
+  logger.info("Package %s", pkgname)
+  orphan_sonames = []
+  required_deps = []
+  isalist = pkg_data["isalist"]
+  for binary_info in pkg_data["binaries_dump_info"]:
+    for soname in binary_info["needed sonames"]:
+      resolved = False
+      path_list = path_and_pkg_by_soname[soname].keys()
+      logger.debug("%s @ %s: looking for %s in %s",
+                   soname, binary_info["path"], binary_info["runpath"], path_list)
+      for runpath in binary_info["runpath"] + checkpkg.SYS_DEFAULT_RUNPATH:
+        resolved_path = checkpkg.ResolveSoname(runpath, soname, isalist, path_list)
+        if resolved_path:
+          logger.debug("%s needed by %s:",
+                 soname, binary_info["path"])
+          # print "%s => %s" % (binary_info["runpath"], resolved_path)
+          logger.debug("=> %s provided by %s",
+              resolved_path, path_and_pkg_by_soname[soname][resolved_path])
+          resolved = True
+          req_pkg = path_and_pkg_by_soname[soname][resolved_path][-1]
+          # TODO: Throw an error when /opt/csw/lib/libdb-4.7.so gets resolved
+          reason = "provides %s/%s needed by %s" % (resolved_path, soname, binary_info["path"])
+          BAD_COMBINATIONS = (
+              ("/opt/csw/lib", "libdb-4.7.so", "Deprecated Berkeley DB location"),
+          )
+          for bad_path, bad_soname, msg in BAD_COMBINATIONS:
+            # print "resolved_path == bad_path", resolved_path, bad_path, resolved_path == bad_path
+            # print "soname == bad_soname", soname, bad_soname, soname == bad_soname
+            if resolved_path == bad_path and soname == bad_soname:
+              logger.debug("Bad lib found: %s/%s", bad_path, bad_soname)
+              error_mgr.ReportError(
+                  "deprecated-library",
+                  "%s %s %s/%s" % (binary_info["path"], msg, resolved_path, soname))
+          required_deps.append((req_pkg, reason))
+          break
+      if not resolved:
+        orphan_sonames.append((soname, binary_info["path"]))
+  orphan_sonames = set(orphan_sonames)
+  for soname, binary_path in orphan_sonames:
+    error_mgr.ReportError(
+        pkgname, "soname-not-found", "%s needed by %s" % (soname, binary_path))
+  # TODO: Report orphan sonames here
+  return required_deps
+
+def ByFilename(pkg_data, error_mgr, logger, path_and_pkg_by_soname):
+  pkgname = pkg_data["basic_stats"]["pkgname"]
+  req_pkgs_reasons = []
+  dep_regexes = [(re.compile(x), x, y)
+                 for x, y in checkpkg.DEPENDENCY_FILENAME_REGEXES]
+  for regex, regex_str, dep_pkgname in dep_regexes:
+    for pkgmap_entry in pkg_data["pkgmap"]:
+      if pkgmap_entry["path"] and regex.match(pkgmap_entry["path"]):
+        msg = ("found file(s) matching %s, e.g. %s"
+               % (regex_str, repr(pkgmap_entry["path"])))
+        req_pkgs_reasons.append((dep_pkgname, msg))
+        break
+  return req_pkgs_reasons


Property changes on: csw/mgar/gar/v2/lib/python/dependency_checks.py
___________________________________________________________________
Added: svn:keywords
   + Id

Modified: csw/mgar/gar/v2/lib/python/opencsw.py
===================================================================
--- csw/mgar/gar/v2/lib/python/opencsw.py	2010-03-23 17:37:18 UTC (rev 9342)
+++ csw/mgar/gar/v2/lib/python/opencsw.py	2010-03-23 22:32:23 UTC (rev 9343)
@@ -797,6 +797,7 @@
       files_root = os.path.join(self.directory, "root")
       if not os.path.exists(files_root):
         return []
+      # FIXME: It thinks that ELFunctionMapper.html is a binary
       find_tmpl = "find '%s' -print | xargs file | grep ELF | nawk -F: '{print $1}'"
       find_proc = subprocess.Popen(find_tmpl % ".",
                                    shell=True,

Modified: csw/mgar/gar/v2/lib/python/package_checks.py
===================================================================
--- csw/mgar/gar/v2/lib/python/package_checks.py	2010-03-23 17:37:18 UTC (rev 9342)
+++ csw/mgar/gar/v2/lib/python/package_checks.py	2010-03-23 22:32:23 UTC (rev 9343)
@@ -15,7 +15,9 @@
 import os
 import checkpkg
 import opencsw
+import pprint
 import textwrap
+import dependency_checks as depchecks
 from Cheetah import Template
 
 PATHS_ALLOWED_ONLY_IN = {
@@ -49,6 +51,13 @@
 }
 DO_NOT_LINK_AGAINST_THESE_SONAMES = set(["libX11.so.4"])
 DISCOURAGED_FILE_PATTERNS = (r"\.py[co]$",)
+BAD_RPATH_LIST = [
+    r'/opt/csw/lib/mysql/lib',
+    r'/opt/csw/lib/mysql/lib/sparcv9',
+    r'/opt/csw/lib/\$ISALIST',
+    r'/opt/csw/lib/$$ISALIST',
+    r'/opt/csw/lib/SALIST',
+]
 
 
 def CatalognameLowercase(pkg_data, error_mgr, logger):
@@ -59,15 +68,6 @@
     error_mgr.ReportError("catalogname-is-not-a-simple-word")
 
 
-def CheckForbiddenPaths(pkg_data, error_mgr, logger):
-  for pkgname in PATHS_ALLOWED_ONLY_IN:
-    if pkgname != pkg_data["basic_stats"]["pkgname"]:
-      for entry in pkg_data["pkgmap"]:
-        for forbidden_path in PATHS_ALLOWED_ONLY_IN[pkgname]:
-          if entry["path"] == forbidden_path:
-            error_mgr.ReportError("forbidden-path", entry["path"])
-
-
 def CheckDirectoryPermissions(pkg_data, error_mgr, logger):
   for entry in pkg_data["pkgmap"]:
     if (entry["type"] == "d"
@@ -109,7 +109,7 @@
     error_mgr.ReportError("pkginfo-description-missing")
   else:
     if len(desc) > MAX_DESCRIPTION_LENGTH:
-      error_mgr.ReportError("pkginfo-description-too-long")
+      error_mgr.ReportError("pkginfo-description-too-long", "length=%s" % len(desc))
     if not desc[0].isupper():
       error_mgr.ReportError("pkginfo-description-not-starting-with-uppercase",
                             desc)
@@ -118,7 +118,7 @@
 def CheckCatalogname(pkg_data, error_mgr, logger):
   pkginfo = pkg_data["pkginfo"]
   catalogname = pkginfo["NAME"].split(" ")[0]
-  catalogname_re = r"^(\w+)$"
+  catalogname_re = r"^([\w\+]+)$"
   if not re.match(catalogname_re, catalogname):
     error_mgr.ReportError("pkginfo-bad-catalogname", catalogname)
 
@@ -136,117 +136,78 @@
           "%s class=%s" % (entry["path"], entry["class"]))
 
 
-def SetCheckSharedLibraryConsistency(pkgs_data, error_mgr, logger):
-  ws_re = re.compile(r"\s+")
-  result_ok = True
-  binaries = []
-  binaries_by_pkgname = {}
-  sonames_by_pkgname = {}
-  pkg_by_any_filename = {}
-  needed_sonames_by_binary = {}
-  filenames_by_soname = {}
+def SetCheckLibraries(pkgs_data, error_mgr, logger):
+  """Second versionof the library checking code.
+
+  1. Collect all the data from the FS:
+     {"<basename>": {"/path/1": ["CSWfoo1"], "/path/2": ["CSWfoo2"]}}
+     1.1. find all needed sonames
+     1.2. get all the data for needed sonames
+  2. Construct an overlay by applying data from the package set
+  3. For each binary
+     3.1. Resolve all NEEDED sonames
+  """
+  needed_sonames = []
   for pkg_data in pkgs_data:
-    binaries_base = [os.path.basename(x) for x in pkg_data["binaries"]]
+    for binary_info in pkg_data["binaries_dump_info"]:
+      needed_sonames.extend(binary_info["needed sonames"])
+  needed_sonames = sorted(set(needed_sonames))
+  # Finding candidate libraries from the filesystem (/var/sadm/install/contents)
+  path_and_pkg_by_soname = {}
+  for needed_soname in needed_sonames:
+    path_and_pkg_by_soname[needed_soname] = error_mgr.GetPathsAndPkgnamesByBasename(
+        needed_soname)
+  # Adding overlay based on the given package set
+  # TODO: Emulate package removal
+  for pkg_data in pkgs_data:
     pkgname = pkg_data["basic_stats"]["pkgname"]
-    binaries_by_pkgname[pkgname] = binaries_base
-    binaries.extend(pkg_data["binaries"])
-    for filename in pkg_data["all_filenames"]:
-      pkg_by_any_filename[filename] = pkgname
-    for binary_data in pkg_data["binaries_dump_info"]:
-      binary_base_name = os.path.basename(binary_data["base_name"])
-      needed_sonames_by_binary[binary_base_name] = binary_data
-      filenames_by_soname[binary_data[checkpkg.SONAME]] = binary_base_name
-
-  # Making the binaries unique
-  binaries = set(binaries)
-  isalist = pkg_data["isalist"]
-
-  # Building indexes by soname to simplify further processing
-  # These are indexes "by soname".
-  (needed_sonames,
-   binaries_by_soname,
-   runpath_by_needed_soname
-  ) = checkpkg.BuildIndexesBySoname(needed_sonames_by_binary)
-
-  logger.debug("Determining the soname-package relationships.")
-  # lines by soname is an equivalent of $EXTRACTDIR/shortcatalog
-  runpath_data_by_soname = {}
-  for soname in needed_sonames:
-    runpath_data_by_soname[soname] = error_mgr.GetPkgmapLineByBasename(soname)
-  lines_by_soname = checkpkg.GetLinesBySoname(
-      runpath_data_by_soname, needed_sonames, runpath_by_needed_soname, isalist)
-
-  logger.debug("Creating a map from files to packages.")
-  pkgs_by_filename = {}
-  for soname, line in lines_by_soname.iteritems():
-    # TODO: Find all the packages, not just the last field.
-    fields = re.split(ws_re, line.strip())
-    # For now, we'll assume that the last field is the package.
-    pkgname = fields[-1]
-    pkgs_by_filename[soname] = pkgname
-
-  # A shared object dependency/provisioning report.
-  #
-  # This section is somewhat overlapping with checkpkg.AnalyzeDependencies(),
-  # it has a different purpose: it reports the relationships between shared
-  # libraries, binaries using them and packages providing them.  Ideally, the
-  # same bit of code would do both checking and reporting.
-  #
-  # TODO: Rewrite this using cheetah templates
-  if True and needed_sonames:
-    print "Analysis of sonames needed by the package set:"
-    binaries_with_missing_sonames = set([])
-    for soname in needed_sonames:
-      logger.debug("Analyzing: %s", soname)
-      if soname in filenames_by_soname:
-        print "%s is provided by the package itself" % soname
-      elif soname in lines_by_soname:
-        print ("%s is provided by %s and required by:"
-               % (soname,
-                  pkgs_by_filename[soname]))
-        filename_lines = " ".join(sorted(binaries_by_soname[soname]))
-        for line in textwrap.wrap(filename_lines, 70):
-          print " ", line
-      else:
-        print ("%s is required by %s, but we don't know what provides it."
-               % (soname, binaries_by_soname[soname]))
-        for binary in binaries_by_soname[soname]:
-          binaries_with_missing_sonames.add(binary)
-        if soname in checkpkg.ALLOWED_ORPHAN_SONAMES:
-          print "However, it's a whitelisted soname."
-        else:
-          print "No package seems to be providing %s" % (soname,)
-    if binaries_with_missing_sonames:
-      print "The following are binaries with missing sonames:"
-      binary_lines = " ".join(sorted(binaries_with_missing_sonames))
-      for line in textwrap.wrap(binary_lines, 70):
-        print " ", line
-    print
-
-  dependent_pkgs = {}
+    for binary_info in pkg_data["binaries_dump_info"]:
+      soname = binary_info["soname"]
+      binary_path, basename = os.path.split(binary_info["path"])
+      if not binary_path.startswith('/'):
+        binary_path = "/" + binary_path
+      if soname not in path_and_pkg_by_soname:
+        path_and_pkg_by_soname[soname] = {}
+      path_and_pkg_by_soname[soname][binary_path] = [pkgname]
+  # Resolving sonames for each binary
   for pkg_data in pkgs_data:
     pkgname = pkg_data["basic_stats"]["pkgname"]
-    declared_dependencies = dict(pkg_data["depends"])
-    missing_deps, surplus_deps, orphan_sonames = checkpkg.AnalyzeDependencies(
-        pkgname,
-        declared_dependencies,
-        binaries_by_pkgname,
-        needed_sonames_by_binary,
-        pkgs_by_filename,
-        filenames_by_soname,
-        pkg_by_any_filename)
+    check_args = (pkg_data, error_mgr, logger, path_and_pkg_by_soname)
+    req_pkgs_reasons = depchecks.Libraries(*check_args)
+    req_pkgs_reasons.extend(depchecks.ByFilename(*check_args))
+    missing_reasons_by_pkg = {}
+    for pkg, reason in req_pkgs_reasons:
+      if pkg not in missing_reasons_by_pkg:
+        missing_reasons_by_pkg[pkg] = set()
+      missing_reasons_by_pkg[pkg].add(reason)
+    declared_deps = pkg_data["depends"]
+    declared_deps_set = set([x[0] for x in declared_deps])
+    req_pkgs_set = set([x[0] for x in req_pkgs_reasons])
+    missing_deps = req_pkgs_set.difference(declared_deps_set)
+    pkgs_to_remove = set()
+    for regex_str in checkpkg.DO_NOT_REPORT_MISSING_RE:
+      regex = re.compile(regex_str)
+      for dep_pkgname in missing_deps:
+        if re.match(regex, dep_pkgname):
+          pkgs_to_remove.add(dep_pkgname)
+    if pkgname in missing_deps:
+      pkgs_to_remove.add(pkgname)
+    logger.debug("Removing %s from the list of missing pkgs.", pkgs_to_remove)
+    missing_deps = missing_deps.difference(pkgs_to_remove)
+    surplus_deps = declared_deps_set.difference(req_pkgs_set)
+    surplus_deps = surplus_deps.difference(checkpkg.DO_NOT_REPORT_SURPLUS)
+    missing_deps_reasons = []
+    for missing_dep in missing_deps:
+      error_mgr.ReportError(pkgname, "missing-dependency", "%s" % (missing_dep))
+      missing_deps_reasons.append((missing_dep, missing_reasons_by_pkg[missing_dep]))
+    for surplus_dep in surplus_deps:
+      error_mgr.ReportError(pkgname, "surplus-dependency", surplus_dep)
     namespace = {
         "pkgname": pkgname,
-        "missing_deps": missing_deps,
+        "missing_deps": missing_deps_reasons,
         "surplus_deps": surplus_deps,
-        "orphan_sonames": orphan_sonames,
+        "orphan_sonames": None,
     }
-    for soname in orphan_sonames:
-      error_mgr.ReportError(pkgname, "orphan-soname", soname)
-    for missing_dep in missing_deps:
-      error_mgr.ReportError(pkgname, "missing-dependency", missing_dep)
-    for surplus_dep in surplus_deps:
-      error_mgr.ReportError(pkgname, "surplus-dependency", surplus_dep)
     t = Template.Template(checkpkg.REPORT_TMPL, searchList=[namespace])
     report = unicode(t)
     if report.strip():
@@ -281,7 +242,8 @@
   arch = pkginfo["ARCH"]
   filename_re = r"-%s-" % arch
   if not re.search(filename_re, filename):
-    error_mgr.ReportError("srv4-filename-architecture-mismatch", arch)
+    error_mgr.ReportError("srv4-filename-architecture-mismatch",
+                          "pkginfo=%s filename=%s" % (arch, filename))
 
 
 def CheckActionClasses(pkg_data, error_mgr, logger):
@@ -446,6 +408,10 @@
     error_mgr.ReportError("pkginfo-version-wrong-format", msg)
   if pkginfo["ARCH"] not in ARCH_LIST:
     error_mgr.ReportError("pkginfo-nonstandard-architecture", pkginfo["ARCH"])
+
+
+def CheckPstamp(pkg_data, error_mgr, logger):
+  pkginfo = pkg_data["pkginfo"]
   if "PSTAMP" in pkginfo:
     if not re.match(checkpkg.PSTAMP_RE, pkginfo["PSTAMP"]):
       msg=("It should be 'username at hostname-timestamp', "
@@ -508,6 +474,16 @@
         error_mgr.ReportError("disallowed-path", disallowed_path)
 
 
+def CheckDisallowedPaths(pkg_data, error_mgr, logger):
+  """This seems to be a duplicate of CheckPkgmapPaths."""
+  for pkgname in PATHS_ALLOWED_ONLY_IN:
+    if pkgname != pkg_data["basic_stats"]["pkgname"]:
+      for entry in pkg_data["pkgmap"]:
+        for forbidden_path in PATHS_ALLOWED_ONLY_IN[pkgname]:
+          if entry["path"] == forbidden_path:
+            error_mgr.ReportError("disallowed-path", entry["path"])
+
+
 def CheckLinkingAgainstSunX11(pkg_data, error_mgr, logger):
   for binary_info in pkg_data["binaries_dump_info"]:
     for soname in binary_info["needed sonames"]:
@@ -539,3 +515,13 @@
     error_mgr.ReportError("pkgchk-failed-with-code", pkg_data["pkgchk"]["return_code"])
     for line in pkg_data["pkgchk"]["stderr_lines"]:
       logger.warn(line)
+
+def CheckRpath(pkg_data, error_mgr, logger):
+  # for bad_rpath in BAD_RPATH_LIST:
+  bad_rpath_set = set(BAD_RPATH_LIST)
+  for binary_info in pkg_data["binaries_dump_info"]:
+    for actual_rpath in binary_info["runpath"]:
+      if actual_rpath in bad_rpath_set:
+        error_mgr.ReportError("bad-rpath-entry",
+                              "%s %s" % (binary_info["path"], actual_rpath))
+

Modified: csw/mgar/gar/v2/lib/python/package_checks_test.py
===================================================================
--- csw/mgar/gar/v2/lib/python/package_checks_test.py	2010-03-23 17:37:18 UTC (rev 9342)
+++ csw/mgar/gar/v2/lib/python/package_checks_test.py	2010-03-23 22:32:23 UTC (rev 9343)
@@ -10,8 +10,10 @@
 import os.path
 import mox
 import logging
+import pprint
 
 import testdata.checkpkg_test_data_CSWdjvulibrert as td_1
+import testdata.checkpkg_pkgs_data_minimal as td_2
 
 BASE_DIR = os.path.dirname(__file__)
 TESTDATA_DIR = os.path.join(BASE_DIR, "testdata")
@@ -33,9 +35,14 @@
     self.mocker = mox.Mox()
 
   def testDefault(self):
+
     class LoggerStub(object):
+
       def debug(self, debug_s, *kwords):
         pass
+
+      def info(self, debug_s, *kwords):
+        pass
     # self.logger_mock = self.mocker.CreateMock(logging.Logger)
     self.logger_mock = LoggerStub()
     self.error_mgr_mock = self.mocker.CreateMock(
@@ -66,7 +73,7 @@
   FUNCTION_NAME = 'CheckDescription'
   def CheckpkgTest(self):
     self.pkg_data["pkginfo"]["NAME"] = 'foo - ' 'A' * 200
-    self.error_mgr_mock.ReportError('pkginfo-description-too-long')
+    self.error_mgr_mock.ReportError('pkginfo-description-too-long', 'length=1394')
 
 
 class TestDescriptionNotCapitalized(CheckpkgUnitTestHelper, unittest.TestCase):
@@ -77,13 +84,20 @@
                                     'lowercase')
 
 
-class TestCheckCatalogname(CheckpkgUnitTestHelper, unittest.TestCase):
+class TestCheckCatalogname_1(CheckpkgUnitTestHelper, unittest.TestCase):
   FUNCTION_NAME = 'CheckCatalogname'
   def CheckpkgTest(self):
     self.pkg_data["pkginfo"]["NAME"] = 'foo-bar - This catalog name is bad'
-    self.error_mgr_mock.ReportError('pkginfo-bad-catalogname')
+    self.error_mgr_mock.ReportError('pkginfo-bad-catalogname', 'foo-bar')
 
-class TestCheckCatalogname(CheckpkgUnitTestHelper, unittest.TestCase):
+
+class TestCheckCatalogname_2(CheckpkgUnitTestHelper, unittest.TestCase):
+  FUNCTION_NAME = 'CheckCatalogname'
+  def CheckpkgTest(self):
+    self.pkg_data["pkginfo"]["NAME"] = 'libsigc++_devel - This catalog name is good'
+
+
+class TestCheckSmfIntegration(CheckpkgUnitTestHelper, unittest.TestCase):
   FUNCTION_NAME = 'CheckSmfIntegration'
   def CheckpkgTest(self):
     self.pkg_data["pkgmap"].append({
@@ -186,7 +200,9 @@
   FUNCTION_NAME = 'CheckArchitectureSanity'
   def CheckpkgTest(self):
     self.pkg_data["pkginfo"]["ARCH"] = "i386"
-    self.error_mgr_mock.ReportError('srv4-filename-architecture-mismatch', 'i386')
+    self.error_mgr_mock.ReportError(
+        'srv4-filename-architecture-mismatch',
+        'pkginfo=i386 filename=rsync-3.0.7,REV=2010.02.17-SunOS5.8-sparc-CSW.pkg.gz')
 
 class TestCheckArchitectureVsContents(CheckpkgUnitTestHelper, unittest.TestCase):
   FUNCTION_NAME = 'CheckArchitectureVsContents'
@@ -236,45 +252,55 @@
     self.error_mgr_mock.ReportError('linked-against-discouraged-library',
                                     'libImlib2.so.1.4.2 libX11.so.4')
 
-class TestSetCheckSharedLibraryConsistency_1(CheckpkgUnitTestHelper, unittest.TestCase):
-  FUNCTION_NAME = 'SetCheckSharedLibraryConsistency'
+class TestSetCheckSharedLibraryConsistency2_1(CheckpkgUnitTestHelper, unittest.TestCase):
+  FUNCTION_NAME = 'SetCheckLibraries'
   def CheckpkgTest(self):
     self.pkg_data = [td_1.pkg_data]
-    self.error_mgr_mock.GetPkgmapLineByBasename('libiconv.so.2').AndReturn(
-      {u'/opt/csw/lib': u'/opt/csw/lib/libiconv.so.2=libiconv.so.2.5.0 s none CSWiconv',
-       u'/opt/csw/lib/sparcv9': u'/opt/csw/lib/sparcv9/libiconv.so.2=libiconv.so.2.5.0 s none CSWiconv'})
-    self.error_mgr_mock.GetPkgmapLineByBasename('libjpeg.so.62').AndReturn(
-      {u'/opt/csw/lib': u'/opt/csw/lib/libjpeg.so.62=libjpeg.so.62.0.0 s none CSWjpeg',
-       u'/opt/csw/lib/sparcv9': u'/opt/csw/lib/sparcv9/libjpeg.so.62=libjpeg.so.62.0.0 s none CSWjpeg',
-       u'/usr/lib': u'/usr/lib/libjpeg.so.62=libjpeg.so.62.0.0 s none SUNWjpg',
-       u'/usr/lib/sparcv9': u'/usr/lib/sparcv9/libjpeg.so.62=libjpeg.so.62.0.0 s none SUNWjpg'})
-    self.error_mgr_mock.GetPkgmapLineByBasename('libCrun.so.1').AndReturn(
-      {u'/usr/lib': u'/usr/lib/libCrun.so.1 f none 0755 root bin 70360 7735 1256313285 *SUNWlibC',
-       u'/usr/lib/sparcv9': u'/usr/lib/sparcv9/libCrun.so.1 f none 0755 root bin 86464 53547 1256313286 *SUNWlibC'})
-    self.error_mgr_mock.GetPkgmapLineByBasename('libCstd.so.1').AndReturn(
-      {u'/usr/lib': u'/usr/lib/libCstd.so.1 f none 0755 root bin 3324372 28085 1256313286 *SUNWlibC',
-       u'/usr/lib/sparcv9': u'/usr/lib/sparcv9/libCstd.so.1 f none 0755 root bin 3773400 36024 1256313286 *SUNWlibC'})
-    self.error_mgr_mock.GetPkgmapLineByBasename('libm.so.1').AndReturn(
-      {u'/lib': u'/lib/libm.so.1 f none 0755 root bin 23828 57225 1106444965 SUNWlibmsr',
-       u'/lib/sparcv9': u'/lib/sparcv9/libm.so.1 f none 0755 root bin 30656 9035 1106444966 SUNWlibmsr',
-       u'/usr/lib': u'/usr/lib/libm.so.1=../../lib/libm.so.1 s none *SUNWlibms',
-       u'/usr/lib/sparcv9': u'/usr/lib/sparcv9/libm.so.1=../../../lib/sparcv9/libm.so.1 s none *SUNWlibms'})
-    self.error_mgr_mock.GetPkgmapLineByBasename('libpthread.so.1').AndReturn(
-      {u'/lib': u'/lib/libpthread.so.1 f none 0755 root bin 21472 2539 1106444694 SUNWcslr',
-       u'/lib/sparcv9': u'/lib/sparcv9/libpthread.so.1 f none 0755 root bin 26960 55139 1106444706 SUNWcslr',
-       u'/usr/lib': u'/usr/lib/libpthread.so.1=../../lib/libpthread.so.1 s none SUNWcsl',
-       u'/usr/lib/sparcv9': u'/usr/lib/sparcv9/libpthread.so.1=../../../lib/sparcv9/libpthread.so.1 s none SUNWcsl'})
-    self.error_mgr_mock.GetPkgmapLineByBasename('libc.so.1').AndReturn(
-      {u'/lib': u'/lib/libc.so.1 f none 0755 root bin 1639840 9259 1253045976 SUNWcslr',
-       u'/lib/sparcv9': u'/lib/sparcv9/libc.so.1 f none 0755 root bin 1779120 22330 1253045979 SUNWcslr',
-       u'/usr/lib': u'/usr/lib/libc.so.1=../../lib/libc.so.1 s none SUNWcsl',
-       u'/usr/lib/libp': u'/usr/lib/libp/libc.so.1=../../../lib/libc.so.1 s none SUNWdpl',
-       u'/usr/lib/libp/sparcv9': u'/usr/lib/libp/sparcv9/libc.so.1=../../../../lib/sparcv9/libc.so.1 s none SUNWdpl',
-       u'/usr/lib/sparcv9': u'/usr/lib/sparcv9/libc.so.1=../../../lib/sparcv9/libc.so.1 s none SUNWcsl'})
-    self.error_mgr_mock.GetPkgmapLineByBasename('libjpeg.so.7').AndReturn(
-      {u'/opt/csw/lib': u'/opt/csw/lib/libjpeg.so.7=libjpeg.so.7.0.0 s none CSWjpeg',
-       u'/opt/csw/lib/sparcv9': u'/opt/csw/lib/sparcv9/libjpeg.so.7=libjpeg.so.7.0.0 s none CSWjpeg'})
+    self.error_mgr_mock.GetPathsAndPkgnamesByBasename('libCrun.so.1').AndReturn(
+      {u'/usr/lib': [u'SUNWlibC'],
+       u'/usr/lib/sparcv9': [u'SUNWlibC']})
+    self.error_mgr_mock.GetPathsAndPkgnamesByBasename('libCstd.so.1').AndReturn(
+      {u'/usr/lib': [u'SUNWlibC'],
+       u'/usr/lib/sparcv9': [u'SUNWlibC']})
+    self.error_mgr_mock.GetPathsAndPkgnamesByBasename('libc.so.1').AndReturn(
+      {u'/lib': [u'SUNWcslr'],
+       u'/lib/sparcv9': [u'SUNWcslr'],
+       u'/usr/lib': [u'SUNWcsl'],
+       u'/usr/lib/libp': [u'SUNWdpl'],
+       u'/usr/lib/libp/sparcv9': [u'SUNWdpl'],
+       u'/usr/lib/sparcv9': [u'SUNWcsl']})
+    self.error_mgr_mock.GetPathsAndPkgnamesByBasename('libiconv.so.2').AndReturn(
+      {u'/opt/csw/lib': [u'CSWiconv'],
+       u'/opt/csw/lib/sparcv9': [u'CSWiconv']})
+    self.error_mgr_mock.GetPathsAndPkgnamesByBasename('libjpeg.so.62').AndReturn(
+      {u'/opt/csw/lib': [u'CSWjpeg'],
+       u'/opt/csw/lib/sparcv9': [u'CSWjpeg'],
+       u'/usr/lib': [u'SUNWjpg'],
+       u'/usr/lib/sparcv9': [u'SUNWjpg']})
+    self.error_mgr_mock.GetPathsAndPkgnamesByBasename('libjpeg.so.7').AndReturn(
+      {u'/opt/csw/lib': [u'CSWjpeg'],
+       u'/opt/csw/lib/sparcv9': [u'CSWjpeg']})
+    self.error_mgr_mock.GetPathsAndPkgnamesByBasename('libm.so.1').AndReturn(
+      {u'/lib': [u'SUNWlibmsr'],
+       u'/lib/sparcv9': [u'SUNWlibmsr'],
+       u'/usr/lib': [u'SUNWlibms'],
+       u'/usr/lib/sparcv9': [u'SUNWlibms']})
+    self.error_mgr_mock.GetPathsAndPkgnamesByBasename('libpthread.so.1').AndReturn(
+      {u'/lib': [u'SUNWcslr'],
+       u'/lib/sparcv9': [u'SUNWcslr'],
+       u'/usr/lib': [u'SUNWcsl'],
+       u'/usr/lib/sparcv9': [u'SUNWcsl']})
     self.error_mgr_mock.ReportError('CSWdjvulibrert', 'missing-dependency', u'CSWiconv')
 
+
+class TestCheckPstamp(CheckpkgUnitTestHelper, unittest.TestCase):
+  FUNCTION_NAME = 'CheckPstamp'
+  def CheckpkgTest(self):
+    self.pkg_data["pkginfo"]["PSTAMP"] = "build8s20090904191054"
+    self.error_mgr_mock.ReportError(
+        'pkginfo-pstamp-in-wrong-format', 'build8s20090904191054',
+        "It should be 'username at hostname-timestamp', but it's 'build8s20090904191054'.")
+
+
 if __name__ == '__main__':
   unittest.main()

Added: csw/mgar/gar/v2/lib/python/testdata/checkpkg_pkgs_data_minimal.py
===================================================================
--- csw/mgar/gar/v2/lib/python/testdata/checkpkg_pkgs_data_minimal.py	                        (rev 0)
+++ csw/mgar/gar/v2/lib/python/testdata/checkpkg_pkgs_data_minimal.py	2010-03-23 22:32:23 UTC (rev 9343)
@@ -0,0 +1,42 @@
+# $Id: checkpkg_test_data_CSWdjvulibrert.py 9248 2010-03-19 10:07:39Z wahwah $
+pkg_data = {
+ 'basic_stats': {
+                 'catalogname': 'foo',
+                 'pkgname': 'CSWfoo',
+                 'stats_version': 2L},
+ 'binaries': ['opt/csw/bin/foo'],
+ 'binaries_dump_info': [{'base_name': 'foo',
+                         'needed sonames': [],
+                         'path': 'opt/csw/bin/foo',
+                         'runpath': [
+                                     '/opt/csw/1/lib',
+                                     '/opt/csw/lib',
+                                     '/lib',
+                                     '/usr/lib',
+                                     '/usr/lib/$ISALIST',
+                                     '/usr/lib',
+                                     '/lib/$ISALIST',
+                                     '/lib'],
+                         'soname': 'foo',
+                         'soname_guessed': True}],
+ 'depends': [],
+ 'isalist': ['sparcv9+vis2', 'sparcv9+vis', 'sparcv9',
+             'sparcv8plus+vis2', 'sparcv8plus+vis', 'sparcv8plus', 'sparcv8', 'sparcv8-fsmuld',
+             'sparcv7', 'sparc'],
+ 'overrides': [],
+ 'pkginfo': {'ARCH': 'sparc',
+             'CATEGORY': 'application',
+             'CLASSES': 'none',
+             'NAME': 'djvulibre_rt - DjVu standalone viewer, browser plug-in, command line tools - runtime package',
+             'PKG': 'CSWdjvulibrert',
+             'VERSION': '3.5.22,REV=2010.03.17',
+             },
+ 'pkgmap': [
+            {'class': 'none',
+             'group': None,
+             'line': None,
+             'mode': None,
+             'path': '/opt/csw/bin/foo',
+             'type': 's',
+             'user': None},
+ ]}

Deleted: csw/mgar/gar/v2/lib/python/testdata/checkpkg_test_data_CSWlibpq_84.py
===================================================================
--- csw/mgar/gar/v2/lib/python/testdata/checkpkg_test_data_CSWlibpq_84.py	2010-03-23 17:37:18 UTC (rev 9342)
+++ csw/mgar/gar/v2/lib/python/testdata/checkpkg_test_data_CSWlibpq_84.py	2010-03-23 22:32:23 UTC (rev 9343)
@@ -1,10 +0,0 @@
-# Testing data for CSWlibpq-84
-# $Id$
-DATA_PKGNAME = 'CSWlibpq-84'
-DATA_DECLARED_DEPENDENCIES = {'CSWlibxml2': 'CSWlibxml2 libxml2 - XML Parser Library ', 'CSWkrb5lib': 'CSWkrb5lib krb5_lib - MIT Kerberos 5 core libraries ', 'CSWlibxslt': 'CSWlibxslt libxslt - XSLT engine runtime package ', 'CSWcommon': 'CSWcommon common - common files and dirs for CSW packages ', 'CSWisaexec': 'CSWisaexec isaexec - sneaky wrapper around Sun isaexec ', 'CSWzlib': 'CSWzlib zlib - Zlib Data Compression Library ', 'CSWosslrt': 'CSWosslrt openssl_rt - Openssl runtime libraries '}
-DATA_BINARIES_BY_PKGNAME = {'CSWpostgresql-84-doc': [], 'CSWpostgresql': [], 'CSWpostgresql-84': ['vacuumdb', 'clusterdb', 'vacuumlo', 'initdb', 'reindexdb', 'createdb', 'pg_dump', 'pg_resetxlog', 'pg_config', 'pg_ctl', 'createlang', 'pg_standby', 'oid2name', 'droplang', 'dropdb', 'pgbench', 'createuser', 'pg_controldata', 'postgres', 'pg_dumpall', 'psql', 'dropuser', 'pg_restore', 'ecpg', 'oid2name', 'pg_ctl', 'droplang', 'pg_controldata', 'postgres', 'pg_dump', 'dropuser', 'dropdb', 'initdb', 'vacuumdb', 'pg_config', 'pg_resetxlog', 'createlang', 'createdb', 'vacuumlo', 'pg_standby', 'pgbench', 'reindexdb', 'pg_restore', 'clusterdb', 'ecpg', 'createuser', 'psql', 'pg_dumpall', 'pg_regress', 'pg_regress'], 'CSWpostgresql-84-dev': [], 'CSWlibpq-84': ['fuzzystrmatch.so', 'utf8_and_iso8859.so', 'seg.so', 'utf8_and_gbk.so', 'utf8_and_euc_jis_2004.so', 'cyrillic_and_mic.so', 'btree_gist.so', 'utf8_and_euc_jp.so', 'utf8_and_big5.so', 'cube.so', 'citext.so', 'insert_username.so', 
 'tsearch2.so', 'pg_stat_statements.so', 'utf8_and_ascii.so', 'lo.so', 'pgxml.so', 'utf8_and_euc_kr.so', 'dict_int.so', 'sslinfo.so', 'btree_gin.so', 'test_parser.so', 'euc_tw_and_big5.so', 'pgcrypto.so', 'latin2_and_win1250.so', 'auto_explain.so', 'tablefunc.so', 'dict_xsyn.so', 'latin_and_mic.so', 'dict_snowball.so', 'euc_jis_2004_and_shift_jis_2004.so', 'chkpass.so', 'utf8_and_shift_jis_2004.so', 'refint.so', 'pgstattuple.so', 'pg_trgm.so', 'utf8_and_uhc.so', 'pgrowlocks.so', 'utf8_and_cyrillic.so', 'pg_freespacemap.so', 'ltree.so', 'libpgtypes.so.3.1', 'libpq.so.5.2', '_int.so', 'utf8_and_win.so', 'pg_buffercache.so', 'euc_jp_and_sjis.so', 'utf8_and_johab.so', 'isn.so', 'timetravel.so', 'earthdistance.so', 'plpgsql.so', 'euc_kr_and_mic.so', 'dblink.so', 'hstore.so', 'pageinspect.so', 'libecpg.so.6.1', 'adminpack.so', 'utf8_and_euc_cn.so', 'utf8_and_sjis.so', 'euc_cn_and_mic.so', 'utf8_and_euc_tw.so', 'autoinc.so', 'libecpg_compat.so.3.1', 'test_parser.so', 'utf8_and_gbk.s
 o', 'utf8_and_euc_tw.so', 'ltree.so', 'timetravel.so', 'euc_cn_and_mic.so', 'utf8_and_euc_cn.so', 'pgrowlocks.so', 'latin_and_mic.so', 'dict_snowball.so', 'cube.so', 'utf8_and_euc_jis_2004.so', 'utf8_and_shift_jis_2004.so', 'libpgtypes.so.3.1', 'dict_xsyn.so', 'utf8_and_gb18030.so', 'tablefunc.so', 'citext.so', 'isn.so', 'fuzzystrmatch.so', 'pg_freespacemap.so', 'sslinfo.so', 'pg_buffercache.so', 'utf8_and_johab.so', 'euc_jp_and_sjis.so', 'libecpg_compat.so.3.1', 'auto_explain.so', 'btree_gin.so', 'euc_kr_and_mic.so', 'chkpass.so', 'utf8_and_big5.so', 'utf8_and_iso8859_1.so', 'tsearch2.so', 'pg_trgm.so', 'utf8_and_ascii.so', 'btree_gist.so', 'utf8_and_sjis.so', 'euc_jis_2004_and_shift_jis_2004.so', 'utf8_and_win.so', '_int.so', 'libecpg.so.6.1', 'utf8_and_uhc.so', 'pageinspect.so', 'utf8_and_euc_kr.so', 'utf8_and_iso8859.so', 'moddatetime.so', 'pg_stat_statements.so', 'utf8_and_cyrillic.so', 'euc_tw_and_big5.so', 'ascii_and_mic.so', 'libpq.so.5.2', 'cyrillic_and_mic.so', 'db
 link.so', 'hstore.so', 'plpgsql.so', 'pgxml.so', 'pgcrypto.so', 'lo.so', 'pgstattuple.so', 'autoinc.so', 'dict_int.so', 'earthdistance.so', 'adminpack.so', 'seg.so', 'utf8_and_euc_jp.so', 'latin2_and_win1250.so', 'refint.so', 'insert_username.so', 'ascii_and_mic.so', 'utf8_and_gb18030.so', 'utf8_and_iso8859_1.so', 'moddatetime.so']}

@@ Diff output truncated at 100000 characters. @@

This was sent by the SourceForge.net collaborative development platform, the world's largest Open Source development site.


More information about the devel mailing list