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

wahwah at users.sourceforge.net wahwah at users.sourceforge.net
Fri Mar 19 11:07:39 CET 2010


Revision: 9248
          http://gar.svn.sourceforge.net/gar/?rev=9248&view=rev
Author:   wahwah
Date:     2010-03-19 10:07:39 +0000 (Fri, 19 Mar 2010)

Log Message:
-----------
mGAR v2: checkpkg, integrated pkgchk test, integrated bad paths check, added a better test case for SetCheckSharedLibraryConsistency()

Modified Paths:
--------------
    csw/mgar/gar/v2/bin/checkpkg
    csw/mgar/gar/v2/bin/checkpkg_collect_stats.py
    csw/mgar/gar/v2/lib/python/checkpkg.py
    csw/mgar/gar/v2/lib/python/checkpkg_test.py
    csw/mgar/gar/v2/lib/python/gartest.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
    csw/mgar/gar/v2/tests/overrides_test.py
    csw/mgar/gar/v2/tests/run_tests.py

Added Paths:
-----------
    csw/mgar/gar/v2/lib/python/testdata/checkpkg_test_data_CSWdjvulibrert.py
    csw/mgar/gar/v2/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/bad_paths.yml
    csw/mgar/gar/v2/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/pkgchk.yml

Modified: csw/mgar/gar/v2/bin/checkpkg
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg	2010-03-19 09:58:56 UTC (rev 9247)
+++ csw/mgar/gar/v2/bin/checkpkg	2010-03-19 10:07:39 UTC (rev 9248)
@@ -7,6 +7,10 @@
 # diff to 1.46a
 #  - check multiple package files
 #  - checkpkg.d plugin support
+#  - getopts support for command line options
+#  - colors
+#  - modular architecture + unit tests
+#  - 
 #
 # This script examines a package that has been put together
 # for submittal to the CSW archive at opencsw.org
@@ -20,6 +24,10 @@
 # Be sure to occasionally do a "pkg-get update cswutils" so that
 # you know you are tracking the most current version.
 # 
+# TODOs before commit:
+#  - bad strings check
+#  - pkgchk run
+#
 
 PATH=$PATH:/usr/sbin
 readonly NAME_MAX_LENGTH=${NAME_MAX_LENGTH:-20}
@@ -31,11 +39,8 @@
 . "${libshdir}/libcheckpkg.sh"
 
 LOCAL_ARCH=`uname -p`
-if [[ -z "${CHECKPKG_TMPDIR}" ]]; then
-  readonly CHECKPKG_TMPDIR="/var/tmp"
-else
-  readonly CHECKPKG_TMPDIR
-fi
+CHECKPKG_TMPDIR=${CHECKPKG_TMPDIR:-/var/tmp}
+readonly CHECKPKG_TMPDIR
 
 # Colors only when running interactively
 if [[ -t 1 ]]; then
@@ -92,7 +97,7 @@
 	cleanup
 	cleanupset
 	print "To run checkpkg in the debug mode, add the '-d' flag, for example:"
-	print "${selfpath} -d ${selfargs}"
+	# print "${selfpath} -d ${selfargs}"
 	print "After you modify any overrides, you need to do gmake remerge repackage"
 	print "or gmake platforms-remerge platforms-repackage."
 	exit 1
@@ -104,40 +109,59 @@
 	fi
 }
 
-set_variables_for_individual_package_check() {
-	f=$1
-	file $f \
-	    | sed 's/^[^:]*://' \
-	    | grep gzip >/dev/null
-	if [ $? -eq 0 ] ; then
-		TMPARCHIVE=$CHECKPKG_TMPDIR/`basename $f`
-		if [[ -f $TMPARCHIVE ]] ; then
-			print ERROR: $TMPARCHIVE already exists
-			
-		fi
-		gzcat $f >$TMPARCHIVE || exit 1
-		f=$TMPARCHIVE
-	fi
-	pkgname=`nawk 'NR == 2 {print $1; exit;}' $f`
-	pkgnames="$pkgnames $pkgname"
-}
+# TODO: Options to add:
+#  - 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
+display_help=0
+SKIP_STATS_COLLECTION=0
+MD5_SUMS_CATALOG_FILE=""
 
-if [[ "$1" == "-d" ]] ; then
-	DEBUG=1
-	shift
-fi
+while getopts hsdNM: opt; do
+	case "${opt}" in
+	  s)
+      SAVE_TAGS=1
+      SAVED_TAGS_FILE=error-tags.txt
+      ;;
+    d)
+      DEBUG=1
+      ;;
+    e)
+      quit_on_warn=1
+      ;;
+    h)
+      display_help=1
+      ;;
+    N)
+      SKIP_STATS_COLLECTION=1
+      ;;
+    M)
+      MD5_SUMS_CATALOG_FILE="${OPTARG}"
+      ;;
+    *)
+      echo "Unknown option '${opt}'"
+      ;;
+  esac
+done
+shift $(( $OPTIND -1 ))
 
-if [[ "$1" == "-e" ]] ; then
-	quit_on_warn=1;
-	shift
-fi
-if [[ "$1" == "-h" ]] ; then
-	print 'Usage: checkpkg [-d] [-e] pkg1 [pkg2 ....]'
+readonly SAVE_TAGS SAVED_TAGS_FILE MD5_SUMS_CATALOG_FILE
+
+if [[ "${display_help}" -eq 1 ]] ; then
+	print 'Usage: checkpkg [options] pkg1 [pkg2 ....]'
+	print 'Options:'
+	print '   -s  save error tags on disk'
 	print '   -d  display debug messages'
 	print '   -e  exit on warnings (soon to be obsolete)'
-	shift
+	exit 0
 fi
 
+if [[ "${SAVE_TAGS}" -eq 1 ]]; then
+  if [[ -f "${SAVED_TAGS_FILE}" ]]; then
+  	rm "${SAVED_TAGS_FILE}"
+  fi
+fi
+
 # a unique filename for the list of package deps and libs we see in a 'set'
 SETINF=$CHECKPKG_TMPDIR/checkpkg.$$.`date +%Y%m%d%H%M%S`
 SETLIBS=$SETINF.libs
@@ -148,87 +172,19 @@
 EXTRACTDIR=$CHECKPKG_TMPDIR/dissect.$$
 
 if [ -d $EXTRACTDIR ] ; then
-	print ERROR: $EXTRACTDIR already exists
-	exit 1
+	errmsg ERROR: $EXTRACTDIR already exists
 fi
 
 for f in "$@"
 do
 
