Merged from trunk 5212:5219
authorFabian Groffen <grobian@gentoo.org>
Fri, 8 Dec 2006 08:12:21 +0000 (08:12 -0000)
committerFabian Groffen <grobian@gentoo.org>
Fri, 8 Dec 2006 08:12:21 +0000 (08:12 -0000)
Add pretty basic vercmp unit testing...need more cases

Make all lock files hidden for bug #142369.

minor syntax changes ( in is faster than has_key ) and docstrings

Allow searching for action terms again

add some portage_util tests

Avoid bogus 'Deprecated use of action' warnings for valid commands such
as `emerge -s sync`.

Simplfy deprecated action parsing logic.

svn path=/main/branches/prefix/; revision=5226

bin/emerge
make.conf.txt
pym/portage_locks.py
pym/portage_util.py
tests/__init__.py [new file with mode: 0644]
tests/runTests [new file with mode: 0755]
tests/test_util.py [new file with mode: 0644]
tests/test_vercmp.py [new file with mode: 0644]

index eb09736ee0d167aca0db10287b1008dee369eb4c..c8ba4d987da91fd11625d9bb857a9e3bde540397 100755 (executable)
@@ -4347,13 +4347,14 @@ def parse_opts(tmpcmdline, silent=False):
                        myaction = action_opt
 
        for x in myargs:
-               if x in actions:
+               if x in actions and myaction != "search":
                        if x not in ["system", "world"]:
                                print red("*** Deprecated use of action '%s', use '--%s' instead" % (x,x))
+                       # special case "search" so people can search for action terms, e.g. emerge -s sync
                        if myaction:
                                multiple_actions(myaction, x)
                                sys.exit(1)
-                       myaction=x
+                       myaction = x
                else:
                        myfiles.append(x)
 
index 611aae360a2adbf79bd66f30e70920c5cf670e6c..6d19059096fb2c6551ecdc7c1fc7ee802b2b9671 100644 (file)
@@ -224,7 +224,7 @@ _`keepwork`
        may occupy a lot of diskspace.
 
 _`metadata-transfer`
-       Automatically perform a metadata transfer when `emerge --sync` is run.
+       Automatically perform a metadata transfer when emerge --sync is run.
 
 _`mirror`
        This will cause `FETCHCOMMAND`_ to always be run even if the file already 
@@ -511,7 +511,7 @@ PORTAGE_RSYNC_EXTRA_OPTS
 :suggest: --exclude=/etc/portage/rsync_exclude
 :valdesc: rsync options
 
-Additional rsync options to be used by `emerge --sync`.
+Additional rsync options to be used by emerge --sync.
 
 PORTAGE_RSYNC_OPTS
 ------------------
@@ -519,7 +519,7 @@ PORTAGE_RSYNC_OPTS
 :default: --recursive --links --safe-links --perms --times --compress --force --whole-file --delete --delete-after --stats --timeout=180 --exclude=/distfiles --exclude=/local --exclude=/packages
 :valdesc: rsync options
 
-Default rsync options to be used by `emerge --sync`. **Don't change this unless
+Default rsync options to be used by emerge --sync. **Don't change this unless
 you know exactly what you're doing!**
 
 PORTAGE_RSYNC_RETRIES
@@ -619,7 +619,7 @@ SYNC
 :valdesc: URI to a portage tree server (rsync or cvs)
 
 Insert your preferred rsync mirror here.  This rsync server is used to sync 
-the local portage tree when `emerge --sync` is run. Only one server can be 
+the local portage tree when emerge --sync is run. Only one server can be 
 specified.
 
 USE
index a27c6974cf37ab268a0ce067a3bfbecd5f1831e0..340fe46f89dbe1127e6eb95147966fa6df318a80 100644 (file)
@@ -41,7 +41,9 @@ def lockfile(mypath,wantnewlockfile=0,unlinkfile=0):
                wantnewlockfile = 0
                unlinkfile      = 0
        elif wantnewlockfile:
-               lockfilename = mypath+".portage_lockfile"
+               base, tail = os.path.split(mypath)
+               lockfilename = os.path.join(base, "." + tail + ".portage_lockfile")
+               del base, tail
                unlinkfile   = 1
        else:
                lockfilename = mypath
