[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