-if [[ ! -f $f ]] ; then
-	print ERROR: $f does not exist
-	exit 1
-fi
-
-
-debugmsg "Examining $f"
-debugmsg "Looking for bad strings..."
-
-# XPG4 grep has some kind of magical "ignore ELF header" power.
-#  but... not on sol8, just sol10?
-# and so does /bin/grep. but NOT /bin/egrep???
-#
-# Need to rewrite this whole thing to also
-# check for badly set RUNPATHs. sigh.
-#
-# Using rot13 so that checkpkg can check itself without reporting
-# an error.
-badpaths="$(echo /rkcbeg/zrqhfn /bcg/ohvyq | gtr a-mn-z n-za-m)"
-for badpath in $badpaths ; do
-  GREP=/bin/grep gzgrep "$badpath" $f
-  if [[ $? -eq 0 ]] ; then
-    print ""
-    print "ERROR: build-machine paths found in file $f"
-    print "($badpath)"
-    exit 1
+  if [[ ! -f $f ]] ; then
+    errmsg ERROR: $f does not exist
   fi
-done
 
-set_variables_for_individual_package_check "$f"
 
 [ -d ${EXTRACTDIR} ] || mkdir ${EXTRACTDIR}
 
-# # FIXME: This doesn't support multiple packages
-# TMPFILE=$EXTRACTDIR/pkginfo
-# 
-# 
-# printf "$pkgname "
-# dd if=$f skip=1 | (cd $EXTRACTDIR; cpio -ivd $pkgname/pkginfo >/dev/null 2>&1)
-# if [[ $? -ne 0 ]] ; then
-# 	print "ERROR: could not extract $f"
-# 	print "with (cd $EXTRACTDIR; cpio -ivd $pkgname/pkginfo)"
-# 	ls -l $EXTRACTDIR
-# 	rm -rf $EXTRACTDIR $TMPARCHIVE
-# 	exit 1
-# fi
-# 
-# mv $EXTRACTDIR/$pkgname/pkginfo $EXTRACTDIR ; rmdir $EXTRACTDIR/$pkgname
-# 
-# software=`sed -n 's/^NAME=\([^ -]*\) -.*$/\1/p' $TMPFILE`
-# version=`sed -n 's/^VERSION=//p' $TMPFILE`
-# desc=`sed -n 's/^DESC=//p' $TMPFILE`
-# email=`sed -n 's/^EMAIL=//p' $TMPFILE`
-# maintname=`sed -n 's/^VENDOR=.*for CSW by //p' $TMPFILE`
-# hotline=`sed -n 's/^HOTLINE=//p' $TMPFILE`
-# basedir=`sed -n 's/^BASEDIR=//p' $TMPFILE`
-# pkgarch=`sed -n 's/^ARCH=//p' $TMPFILE|head -1`
-# 
-# rm $TMPFILE
-
-# strip out '' chars, because it interferes with mysql
-# desc=`print $desc | sed "s/'//g"`
-
-#############################################################
-# We now have the package expanded, in "directory" form, in
-# $EXTRACTDIR/$pkgname
-# Now do some extended error checking on it.
-# This is similar to Debians "Lintian" phase for packages.
-
-# TODO: Run this during the stats collection stage.
-# /usr/sbin/pkgchk -d $EXTRACTDIR $pkgname || errmsg "Package failed integrity check"
-# print "/usr/sbin/pkgchk passed."
-
-
 ########################################
 # Check for some common errors
 #########################################
@@ -254,14 +210,14 @@
 tmparchives="$tmparchives $TMPARCHIVE"
 done
 
-# Plugin section.
+# Plugin section.  This is here for support for other programming languages
+# than Python.  As of 2010-03-16 there are no checks in there.  If this keeps
+# empty, if no checks in other languages get written, it could be removed.
 #
 # Plugins should live in checkpkg.d subdirectory in the same directory in which
 # checkpkg is.  Each plugin file name should be an executable and begin with
 # "checkpkg-".
 
-set_variables_for_individual_package_check "$f"
-
 test_suite_ok=1
 checkpkg_module_dir=${command_basedir}/../lib/checkpkg.d
 checkpkg_module_tag="checkpkg-"
@@ -283,13 +239,22 @@
 
 # /var/sadm/install/contents cache update
 ${command_basedir}/update_contents_cache.py
-# Collects package stats to be later analyzed
-${command_basedir}/checkpkg_collect_stats.py ${extra_options} "$@"
+if [[ "${SKIP_STATS_COLLECTION}" -eq 0 ]]; then
+  # Collects package stats to be later analyzed
+  ${command_basedir}/checkpkg_collect_stats.py ${extra_options} "$@"
+  if [[ "$?" -ne 0 ]]; then
+    errmsg "Stats collection phase has failed."
+  fi
+fi
 
 debugmsg "checkpkg_module_dir: '$checkpkg_module_dir'"
 log_files=""
 module_name_format="%-40s"
+# TODO: A performance problem. The following line means that the md5sums are
+# calculated once more.
+debugmsg "Calculating md5 sums of all the package files."
 md5sums=`gmd5sum "$@" | awk '{print $1}'`
+debugmsg "All md5 sums: ${md5sums}"
 if [[ -d "${checkpkg_module_dir}" ]]; then
 	for plugin in "${checkpkg_module_dir}/${checkpkg_module_tag}"*; do
 		if [[ -x "${plugin}" ]]; then
@@ -362,6 +327,10 @@
 			echo "# ${tagfile}:"
 			cat "${tagfile}"
 		fi
+    if [[ "${SAVE_TAGS}" -eq 1 ]]; then
+    	echo "Saving ${tagfile} to `pwd`/${SAVED_TAGS_FILE}"
+      cat "${tagfile}" >> "${SAVED_TAGS_FILE}"
+    fi
 	done
 fi
 

Modified: csw/mgar/gar/v2/bin/checkpkg_collect_stats.py
===================================================================
--- csw/mgar/gar/v2/bin/checkpkg_collect_stats.py	2010-03-19 09:58:56 UTC (rev 9247)
+++ csw/mgar/gar/v2/bin/checkpkg_collect_stats.py	2010-03-19 10:07:39 UTC (rev 9248)
@@ -5,6 +5,7 @@
 # Collects statistics about a package and saves to a directory, for later use
 # by checkpkg modules.
 
+import itertools
 import logging
 import optparse
 import os
@@ -35,8 +36,17 @@
   logging.debug("calling: %s, please be patient", args)
   packages = [opencsw.CswSrv4File(x, options.debug) for x in args]
   stats_list = [checkpkg.PackageStats(pkg) for pkg in packages]
