--- a/src/modules/client/api.py Thu Apr 08 14:10:41 2010 -0700
+++ b/src/modules/client/api.py Thu Apr 08 17:17:41 2010 -0500
@@ -30,6 +30,7 @@
Refer to pkg.api_common for additional core class documentation."""
+import collections
import copy
import errno
import fnmatch
@@ -1176,7 +1177,7 @@
# Keep track of listed stems for all other packages on a
# per-publisher basis.
- nlist = set()
+ nlist = collections.defaultdict(int)
def check_state(t, entry):
states = entry["metadata"]["states"]
@@ -1243,7 +1244,7 @@
return True
return False
- pkg_stem = pub + "!" + stem
+ pkg_stem = "!".join((pub, stem))
if pkg_stem in nlist:
# A newer version has already been listed for
# this stem and publisher.
@@ -1332,9 +1333,8 @@
# Package is for zones only.
omit_package = True
- if filter_cb is not None:
- pkg_stem = pub + "!" + stem
- nlist.add(pkg_stem)
+ pkg_stem = "!".join((pub, stem))
+ nlist[pkg_stem] += 1
if not pkgi and pkgr and stem in inc_vers:
# If the package is not installed, but this is
@@ -1354,6 +1354,7 @@
# Pattern filtering has to be applied last so that
# renames, incorporations, and everything else is
# handled correctly.
+ omit_ver = False
if not omit_package:
for pat in patterns:
(pat_pub, pat_stem, pat_ver), matcher = \
@@ -1389,6 +1390,7 @@
if not ever.is_successor(pat_ver,
pkg.version.CONSTRAINT_AUTO):
omit_package = True
+ omit_ver = True
continue
# If this entry matched at least one
@@ -1397,6 +1399,15 @@
break
if omit_package:
+ if filter_cb is not None and omit_ver and \
+ nlist[pkg_stem] == 1:
+ # If omitting because of version, and
+ # no other versions have been returned
+ # yet for this stem, then discard
+ # tracking entry so that other
+ # versions will be listed.
+ del nlist[pkg_stem]
+ slist.discard(stem)
continue
if cats is not None:
--- a/src/tests/api/t_api_list.py Thu Apr 08 14:10:41 2010 -0700
+++ b/src/tests/api/t_api_list.py Thu Apr 08 17:17:41 2010 -0500
@@ -628,7 +628,6 @@
self.assertEqual(len(returned), 10)
self.assertPrettyEqual(returned, expected)
-
# Re-test, including variants.
returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
api_obj=api_obj, variants=True)
@@ -656,13 +655,10 @@
"1.0,5.11"),
self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11",
installed=True),
-# self.__get_exp_pub_entry("test1", 18, "qux", "1.0,5.11",
-# installed=True),
]
self.assertEqual(len(returned), 12)
self.assertPrettyEqual(returned, expected)
-
# Verify results of LIST_INSTALLED_NEWEST when not including
# the publisher of installed packages.
returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
@@ -743,8 +739,7 @@
# Verify the results for LIST_INSTALLED_NEWEST after
# all packages have been uninstalled.
- api_obj.plan_uninstall(["entire", "apple",
- "grault"], False)
+ api_obj.plan_uninstall(["*"], False)
api_obj.prepare()
api_obj.execute_plan()
api_obj.reset()
@@ -813,6 +808,42 @@
self.assertPrettyEqual(returned, expected)
self.assertEqual(len(returned), 18)
+ # Re-test, including only a specific package version, which
+ # should show the requested versions even though newer
+ # versions are available. 'baz' should be omitted because
+ # it doesn't apply to the current image variants.
+ returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+ api_obj=api_obj, patterns=["[email protected],5.11.0", "baz",
+ "[email protected]"])
+
+ expected = [
+ self.__get_exp_pub_entry("test1", 1, "apple", "1.0,5.11-0"),
+ self.__get_exp_pub_entry("test2", 1, "apple", "1.0,5.11-0"),
+ self.__get_exp_pub_entry("test1", 17, "qux", "0.9,5.11"),
+ self.__get_exp_pub_entry("test2", 17, "qux", "0.9,5.11"),
+ ]
+ self.assertPrettyEqual(returned, expected)
+ self.assertEqual(len(returned), 4)
+
+ # Re-test, including only a specific package version, which
+ # should show the requested versions even though newer
+ # versions are available, and all variants. 'baz' should be
+ # included this time.
+ returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+ api_obj=api_obj, patterns=["[email protected],5.11.0", "baz",
+ "[email protected]"], variants=True)
+
+ expected = [
+ self.__get_exp_pub_entry("test1", 1, "apple", "1.0,5.11-0"),
+ self.__get_exp_pub_entry("test2", 1, "apple", "1.0,5.11-0"),
+ self.__get_exp_pub_entry("test1", 10, "baz", "1.3,5.11"),
+ self.__get_exp_pub_entry("test2", 10, "baz", "1.3,5.11"),
+ self.__get_exp_pub_entry("test1", 17, "qux", "0.9,5.11"),
+ self.__get_exp_pub_entry("test2", 17, "qux", "0.9,5.11"),
+ ]
+ self.assertPrettyEqual(returned, expected)
+ self.assertEqual(len(returned), 6)
+
# Test results after installing packages and only listing the
# installed packages.
af = self.__get_pub_entry("test1", 1, "apple", "1.0,5.11-0")[0]
@@ -863,6 +894,18 @@
self.assertPrettyEqual(returned, expected)
self.assertEqual(len(returned), 9)
+ # Re-test last but specify patterns for versions newer than
+ # what is installed; nothing should be returned as
+ # LIST_INSTALLED_NEWEST is supposed to omit versions newer
+ # than what is installed, allowed by installed incorporations,
+ # or doesn't apply to image variants.
+ returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+ api_obj=api_obj, patterns=["[email protected],5.11-1",
+ "[email protected]", "[email protected]"])
+ expected = []
+ self.assertPrettyEqual(returned, expected)
+ self.assertEqual(len(returned), 0)
+
# Remove corge, install grault, retest for
# LIST_INSTALLED_NEWEST. corge, grault, qux, and
# quux should be listed since none of them are
@@ -957,6 +1000,26 @@
self.assertPrettyEqual(returned, expected)
self.assertEqual(len(returned), 11)
+ # Re-test, specifying versions older than the newest, with
+ # some older than that allowed by the incorporation (should
+ # be omitted) and with versions allowed by the incorporation
+ # (should be returned).
+ returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+ api_obj=api_obj, patterns=["[email protected],5.11-0", "[email protected]"])
+
+ expected = [
+ self.__get_exp_pub_entry("test1", 3, "apple",
+ "1.2.0,5.11-0"),
+ ]
+ self.assertPrettyEqual(returned, expected)
+ self.assertEqual(len(returned), 1)
+
+ # Re-test, specifying versions newer than that allowed by the
+ # incorporation.
+ returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+ api_obj=api_obj, patterns=["[email protected],5.11-1"])
+ self.assertEqual(len(returned), 0)
+
# Re-test, only including test1's packages.
returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
api_obj=api_obj, pubs=["test1"])