index 7a312deb49b1fec293d175a92340a5ffdb4cee04..17e669d3180dbb2189381dfd976ea1f8c0e21a3e 100644 (file)
@@ -77,15 +77,44 @@ def map_dictlist_vals(func,myDict):
        return new_dl
 
 def stack_dictlist(original_dicts, incremental=0, incrementals=[], ignore_none=0):
-       """Stacks an array of dict-types into one array. Optionally merging or
+       """
+       Stacks an array of dict-types into one array. Optionally merging or
        overwriting matching key/value pairs for the dict[key]->list.
-       Returns a single dict. Higher index in lists is preferenced."""
+       Returns a single dict. Higher index in lists is preferenced.
+       
+       Example usage:
+          >>> from portage_util import stack_dictlist
+               >>> print stack_dictlist( [{'a':'b'},{'x':'y'}])
+               >>> {'a':'b','x':'y'}
+               >>> print stack_dictlist( [{'a':'b'},{'a':'c'}], incremental = True )
+               >>> {'a':['b','c'] }
+               >>> a = {'KEYWORDS':['x86','alpha']}
+               >>> b = {'KEYWORDS':['-x86']}
+               >>> print stack_dictlist( [a,b] )
+               >>> { 'KEYWORDS':['x86','alpha','-x86']}
+               >>> print stack_dictlist( [a,b], incremental=True)
+               >>> { 'KEYWORDS':['alpha'] }
+               >>> print stack_dictlist( [a,b], incrementals=['KEYWORDS'])
+               >>> { 'KEYWORDS':['alpha'] }
+       
+       @param original_dicts a list of (dictionary objects or None)
+       @type list
+       @param incremental True or false depending on whether new keys should overwrite
+          keys which already exist.
+       @type boolean
+       @param incrementals A list of items that should be incremental (-foo removes foo from
+          the returned dict).
+       @type list
+       @param ignore_none Appears to be ignored, but probably was used long long ago.
+       @type boolean
+       
+       """
        final_dict = {}
        for mydict in original_dicts:
                if mydict is None:
                        continue
                for y in mydict.keys():
-                       if not final_dict.has_key(y):
+                       if not y in final_dict:
                                final_dict[y] = []
                        
                        for thing in mydict[y]:
@@ -102,7 +131,7 @@ def stack_dictlist(original_dicts, incremental=0, incrementals=[], ignore_none=0
                                                        continue
                                        if thing not in final_dict[y]:
                                                final_dict[y].append(thing)
-                       if final_dict.has_key(y) and not final_dict[y]:
+                       if y in final_dict and not final_dict[y]:
                                del final_dict[y]
        return final_dict
 
diff --git a/tests/__init__.py b/tests/__init__.py
new file mode 100644 (file)
index 0000000..1a235ff
--- /dev/null
@@ -0,0 +1,21 @@
+# tests/__init__.py -- Portage Unit Test functionality
+# Copyright 2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+import unittest
+
+def main():
+       
+       tests = ["test_vercmp", "test_util"]
+
+       suite = unittest.TestSuite()
+
+       for mod in tests:
+               try:
+                       test_mod = __import__(mod)
+                       suite.addTest(test_mod.suite())
+               except ImportError:
+                       pass
+
+       unittest.TextTestRunner(verbosity=2).run(suite) 
diff --git a/tests/runTests b/tests/runTests
new file mode 100755 (executable)
index 0000000..74b853f
--- /dev/null
@@ -0,0 +1,20 @@
+#!/usr/bin/python
+# runTests.py -- Portage Unit Test Functionality
+# Copyright 2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+
+import sys
+import os.path as osp
+
+# Grab SVN portage files instead of normal ones.
+sys.path.insert(0,'../pym')
+
+# Insert our parent dir so we can do shiny import "tests"
+# This line courtesy of Marienz and Pkgcore ;)
+sys.path.insert(0, osp.dirname(osp.dirname(osp.abspath(__file__))))
+
+import tests
+
+tests.main()
diff --git a/tests/test_util.py b/tests/test_util.py
new file mode 100644 (file)
index 0000000..59d82b9
--- /dev/null
@@ -0,0 +1,42 @@
+# test_vercmp.py -- Portage Unit Testing Functionality
+# Copyright 2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id: test_vercmp.py 5213 2006-12-08 00:12:41Z antarus $
+
+from unittest import TestCase, TestLoader
+
+class UtilTestCase(TestCase):
+       
+       def testUniqueArray(self):
+               pass
+               
+       def testVarexpand(self):
+               pass
+               
+       def testStackLists(self):
+               pass
+       
+       def testStackDicts(self):
+               pass
+       
+       def testStackDictList(self):
+               from portage_util import stack_dictlist
+               
+               tests = [ ({'a':'b'},{'x':'y'},False,{'a':['b'],'x':['y']}) ]
+               tests.append(( {'KEYWORDS':['alpha','x86']},{'KEYWORDS':['-*']},True,{} ))
+               tests.append(( {'KEYWORDS':['alpha','x86']},{'KEYWORDS':['-x86']},True,{'KEYWORDS':['alpha']} ))
+               for test in tests:
+                       self.failUnless(stack_dictlist([test[0],test[1]],incremental=test[2]) == test[3],
+                               msg="%s and %s combined, was expecting: %s and got: %s" % (test[0],test[1],test[3],
+                               stack_dictlist([test[0],test[1]],incremental=test[2])) )
+
+       def testNormalizePath(self):
+               
+               from portage_util import normalize_path
+               path = "///foo/bar/baz"
+               good = "/foo/bar/baz"
+               self.failUnless(normalize_path(path) == good, msg="NormalizePath(%s) failed to produce %s" % (path, good))
+
+def suite():
+       return TestLoader().loadTestsFromTestCase(UtilTestCase)
+
diff --git a/tests/test_vercmp.py b/tests/test_vercmp.py
new file mode 100644 (file)
index 0000000..624950c
--- /dev/null
@@ -0,0 +1,46 @@
+# test_vercmp.py -- Portage Unit Testing Functionality
+# Copyright 2006 Gentoo Foundation
+# Distributed under the terms of the GNU General Public License v2
+# $Id$
+
+from unittest import TestCase
+from unittest import TestLoader
+from portage_versions import vercmp
+
+class VerCmpTestCase(TestCase):
+       """ A simple testCase for portage_versions.vercmp()
+       """
+
+       
+       def testVerCmpGreater(self):
+               
+               tests = [ ( "6.0", "5.0"), ("5.0","5")]
+               for test in tests:
+                       self.failIf( vercmp( test[0], test[1] ) <= 0, msg="%s < %s? Wrong!" % (test[0],test[1]) )
+
+       def testVerCmpLess(self):
+               """
+               pre < alpha < beta < rc < p -> test each of these, they are inductive (or should be..)
+               """
+               tests = [ ( "4.0", "5.0"), ("5", "5.0"), ("1.0_pre2","1.0_p2"),
+                       ("1.0_alpha2", "1.0_p2"),("1.0_alpha1", "1.0_beta1"),("1.0_beta3","1.0_rc3")]
+               for test in tests:
+                       self.failIf( vercmp( test[0], test[1]) >= 0, msg="%s > %s? Wrong!" % (test[0],test[1]))
+       
+       
+       def testVerCmpEqual(self):
+               
+               tests = [ ("4.0", "4.0") ]
+               for test in tests:
+                       self.failIf( vercmp( test[0], test[1]) != 0, msg="%s != %s? Wrong!" % (test[0],test[1]))
+                       
+       def testVerNotEqual(self):
+               
+               tests = [ ("1","2"),("1.0_alpha","1.0_pre"),("1.0_beta","1.0_alpha"),
+                       ("0", "0.0")]
+               for test in tests:
+                       self.failIf( vercmp( test[0], test[1]) == 0, msg="%s == %s? Wrong!" % (test[0],test[1]))
+
+def suite():
+       return TestLoader().loadTestsFromTestCase(VerCmpTestCase)
+