-  for pkg_stats in stats_list:
-    pkg_stats.CollectStats()
+  del(packages)
+  stats_list.reverse()
+  total_packages = len(stats_list)
+  counter = itertools.count(1)
+  while stats_list:
+    # This way objects will get garbage collected as soon as they are removed
+    # from the list by pop().  The destructor (__del__()) of the srv4 class
+    # removes the temporary directory from the disk.  This allows to process
+    # the whole catalog.
+    stats_list.pop().CollectStats()
+    logging.debug("Collected stats %s of %s.", counter.next(), total_packages)
 
 if __name__ == '__main__':
   main()

Modified: csw/mgar/gar/v2/lib/python/checkpkg.py
===================================================================
--- csw/mgar/gar/v2/lib/python/checkpkg.py	2010-03-19 09:58:56 UTC (rev 9247)
+++ csw/mgar/gar/v2/lib/python/checkpkg.py	2010-03-19 10:07:39 UTC (rev 9248)
@@ -21,6 +21,8 @@
 import opencsw
 import package_checks
 
+DB_SCHEMA_VERSION = 2L
+PACKAGE_STATS_VERSION = 3L
 SYSTEM_PKGMAP = "/var/sadm/install/contents"
 WS_RE = re.compile(r"\s+")
 NEEDED_SONAMES = "needed sonames"
@@ -33,6 +35,11 @@
 DUMP_BIN = "/usr/ccs/bin/dump"
 PSTAMP_RE = r"(?P<username>\w+)@(?P<hostname>[\w\.-]+)-(?P<timestamp>\d+)"
 DESCRIPTION_RE = r"^([\S]+) - (.*)$"
+BAD_CONTENT_REGEXES = (
+    # No need to encode / obfuscate these, as overrides can be used.
+    r'/export/medusa',
+    r'/opt/build',
+)
 
 SYSTEM_SYMLINKS = (
     ("/opt/csw/bdb4",     ["/opt/csw/bdb42"]),
@@ -40,8 +47,6 @@
     ("/opt/csw/lib/i386", ["/opt/csw/lib"]),
 )
 INSTALL_CONTENTS_AVG_LINE_LENGTH = 102.09710677919261
-DB_SCHEMA_VERSION = 2L
-PACKAGE_STATS_VERSION = 2L
 
 # 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.
@@ -774,6 +779,20 @@
         errors["package-set"].append(error)
     return a_dict
 
+  def GetOptimizedAllStats(self, stats_obj_list):
+    pkgs_data = []
+    for stats_obj in stats_obj_list:
+      # pkg_data = {}
+      # This bit is tightly tied to the data structures returned by
+      # PackageStats.
+      #
+      # Python strings are already implementing the flyweight pattern. What's
+      # left is lists and dictionaries.
+      raw_pkg_data = stats_obj.GetAllStats()
+      pkg_data = raw_pkg_data
+      pkgs_data.append(pkg_data)
+    return pkgs_data
+
   def Run(self):
     """Runs all the checks
 
@@ -786,6 +805,9 @@
     return (exit_code, screen_report, tags_report)
 
 
+class Flyweight(object):
+  pass
+
 class CheckInterfaceBase(object):
   """Base class for check proxies.
 
@@ -863,27 +885,42 @@
           logging.debug("Registering set check %s", repr(member_name))
           self._RegisterSetCheck(member)
 
-  def GetAllTags(self, packages_data):
+  def GetAllTags(self, stats_obj_list):
     errors = {}
-    # TODO: Configure the logger with the logging level.
+    # TODO: Actually configure the logger with the logging level.
     logging_level = logging.INFO
     if self.debug:
       logging_level = logging.DEBUG
     pkgmap = SystemPkgmap()
+
+    # TODO: In order to process all the catalog, and load them all into the
+    # memory, we need to store them more efficiently.  Currently, the process
+    # grows up to 9GB of RAM usage, and it doesn't end there.  Some ideas how to
+    # use less RAM:
+    # - some values (tuples, lists) repeat, and there's no need to store
+    #   all the copies. Instead, store references.  (the Flyweight design
+    #   pattern)
+    # - enclose data loading in a separate function, which will merge data
+    #   from all the packages.
+    # 
+    # In other words, the following line needs to be smart:
+    # pkgs_data = [x.GetAllStats() for x in stats_obj_list]
+    pkgs_data = self.GetOptimizedAllStats(stats_obj_list)
+
     # Individual checks
-    for pkg_data in packages_data:
+    for package_stats_obj in stats_obj_list:
+      pkg_data = package_stats_obj.GetAllStats()
+      pkgname = pkg_data["basic_stats"]["pkgname"]
+      check_interface = IndividualCheckInterface(pkgname, pkgmap)
       for function in self.individual_checks:
-        all_stats = pkg_data.GetAllStats()
-        pkgname = all_stats["basic_stats"]["pkgname"]
-        check_interface = IndividualCheckInterface(pkgname, pkgmap)
         logger = logging.getLogger("%s-%s" % (pkgname, function.__name__))
         logger.debug("Calling %s", function.__name__)
-        function(all_stats, check_interface, logger=logger)
+        function(pkg_data, check_interface, logger=logger)
         if check_interface.errors:
           errors[pkgname] = check_interface.errors
     # Set checks
     for function in self.set_checks:
-      pkgs_data = [x.GetAllStats() for x in packages_data]
+      pkgs_data = [x.GetAllStats() for x in stats_obj_list]
       logger = logging.getLogger("SetCheck-%s" % (function.__name__,))
       check_interface = SetCheckInterface(pkgmap)
       logger.debug("Calling %s", function.__name__)
@@ -1002,6 +1039,7 @@
   # This list needs to be synchronized with the CollectStats() method.
   STAT_FILES = [
       "all_filenames",
+      "bad_paths",
       "basic_stats",
       "binaries",
       "binaries_dump_info",
@@ -1010,6 +1048,7 @@
       "isalist",
       # "ldd_dash_r",
       "overrides",
+      "pkgchk",
       "pkginfo",
       "pkgmap",
   ]
@@ -1026,6 +1065,15 @@
       parts = [home, ".checkpkg", "stats"]
       self.stats_basedir = os.path.join(*parts)
 
+  def GetPkgchkData(self):
+    ret, stdout, stderr = self.srv4_pkg.GetPkgchkOutput()
+    data = {
+        'return_code': ret,
+        'stdout_lines': stdout.splitlines(),
+        'stderr_lines': stderr.splitlines(),
+    }
+    return data
+
   def GetMd5sum(self):
     if not self.md5sum:
       self.md5sum = self.srv4_pkg.GetMd5sum()
@@ -1059,13 +1107,16 @@
     return self.dir_format_pkg
 
   def MakeStatsDir(self):
+    stats_path = self.GetStatsPath()
+    self._MakeDirP(stats_path)
+
+  def _MakeDirP(self, dir_path):
     """mkdir -p equivalent.
 
     http://stackoverflow.com/questions/600268/mkdir-p-functionality-in-python
     """
-    stats_path = self.GetStatsPath()
     try:
-      os.makedirs(stats_path)
+      os.makedirs(dir_path)
     except OSError, e:
       if e.errno == errno.EEXIST:
         pass
@@ -1201,12 +1252,26 @@
     return sym
 
   def CollectStats(self, force=False):
+    """Lazy stats collection."""
     if not self.StatsDirExists() or force:
       self._CollectStats()
+      return
+    basic_stats_file = in_file_name_pickle = os.path.join(
+        self.GetStatsPath(), "basic_stats.pickle")
+    f = open(basic_stats_file, "r")
+    obj = cPickle.load(f)
+    f.close()
+    saved_version = obj["stats_version"]
+    if saved_version < PACKAGE_STATS_VERSION:
+      self._CollectStats()
 
   def _CollectStats(self):
     """The list of variables needs to be synchronized with the one
     at the top of this class.
+
+    TODO:
+    - Run pkgchk against the package file.
+    - Grep all the files for bad paths.
     """
     stats_path = self.GetStatsPath()
     self.MakeStatsDir()
@@ -1219,13 +1284,15 @@
     self.DumpObject(dir_pkg.GetDependencies(), "depends")
     self.DumpObject(GetIsalist(), "isalist")
     self.DumpObject(self.GetOverrides(), "overrides")
+    self.DumpObject(self.GetPkgchkData(), "pkgchk")
     self.DumpObject(dir_pkg.GetParsedPkginfo(), "pkginfo")
     self.DumpObject(dir_pkg.GetPkgmap().entries, "pkgmap")
     # This check is currently disabled, let's save time by not collecting
     # these data.
     # self.DumpObject(self.GetLddMinusRlines(), "ldd_dash_r")
     # self.DumpObject(self.GetDefinedSymbols(), "defined_symbols")
-    logging.debug("Statistics collected.")
+    self.DumpObject(dir_pkg.GetFilesContaining(BAD_CONTENT_REGEXES), "bad_paths")
+    logging.debug("Statistics of %s have been collected.", repr(dir_pkg.pkgname))
 
   def GetAllStats(self):
     if self.StatsExist():
@@ -1242,10 +1309,7 @@
     return overrides
 
   def DumpObject(self, obj, name):
-    """Saves an object.
-
-    TODO(maciej): Implement pickling with cPickle.
-    """
+    """Saves an object."""
     stats_path = self.GetStatsPath()
     # yaml
     out_file_name = os.path.join(stats_path, "%s.yml" % name)
@@ -1266,18 +1330,13 @@
     in_file_name = os.path.join(stats_path, "%s.yml" % name)
     in_file_name_pickle = os.path.join(stats_path, "%s.pickle" % name)
     if os.path.exists(in_file_name_pickle):
-      # logging.debug("ReadObject(): reading %s", repr(in_file_name_pickle))
       f = open(in_file_name_pickle, "r")
       obj = cPickle.load(f)
       f.close()
-      # logging.debug("ReadObject(): finished reading %s",
-      #               repr(in_file_name_pickle))
     else:
-      # logging.debug("ReadObject(): reading %s", repr(in_file_name))
       f = open(in_file_name, "r")
       obj = yaml.safe_load(f)
       f.close()
-      # logging.debug("ReadObject(): finished reading %s", repr(in_file_name))
     return obj
 
   def ReadSavedStats(self):

Modified: csw/mgar/gar/v2/lib/python/checkpkg_test.py
===================================================================
--- csw/mgar/gar/v2/lib/python/checkpkg_test.py	2010-03-19 09:58:56 UTC (rev 9247)
+++ csw/mgar/gar/v2/lib/python/checkpkg_test.py	2010-03-19 10:07:39 UTC (rev 9248)
@@ -603,7 +603,7 @@
 class CheckpkgTagsUnitTest(unittest.TestCase):
   
   def test_1(self):
-    m = checkpkg.CheckpkgManager("testname", "/tmp", ["CSWfoo"])
+    m = checkpkg.CheckpkgManager2("testname", "/tmp", ["CSWfoo"])
     tags = {
         "CSWfoo": [
           checkpkg.CheckpkgTag("CSWfoo", "foo-tag", "foo-info"),
@@ -614,7 +614,7 @@
     self.assertEqual(expected, tags_report)
 
   def test_2(self):
-    m = checkpkg.CheckpkgManager("testname", "/tmp", ["CSWfoo"])
+    m = checkpkg.CheckpkgManager2("testname", "/tmp", ["CSWfoo"])
     tags = {
         "CSWfoo": [
           checkpkg.CheckpkgTag("CSWfoo", "foo-tag", "foo-info"),

Modified: csw/mgar/gar/v2/lib/python/gartest.py
===================================================================
--- csw/mgar/gar/v2/lib/python/gartest.py	2010-03-19 09:58:56 UTC (rev 9247)
+++ csw/mgar/gar/v2/lib/python/gartest.py	2010-03-19 10:07:39 UTC (rev 9248)
@@ -3,13 +3,14 @@
 # Style guide:
 # http://code.google.com/p/soc/wiki/PythonStyleGuide
 
-import Cheetah.Template
-import shutil
-import tempfile
+import logging
 import os
 import os.path
+import shutil
 import subprocess
+import tempfile
 import opencsw
+import Cheetah.Template
 
 """A module used to do end-to-end testing of GAR."""
 
@@ -177,6 +178,8 @@
     if self.cleanup:
       if os.path.isdir(self.build_dir):
         shutil.rmtree(self.build_dir)
+    else:
+      logging.warn("Not removing files from %s", repr(self.build_dir))
 
 
 class StaticGarBuild(GarBuild):

Modified: csw/mgar/gar/v2/lib/python/opencsw.py
===================================================================
--- csw/mgar/gar/v2/lib/python/opencsw.py	2010-03-19 09:58:56 UTC (rev 9247)
+++ csw/mgar/gar/v2/lib/python/opencsw.py	2010-03-19 10:07:39 UTC (rev 9248)
@@ -405,6 +405,7 @@
     self.transformed = False
     self.dir_format_pkg = None
     self.debug = debug
+    self.pkgname = None
 
   def __repr__(self):
     return u"CswSrv4File(%s)" % repr(self.pkg_path)
@@ -457,14 +458,15 @@
     """It's necessary to figure out the pkgname from the .pkg file.
     # nawk 'NR == 2 {print $1; exit;} $f
     """
-    gunzipped_path = self.GetGunzippedPath()
-    args = ["nawk", "NR == 2 {print $1; exit;}", gunzipped_path]
-    nawk_proc = subprocess.Popen(args, stdout=subprocess.PIPE)
-    stdout, stderr = nawk_proc.communicate()
-    ret_code = nawk_proc.wait()
-    pkgname = stdout.strip()
-    logging.debug("GetPkgname(): %s", repr(pkgname))
-    return pkgname
+    if not self.pkgname:
+      gunzipped_path = self.GetGunzippedPath()
+      args = ["nawk", "NR == 2 {print $1; exit;}", gunzipped_path]
+      nawk_proc = subprocess.Popen(args, stdout=subprocess.PIPE)
+      stdout, stderr = nawk_proc.communicate()
+      ret_code = nawk_proc.wait()
+      self.pkgname = stdout.strip()
+      logging.debug("GetPkgname(): %s", repr(self.pkgname))
+    return self.pkgname
 
   def TransformToDir(self):
     """Transforms the file to the directory format.
@@ -506,12 +508,21 @@
     return dir_format_pkg.GetPkgmap(analyze_permissions, strip)
 
   def GetMd5sum(self):
+    logging.debug("GetMd5sum() (%s)", repr(self.pkg_path))
     fp = open(self.pkg_path)
     hash = hashlib.md5()
     hash.update(fp.read())
     fp.close()
     return hash.hexdigest()
 
+  def GetPkgchkOutput(self):
+    """Returns: (exit code, stdout, stderr)."""
+    args = ["pkgchk", "-d", self.GetPkgname()]
+    pkgchk_proc = subprocess.Popen(args, stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+    stdout, stderr = pkgchk_proc.communicate()
+    ret = pkgchk_proc.wait()
+    return ret, stdout, stderr
+
   def __del__(self):
     if self.workdir:
       logging.debug("Removing %s", repr(self.workdir))
@@ -635,6 +646,7 @@
     self.pkgpath = self.directory
     self.pkginfo_dict = None
     self.binaries = None
+    self.file_paths = None
 
   def GetCatalogname(self):
     """Returns the catalog name of the package.
@@ -741,10 +753,13 @@
     self.SetPkginfoEntry("NAME", pkginfo_name)
 
   def GetDependencies(self):
+    depends = []
+    depend_file_path = os.path.join(self.directory, "install", "depend")
+    if not os.path.exists(depend_file_path):
+      return depends
     fd = open(os.path.join(self.directory, "install", "depend"), "r")
     # It needs to be a list because there might be duplicates and it's
     # necessary to carry that information.
-    depends = []
     for line in fd:
       fields = re.split(WS_RE, line)
       if fields[0] == "P":
@@ -798,12 +813,20 @@
     return self.binaries
 
   def GetAllFilenames(self):
-    self.CheckPkgpathExists()
-    file_basenames = []
-    for root, dirs, files in os.walk(self.pkgpath):
-      file_basenames.extend(files)
-    return file_basenames
+    file_paths = self.GetAllFilePaths()
+    return [os.path.basename(f) for f in file_paths]
 
+  def GetAllFilePaths(self):
+    """Similar to GetAllFilenames, but returns full paths."""
+    if not self.file_paths:
+      self.CheckPkgpathExists()
+      remove_prefix = "%s/" % self.pkgpath
+      self.file_paths = []
+      for root, dirs, files in os.walk(os.path.join(self.pkgpath, "root")):
+        full_paths = [os.path.join(root, f) for f in files]
+        self.file_paths.extend([f.replace(remove_prefix, "") for f in full_paths])
+    return self.file_paths
+
   def _GetOverridesStream(self):
     catalogname = self.GetCatalogname()
     file_path = os.path.join(self.directory,
@@ -837,13 +860,29 @@
   def GetFileContent(self, pkg_file_path):
     if pkg_file_path.startswith("/"):
       pkg_file_path = pkg_file_path[1:]
+    # TODO: Write a unit test for the right path
     file_path = os.path.join(self.directory, "root", pkg_file_path)
-    fd = open(file_path, "r")
-    content = fd.read()
-    fd.close()
-    return content
+    try:
+      fd = open(file_path, "r")
+      content = fd.read()
+      fd.close()
+      return content
+    except IOError, e:
+      raise PackageError(e)
 
+  def GetFilesContaining(self, regex_list):
+    full_paths = self.GetAllFilePaths()
+    files_by_pattern = {}
+    for full_path in full_paths:
+      content = open(os.path.join(self.pkgpath, full_path), "rb").read()
+      for regex in regex_list:
+        if re.search(regex, content):
+          if regex not in files_by_pattern:
+            files_by_pattern[regex] = []
+          files_by_pattern[regex].append(full_path)
+    return files_by_pattern
 
+
 class Pkgmap(object):
   """Represents the pkgmap of the package.
 

Modified: csw/mgar/gar/v2/lib/python/package_checks.py
===================================================================
--- csw/mgar/gar/v2/lib/python/package_checks.py	2010-03-19 09:58:56 UTC (rev 9247)
+++ csw/mgar/gar/v2/lib/python/package_checks.py	2010-03-19 10:07:39 UTC (rev 9248)
@@ -15,6 +15,7 @@
 import os
 import checkpkg
 import opencsw
+import textwrap
 from Cheetah import Template
 
 PATHS_ALLOWED_ONLY_IN = {
@@ -47,6 +48,7 @@
     "CSWcommon": ("/opt", )
 }
 DO_NOT_LINK_AGAINST_THESE_SONAMES = set(["libX11.so.4"])
+DISCOURAGED_FILE_PATTERNS = (r"\.py[co]$",)
 
 
 def CatalognameLowercase(pkg_data, error_mgr, logger):
@@ -68,17 +70,20 @@
 
 def CheckDirectoryPermissions(pkg_data, error_mgr, logger):
   for entry in pkg_data["pkgmap"]:
-    if entry["type"] == "d":
-      if entry["mode"][1] == "6":
-        error_mgr.ReportError("executable-bit-missing-on-a-directory",
-                              entry["path"])
+    if (entry["type"] == "d"
+          and
+        entry["mode"] != "?"
+          and
+        entry["mode"][1] == "6"):
+      error_mgr.ReportError("executable-bit-missing-on-a-directory",
+                            entry["path"])
 
 
 def CheckNonCswPathsDirectoryPerms(pkg_data, error_mgr, logger):
   for entry in pkg_data["pkgmap"]:
     if entry["user"] == "?" or entry["group"] == "?" or entry["mode"] == "?":
       if entry["path"].startswith("/opt/csw"):
-        error_mgr.ReportError("question-mark-perms-in-opt-csw", entry["path"])
+        error_mgr.ReportError("pkgmap-question-mark-perms-in-opt-csw", entry["path"])
 
 
 def CheckPerlLocal(pkg_data, error_mgr, logger):
@@ -188,7 +193,7 @@
   # same bit of code would do both checking and reporting.
   #
   # TODO: Rewrite this using cheetah templates
-  if False and needed_sonames:
+  if True and needed_sonames:
     print "Analysis of sonames needed by the package set:"
     binaries_with_missing_sonames = set([])
     for soname in needed_sonames:
@@ -196,7 +201,7 @@
       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:" 
+        print ("%s is provided by %s and required by:"
                % (soname,
                   pkgs_by_filename[soname]))
         filename_lines = " ".join(sorted(binaries_by_soname[soname]))
@@ -210,7 +215,7 @@
         if soname in checkpkg.ALLOWED_ORPHAN_SONAMES:
           print "However, it's a whitelisted soname."
         else:
-          pass
+          print "No package seems to be providing %s" % (soname,)
           # The error checking needs to be unified: done in one place only.
           # errors.append(
           #     checkpkg.CheckpkgTag(
@@ -242,14 +247,16 @@
         "surplus_deps": surplus_deps,
         "orphan_sonames": orphan_sonames,
     }
+    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():
       print report
-    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)
 
 
 def SetCheckDependencies(pkgs_data, error_mgr, logger):
@@ -285,6 +292,8 @@
   """Checks the consistency between classes in the prototype and pkginfo."""
   pkginfo = pkg_data["pkginfo"]
   pkgmap = pkg_data["pkgmap"]
+  if "CLASSES" not in pkginfo:
+    return
   pkginfo_classes = set(re.split(opencsw.WS_RE, pkginfo["CLASSES"]))
   pkgmap_classes = set()
   for entry in pkgmap:
@@ -410,6 +419,10 @@
   catalogname = pkg_data["basic_stats"]["catalogname"]
   pkgname = pkg_data["basic_stats"]["pkgname"]
   pkginfo = pkg_data["pkginfo"]
+  # PKG, NAME, ARCH, VERSION and CATEGORY
+  for parameter in ("PKG", "NAME", "ARCH", "VERSION", "CATEGORY"):
+    if parameter not in pkginfo:
+      error_mgr.ReportError("pkginfo-missing-parameter", parameter)
   if not catalogname:
     error_mgr.ReportError("pkginfo-empty-catalogname")
   if not pkgname:
@@ -507,3 +520,24 @@
           soname in DO_NOT_LINK_AGAINST_THESE_SONAMES):
         error_mgr.ReportError("linked-against-discouraged-library",
                               "%s %s" % (binary_info["base_name"], soname))
+
+def CheckDiscouragedFileNamePatterns(pkg_data, error_mgr, logger):
+  patterns = [re.compile(x) for x in DISCOURAGED_FILE_PATTERNS]
+  for entry in pkg_data["pkgmap"]:
+    if entry["path"]:
+      for pattern in patterns:
+        if re.search(pattern, entry["path"]):
+          error_mgr.ReportError("discouraged-path-in-pkgmap",
+                                entry["path"])
+
+def CheckBadPaths(pkg_data, error_mgr, logger):
+  for regex in pkg_data["bad_paths"]:
+    for file_name in pkg_data["bad_paths"][regex]:
+      error_mgr.ReportError("file-with-bad-content", "%s %s" % (regex, file_name))
+
+def CheckPkgchk(pkg_data, error_mgr, logger):
+  if pkg_data["pkgchk"]["return_code"] != 0:
+    error_mgr.ReportError("pkgchk-failed-with-code", pkg_data["pkgchk"]["return_code"])
+    for line in pkg_data["pkgchk"]["stderr_lines"]:
+      logger.warn(line)
+

Modified: csw/mgar/gar/v2/lib/python/package_checks_test.py
===================================================================
--- csw/mgar/gar/v2/lib/python/package_checks_test.py	2010-03-19 09:58:56 UTC (rev 9247)
+++ csw/mgar/gar/v2/lib/python/package_checks_test.py	2010-03-19 10:07:39 UTC (rev 9248)
@@ -11,6 +11,8 @@
 import mox
 import logging
 
+import testdata.checkpkg_test_data_CSWdjvulibrert as td_1
+
 BASE_DIR = os.path.dirname(__file__)
 TESTDATA_DIR = os.path.join(BASE_DIR, "testdata")
 CHECKPKG_STATS_DIR = os.path.join(TESTDATA_DIR, "stats")
@@ -31,12 +33,18 @@
     self.mocker = mox.Mox()
 
   def testDefault(self):
-    self.logger_mock = self.mocker.CreateMock(logging.Logger)
+    class LoggerStub(object):
+      def debug(self, debug_s, *kwords):
+        pass
+    # self.logger_mock = self.mocker.CreateMock(logging.Logger)
+    self.logger_mock = LoggerStub()
     self.error_mgr_mock = self.mocker.CreateMock(
         checkpkg.IndividualCheckInterface)
     self.CheckpkgTest()
     self.mocker.ReplayAll()
-    getattr(pc, self.FUNCTION_NAME)(self.pkg_data, self.error_mgr_mock, self.logger_mock)
+    getattr(pc, self.FUNCTION_NAME)(self.pkg_data,
+                                    self.error_mgr_mock,
+                                    self.logger_mock)
     self.mocker.VerifyAll()
 
 
@@ -228,6 +236,45 @@
     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'
+  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.ReportError('CSWdjvulibrert', 'missing-dependency', u'CSWiconv')
 
 if __name__ == '__main__':
   unittest.main()

Added: csw/mgar/gar/v2/lib/python/testdata/checkpkg_test_data_CSWdjvulibrert.py
===================================================================
--- csw/mgar/gar/v2/lib/python/testdata/checkpkg_test_data_CSWdjvulibrert.py	                        (rev 0)
+++ csw/mgar/gar/v2/lib/python/testdata/checkpkg_test_data_CSWdjvulibrert.py	2010-03-19 10:07:39 UTC (rev 9248)
@@ -0,0 +1,219 @@
+# $Id$
+pkg_data = {
+ 'all_filenames': ['license',
+                   'libdjvulibre.so.15',
+                   'libdjvulibre.so.21.1.0',
+                   'libdjvulibre.so.21.1.0'],
+ 'basic_stats': {'catalogname': 'djvulibre_rt',
+                 'parsed_basename': {'arch': 'sparc',
+                                     'catalogname': 'djvulibre_rt',
+                                     'full_version_string': '3.5.22,REV=2010.03.17',
+                                     'osrel': 'SunOS5.8',
+                                     'revision_info': {'REV': '2010.03.17'},
+                                     'vendortag': 'CSW',
+                                     'version': '3.5.22',
+                                     'version_info': {'major version': '3',
+                                                      'minor version': '5',
+                                                      'patchlevel': '22'}},
+                 'pkg_basename': 'djvulibre_rt-3.5.22,REV=2010.03.17-SunOS5.8-sparc-CSW.pkg.gz',
+                 'pkg_path': '/tmp/pkg_60J_Gm/djvulibre_rt-3.5.22,REV=2010.03.17-SunOS5.8-sparc-CSW.pkg.gz',
+                 'pkgname': 'CSWdjvulibrert',
+                 'stats_version': 2L},
+ 'binaries': ['opt/csw/lib/libdjvulibre.so.15',
+              'opt/csw/lib/sparcv9/libdjvulibre.so.21.1.0',
+              'opt/csw/lib/libdjvulibre.so.21.1.0'],
+ 'binaries_dump_info': [{'base_name': 'libdjvulibre.so.15',
+                         'needed sonames': ['libjpeg.so.62',
+                                            'libpthread.so.1',
+                                            'libiconv.so.2',
+                                            'libm.so.1',
+                                            'libCstd.so.1',
+                                            'libCrun.so.1',
+                                            'libc.so.1'],
+                         'path': 'opt/csw/lib/libdjvulibre.so.15',
+                         'runpath': ['/opt/csw/lib/$ISALIST',
+                                     '/opt/csw/lib',
+                                     '/opt/SUNWspro/lib/rw7',
+                                     '/opt/SUNWspro/lib/v8',
+                                     '/opt/SUNWspro/lib',
+                                     '/usr/ccs/lib',
+                                     '/lib',
+                                     '/usr/lib',
+                                     '/usr/lib/$ISALIST',
+                                     '/usr/lib',
+                                     '/lib/$ISALIST',
+                                     '/lib'],
+                         'soname': 'libdjvulibre.so.15',
+                         'soname_guessed': False},
+                        {'base_name': 'libdjvulibre.so.21.1.0',
+                         'needed sonames': ['libjpeg.so.7',
+                                            'libpthread.so.1',
+                                            'libm.so.1',
+                                            'libCstd.so.1',
+                                            'libCrun.so.1',
+                                            'libc.so.1'],
+                         'path': 'opt/csw/lib/sparcv9/libdjvulibre.so.21.1.0',
+                         'runpath': ['/opt/csw/X11/lib/$ISALIST',
+                                     '/opt/csw/X11/lib/64',
+                                     '/opt/csw/lib/$ISALIST',
+                                     '/opt/csw/lib/64',
+                                     '/opt/studio/SOS11/SUNWspro/lib/rw7/v9',
+                                     '/opt/studio/SOS11/SUNWspro/lib/v9',
+                                     '/opt/SUNWspro/lib/v9',
+                                     '/usr/ccs/lib/sparcv9',
+                                     '/lib/sparcv9',
+                                     '/usr/lib/sparcv9',
+                                     '/usr/lib/$ISALIST',
+                                     '/usr/lib',
+                                     '/lib/$ISALIST',
+                                     '/lib'],
+                         'soname': 'libdjvulibre.so.21',
+                         'soname_guessed': False},
+                        {'base_name': 'libdjvulibre.so.21.1.0',
+                         'needed sonames': ['libjpeg.so.7',
+                                            'libpthread.so.1',
+                                            'libm.so.1',
+                                            'libCstd.so.1',
+                                            'libCrun.so.1',
+                                            'libc.so.1'],
+                         'path': 'opt/csw/lib/libdjvulibre.so.21.1.0',
+                         'runpath': ['/opt/csw/X11/lib/$ISALIST',
+                                     '/opt/csw/X11/lib',
+                                     '/opt/csw/lib/$ISALIST',
+                                     '/opt/csw/lib',
+                                     '/opt/studio/SOS11/SUNWspro/lib/rw7',
+                                     '/opt/studio/SOS11/SUNWspro/lib/v8',
+                                     '/opt/studio/SOS11/SUNWspro/lib',
+                                     '/opt/SUNWspro/lib/v8',
+                                     '/opt/SUNWspro/lib',
+                                     '/usr/ccs/lib',
+                                     '/lib',
+                                     '/usr/lib',
+                                     '/usr/lib/$ISALIST',
+                                     '/usr/lib',
+                                     '/lib/$ISALIST',
+                                     '/lib'],
+                         'soname': 'libdjvulibre.so.21',
+                         'soname_guessed': False}],
+ 'depends': [('CSWcommon',
+              'CSWcommon common - common files and dirs for CSW packages '),
+             ('CSWisaexec',
+              'CSWisaexec isaexec - sneaky wrapper around Sun isaexec '),
+             ('CSWjpeg',
+              'CSWjpeg jpeg - JPEG library and tools by the Independent JPEG Group ')],
+ 'isalist': ['sparcv9+vis2',
+             'sparcv9+vis',
+             'sparcv9',
+             'sparcv8plus+vis2',
+             'sparcv8plus+vis',
+             'sparcv8plus',
+             'sparcv8',
+             'sparcv8-fsmuld',
+             'sparcv7',
+             'sparc'],
+ 'overrides': [],
+ 'pkginfo': {'ARCH': 'sparc',
+             'CATEGORY': 'application',
+             'CLASSES': 'none',
+             'EMAIL': 'hson at opencsw.org',
+             'HOTLINE': 'http://www.opencsw.org/bugtrack/',
+             'NAME': 'djvulibre_rt - DjVu standalone viewer, browser plug-in, command line tools - runtime package',
+             'OPENCSW_CATALOGNAME': 'djvulibre_rt',
+             'OPENCSW_MODE64': '32/64/isaexec',
+             'OPENCSW_REPOSITORY': 'https://gar.svn.sourceforge.net/svnroot/gar/csw/mgar/pkg/djvulibre/trunk@9213',
+             'PKG': 'CSWdjvulibrert',
+             'PSTAMP': 'hson at build8s-20100317033724',
+             'VENDOR': 'http://djvu.sourceforge.net/ packaged for CSW by Roger Hakansson',
+             'VERSION': '3.5.22,REV=2010.03.17',
+             'WORKDIR_FIRSTMOD': '../build-isa-sparcv8'},
+ 'pkgmap': [{'class': None,
+             'group': None,
+             'line': ': 1 15667',
+             'mode': None,
+             'path': None,
+             'type': '1',
+             'user': None},
+            {'class': 'none',
+             'group': None,
+             'line': '1 s none /opt/csw/lib/libdjvulibre.so=libdjvulibre.so.21.1.0',
+             'mode': None,
+             'path': '/opt/csw/lib/libdjvulibre.so',
+             'type': 's',
+             'user': None},
+            {'class': 'none',
+             'group': 'bin',
+             'line': '1 f none /opt/csw/lib/libdjvulibre.so.15 0755 root bin 2179976 17791 1268791023',
+             'mode': '0755',
+             'path': '/opt/csw/lib/libdjvulibre.so.15',
+             'type': 'f',
+             'user': 'root'},
+            {'class': 'none',
+             'group': None,
+             'line': '1 s none /opt/csw/lib/libdjvulibre.so.21=libdjvulibre.so.21.1.0',
+             'mode': None,
+             'path': '/opt/csw/lib/libdjvulibre.so.21',
+             'type': 's',
+             'user': None},
+            {'class': 'none',
+             'group': 'bin',
+             'line': '1 f none /opt/csw/lib/libdjvulibre.so.21.1.0 0755 root bin 2316572 5640 1268790998',
+             'mode': '0755',
+             'path': '/opt/csw/lib/libdjvulibre.so.21.1.0',
+             'type': 'f',
+             'user': 'root'},
+            {'class': 'none',
+             'group': None,
+             'line': '1 s none /opt/csw/lib/sparcv9/libdjvulibre.so=libdjvulibre.so.21.1.0',
+             'mode': None,
+             'path': '/opt/csw/lib/sparcv9/libdjvulibre.so',
+             'type': 's',
+             'user': None},
+            {'class': 'none',
+             'group': None,
+             'line': '1 s none /opt/csw/lib/sparcv9/libdjvulibre.so.21=libdjvulibre.so.21.1.0',
+             'mode': None,
+             'path': '/opt/csw/lib/sparcv9/libdjvulibre.so.21',
+             'type': 's',
+             'user': None},
+            {'class': 'none',
+             'group': 'bin',
+             'line': '1 f none /opt/csw/lib/sparcv9/libdjvulibre.so.21.1.0 0755 root bin 2950128 36235 1268791033',
+             'mode': '0755',
+             'path': '/opt/csw/lib/sparcv9/libdjvulibre.so.21.1.0',
+             'type': 'f',
+             'user': 'root'},
+            {'class': 'none',
+             'group': 'bin',
+             'line': '1 d none /opt/csw/share/doc/djvulibre_rt 0755 root bin',
+             'mode': '0755',
+             'path': '/opt/csw/share/doc/djvulibre_rt',
+             'type': 'd',
+             'user': 'root'},
+            {'class': 'none',
+             'group': 'bin',
+             'line': '1 f none /opt/csw/share/doc/djvulibre_rt/license 0644 root bin 17989 29204 1268793418',
+             'mode': '0644',
+             'path': '/opt/csw/share/doc/djvulibre_rt/license',
+             'type': 'f',
+             'user': 'root'},
+            {'class': None,
+             'group': None,
+             'line': '1 i copyright 76 7217 1268793418',
+             'mode': None,
+             'path': None,
+             'type': 'i',
+             'user': None},
+            {'class': None,
+             'group': None,
+             'line': '1 i depend 187 16539 1268793444',
+             'mode': None,
+             'path': None,
+             'type': 'i',
+             'user': None},
+            {'class': None,
+             'group': None,
+             'line': '1 i pkginfo 560 47879 1268793447',
+             'mode': None,
+             'path': None,
+             'type': 'i',
+             'user': None}]}


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

Added: csw/mgar/gar/v2/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/bad_paths.yml
===================================================================
--- csw/mgar/gar/v2/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/bad_paths.yml	                        (rev 0)
+++ csw/mgar/gar/v2/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/bad_paths.yml	2010-03-19 10:07:39 UTC (rev 9248)
@@ -0,0 +1 @@
+{}

Added: csw/mgar/gar/v2/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/pkgchk.yml
===================================================================
--- csw/mgar/gar/v2/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/pkgchk.yml	                        (rev 0)
+++ csw/mgar/gar/v2/lib/python/testdata/stats/46/461a24f02dd5020b4aa014b76f3ec2cc/pkgchk.yml	2010-03-19 10:07:39 UTC (rev 9248)
@@ -0,0 +1 @@
+[]

Modified: csw/mgar/gar/v2/tests/overrides_test.py
===================================================================
--- csw/mgar/gar/v2/tests/overrides_test.py	2010-03-19 09:58:56 UTC (rev 9247)
+++ csw/mgar/gar/v2/tests/overrides_test.py	2010-03-19 10:07:39 UTC (rev 9248)
@@ -5,6 +5,7 @@
 import unittest
 sys.path.append("../lib/python")
 import gartest
+import opencsw
 
 class OverridesUnitTest_1(unittest.TestCase):
   """Tests CHECKPKG_OVERRIDES support."""
@@ -21,9 +22,13 @@
     pkg = mybuild.GetFirstBuiltPackage()
     overr_file = "/opt/csw/share/checkpkg/overrides/overrides_test"
     expected = 'CSWoverrides-test: example-tag example-parameter\n'
-    self.assertEqual(expected, pkg.GetFileContent(overr_file))
-    overrides = pkg.GetOverrides()
-    self.assertEqual(1, len(overrides))
+    try:
+      self.assertEqual(expected, pkg.GetFileContent(overr_file))
+      overrides = pkg.GetOverrides()
+      self.assertEqual(1, len(overrides))
+    except opencsw.PackageError, e:
+      mybuild.cleanup = False
+      self.fail(e)
 
   def testTwoOverriders(self):
     """Checks that CHECKPKG_OVERRIDES variable creates overrides."""
@@ -79,3 +84,6 @@
 #     self.assertEqual(expected, pkg.GetFileContent(overr_file_1))
 #     overrides = pkg.GetOverrides()
 #     self.assertEqual(1, len(overrides))
+
+if __name__ == '__main__':
+	unittest.main()

Modified: csw/mgar/gar/v2/tests/run_tests.py
===================================================================
--- csw/mgar/gar/v2/tests/run_tests.py	2010-03-19 09:58:56 UTC (rev 9247)
+++ csw/mgar/gar/v2/tests/run_tests.py	2010-03-19 10:07:39 UTC (rev 9248)
@@ -15,7 +15,6 @@
 from opencsw_test            import *
 from overrides_test          import *
 from package_checks_test     import *
-from package_checks_old_test import *
 
 if __name__ == '__main__':
   unittest.main()


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