8265 EINVAL on rmdir running "make test"
authorDan Price <dp@eng.sun.com>
Sat, 30 Jan 2010 01:07:14 -0800
changeset 1715 8f305f0a6864
parent 1714 0de56d0c903a
child 1716 10e09e28528a
8265 EINVAL on rmdir running "make test" 9828 testsuite leaves turds in my tempdir 12257 setup.py doesn't respect run.py options 12259 run.py -x can cause traceback for failed api tests 13715 commonize duplicated misc_files mechanism 13717 lift debug functionality from cli suite into pkg5unittest base class 14215 test suite can publish using relative paths, saving complexity 14216 forked indexer process can race with testcase teardown 14217 Need a run.py option to enable debug output from suite 14218 Need a run.py option to archive the remains of failed tests 14219 test suite vomits when $DISPLAY isn't set 14220 test cases which depend on sun studio compilers need work 14270 cli tools should treat python warnings as errors
src/client.py
src/modules/depotcontroller.py
src/modules/flavor/elf.py
src/pkgdep.py
src/publish.py
src/pull.py
src/setup.py
src/tests/api/t_action.py
src/tests/api/t_api.py
src/tests/api/t_api_info.py
src/tests/api/t_api_list.py
src/tests/api/t_api_search.py
src/tests/api/t_bootenv.py
src/tests/api/t_catalog.py
src/tests/api/t_client.py
src/tests/api/t_dependencies.py
src/tests/api/t_elf.py
src/tests/api/t_file_manager.py
src/tests/api/t_fmri.py
src/tests/api/t_history.py
src/tests/api/t_imageconfig.py
src/tests/api/t_indexer.py
src/tests/api/t_manifest.py
src/tests/api/t_misc.py
src/tests/api/t_p5i.py
src/tests/api/t_pkg_api_install.py
src/tests/api/t_pkgtarfile.py
src/tests/api/t_plat.py
src/tests/api/t_publisher.py
src/tests/api/t_repositoryconfig.py
src/tests/api/t_smf.py
src/tests/api/t_solver.py
src/tests/api/t_unix_usergrp.py
src/tests/api/t_variant.py
src/tests/api/t_version.py
src/tests/api/testutils.py
src/tests/baseline.py
src/tests/baseline.txt
src/tests/cli/t_actuators.py
src/tests/cli/t_api.py
src/tests/cli/t_api_info.py
src/tests/cli/t_api_list.py
src/tests/cli/t_api_search.py
src/tests/cli/t_change_facet.py
src/tests/cli/t_change_variant.py
src/tests/cli/t_colliding_links.py
src/tests/cli/t_fix.py
src/tests/cli/t_lock.py
src/tests/cli/t_pkg_R_option.py
src/tests/cli/t_pkg_api_install.py
src/tests/cli/t_pkg_contents.py
src/tests/cli/t_pkg_depotd.py
src/tests/cli/t_pkg_help.py
src/tests/cli/t_pkg_history.py
src/tests/cli/t_pkg_image_create.py
src/tests/cli/t_pkg_image_update.py
src/tests/cli/t_pkg_info.py
src/tests/cli/t_pkg_install.py
src/tests/cli/t_pkg_intent.py
src/tests/cli/t_pkg_list.py
src/tests/cli/t_pkg_property.py
src/tests/cli/t_pkg_publisher.py
src/tests/cli/t_pkg_rebuild_index.py
src/tests/cli/t_pkg_refresh.py
src/tests/cli/t_pkg_search.py
src/tests/cli/t_pkg_uninstall.py
src/tests/cli/t_pkg_verify.py
src/tests/cli/t_pkg_version.py
src/tests/cli/t_pkgdep.py
src/tests/cli/t_pkgdep_resolve.py
src/tests/cli/t_pkgmogrify.py
src/tests/cli/t_pkgrecv.py
src/tests/cli/t_pkgsend.py
src/tests/cli/t_publish_api.py
src/tests/cli/t_setUp.py
src/tests/cli/t_solver.py
src/tests/cli/t_util_merge.py
src/tests/cli/t_util_update_file_layout.py
src/tests/cli/t_variants.py
src/tests/cli/testutils.py
src/tests/gui/t_pm_addrepo.py
src/tests/gui/t_pm_helpabout.py
src/tests/gui/t_pm_rmrepo.py
src/tests/gui/t_pm_start.py
src/tests/gui/t_pm_uninstall.py
src/tests/gui/testutils.py
src/tests/pkg5testenv.py
src/tests/pkg5unittest.py
src/tests/run.py
src/tests/testsuite/__init__.py
src/tests/testsuite/t_setup_teardown.py
src/tests/testsuite/testutils.py
src/util/publish/merge.py
src/util/publish/pkgmogrify.py
--- a/src/client.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/client.py	Sat Jan 30 01:07:14 2010 -0800
@@ -59,6 +59,7 @@
 import traceback
 import urllib2
 import urlparse
+import warnings
 
 import pkg
 import pkg.actions as actions
@@ -3572,6 +3573,10 @@
 if __name__ == "__main__":
         misc.setlocale(locale.LC_ALL, "", error)
         gettext.install("pkg", "/usr/share/locale")
+
+        # Make all warnings be errors.
+        warnings.simplefilter('error')
+
         __retval = handle_errors(main_func)
         try:
                 logging.shutdown()
--- a/src/modules/depotcontroller.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/modules/depotcontroller.py	Sat Jan 30 01:07:14 2010 -0800
@@ -226,7 +226,13 @@
                 """ Return the equivalent command line invocation (as an
                     array) for the depot as currently configured. """
 
-                args = self.__wrapper_start[:]
+                args = []
+
+                # The depot may fork off children of its own, so we place
+                # them all together in a process group.  This allows us to
+                # nuke everything later on.
+                args.append("setpgrp")
+                args.extend(self.__wrapper_start[:])
                 args.append(self.__depot_path)
                 if self.__depot_content_root:
                         args.append("--content-root")
@@ -305,55 +311,67 @@
                 self.__starttime = time.time()
 
         def start(self):
-                self.__initial_start()
-
-                if self.__refresh_index:
-                        return
+                try:
+                        self.__initial_start()
 
-                sleeptime = 0.05
-                contact = False
-                while sleeptime <= 40.0:
-                        rc = self.__depot_handle.poll()
-                        if rc is not None:
-                                raise DepotStateException("Depot exited "
-                                    "unexpectedly while starting "
-                                    "(exit code %d)" % rc)
+                        if self.__refresh_index:
+                                return
+
+                        begintime = time.time()
 
-                        if self.is_alive():
-                                contact = True
-                                break
-                        time.sleep(sleeptime)
-                        sleeptime *= 2
+                        sleeptime = 0.0
+                        check_interval = 0.20
+                        contact = False
+                        while (time.time() - begintime) <= 40.0:
+                                rc = self.__depot_handle.poll()
+                                if rc is not None:
+                                        raise DepotStateException("Depot exited "
+                                            "unexpectedly while starting "
+                                            "(exit code %d)" % rc)
 
-                if contact == False:
-                        self.kill()
-                        self.__state = self.HALTED
-                        raise DepotStateException("Depot did not respond to "
-                            "repeated attempts to make contact")
+                                if self.is_alive():
+                                        contact = True
+                                        break
+                                time.sleep(check_interval)
 
-                self.__state = self.RUNNING
+                        if contact == False:
+                                self.kill()
+                                self.__state = self.HALTED
+                                raise DepotStateException("Depot did not respond to "
+                                    "repeated attempts to make contact")
+
+                        self.__state = self.RUNNING
+                except KeyboardInterrupt:
+                        if self.__depot_handle:
+                                self.kill(now=True)
+                        raise
 
         def start_expected_fail(self, exit=2):
-                self.__initial_start()
+                try:
+                        self.__initial_start()
 
-                sleeptime = 0.05
-                died = False
-                rc = None
-                while sleeptime <= 10.0:
+                        sleeptime = 0.05
+                        died = False
+                        rc = None
+                        while sleeptime <= 10.0:
 
-                        rc = self.__depot_handle.poll()
-                        if rc is not None:
-                                died = True
-                                break
-                        time.sleep(sleeptime)
-                        sleeptime *= 2
+                                rc = self.__depot_handle.poll()
+                                if rc is not None:
+                                        died = True
+                                        break
+                                time.sleep(sleeptime)
+                                sleeptime *= 2
 
-                if died and rc == exit:
-                        self.__state = self.HALTED
-                        return True
-                else:
-                        self.stop()
-                        return False
+                        if died and rc == exit:
+                                self.__state = self.HALTED
+                                return True
+                        else:
+                                self.stop()
+                                return False
+                except KeyboardInterrupt:
+                        if self.__depot_handle:
+                                self.kill(now=True)
+                        raise
 
         def refresh(self):
                 if self.__depot_handle == None:
@@ -364,55 +382,31 @@
                 os.kill(self.__depot_handle.pid, signal.SIGUSR1)
                 return self.__depot_handle.poll()
 
-        def kill(self):
+        def kill(self, now=False):
                 """kill the depot; letting it live for
                 a little while helps get reliable death"""
 
-                lifetime = time.time() - self.__starttime
-                if lifetime < 1.0:
-                        time.sleep(1.0 - lifetime)
-
                 if self.__depot_handle == None:
                         # XXX might want to remember and return saved
                         # exit status
                         return 0
 
-                status = -1
-
-                wait_to_exit = 5.0
-                sleeptime = 0.05
-                firsttime = True
-
-                while wait_to_exit > 0:
-                        status = self.__depot_handle.poll()
-                        if status is not None:
-                                break
+                try:
+                        lifetime = time.time() - self.__starttime
+                        if now == False and lifetime < 1.0:
+                                time.sleep(1.0 - lifetime)
 
-                        #
-                        # No status, Depot process seems to be running
-                        # XXX could also check liveness with a kill.
-                        #
-                        if firsttime:
-                                # XXX porting issue
-                                os.kill(self.__depot_handle.pid, signal.SIGTERM)
-                                firsttime = False
-
-                        time.sleep(sleeptime)
-                        wait_to_exit -= sleeptime
-                        sleeptime *= 2
-                else:
-                        assert status is None
-                        print >> sys.stderr, \
-                            "Depot did not shut down, trying kill -9 %d" % \
-                            self.__depot_handle.pid
-                        os.kill(self.__depot_handle.pid, signal.SIGKILL)
-                        #self.__depot_handle.wait()
-                        status = self.__depot_handle.poll()
-
-                # XXX do something useful with status
-                self.__state = self.HALTED
-                self.__depot_handle = None
-                return status
+                finally:
+                        # By sticking in this finally: block we ensure that even
+                        # if the kill gets ctrl-c'd, we'll at least take a good
+                        # final whack at the depot by killing -9 its process group.
+                        try:
+                                os.kill(-1 * self.__depot_handle.pid, signal.SIGKILL)
+                        except OSError:
+                                pass
+                        self.__state = self.HALTED
+                        self.__depot_handle.wait()
+                        self.__depot_handle = None
 
         def stop(self):
                 if self.__state == self.HALTED:
--- a/src/modules/flavor/elf.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/modules/flavor/elf.py	Sat Jan 30 01:07:14 2010 -0800
@@ -21,7 +21,7 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -105,8 +105,8 @@
                         return err, vars
 
         def __repr__(self):
-                return "ElfDep(%s, %s, %s, %s)" % (self.action, self.base_name,
-                    self.run_paths, self.pkg_vars)
+                return "ElfDep(%s, %s, %s, %s)" % (self.action,
+                    self.base_names[0], self.run_paths, self.pkg_vars)
 
 def expand_variables(paths, dyn_tok_conv):
         """Replace dynamic tokens, such as $PLATFORM, in the paths in the
--- a/src/pkgdep.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/pkgdep.py	Sat Jan 30 01:07:14 2010 -0800
@@ -32,6 +32,7 @@
 import os
 import sys
 import traceback
+import warnings
 
 import pkg
 import pkg.actions as actions
@@ -475,6 +476,10 @@
 # so that we can more easily detect these in testing of the CLI commands.
 #
 if __name__ == "__main__":
+
+        # Make all warnings be errors.
+        warnings.simplefilter('error')
+
         try:
                 __ret = main_func()
         except api_errors.MissingFileArgumentException, e:
--- a/src/publish.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/publish.py	Sat Jan 30 01:07:14 2010 -0800
@@ -43,6 +43,7 @@
 import os
 import sys
 import traceback
+import warnings
 
 import pkg.actions
 import pkg.bundle
@@ -547,6 +548,10 @@
 # so that we can more easily detect these in testing of the CLI commands.
 #
 if __name__ == "__main__":
+        
+        # Make all warnings be errors.
+        warnings.simplefilter('error')
+
         try:
                 __ret = main_func()
         except (pkg.actions.ActionError, trans.TransactionError,
--- a/src/pull.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/pull.py	Sat Jan 30 01:07:14 2010 -0800
@@ -21,7 +21,7 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -35,6 +35,7 @@
 import traceback
 import urllib
 import urlparse
+import warnings
 
 import pkg.catalog as catalog
 import pkg.client.progress as progress
@@ -789,6 +790,10 @@
         return 0
 
 if __name__ == "__main__":
+
+        # Make all warnings be errors.
+        warnings.simplefilter('error')
+
         try:
                 __ret = main_func()
         except (pkg.actions.ActionError, trans.TransactionError,
--- a/src/setup.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/setup.py	Sat Jan 30 01:07:14 2010 -0800
@@ -770,6 +770,7 @@
         # list of options stored in initialize_options below. The first entry
         # in each tuple must be the exact name of a member variable.
         user_options = [
+            ("archivedir=", 'a', "archive failed tests <dir>"),
             ("baselinefile=", 'b', "baseline file <file>"),
             ("coverage", "c", "collect code coverage data"),
             ("genbaseline", 'g', "generate test baseline"),
@@ -777,6 +778,11 @@
             ("parseable", 'p', "parseable output"),
             ("timing", "t", "timing file <file>"),
             ("verbosemode", 'v', "run tests in verbose mode"),
+            ("stoponerr", 'x', "stop when a baseline mismatch occurs"),
+            ("debugoutput", 'd', "emit debugging output"),
+            ("show_on_expected_fail", 'f',
+                "show all failure info, even for expected fails"),
+            ("startattest=", 's', "start at indicated test"),
         ]
         description = "Runs unit and functional tests"
 
@@ -788,6 +794,11 @@
                 self.genbaseline = 0
                 self.timing = 0
                 self.coverage = 0
+                self.stoponerr = 0
+                self.debugoutput = 0
+                self.show_on_expected_fail = 0
+                self.startattest = ""
+                self.archivedir = ""
 
         def finalize_options(self):
                 pass
--- a/src/tests/api/t_action.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_action.py	Sat Jan 30 01:07:14 2010 -0800
@@ -23,17 +23,17 @@
 # Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import unittest
 import pkg.actions as action
 
 import os
 import sys
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-import pkg5unittest
-
 class TestActions(pkg5unittest.Pkg5TestCase):
 
         def assertAttributeValue(self, action, attr, value):
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/api/t_api.py	Sat Jan 30 01:07:14 2010 -0800
@@ -0,0 +1,916 @@
+#!/usr/bin/python
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+import testutils
+if __name__ == "__main__":
+	testutils.setup_environment("../../../proto")
+import pkg5unittest
+
+import cStringIO
+import os
+import pkg.client.api as api
+import pkg.client.api_errors as api_errors
+import pkg.client.progress as progress
+import pkg.fmri as fmri
+import sys
+import tempfile
+import time
+import unittest
+
+API_VERSION = 31
+PKG_CLIENT_NAME = "pkg"
+
+class TestPkgApi(pkg5unittest.SingleDepotTestCase):
+        # restart the depot for every test
+        persistent_setup = False
+
+        foo10 = """
+            open [email protected],5.11-0
+            close """
+
+        foo12 = """
+            open [email protected],5.11-0
+            add file libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
+            close """
+
+        bar10 = """
+            open [email protected],5.11-0
+            close """
+
+        baz10 = """
+            open [email protected],5.11-0
+            add license copyright.baz license=copyright.baz
+            close """
+
+        quux10 = """
+            open [email protected],5.11-0
+            add depend type=require [email protected]
+            close """
+
+        # First iteration has just a copyright.
+        licensed10 = """
+            open [email protected],5.11-0
+            add depend type=require [email protected]
+            add license copyright.licensed license=copyright.licensed
+            close """
+
+        # Second iteration has copyright that must-display and a new license
+        # that doesn't require acceptance.
+        licensed12 = """
+            open [email protected],5.11-0
+            add depend type=require [email protected]
+            add file libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
+            add license copyright.licensed license=copyright.licensed must-display=True
+            add license license.licensed license=license.licensed
+            close """
+
+        # Third iteration now requires acceptance of license.
+        licensed13 = """
+            open [email protected],5.11-0
+            add depend type=require [email protected]
+            add file libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
+            add license copyright.licensed license=copyright.licensed must-display=True
+            add license license.licensed license=license.licensed must-accept=True
+            close """
+
+        p5i_bobcat = """{
+  "packages": [
+    "pkg:/[email protected],5.11-0", 
+    "baz"
+  ], 
+  "publishers": [
+    {
+      "alias": "cat", 
+      "name": "bobcat", 
+      "packages": [
+        "pkg:/[email protected],5.11-0"
+      ], 
+      "repositories": [
+        {
+          "collection_type": "core", 
+          "description": "xkcd.net/325", 
+          "legal_uris": [
+            "http://xkcd.com/license.html"
+          ], 
+          "mirrors": [], 
+          "name": "source", 
+          "origins": [
+            "http://localhost:12001/"
+          ], 
+          "refresh_seconds": 43200, 
+          "registration_uri": "", 
+          "related_uris": []
+        }
+      ]
+    }
+  ], 
+  "version": 1
+}
+"""
+
+
+        misc_files = ["copyright.baz", "copyright.licensed", "libc.so.1",
+            "license.licensed", "license.licensed.addendum"]
+
+        def setUp(self):
+                pkg5unittest.SingleDepotTestCase.setUp(self, publisher="bobcat")
+                self.make_misc_files(self.misc_files)
+
+        def __try_bad_installs(self, api_obj):
+
+                self.assertRaises(api_errors.PlanExistsException,
+                    api_obj.plan_install,["foo"])
+
+                self.assertRaises(api_errors.PlanExistsException,
+                    api_obj.plan_uninstall,["foo"], False)
+                self.assertRaises(api_errors.PlanExistsException,
+                    api_obj.plan_update_all, sys.argv[0])
+                try:
+                        api_obj.plan_update_all(sys.argv[0])
+                except api_errors.PlanExistsException:
+                        pass
+                else:
+                        assert 0
+
+        def __try_bad_combinations_and_complete(self, api_obj):
+                self.__try_bad_installs(api_obj)
+
+                self.assertRaises(api_errors.PrematureExecutionException,
+                    api_obj.execute_plan)
+
+                api_obj.prepare()
+                self.__try_bad_installs(api_obj)
+
+                self.assertRaises(api_errors.AlreadyPreparedException,
+                    api_obj.prepare)
+
+                api_obj.execute_plan()
+                self.__try_bad_installs(api_obj)
+                self.assertRaises(api_errors.AlreadyPreparedException,
+                    api_obj.prepare)
+                self.assertRaises(api_errors.AlreadyExecutedException,
+                    api_obj.execute_plan)
+
+        def test_bad_orderings(self):
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.foo10)
+                self.image_create(durl, prefix="bobcat")
+
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                self.assert_(api_obj.describe() is None)
+
+                self.assertRaises(api_errors.PlanMissingException,
+                    api_obj.prepare)
+
+                api_obj.plan_install(["foo"])
+                self.__try_bad_combinations_and_complete(api_obj)
+                api_obj.reset()
+
+                self.assertRaises(api_errors.PlanMissingException,
+                    api_obj.prepare)
+
+                self.assert_(api_obj.describe() is None)
+
+                self.pkgsend_bulk(durl, self.foo12)
+                api_obj.refresh(immediate=True)
+
+                api_obj.plan_update_all(sys.argv[0])
+                self.__try_bad_combinations_and_complete(api_obj)
+                api_obj.reset()
+
+                self.assertRaises(api_errors.PlanMissingException,
+                    api_obj.prepare)
+                self.assert_(api_obj.describe() is None)
+
+                api_obj.plan_uninstall(["foo"], False)
+                self.__try_bad_combinations_and_complete(api_obj)
+                api_obj.reset()
+
+                self.assertRaises(api_errors.PlanMissingException,
+                    api_obj.prepare)
+                self.assert_(api_obj.describe() is None)
+
+        def test_reset(self):
+                """ Send empty package [email protected], install and uninstall """
+
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.foo10)
+                self.image_create(durl, prefix="bobcat")
+
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                recursive_removal = False
+
+                api_obj.plan_install(["foo"])
+                self.assert_(api_obj.describe() is not None)
+                api_obj.reset()
+                self.assert_(api_obj.describe() is None)
+                api_obj.plan_install(["foo"])
+                self.assert_(api_obj.describe() is not None)
+                api_obj.prepare()
+                api_obj.reset()
+                self.assert_(api_obj.describe() is None)
+                api_obj.plan_install(["foo"])
+                self.assert_(api_obj.describe() is not None)
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+                self.assert_(api_obj.describe() is None)
+
+                self.pkg("list")
+                self.pkg("verify")
+
+                self.pkgsend_bulk(durl, self.foo12)
+                api_obj.refresh(immediate=True)
+
+                api_obj.plan_update_all(sys.argv[0])
+                self.assert_(api_obj.describe() is not None)
+                api_obj.reset()
+                self.assert_(api_obj.describe() is None)
+                api_obj.plan_update_all(sys.argv[0])
+                self.assert_(api_obj.describe() is not None)
+                api_obj.prepare()
+                api_obj.reset()
+                self.assert_(api_obj.describe() is None)
+                api_obj.plan_update_all(sys.argv[0])
+                self.assert_(api_obj.describe() is not None)
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+                self.assert_(api_obj.describe() is None)
+
+                self.pkg("list")
+                self.pkg("verify")
+
+                api_obj.plan_uninstall(["foo"], recursive_removal)
+                self.assert_(api_obj.describe() is not None)
+                api_obj.reset()
+                self.assert_(api_obj.describe() is None)
+                api_obj.plan_uninstall(["foo"], recursive_removal)
+                self.assert_(api_obj.describe() is not None)
+                api_obj.prepare()
+                api_obj.reset()
+                self.assert_(api_obj.describe() is None)
+                api_obj.plan_uninstall(["foo"], recursive_removal)
+                self.assert_(api_obj.describe() is not None)
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+                self.assert_(api_obj.describe() is None)
+
+                self.pkg("verify")
+
+        def test_refresh_transition(self):
+                """Verify that refresh works for a v0 catalog source and that
+                if the client transitions from v0 to v1 or back that the correct
+                state information is recorded in the image catalog."""
+
+                # First create the image and get v1 catalog.
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.foo10 + self.quux10)
+                self.image_create(durl, prefix="bobcat")
+
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+                img = api_obj.img
+                kcat = img.get_catalog(img.IMG_CATALOG_KNOWN)
+                entry = [e for f, e in kcat.entries()][0]
+                states = entry["metadata"]["states"]
+                self.assert_(img.PKG_STATE_V1 in states)
+                self.assert_(img.PKG_STATE_V0 not in states)
+
+                # Next, disable v1 catalog for the depot and force a client
+                # refresh.  Only v0 state should be present.
+                self.dc.set_disable_ops(["catalog/1"])
+                self.dc.stop()
+                self.dc.start()
+                api_obj.refresh(immediate=True)
+                api_obj.reset()
+                img = api_obj.img
+
+                kcat = img.get_catalog(img.IMG_CATALOG_KNOWN)
+                entry = [e for f, e in kcat.entries()][0]
+                states = entry["metadata"]["states"]
+                self.assert_(img.PKG_STATE_V1 not in states)
+                self.assert_(img.PKG_STATE_V0 in states)
+
+                # Verify that there is no dependency information present
+                # in the known or installed catalog.
+                icat = img.get_catalog(img.IMG_CATALOG_INSTALLED)
+                for cat in kcat, icat:
+                        dpart = cat.get_part("catalog.dependency.C")
+                        dep_acts = [
+                            acts
+                            for t, entry in dpart.tuple_entries()
+                            for acts in entry.get("actions", [])
+                        ]
+                        self.assertEqual(dep_acts, [])
+
+                # Now install a package, and verify that the entries in the
+                # known catalog for installed packages exist in the installed
+                # catalog and are identical.
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+                img = api_obj.img
+
+                # Get image catalogs.
+                kcat = img.get_catalog(img.IMG_CATALOG_KNOWN)
+                icat = img.get_catalog(img.IMG_CATALOG_INSTALLED)
+
+                # Verify quux package is only in known catalog.
+                self.assertTrue("quux" in kcat.names())
+                self.assertTrue("foo" in kcat.names())
+                self.assertTrue("quux" not in icat.names())
+                self.assertTrue("foo" not in icat.names())
+
+                # Install the packages.
+                api_obj.plan_install(["[email protected]"])
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+                # Get image catalogs.
+                kcat = img.get_catalog(img.IMG_CATALOG_KNOWN)
+                icat = img.get_catalog(img.IMG_CATALOG_INSTALLED)
+
+                # Verify quux package is in both catalogs.
+                self.assertTrue("quux" in kcat.names())
+                self.assertTrue("foo" in kcat.names())
+                self.assertTrue("quux" in icat.names())
+                self.assertTrue("foo" in icat.names())
+
+                # Verify state info.
+                for cat in kcat, icat:
+                        entry = [e for f, e in cat.entries()][0]
+                        states = entry["metadata"]["states"]
+                        self.assert_(img.PKG_STATE_INSTALLED in states)
+                        self.assert_(img.PKG_STATE_V0 in states)
+
+                # Finally, transition back to v1 catalog.  This requires
+                # creating a new api object since transport will think that
+                # v1 catalogs are still unsupported.
+                self.dc.unset_disable_ops()
+                self.dc.stop()
+                self.dc.start()
+
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+                api_obj.refresh(immediate=True)
+                img = api_obj.img
+
+                # Get image catalogs.
+                kcat = img.get_catalog(img.IMG_CATALOG_KNOWN)
+                icat = img.get_catalog(img.IMG_CATALOG_INSTALLED)
+
+                # Verify quux package is in both catalogs.
+                self.assertTrue("quux" in kcat.names())
+                self.assertTrue("foo" in kcat.names())
+                self.assertTrue("quux" in icat.names())
+                self.assertTrue("foo" in icat.names())
+
+                # Verify state info.
+                for f, entry in kcat.entries():
+                        states = entry["metadata"]["states"]
+                        self.assert_(img.PKG_STATE_V1 in states)
+                        self.assert_(img.PKG_STATE_V0 not in states)
+
+                # Verify that there is dependency information present
+                # in the known and installed catalog.
+                for cat in kcat, icat:
+                        dpart = cat.get_part("catalog.dependency.C")
+                        entries = [(t, entry) for t, entry in dpart.tuple_entries()]
+                        dep_acts = [
+                            acts
+                            for t, entry in dpart.tuple_entries()
+                            for acts in entry.get("actions", [])
+                            if t[1] == "quux"
+                        ]
+                        self.assertNotEqual(dep_acts, [])
+
+                # Verify that every installed package is in known and has
+                # identical entries and that every installed package in
+                # the installed catalog is in the known catalog and has
+                # entries.
+                for src, dest in ((kcat, icat), (icat, kcat)):
+                        src_base = src.get_part("catalog.base.C",
+                            must_exist=True)
+                        self.assertNotEqual(src_base, None)
+
+                        for f, bentry in src_base.entries():
+                                states = bentry["metadata"]["states"]
+                                if img.PKG_STATE_INSTALLED not in states:
+                                        continue
+
+                                for name in src.parts:
+                                        spart = src.get_part(name,
+                                            must_exist=True)
+                                        self.assertNotEqual(spart, None)
+
+                                        dpart = dest.get_part(name,
+                                            must_exist=True)
+                                        self.assertNotEqual(dpart, None)
+
+                                        sentry = spart.get_entry(pfmri=f)
+                                        dentry = dpart.get_entry(pfmri=f)
+                                        self.assertEqual(sentry, dentry)
+
+        def test_properties(self):
+                """Verify that properties of the ImageInterface api object are
+                accessible and return expected values."""
+
+                durl = self.dc.get_depot_url()
+                self.image_create(durl, prefix="bobcat")
+
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                self.assertEqual(api_obj.root, self.img_path)
+
+        def test_publisher_apis(self):
+                """Verify that the publisher api methods work as expected.
+
+                Note that not all methods are tested here as this would be
+                redundant since other tests for the client will use those
+                methods indirectly."""
+
+                durl = self.dc.get_depot_url()
+                plist = self.pkgsend_bulk(durl, self.foo10 + self.bar10)
+                self.image_create(durl, prefix="bobcat")
+
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                # Verify that existence tests succeed.
+                self.assertTrue(api_obj.has_publisher("bobcat"))
+
+                # Verify preferred publisher prefix is returned correctly.
+                self.assertEqual(api_obj.get_preferred_publisher(), "bobcat")
+
+                # Verify that get_publisher returned the correct publisher object.
+                pub = api_obj.get_publisher(prefix="bobcat")
+                self.assertEqual(pub.prefix, "bobcat")
+
+                # Verify that not specifying matching criteria for get_publisher
+                # raises a UnknownPublisher exception.
+                self.assertRaises(api_errors.UnknownPublisher,
+                    api_obj.get_publisher, "zuul")
+                self.assertRaises(api_errors.UnknownPublisher,
+                    api_obj.get_publisher)
+
+                # Verify that publisher objects returned from get_publishers
+                # match those returned by get_publisher.
+                pubs = api_obj.get_publishers()
+                self.assertEqual(pub.prefix, pubs[0].prefix)
+                self.assertEqual(id(pub), id(pubs[0]))
+
+                # Verify that duplicate actually creates duplicates.
+                cpub = api_obj.get_publisher(prefix="bobcat", duplicate=True)
+                self.assertNotEqual(id(pub), id(cpub))
+
+                # Now modify publisher information and update.
+                cpub.alias = "cat"
+                repo = cpub.selected_repository
+                repo.name = "source"
+                repo.description = "xkcd.net/325"
+                repo.legal_uris = ["http://xkcd.com/license.html"]
+                repo.refresh_seconds = 43200
+                repo.registered = False
+                api_obj.update_publisher(cpub)
+
+                # Verify that the update happened.
+                pub = api_obj.get_publisher(prefix="bobcat")
+                self.assertEqual(pub.alias, "cat")
+                repo = pub.selected_repository
+                self.assertEqual(repo.name, "source")
+                self.assertEqual(repo.description, "xkcd.net/325")
+                self.assertEqual(repo.legal_uris[0],
+                    "http://xkcd.com/license.html")
+                self.assertEqual(repo.refresh_seconds, 43200)
+                self.assertEqual(repo.registered, False)
+
+                # Verify that duplicates match their original.
+                cpub = api_obj.get_publisher(alias=pub.alias, duplicate=True)
+                for p in ("alias", "prefix", "meta_root"):
+                        self.assertEqual(getattr(pub, p), getattr(cpub, p))
+
+                for p in ("collection_type", "description", "legal_uris",
+                    "mirrors", "name", "origins", "refresh_seconds",
+                    "registered", "registration_uri", "related_uris",
+                    "sort_policy"):
+                        srepo = pub.selected_repository
+                        crepo = cpub.selected_repository
+                        self.assertEqual(getattr(srepo, p), getattr(crepo, p))
+                cpub = None
+
+                cpubs = api_obj.get_publishers(duplicate=True)
+                self.assertNotEqual(id(pub), id(cpubs[0]))
+                cpubs = None
+
+                # Verify that publisher_last_update_time returns a value.
+                self.assertTrue(
+                    api_obj.get_publisher_last_update_time("bobcat"))
+
+                # Verify that p5i export and parse works as expected.
+
+                # Ensure that PackageInfo, PkgFmri, and strings are all
+                # supported properly.
+
+                # Strip timestamp information so that comparison with
+                # pre-generated test data will succeed.
+                ffoo = fmri.PkgFmri(plist[0])
+                sfoo = str(ffoo).replace(":%s" % ffoo.version.timestr, "")
+                ffoo = fmri.PkgFmri(sfoo)
+                sfoo = ffoo.get_fmri(anarchy=True)
+
+                fbar = fmri.PkgFmri(plist[1])
+                sbar = str(fbar).replace(":%s" % fbar.version.timestr, "")
+                fbar = fmri.PkgFmri(sbar)
+                sbar = fbar.get_fmri(anarchy=True)
+
+                # Build a simple list of packages.
+                pnames = {
+                    "bobcat": (api.PackageInfo(ffoo),),
+                    "": [fbar, "baz"],
+                }
+
+                # Dump the p5i data.
+                fobj = cStringIO.StringIO()
+                api_obj.write_p5i(fobj, pkg_names=pnames, pubs=[pub])
+
+                # Verify that output matches expected output.
+                fobj.seek(0)
+                output = fobj.read()
+                self.assertEqual(output, self.p5i_bobcat)
+
+                def validate_results(results):
+                        # First result should be 'bobcat' publisher and its
+                        # pkg_names.
+                        pub, pkg_names = results[0]
+
+                        self.assertEqual(pub.prefix, "bobcat")
+                        self.assertEqual(pub.alias, "cat")
+                        repo = pub.selected_repository
+                        self.assertEqual(repo.name, "source")
+                        self.assertEqual(repo.description, "xkcd.net/325")
+                        self.assertEqual(repo.legal_uris[0],
+                            "http://xkcd.com/license.html")
+                        self.assertEqual(repo.refresh_seconds, 43200)
+                        self.assertEqual(pkg_names, [sfoo])
+
+                        # Last result should be no publisher and a list of
+                        # pkg_names.
+                        pub, pkg_names = results[1]
+                        self.assertEqual(pub, None)
+                        self.assertEqual(pkg_names, [sbar, "baz"])
+
+                # Verify that parse returns the expected object and information
+                # when provided a fileobj.
+                fobj.seek(0)
+                validate_results(api_obj.parse_p5i(fileobj=fobj))
+
+                # Verify that an add of the parsed object works (the name has to
+                # be changed to prevent a duplicate error here).
+                fobj.seek(0)
+                results = api_obj.parse_p5i(fileobj=fobj)
+                pub, pkg_names = results[0]
+
+                pub.prefix = "p5icat"
+                pub.alias = "copycat"
+                api_obj.add_publisher(pub, refresh_allowed=False)
+
+                # Now verify that we can retrieve the added publisher.
+                api_obj.get_publisher(prefix=pub.prefix)
+                cpub = api_obj.get_publisher(alias=pub.alias, duplicate=True)
+
+                # Now update the publisher and set it to disabled, to verify
+                # that api functions still work as expected.
+                cpub.disabled = True
+                api_obj.update_publisher(cpub)
+
+                cpub = api_obj.get_publisher(alias=cpub.alias, duplicate=True)
+                self.assertTrue(cpub.disabled)
+
+                self.assertTrue(api_obj.has_publisher(prefix=cpub.prefix))
+
+                # Now attempt to update the disabled publisher.
+                cpub = api_obj.get_publisher(alias=cpub.alias, duplicate=True)
+                cpub.alias = "copycopycat"
+                api_obj.update_publisher(cpub)
+                cpub = None
+
+                # Verify that parse returns the expected object and information
+                # when provided a file path.
+                fobj.seek(0)
+                (fd1, path1) = tempfile.mkstemp(dir=self.test_root)
+                os.write(fd1, fobj.read())
+                validate_results(api_obj.parse_p5i(location=path1))
+
+                # Verify that parse returns the expected object and information
+                # when provided a file URI.
+                validate_results(api_obj.parse_p5i(location="file://" + path1))
+                fobj.close()
+                fobj = None
+
+                # Verify that appropriate exceptions are raised for p5i
+                # information that can't be retrieved (doesn't exist).
+                nefpath = os.path.join(self.test_root, "non-existent")
+                self.assertRaises(api_errors.RetrievalError,
+                    api_obj.parse_p5i, location="file://%s" % nefpath)
+
+                self.assertRaises(api_errors.RetrievalError,
+                    api_obj.parse_p5i, location=nefpath)
+
+                # Verify that appropriate exceptions are raised for invalid
+                # p5i information.
+                lcpath = os.path.join(self.test_root, "libc.so.1")
+                self.assertRaises(api_errors.InvalidP5IFile, api_obj.parse_p5i,
+                    location="file://%s" % lcpath)
+
+                self.assertRaises(api_errors.InvalidP5IFile, api_obj.parse_p5i,
+                    location=lcpath)
+
+        def test_license(self):
+                """ Send various packages and then verify that install and
+                update operations will raise the correct exceptions or
+                enforce the requirements of the license actions within. """
+
+                durl = self.dc.get_depot_url()
+                plist = self.pkgsend_bulk(durl, self.licensed10 + \
+                    self.licensed12 + self.licensed13 + self.bar10 + self.baz10)
+                self.image_create(durl, prefix="bobcat")
+
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                # First, test the basic install case to see if expected license
+                # data is returned.
+                api_obj.plan_install(["[email protected]"])
+
+                def lic_sort(a, b):
+                        adest = a[2]
+                        bdest = b[2]
+                        return cmp(adest.license, bdest.license)
+
+                plan = api_obj.describe()
+                lics = sorted(plan.get_licenses(), cmp=lic_sort)
+
+                # Expect one license action for each package: "licensed", and
+                # its dependency "baz".
+                self.assertEqual(len(lics), 2)
+
+                # Now verify license entry for "[email protected]" and "[email protected]".
+                for i, p in enumerate([plist[4], plist[0]]):
+                        pfmri = fmri.PkgFmri(p)
+                        dest_fmri, src, dest, accepted, displayed = lics[i]
+
+                        # Expect license information to be for this package.
+                        self.assertEqual(pfmri, dest_fmri)
+
+                        # This is an install, not an update, so there should be
+                        # no src.
+                        self.assertEqual(src, None)
+
+                        # dest should be a LicenseInfo object.
+                        self.assertEqual(type(dest), api.LicenseInfo)
+
+                        # Verify the identity of the LicenseInfo objects.
+                        self.assertEqual(dest.license,
+                            "copyright.%s" % pfmri.pkg_name)
+
+                        # The license hasn't been accepted yet.
+                        self.assertEqual(accepted, False)
+
+                        # The license hasn't beend displayed yet.
+                        self.assertEqual(displayed, False)
+
+                        # The license action doesn't require acceptance.
+                        self.assertEqual(dest.must_accept, False)
+
+                        # The license action doesn't require display.
+                        self.assertEqual(dest.must_display, False)
+
+                        # Verify license text.
+                        text = dest.license
+                        self.assertEqual(dest.get_text(), text)
+
+                # Install the packages.
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+                # Next, check that an upgrade produces expected license data.
+                api_obj.plan_install(["[email protected]"])
+
+                plan = api_obj.describe()
+                lics = sorted(plan.get_licenses(), cmp=lic_sort)
+
+                # Expect two license actions, both of which should be for the
+                # [email protected] package.
+                self.assertEqual(len(lics), 2)
+
+                # Now verify license entries for "[email protected]".
+                pfmri = fmri.PkgFmri(plist[1])
+                for dest_fmri, src, dest, accepted, displayed in lics:
+                        # License information should only be for "[email protected]".
+                        self.assertEqual(pfmri, dest_fmri)
+
+                        must_accept = False
+                        must_display = False
+                        if dest.license.startswith("copyright"):
+                                # This is an an update, so src should be a
+                                # LicenseInfo object.
+                                self.assertEqual(type(src), api.LicenseInfo)
+
+                                # In this version, copyright must be displayed
+                                # for dest.
+                                must_display = True
+
+                        # dest should be a LicenseInfo object.
+                        self.assertEqual(type(dest), api.LicenseInfo)
+
+                        # Verify LicenseInfo attributes.
+                        self.assertEqual(accepted, False)
+                        self.assertEqual(displayed, False)
+                        self.assertEqual(dest.must_accept, must_accept)
+                        self.assertEqual(dest.must_display, must_display)
+
+                        # Verify license text.
+                        text = dest.license
+                        self.assertEqual(dest.get_text(), text)
+
+                # Attempt to prepare plan; this should raise a license
+                # exception.
+                self.assertRaises(api_errors.PlanLicenseErrors,
+                    api_obj.prepare)
+
+                # Plan will have to be re-created first before continuing.
+                api_obj.reset()
+                api_obj.plan_install(["[email protected]"])
+                plan = api_obj.describe()
+
+                # Set the copyright as having been displayed.
+                api_obj.set_plan_license_status(pfmri, "copyright.licensed",
+                    displayed=True)
+                lics = sorted(plan.get_licenses(pfmri=pfmri), cmp=lic_sort)
+
+                # Verify displayed was updated and accepted remains False.
+                dest_fmri, src, dest, accepted, displayed = lics[0]
+                self.assertEqual(src.license, "copyright.licensed")
+                self.assertEqual(accepted, False)
+                self.assertEqual(displayed, True)
+
+                # Prepare should succeed this time; so execute afterwards.
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+                # Next, check that an image-update produces expected license
+                # data.
+                api_obj.plan_update_all(sys.argv[0])
+
+                plan = api_obj.describe()
+                lics = sorted(plan.get_licenses(), cmp=lic_sort)
+
+                # Expect two license actions, both of which should be for the
+                # [email protected] package.
+                self.assertEqual(len(lics), 2)
+
+                # Now verify license entries for "[email protected]".
+                pfmri = fmri.PkgFmri(plist[2])
+                for dest_fmri, src, dest, accepted, displayed in lics:
+                        # License information should only be for "[email protected]".
+                        self.assertEqual(pfmri, dest_fmri)
+
+                        must_accept = False
+                        must_display = False
+
+                        # This is an an update, so src should be a LicenseInfo
+                        # object.
+                        self.assertEqual(type(src), api.LicenseInfo)
+
+                        if dest.license.startswith("copyright."):
+                                # copyright must be displayed for dest.
+                                must_display = True
+                        elif dest.license.startswith("license."):
+                                # license must be accepted for dest.
+                                must_accept = True
+
+                        # dest should be a LicenseInfo object.
+                        self.assertEqual(type(dest), api.LicenseInfo)
+
+                        # Verify LicenseInfo attributes.
+                        self.assertEqual(accepted, False)
+                        self.assertEqual(displayed, False)
+                        self.assertEqual(dest.must_accept, must_accept)
+                        self.assertEqual(dest.must_display, must_display)
+
+                        # Verify license text.
+                        text = dest.license
+                        self.assertEqual(dest.get_text(), text)
+
+                # Attempt to prepare plan; this should raise a license
+                # exception.
+                self.assertRaises(api_errors.PlanLicenseErrors,
+                    api_obj.prepare)
+
+                # Plan will have to be re-created first before continuing.
+                api_obj.reset()
+                api_obj.plan_update_all(sys.argv[0])
+                plan = api_obj.describe()
+                lics = sorted(plan.get_licenses(pfmri=pfmri), cmp=lic_sort)
+
+                # Set the license status of only one license.
+                api_obj.set_plan_license_status(pfmri, "license.licensed",
+                    accepted=True)
+                lics = sorted(plan.get_licenses(pfmri=pfmri), cmp=lic_sort)
+
+                # Verify only license.licensed was updated.
+                dest_fmri, src, dest, accepted, displayed = lics[0]
+                self.assertEqual(src.license, "copyright.licensed")
+                self.assertEqual(accepted, False)
+                self.assertEqual(displayed, False)
+
+                dest_fmri, src, dest, accepted, displayed = lics[1]
+                self.assertEqual(src.license, "license.licensed")
+                self.assertEqual(accepted, True)
+                self.assertEqual(displayed, False)
+
+                # Attempt to prepare plan; this should raise a license
+                # exception since the copyright wasn't displayed.
+                self.assertRaises(api_errors.PlanLicenseErrors,
+                    api_obj.prepare)
+
+                # Plan will have to be re-created first before continuing.
+                api_obj.reset()
+                api_obj.plan_update_all(sys.argv[0])
+                plan = api_obj.describe()
+
+                # Set the correct license status for all licenses.
+                api_obj.set_plan_license_status(pfmri, "copyright.licensed",
+                    displayed=True)
+                api_obj.set_plan_license_status(pfmri, "license.licensed",
+                    accepted=True)
+                lics = sorted(plan.get_licenses(pfmri=pfmri), cmp=lic_sort)
+
+                # Verify status for both license actions.
+                dest_fmri, src, dest, accepted, displayed = lics[0]
+                self.assertEqual(src.license, "copyright.licensed")
+                self.assertEqual(accepted, False)
+                self.assertEqual(displayed, True)
+
+                dest_fmri, src, dest, accepted, displayed = lics[1]
+                self.assertEqual(src.license, "license.licensed")
+                self.assertEqual(accepted, True)
+                self.assertEqual(displayed, False)
+
+                # Prepare should succeed this time; so execute afterwards.
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+                # Finally, verify that an uninstall won't trigger license
+                # errors as acceptance should never be applied to it.
+                api_obj.plan_uninstall(["*"], False)
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+
+
+if __name__ == "__main__":
+        unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/api/t_api_info.py	Sat Jan 30 01:07:14 2010 -0800
@@ -0,0 +1,310 @@
+#!/usr/bin/python
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+import testutils
+if __name__ == "__main__":
+	testutils.setup_environment("../../../proto")
+import pkg5unittest
+
+import unittest
+import os
+import re
+import shutil
+import difflib
+import time
+
+import pkg.client.api as api
+import pkg.client.api_errors as api_errors
+import pkg.client.progress as progress
+
+API_VERSION = 31
+PKG_CLIENT_NAME = "pkg"
+
+class TestApiInfo(pkg5unittest.SingleDepotTestCase):
+        # Only start/stop the depot once (instead of for every test)
+        persistent_setup = True
+
+        def test_info_local_remote(self):
+                self.image_create(self.dc.get_depot_url())
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                self.assertRaises(api_errors.NoPackagesInstalledException,
+                    api_obj.info, [], True, api.PackageInfo.ALL_OPTIONS -
+                    (frozenset([api.PackageInfo.LICENSES]) |
+                    api.PackageInfo.ACTION_OPTIONS))
+
+                self.assertRaises(api_errors.UnrecognizedOptionsToInfo,
+                    api_obj.info, [], True, set([-1]))
+                self.assertRaises(api_errors.UnrecognizedOptionsToInfo,
+                    api_obj.info, [], True, set('a'))
+
+                misc_files = ["tmp/copyright1", "tmp/example_file"]
+                self.make_misc_files(misc_files)
+
+                pkg1 = """
+                    open [email protected],5.11-0
+                    add dir mode=0755 owner=root group=bin path=/bin
+                    add set name=info.classification value="org.opensolaris.category.2008:Applications/Sound and Video"
+                    close
+                """
+
+                pkg2 = """
+                    open [email protected],5.11-0
+                    add dir mode=0755 owner=root group=bin path=/bin
+                    add set name=info.classification value=org.opensolaris.category.2008:System/Security/Foo/bar/Baz
+                    close
+                """
+
+                pkg3 = """
+                    open [email protected],5.11-0
+                    close
+                """
+
+                pkg4 = """
+                    open [email protected],5.11-0
+                    add depend fmri=pkg:/[email protected] type=require
+                    add dir mode=0755 owner=root group=bin path=/bin
+                    add file tmp/example_file mode=0555 owner=root group=bin path=/bin/example_path
+                    add hardlink path=/bin/example_path2 target=/bin/example_path
+                    add link path=/bin/example_path3 target=/bin/example_path
+                    add set description='FOOO bAr O OO OOO'
+                    add license tmp/copyright1 license=copyright
+                    add set name=info.classification value=org.opensolaris.category.2008:System/Security/Foo/bar/Baz
+                    add set pkg.description="DESCRIPTION 1"
+                    close """
+
+                pkg5 = """
+                    open [email protected],5.11-0
+                    add dir mode=0755 owner=root group=bin path=/bin
+                    add set pkg.summary='SUMMARY: Example Package 5'
+                    add set pkg.description="DESCRIPTION 2"
+                    close
+                """
+
+                pkg6 = """
+                    open [email protected],5.11-0
+                    add dir mode=0755 owner=root group=bin path=/bin
+                    add set description='DESCRIPTION: Example Package 6'
+                    add set pkg.summary='SUMMARY: Example Package 6'
+                    add set pkg.description="DESCRIPTION 3"
+                    close
+                """
+
+                durl = self.dc.get_depot_url()
+
+                self.pkgsend_bulk(durl, pkg1)
+                self.pkgsend_bulk(durl, pkg2)
+                self.pkgsend_bulk(durl, pkg4)
+                self.pkgsend_bulk(durl, pkg5)
+                self.pkgsend_bulk(durl, pkg6)
+
+                self.image_create(durl)
+
+                local = True
+                get_license = False
+
+                info_needed = api.PackageInfo.ALL_OPTIONS - \
+                    (api.PackageInfo.ACTION_OPTIONS |
+                    frozenset([api.PackageInfo.LICENSES]))
+                
+                ret = api_obj.info(["jade"], local, info_needed)
+                self.assert_(not ret[api.ImageInterface.INFO_FOUND])
+                self.assert_(len(ret[api.ImageInterface.INFO_MISSING]) == 1)
+                
+                api_obj.plan_install(["jade"])
+                api_obj.prepare()
+                api_obj.execute_plan()
+
+                self.pkg("verify -v")
+                
+                ret = api_obj.info(["jade", "turquoise", "emerald"],
+                    local, info_needed)
+                pis = ret[api.ImageInterface.INFO_FOUND]
+                notfound = ret[api.ImageInterface.INFO_MISSING]
+                illegals = ret[api.ImageInterface.INFO_ILLEGALS]
+                self.assert_(len(pis) == 1)
+                self.assert_(api.PackageInfo.INSTALLED in pis[0].states)
+                self.assert_(pis[0].pkg_stem == 'jade')
+                self.assert_(len(notfound) == 2)
+                self.assert_(len(illegals) == 0)
+                self.assert_(len(pis[0].category_info_list) == 1)
+
+                ret = api_obj.info(["j*"], local, info_needed)
+                pis = ret[api.ImageInterface.INFO_FOUND]
+                notfound = ret[api.ImageInterface.INFO_MISSING]
+                illegals = ret[api.ImageInterface.INFO_ILLEGALS]
+                self.assert_(len(pis))
+
+                ret = api_obj.info(["*a*"], local, info_needed)
+                pis = ret[api.ImageInterface.INFO_FOUND]
+                notfound = ret[api.ImageInterface.INFO_MISSING]
+                illegals = ret[api.ImageInterface.INFO_ILLEGALS]
+                self.assert_(len(pis))
+
+                local = False
+
+                ret = api_obj.info(["jade"], local, info_needed)
+                pis = ret[api.ImageInterface.INFO_FOUND]
+                notfound = ret[api.ImageInterface.INFO_MISSING]
+                illegals = ret[api.ImageInterface.INFO_ILLEGALS]
+                self.assert_(len(pis) == 1)
+                self.assert_(api.PackageInfo.INSTALLED in pis[0].states)
+                self.assert_(len(pis[0].category_info_list) == 1)
+
+                ret = api_obj.info(["turquoise"], local, info_needed)
+                pis = ret[api.ImageInterface.INFO_FOUND]
+                notfound = ret[api.ImageInterface.INFO_MISSING]
+                illegals = ret[api.ImageInterface.INFO_ILLEGALS]
+                self.assert_(len(pis) == 1)
+                self.assert_(api.PackageInfo.INSTALLED not in pis[0].states)
+                self.assert_(len(pis[0].category_info_list) == 1)
+
+                ret = api_obj.info(["example_pkg"], local,
+                    api.PackageInfo.ALL_OPTIONS)
+                pis = ret[api.ImageInterface.INFO_FOUND]
+                self.assert_(len(pis) == 1)
+                res = pis[0]
+                self.assert_(api.PackageInfo.INSTALLED not in res.states)
+                self.assert_(len(res.category_info_list) == 1)
+
+                self.assert_(res.pkg_stem is not None)
+                self.assert_(res.summary is not None)
+                self.assert_(res.publisher is not None)
+                self.assert_(res.preferred_publisher is not None)
+                self.assert_(res.version is not None)
+                self.assert_(res.build_release is not None)
+                self.assert_(res.branch is not None)
+                self.assert_(res.packaging_date is not None)
+                total_size = 0
+                for p in misc_files:
+                        total_size += \
+                            os.stat(os.path.join(self.test_root, p)).st_size
+                self.assertEqual(res.size, total_size)
+                self.assert_(res.licenses is not None)
+                self.assert_(res.links is not None)
+                self.assert_(res.hardlinks is not None)
+                self.assert_(res.files is not None)
+                self.assert_(res.dirs is not None)
+                self.assert_(res.dependencies is not None)
+                # A test for bug 8868 which ensures the pkg.description field
+                # is as exected.
+                self.assertEqual(res.description, "DESCRIPTION 1")
+
+                ret = api_obj.info(["emerald"], local, info_needed)
+                pis = ret[api.ImageInterface.INFO_FOUND]
+                notfound = ret[api.ImageInterface.INFO_MISSING]
+                illegals = ret[api.ImageInterface.INFO_ILLEGALS]
+                self.assert_(len(notfound) == 1)
+
+                local = True
+                get_license = False
+                get_action_info = True
+
+                info_needed = api.PackageInfo.ALL_OPTIONS - \
+                    frozenset([api.PackageInfo.LICENSES])
+                
+                ret = api_obj.info(["jade"],
+                    local, info_needed)
+                pis = ret[api.ImageInterface.INFO_FOUND]
+                notfound = ret[api.ImageInterface.INFO_MISSING]
+                illegals = ret[api.ImageInterface.INFO_ILLEGALS]
+                self.assert_(len(pis) == 1)
+                self.assert_(len(pis[0].dirs) == 1)
+                
+                ret = api_obj.info(["jade"], local, set())
+                pis = ret[api.ImageInterface.INFO_FOUND]
+                self.assert_(len(pis) == 1)
+                res = pis[0]
+                self.assert_(res.pkg_stem is None)
+                self.assert_(res.summary is None)
+                self.assertEqual(res.category_info_list, [])
+                self.assertEqual(res.states, set())
+                self.assert_(res.publisher is None)
+                self.assert_(res.preferred_publisher is None)
+                self.assert_(res.version is None)
+                self.assert_(res.build_release is None)
+                self.assert_(res.branch is None)
+                self.assert_(res.packaging_date is None)
+                self.assert_(res.size is None)
+                self.assert_(res.licenses is None)
+                self.assert_(res.links is None)
+                self.assert_(res.hardlinks is None)
+                self.assert_(res.files is None)
+                self.assert_(res.dirs is None)
+                self.assert_(res.dependencies is None)
+                
+                local = False
+
+                ret = api_obj.info(["jade"],
+                    local, info_needed)
+                pis = ret[api.ImageInterface.INFO_FOUND]
+                notfound = ret[api.ImageInterface.INFO_MISSING]
+                illegals = ret[api.ImageInterface.INFO_ILLEGALS]
+                self.assert_(len(pis) == 1)
+                self.assert_(len(pis[0].dirs) == 1)
+
+                self.assertRaises(api_errors.UnrecognizedOptionsToInfo,
+                    api_obj.info, ["jade"], local, set([-1]))
+                self.assertRaises(api_errors.UnrecognizedOptionsToInfo,
+                    api_obj.info, ["jade"], local, set('a'))
+
+                self.assertRaises(api_errors.UnrecognizedOptionsToInfo,
+                    api_obj.info, ["foo"], local, set([-1]))
+                self.assertRaises(api_errors.UnrecognizedOptionsToInfo,
+                    api_obj.info, ["foo"], local, set('a'))
+
+                # Test if the package summary has been correctly set if just
+                # a pkg.summary had been set in the package.
+                # See bug #4395 and bug #8829 for more details.
+                ret = api_obj.info(["example_pkg5"], local,
+                    api.PackageInfo.ALL_OPTIONS)
+                pis = ret[api.ImageInterface.INFO_FOUND]
+                self.assert_(len(pis) == 1)
+                res = pis[0]
+                self.assert_(res.summary == "SUMMARY: Example Package 5")
+                # A test for bug 8868 which ensures the pkg.description field
+                # is as exected.
+                self.assertEqual(res.description, "DESCRIPTION 2")
+
+                # Test if the package summary has been correctly set if both
+                # a pkg.summary and a description had been set in the package.
+                # See bug #4395 and bug #8829 for more details.
+                ret = api_obj.info(["example_pkg6"], local,
+                    api.PackageInfo.ALL_OPTIONS)
+                pis = ret[api.ImageInterface.INFO_FOUND]
+                self.assert_(len(pis) == 1)
+                res = pis[0]
+                self.assert_(res.summary == "SUMMARY: Example Package 6")
+                # A test for bug 8868 which ensures the pkg.description field
+                # is as exected.
+                self.assertEqual(res.description, "DESCRIPTION 3")
+
+
+if __name__ == "__main__":
+        unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/api/t_api_list.py	Sat Jan 30 01:07:14 2010 -0800
@@ -0,0 +1,1388 @@
+#!/usr/bin/python
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
+import calendar
+import difflib
+import os
+import platform
+import pprint
+import re
+import shutil
+import simplejson as json
+import unittest
+
+import pkg.client.api as api
+import pkg.client.api_errors as api_errors
+import pkg.client.progress as progress
+import pkg.fmri as fmri
+import pkg.misc as misc
+import pkg.version as version
+
+API_VERSION = 31
+PKG_CLIENT_NAME = "pkg"
+
+class TestApiList(pkg5unittest.ManyDepotTestCase):
+        # Only start/stop the depot once (instead of for every test)
+        persistent_setup = True
+
+        packages = [
+            "apple@1,5.11-0",
+            "[email protected],5.11-0",
+            "[email protected],5.11-0",
+            "[email protected],5.11-0",
+            "[email protected],5.11-0",
+            "[email protected],5.11-0",
+            "[email protected],5.11-1",
+            "bat/[email protected],5.11-0",
+            "[email protected]",
+            "[email protected]",
+            "[email protected]",
+            "[email protected]",
+            "[email protected]",
+            "[email protected]",
+            "[email protected]",
+            "[email protected]",
+            "[email protected]",
+            "[email protected]",
+            "[email protected]",
+        ]
+
+        @staticmethod
+        def __tuple_order(a, b):
+                apub, astem, aver = a
+                bpub, bstem, bver = b
+                rval = cmp(astem, bstem)
+                if rval != 0:
+                        return rval
+                rval = cmp(apub, bpub)
+                if rval != 0:
+                        return rval
+                aver = version.Version(aver, "5.11")
+                bver = version.Version(bver, "5.11")
+                return cmp(aver, bver) * -1
+
+        @staticmethod
+        def __get_pkg_arch(stem, ver):
+                # Attempt to determine current arch and opposite arch.
+                # This is so that the tests will see the set of packages
+                # they expect to be omitted.
+                parch = platform.processor()
+                if parch == "i386":
+                        oparch = "sparc"
+                else:
+                        oparch = "i386"
+
+                if stem == "apple":
+                        return [parch]
+                elif stem in ("entire", "bat/bar", "obsolete"):
+                        return
+                elif stem in ("corge", "grault", "qux", "quux"):
+                        return [parch, oparch]
+                return [oparch]
+
+        @staticmethod
+        def __get_pkg_cats(stem, ver):
+                if stem == "apple":
+                        return [
+                            "fruit",
+                            "org.opensolaris.category.2008:"
+                            "Applications/Sound and Video"
+                        ]
+                elif stem == "bat/bar":
+                        return [
+                            "food",
+                            "org.opensolaris.category.2008:"
+                            "Development/Python"
+                        ]
+                return []
+
+        @staticmethod
+        def __get_pkg_summ_desc(stem, ver):
+                summ = "Summ. is %s %s" % (stem, ver)
+                desc = "Desc. is %s %s" % (stem, ver)
+                return summ, desc
+
+        def __get_pkg_states(self, pub, stem, ver, installed=False):
+                states = [api.PackageInfo.KNOWN]
+                if installed:
+                        states.append(api.PackageInfo.INSTALLED)
+                if stem == "apple":
+                        # Compare with newest version entry for this stem.
+                        if ver != str(self.dlist1[6].version):
+                                states.append(api.PackageInfo.UPGRADABLE)
+                elif stem == "baz":
+                        # Compare with newest version entry for this stem.
+                        if ver != str(self.dlist1[10].version):
+                                states.append(api.PackageInfo.UPGRADABLE)
+                elif stem == "corge":
+                        # Compare with newest version entry for this stem.
+                        nver = str(self.dlist1[12].version)
+                        if ver != nver:
+                                states.append(api.PackageInfo.UPGRADABLE)
+                        if ver == nver:
+                                states.append(api.PackageInfo.RENAMED)
+                elif stem == "obsolete":
+                        states.append(api.PackageInfo.OBSOLETE)
+                elif stem == "qux":
+                        # Compare with newest version entry for this stem.
+                        nver = str(self.dlist1[18].version)
+                        if ver != nver:
+                                states.append(api.PackageInfo.UPGRADABLE)
+                        if ver == nver:
+                                states.append(api.PackageInfo.RENAMED)
+                return frozenset(states)
+
+        def __get_pub_entry(self, pub, idx, name, ver):
+                if pub == "test1":
+                        l = self.dlist1
+                else:
+                        l = self.dlist2
+
+                f = l[idx]
+                self.assertEqual(f.pkg_name, name)
+                v = str(f.version)
+                try:
+                        self.assertTrue(v.startswith(ver + ":"))
+                except AssertionError:
+                        self.debug("\n%s does not start with %s:" % (v, ver))
+                        raise
+                return f, v
+
+        def __get_exp_pub_entry(self, pub, idx, name, ver, installed=False):
+                f, v = self.__get_pub_entry(pub, idx, name, ver)
+                return self.__get_expected_entry(pub, name, v,
+                    installed=installed)
+
+        def setUp(self):
+                pkg5unittest.ManyDepotTestCase.setUp(self, ["test1", "test2",
+                    "test3"])
+
+                pkg_data = ""
+                for p in self.packages:
+                        pkg_data += p
+                        stem, ver = p.split("@")
+
+                        # XXX version should not require 5.11
+                        sver = version.Version(ver, "5.11")
+                        sver = str(sver).split(":", 1)[0]
+
+                        summ, desc = self.__get_pkg_summ_desc(stem, sver)
+                        pkg_data += """
+open %(stem)s@%(ver)s
+add set name=pkg.summary value="%(summ)s"
+add set name=pkg.description value="%(desc)s"
+""" % { "stem": stem, "ver": ver, "summ": summ, "desc": desc }
+
+                        cats = self.__get_pkg_cats(stem, sver)
+                        if cats:
+                                pkg_data += "add set name=info.classification"
+                                for cat in cats:
+                                        pkg_data += ' value="%s"' % cat
+                                pkg_data += "\n"
+
+                        arch = self.__get_pkg_arch(stem, sver)
+                        if arch:
+                                adata = "value="
+                                adata += " value=".join(arch)
+                                pkg_data += "add set name=variant.arch " \
+                                    "%s\n" % adata
+
+                        if stem == "corge" and sver.startswith("1.0"):
+                                pkg_data += "add set name=pkg.renamed " \
+                                    "value=true\n"
+                                pkg_data += "add depend type=require " \
+                                    "fmri=grault\n"
+                        elif stem == "entire":
+                                pkg_data += "add depend type=incorporate " \
+                                    "[email protected]\n"
+                                pkg_data += "add depend type=incorporate " \
+                                    "[email protected]\n"
+                                pkg_data += "add depend type=incorporate " \
+                                    "[email protected]\n"
+                        elif stem == "obsolete":
+                                pkg_data += "add set name=pkg.obsolete " \
+                                    "value=true\n"
+                        elif stem == "qux" and sver.startswith("1.0"):
+                                pkg_data += "add set name=pkg.renamed " \
+                                    "value=true\n"
+                                pkg_data += "add depend type=require " \
+                                    "fmri=quux\n"
+
+                        pkg_data += "close\n"
+
+                durl1 = self.dcs[1].get_depot_url()
+                plist = self.pkgsend_bulk(durl1, pkg_data)
+                durl2 = self.dcs[2].get_depot_url()
+
+                # Ensure that the second repo's packages have exactly the same
+                # timestamps as those in the first ... by copying the repo over.
+                self.dcs[2].stop()
+                d1dir = self.dcs[1].get_repodir()
+                d2dir = self.dcs[2].get_repodir()
+                self.copy_repository(d1dir, "test1", d2dir, "test2")
+
+                self.dlist1 = []
+                self.dlist2 = []
+                for e in plist:
+                        # Unique FMRI object is needed for each list.
+                        f = fmri.PkgFmri(str(e))
+                        self.dlist1.append(f)
+
+                        f = fmri.PkgFmri(str(e))
+                        f.set_publisher("test2")
+                        self.dlist2.append(f)
+
+                self.dlist1.sort()
+                self.dlist2.sort()
+
+                # The new repository won't have a catalog, so set the depot
+                # server to rebuild it.
+                self.dcs[2].set_rebuild()
+                self.dcs[2].start()
+                self.dcs[2].set_norebuild()
+
+                # The third repository should remain empty and not be
+                # published to.
+
+                # Next, create the image and configure publishers.
+                self.image_create(durl1, prefix="test1")
+                self.pkg("set-publisher -g " + durl2 + " test2")
+
+        def assertPrettyEqual(self, actual, expected):
+                if actual == expected:
+                        return
+
+                actual = pprint.pformat(actual, indent=2)
+                expected = pprint.pformat(expected, indent=2)
+
+                self.assertEqual(expected, actual,
+                    "Actual output differed from expected output.\n" +
+                    "\n".join(difflib.unified_diff(
+                        expected.splitlines(), actual.splitlines(),
+                        "Expected output", "Actual output", lineterm="")))
+                raise AssertionError(output)
+
+        def __get_expected_entry(self, pub, stem, ver, installed=False):
+                states = self.__get_pkg_states(pub, stem, ver,
+                    installed=installed)
+
+                sver = ver.split(":", 1)[0]
+                raw_cats = self.__get_pkg_cats(stem, sver)
+                summ, desc = self.__get_pkg_summ_desc(stem, sver)
+
+                scheme = None
+                cat = None
+                pcats = []
+                for e in raw_cats:
+                        if e and ":" in e:
+                                scheme, cat = e.split(":", 1)
+                        else:
+                                scheme = ""
+                                cat = e
+                        pcats.append((scheme, cat))
+                return ((pub, stem, ver), summ, pcats, states)
+
+        def __get_expected(self, pkg_list, cats=None, pubs=misc.EmptyI,
+            variants=False):
+                nlist = {}
+                newest = pkg_list == api.ImageInterface.LIST_NEWEST
+                if newest:
+                        # Get the newest FMRI for each unique package stem on
+                        # a per-publisher basis.
+                        for plist in (self.dlist1, self.dlist2):
+                                for f in plist:
+                                        pstem = f.get_pkg_stem()
+                                        if pstem not in nlist:
+                                                nlist[pstem] = f
+                                        elif f.version > nlist[pstem]:
+                                                nlist[pstem] = f
+                nlist = sorted(nlist.values())
+
+                expected = []
+                for plist in (self.dlist1, self.dlist2):
+                        for f in plist:
+                                pub, stem, ver = f.tuple()
+                                ver = str(f.version)
+                                if pubs and pub not in pubs:
+                                        continue
+
+                                sver = ver.split(":", 1)[0]
+                                arch = self.__get_pkg_arch(stem, sver)
+                                parch = platform.processor()
+                                if not variants and arch and parch not in arch:
+                                        continue
+
+                                if newest and f not in nlist:
+                                        continue
+
+                                t, summ, pcats, states = \
+                                    self.__get_expected_entry(pub, stem, ver)
+                                if cats is not None:
+                                        if not cats:
+                                                if pcats:
+                                                        # Want packages with no
+                                                        # category.
+                                                        continue
+                                        elif not \
+                                            [sc for sc in cats if sc in pcats]:
+                                                # Doesn't match specified
+                                                # categories.
+                                                continue
+
+                                expected.append((t, summ, pcats, states))
+
+                def pkg_list_order(a, b):
+                        at = a[0]
+                        bt = b[0]
+                        return self.__tuple_order(at, bt)
+                expected.sort(cmp=pkg_list_order)
+                return expected
+
+        def __get_returned(self, pkg_list, api_obj=None, cats=None,
+            num_expected=None, patterns=misc.EmptyI,
+            pubs=misc.EmptyI, variants=False):
+
+                if not api_obj:
+                        progresstracker = progress.NullProgressTracker()
+                        api_obj = api.ImageInterface(self.get_img_path(),
+                            API_VERSION, progresstracker, lambda x: False,
+                            PKG_CLIENT_NAME)
+
+                # Set of states exposed by the API.
+                exp_states = set([api.PackageInfo.FROZEN,
+                    api.PackageInfo.INCORPORATED, api.PackageInfo.EXCLUDES,
+                    api.PackageInfo.KNOWN, api.PackageInfo.INSTALLED,
+                    api.PackageInfo.UPGRADABLE, api.PackageInfo.OBSOLETE,
+                    api.PackageInfo.RENAMED])
+
+                # Get ordered list of all packages.
+                returned = []
+                for entry in api_obj.get_pkg_list(pkg_list, cats=cats,
+                    patterns=patterns, pubs=pubs, variants=variants):
+                        (pub, stem, ver), summ, pcats, raw_states = entry
+
+                        sver = ver.split(":", 1)[0]
+
+                        # Eliminate states not exposed by the api.
+                        states = raw_states.intersection(exp_states)
+                        returned.append(((pub, stem, ver), summ, pcats, states))
+                return returned
+
+        def __test_list(self, pkg_list, api_obj=None,
+            cats=None, num_expected=None, pubs=misc.EmptyI,
+            variants=False):
+
+                # Get package list.
+                returned = self.__get_returned(pkg_list, api_obj=api_obj,
+                    cats=cats, pubs=pubs, variants=variants)
+
+                # Now generate expected list.
+                expected = self.__get_expected(pkg_list, cats=cats,
+                    pubs=pubs, variants=variants)
+
+                # Compare returned and expected.
+                self.assertPrettyEqual(returned, expected)
+
+                if num_expected is not None:
+                        self.assertEqual(len(returned), num_expected)
+
+        def test_list_01_full(self):
+                """Verify the sort order and content of a full list and
+                combinations thereof."""
+
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                # First check all variants case.
+                returned = self.__get_returned(api_obj.LIST_ALL,
+                    api_obj=api_obj, variants=True)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 6, "apple",
+                        "1.2.1,5.11-1"),
+                    self.__get_exp_pub_entry("test1", 5, "apple",
+                        "1.2.1,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 4, "apple",
+                        "1.2.1,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 3, "apple",
+                        "1.2.0,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 2, "apple", "1.1,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 1, "apple", "1.0,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 0, "apple", "1,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 6, "apple",
+                        "1.2.1,5.11-1"),
+                    self.__get_exp_pub_entry("test2", 5, "apple",
+                        "1.2.1,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 4, "apple",
+                        "1.2.1,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 3, "apple",
+                        "1.2.0,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 2, "apple", "1.1,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 1, "apple", "1.0,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 0, "apple", "1,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 10, "baz", "1.3,5.11"),
+                    self.__get_exp_pub_entry("test1", 9, "baz", "1.0.1,5.11"),
+                    self.__get_exp_pub_entry("test1", 8, "baz", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 10, "baz", "1.3,5.11"),
+                    self.__get_exp_pub_entry("test2", 9, "baz", "1.0.1,5.11"),
+                    self.__get_exp_pub_entry("test2", 8, "baz", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 11, "corge", "0.9,5.11"),
+                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 11, "corge", "0.9,5.11"),
+                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 13, "entire", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 16, "quux", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 18, "qux", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 17, "qux", "0.9,5.11"),
+                    self.__get_exp_pub_entry("test2", 18, "qux", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 17, "qux", "0.9,5.11"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 38)
+
+                # Next, check no variants case (which has to be done
+                # programatically to deal with unit test running on
+                # different platforms).
+                self.__test_list(api.ImageInterface.LIST_ALL, api_obj=api_obj,
+                    num_expected=32, variants=False)
+
+        def test_list_02_newest(self):
+                """Verify the sort order and content of a list excluding
+                packages not for the current image variant, and all but
+                the newest versions of each package for each publisher."""
+
+                self.__test_list(api.ImageInterface.LIST_NEWEST,
+                    num_expected=16, variants=False)
+
+        def test_list_03_cats(self):
+                """Verify the sort order and content of a list excluding
+                packages not for the current image variant, and packages
+                that don't match the specified scheme, category
+                combinations."""
+
+                combos = [
+                    ([
+                        ("", "fruit"),
+                        ("org.opensolaris.category.2008",
+                        "Applications/Sound and Video"),
+                        ("", "food"),
+                        ("org.opensolaris.category.2008",
+                        "Development/Python")
+                    ], 16),
+                    ([
+                        ("org.opensolaris.category.2008",
+                        "Development/Python")
+                    ], 2),
+                    ([
+                        ("org.opensolaris.category.2008",
+                        "Applications/Sound and Video"),
+                        ("", "food")
+                    ], 16),
+                    ([
+                        ("", "fruit")
+                    ], 14),
+                    ([
+                        ("", "food")
+                    ], 2),
+                    ([], 16) # Only packages with no category assigned.
+                ]
+
+                for combo, expected in combos:
+                        self.__test_list(api.ImageInterface.LIST_ALL,
+                            cats=combo, num_expected=expected, variants=False)
+
+        def test_list_04_pubs(self):
+                """Verify the sort order and content of list filtered using
+                various publisher and variant combinations."""
+
+                combos = [
+                    (["test1", "test2"], 32, False),
+                    (["test1", "test2"], 38, True),
+                    (["test2"], 16, False),
+                    (["test2"], 19, True),
+                    (["test1"], 16, False),
+                    (["test1"], 19, True),
+                    (["test3"], 0, False),
+                    (["test3"], 0, True),
+                    ([], 32, False),
+                    ([], 38, True)
+                ]
+
+                for combo, expected, variants in combos:
+                        self.__test_list(api.ImageInterface.LIST_ALL,
+                            num_expected=expected, pubs=combo,
+                            variants=variants)
+
+        def test_list_05_installed(self):
+                """Verify the sort order and content of a list containing
+                only installed packages and combinations thereof."""
+
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                # Verify no installed packages case.
+                returned = self.__get_returned(api_obj.LIST_INSTALLED,
+                    api_obj=api_obj)
+                self.assertEqual(len(returned), 0)
+
+                # Test results after installing packages and only listing the
+                # installed packages.  Note that the 'obsolete' package here
+                # won't be installed since it has no dependencies.
+                af = self.__get_pub_entry("test1", 3, "apple",
+                    "1.2.0,5.11-0")[0]
+                api_obj.plan_install(["entire", af.get_fmri(), "corge",
+                    "obsolete", "qux"])
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+                # Verify the results for LIST_INSTALLED.
+                returned = self.__get_returned(api_obj.LIST_INSTALLED,
+                    api_obj=api_obj)
+                self.assertEqual(len(returned), 6)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 3, "apple",
+                        "1.2.0,5.11-0", installed=True),
+                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11",
+                        installed=True),
+                    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.assertPrettyEqual(returned, expected)
+
+                # Verify the results for LIST_INSTALLED_NEWEST.
+                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+                    api_obj=api_obj)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 3, "apple",
+                        "1.2.0,5.11-0", installed=True),
+                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "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.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 10)
+
+                # Re-test, including variants.
+                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+                    api_obj=api_obj, variants=True)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 3, "apple",
+                        "1.2.0,5.11-0", installed=True),
+                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,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", 12, "corge", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "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.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 12)
+
+                # Verify results of LIST_INSTALLED_NEWEST when not including
+                # the publisher of installed packages.
+                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+                    api_obj=api_obj, pubs=["test2"])
+
+                expected = [
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "1.0,5.11"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 2)
+
+                # Verify the results for LIST_INSTALLED_NEWEST after
+                # uninstalling 'qux'.  'qux' should not be listed as
+                # its replacement is incorporated.
+                api_obj.plan_uninstall(["qux"], False)
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+                    api_obj=api_obj)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 3, "apple",
+                        "1.2.0,5.11-0", installed=True),
+                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11",
+                        installed=True),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 9)
+
+                # Verify the results for LIST_INSTALLED_NEWEST after
+                # uninstalling 'quux' and 'qux'.
+                api_obj.plan_uninstall(["quux"], False)
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+                    api_obj=api_obj)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 3, "apple",
+                        "1.2.0,5.11-0", installed=True),
+                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 9)
+
+                # Verify the results for LIST_INSTALLED_NEWEST after
+                # all packages have been uninstalled.
+                api_obj.plan_uninstall(["entire", "corge", "apple",
+                    "grault"], False)
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+                    api_obj=api_obj)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 6, "apple",
+                        "1.2.1,5.11-1"),
+                    self.__get_exp_pub_entry("test2", 6, "apple",
+                        "1.2.1,5.11-1"),
+                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 13, "entire", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 16, "quux", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 18, "qux", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 18, "qux", "1.0,5.11"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 16)
+
+                # Re-test, including variants.
+                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+                    api_obj=api_obj, variants=True)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 6, "apple",
+                        "1.2.1,5.11-1"),
+                    self.__get_exp_pub_entry("test2", 6, "apple",
+                        "1.2.1,5.11-1"),
+                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,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", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 13, "entire",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 13, "entire", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 16, "quux", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 18, "qux", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 18, "qux", "1.0,5.11"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 18)
+
+                # 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]
+                api_obj.plan_install([af.get_fmri(), "[email protected]", "[email protected]"])
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+                # Verify the results for LIST_INSTALLED and
+                # LIST_INSTALLED_NEWEST when future versions
+                # are renamed and current versions are not
+                # incorporated.
+                returned = self.__get_returned(api_obj.LIST_INSTALLED,
+                    api_obj=api_obj)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 1, "apple", "1.0,5.11-0",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 11, "corge", "0.9,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 17, "qux", "0.9,5.11",
+                        installed=True),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 3)
+
+                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+                    api_obj=api_obj)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 1, "apple", "1.0,5.11-0",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 11, "corge", "0.9,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 13, "entire", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 17, "qux", "0.9,5.11",
+                        installed=True),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 9)
+
+                # Remove corge, install grault, retest for
+                # LIST_INSTALLED_NEWEST.  corge, grault, qux, and
+                # quux should be listed since none of them are
+                # listed in an installed incorporation.
+
+                # XXX due to bug 12898 attempting to install
+                # any more packages after this would result
+                # in quux being installed even when the
+                # requested packages do not have quux as a
+                # dependency.  As such, uninstall all packages
+                # here and then install apple, qux and grault.
+                api_obj.plan_uninstall(["*"], False)
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+                af = self.__get_pub_entry("test1", 1, "apple", "1.0,5.11-0")[0]
+                api_obj.plan_install([af.get_fmri(), "[email protected]",
+                    "pkg://test2/grault"])
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+                    api_obj=api_obj)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 1, "apple", "1.0,5.11-0",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 13, "entire", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 17, "qux", "0.9,5.11",
+                        installed=True),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 11)
+
+                # Now verify that publisher search order determines the entries
+                # that are listed when those entries are part of an installed
+                # incorporation.
+                api_obj.plan_uninstall(["*"], False)
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+                api_obj.plan_install(["entire"])
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+                # In this case, any packages present in an installed
+                # incorporation and that are not installed should be
+                # listed using the highest ranked publisher (test1).
+                # Only apple and quux are incorporated, and build
+                # 0 of apple should be listed here instead of build 1
+                # since the installed incorporation doesn't allow the
+                # build 1 version.
+                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+                    api_obj=api_obj)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 5, "apple",
+                        "1.2.1,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 11)
+
+                # Re-test, only including test1's packages.
+                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+                    api_obj=api_obj, pubs=["test1"])
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 5, "apple",
+                        "1.2.1,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 7)
+
+                # Re-test, only including test2's packages.  Since none of
+                # the other packages are installed for test1, and they meet
+                # the requirements of the installed incorporations, this is
+                # the expected result.
+                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+                    api_obj=api_obj, pubs=["test2"])
+
+                expected = [
+                    self.__get_exp_pub_entry("test2", 5, "apple",
+                        "1.2.1,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 16, "quux", "1.0,5.11"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 6)
+
+                # Change test2 to be ranked higher than test1.
+                api_obj.set_pub_search_before("test2", "test1")
+
+                # Re-test; test2 should now have its entries listed in place
+                # of test1's for the non-filtered case.
+                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+                    api_obj=api_obj)
+
+                expected = [
+                    self.__get_exp_pub_entry("test2", 5, "apple",
+                        "1.2.1,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 16, "quux", "1.0,5.11"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 11)
+
+                # Now install one of the incorporated packages and check
+                # that test2 is still listed for the remaining package
+                # for the non-filtered case.
+                api_obj.plan_install(["apple"])
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+                    api_obj=api_obj)
+
+                expected = [
+                    self.__get_exp_pub_entry("test2", 5, "apple",
+                        "1.2.1,5.11-0", installed=True),
+                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 16, "quux", "1.0,5.11"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 11)
+
+                # Reset publisher search order and re-test.
+                api_obj.set_pub_search_before("test1", "test2")
+
+                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
+                    api_obj=api_obj)
+
+                expected = [
+                    self.__get_exp_pub_entry("test2", 5, "apple",
+                        "1.2.1,5.11-0", installed=True),
+                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
+                        installed=True),
+                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 11)
+
+                # Reset image state for following tests.
+                api_obj.plan_uninstall(["*"], False)
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+        def test_list_06_upgradable(self):
+                """Verify the sort order and content of a list containing
+                only upgradable packages and combinations thereof."""
+
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                # Verify no installed packages case.
+                returned = self.__get_returned(api_obj.LIST_UPGRADABLE,
+                    api_obj=api_obj)
+                self.assertEqual(len(returned), 0)
+
+                # Test results after installing packages and only listing the
+                # installed, upgradable packages.
+                af = self.__get_pub_entry("test1", 3, "apple",
+                    "1.2.0,5.11-0")[0]
+                api_obj.plan_install([af.get_fmri(), "bat/bar", "qux"])
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+                # Verify the results for LIST_UPGRADABLE.
+                returned = self.__get_returned(api_obj.LIST_UPGRADABLE,
+                    api_obj=api_obj)
+                self.assertEqual(len(returned), 1)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 3, "apple",
+                        "1.2.0,5.11-0", installed=True),
+                ]
+                self.assertPrettyEqual(returned, expected)
+
+                # Reset image state for following tests.
+                api_obj.plan_uninstall(["*"], False)
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+        def test_list_07_get_pkg_categories(self):
+                """Verify that get_pkg_categories returns expected results."""
+
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                # Verify no installed packages case.
+                returned = api_obj.get_pkg_categories(installed=True)
+                self.assertEqual(len(returned), 0)
+
+                def get_pkg_cats(p):
+                        stem, ver = p.split("@")
+
+                        # XXX version should not require 5.11
+                        sver = version.Version(ver, "5.11")
+                        sver = str(sver).split(":", 1)[0]
+                        raw_cats = self.__get_pkg_cats(stem, sver)
+
+                        pcats = []
+                        for e in raw_cats:
+                                if e and ":" in e:
+                                        scheme, cat = e.split(":", 1)
+                                else:
+                                        scheme = ""
+                                        cat = e
+                                pcats.append((scheme, cat))
+                        return pcats
+
+                # Verify all case.
+                returned = api_obj.get_pkg_categories()
+                all_pkgs = self.packages
+                all_cats = sorted(set(
+                    sc
+                    for p in all_pkgs
+                    for sc in get_pkg_cats(p)
+                ))
+                self.assertPrettyEqual(returned, all_cats)
+
+                # Verify all case with a few different pub combos.
+                combos = [
+                    (["test1", "test2"], all_cats),
+                    (["test1"], all_cats),
+                    (["test2"], all_cats),
+                    (["test3"], []),
+                    ([], all_cats),
+                ]
+
+                for combo, expected in combos:
+                        returned = api_obj.get_pkg_categories(pubs=combo)
+                        self.assertPrettyEqual(returned, expected)
+
+                # Now install different sets of packages and ensure the
+                # results match what is expected.
+                combos = [
+                    [
+                        self.dlist1[6], # "[email protected],5.11-1"
+                        self.dlist1[7], # "[email protected],5.11-0"
+                    ],
+                    [
+                        self.dlist1[12], # "[email protected]"
+                        self.dlist1[14], # "[email protected]"
+                    ],
+                    [
+                        self.dlist1[16], # "[email protected]"
+                    ],
+                ]
+
+                for combo in combos:
+                        import time
+                        self.debug("combo: %s, time: %s" % (combo, time.ctime()))
+                        pkgs = [
+                            f.get_fmri(anarchy=True, include_scheme=False)
+                            for f in combo
+                        ]
+                        self.debug("plan install: %s" % time.ctime())
+                        api_obj.plan_install(pkgs)
+                        self.debug("prepare install: %s" % time.ctime())
+                        api_obj.prepare()
+                        self.debug("execute install: %s" % time.ctime())
+                        api_obj.execute_plan()
+                        self.debug("1reset: %s" % time.ctime())
+                        api_obj.reset()
+
+                        returned = api_obj.get_pkg_categories(installed=True)
+                        expected = sorted(set(
+                            sc
+                            for p in pkgs
+                            for sc in get_pkg_cats(p)
+                        ))
+                        self.assertPrettyEqual(returned, expected)
+
+                        # Prepare for next test.
+                        self.debug("plan uninstall: %s" % time.ctime())
+                        api_obj.plan_uninstall(pkgs, False)
+                        self.debug("prepare uninstall: %s" % time.ctime())
+                        api_obj.prepare()
+                        self.debug("execute uninstall: %s" % time.ctime())
+                        api_obj.execute_plan()
+                        self.debug("2reset: %s" % time.ctime())
+                        api_obj.reset()
+                self.debug("test finished: %s" % time.ctime())
+
+        def test_list_08_patterns(self):
+                """Verify that pattern filtering works as expected."""
+
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                # First, check all variants, but with multiple patterns for the
+                # partial, exact, and wildcard match cases.
+                patterns = ["bar", "pkg:/baz", "*obs*"]
+                returned = self.__get_returned(api_obj.LIST_ALL,
+                    api_obj=api_obj, patterns=patterns, variants=True)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test1", 10, "baz", "1.3,5.11"),
+                    self.__get_exp_pub_entry("test1", 9, "baz", "1.0.1,5.11"),
+                    self.__get_exp_pub_entry("test1", 8, "baz", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 10, "baz", "1.3,5.11"),
+                    self.__get_exp_pub_entry("test2", 9, "baz", "1.0.1,5.11"),
+                    self.__get_exp_pub_entry("test2", 8, "baz", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "1.0,5.11"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 10)
+
+                # Next, check all variants, but with exact and partial match.
+                patterns = ["pkg:/bar", "obsolete"]
+                returned = self.__get_returned(api_obj.LIST_ALL,
+                    api_obj=api_obj, patterns=patterns, variants=True)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 15, "obsolete",
+                        "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 15, "obsolete",
+                        "1.0,5.11"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 2)
+
+                # Next, check all variants, but for publisher and exact
+                # match case only.
+                patterns = ["pkg://test2/bat/bar"]
+                returned = self.__get_returned(api_obj.LIST_ALL,
+                    api_obj=api_obj, patterns=patterns, variants=True)
+
+                expected = [
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 1)
+
+                # Should return no matches.
+                patterns = ["pkg://test2/bar"]
+                returned = self.__get_returned(api_obj.LIST_ALL,
+                    api_obj=api_obj, patterns=patterns, variants=True)
+                expected = []
+                self.assertPrettyEqual(returned, expected)
+
+                # Next, check all variants, but for exact match case only.
+                patterns = ["pkg:/bat/bar"]
+                returned = self.__get_returned(api_obj.LIST_ALL,
+                    api_obj=api_obj, patterns=patterns, variants=True)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
+                        "1.2,5.11-0"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 2)
+
+                # Next, check version matching for a single pattern.
+                patterns = ["[email protected]"]
+                returned = self.__get_returned(api_obj.LIST_ALL,
+                    api_obj=api_obj, patterns=patterns, variants=True)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 3, "apple",
+                        "1.2.0,5.11-0"),
+                    self.__get_exp_pub_entry("test2", 3, "apple",
+                        "1.2.0,5.11-0"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 2)
+
+                patterns = ["[email protected]"]
+                returned = self.__get_returned(api_obj.LIST_ALL,
+                    api_obj=api_obj, patterns=patterns, 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.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 2)
+
+                patterns = ["apple@*,*-1"]
+                returned = self.__get_returned(api_obj.LIST_ALL,
+                    api_obj=api_obj, patterns=patterns, variants=True)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 6, "apple",
+                        "1.2.1,5.11-1"),
+                    self.__get_exp_pub_entry("test2", 6, "apple",
+                        "1.2.1,5.11-1"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 2)
+
+                # Next, check version matching for multiple patterns.
+                patterns = ["[email protected]", "pkg:/[email protected]",
+                    "pkg://test1/[email protected]"]
+                returned = self.__get_returned(api_obj.LIST_ALL,
+                    api_obj=api_obj, patterns=patterns, variants=True)
+
+                expected = [
+                    self.__get_exp_pub_entry("test1", 9, "baz", "1.0.1,5.11"),
+                    self.__get_exp_pub_entry("test1", 8, "baz", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test2", 9, "baz", "1.0.1,5.11"),
+                    self.__get_exp_pub_entry("test2", 8, "baz", "1.0,5.11"),
+                    self.__get_exp_pub_entry("test1", 17, "qux", "0.9,5.11"),
+                ]
+                self.assertPrettyEqual(returned, expected)
+                self.assertEqual(len(returned), 5)
+
+                # Finally, verify that specifying an illegal pattern will
+                # raise an InventoryException.
+                patterns = ["baz@1.*.a", "baz@*-1"]
+                try:
+                        returned = self.__get_returned(api_obj.LIST_ALL,
+                            api_obj=api_obj, patterns=patterns, variants=True)
+                except api_errors.InventoryException, e:
+                        self.assertEqual(e.illegal, patterns)
+                else:
+                        raise RuntimeError("InventoryException not raised!")
+
+
+if __name__ == "__main__":
+        unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/api/t_api_search.py	Sat Jan 30 01:07:14 2010 -0800
@@ -0,0 +1,2514 @@
+#!/usr/bin/python
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+
+import testutils
+if __name__ == "__main__":
+	testutils.setup_environment("../../../proto")
+import pkg5unittest
+
+import copy
+import difflib
+import os
+import re
+import shutil
+import sys
+import tempfile
+import time
+import unittest
+import urllib2
+
+import pkg.client.api as api
+import pkg.client.api_errors as api_errors
+import pkg.client.query_parser as query_parser
+import pkg.client.progress as progress
+import pkg.fmri as fmri
+import pkg.indexer as indexer
+import pkg.portable as portable
+import pkg.search_storage as ss
+import pkg.server.repository as srepo
+
+API_VERSION = 31
+PKG_CLIENT_NAME = "pkg"
+
+class TestApiSearchBasics(pkg5unittest.SingleDepotTestCase):
+
+        example_pkg10 = """
+            open [email protected],5.11-0
+            add dir mode=0755 owner=root group=bin path=/bin
+            add dir mode=0755 owner=root group=bin path=/bin/example_dir
+            add dir mode=0755 owner=root group=bin path=/usr/lib/python2.6/vendor-packages/OpenSSL
+            add file tmp/example_file mode=0555 owner=root group=bin path=/bin/example_path
+            add set name=com.sun.service.incorporated_changes value="6556919 6627937"
+            add set name=com.sun.service.random_test value=42 value=79
+            add set name=com.sun.service.bug_ids value=4641790 value=4725245 value=4817791 value=4851433 value=4897491 value=4913776 value=6178339 value=6556919 value=6627937
+            add set name=com.sun.service.keywords value="sort null -n -m -t sort 0x86 separator"
+            add set name=com.sun.service.info_url value=http://service.opensolaris.com/xml/pkg/[email protected],5.11-1:20080514I120000Z
+            add set name=description value='FOOO bAr O OO OOO' value="whee fun"
+            add set name='weirdness' value='] [ * ?'
+            add signature pkg.sig_bit1=sig_bit_val1 pkg.sig_bit2=sig_bit_val2
+            close """
+
+        example_pkg11 = """
+            open [email protected],5.11-0
+            add dir mode=0755 owner=root group=bin path=/bin
+            add file tmp/example_file mode=0555 owner=root group=bin path=/bin/example_path11
+            close """
+
+        another_pkg10 = """
+            open [email protected],5.11-0
+            add dir mode=0755 owner=root group=bin path=/bazbin
+            close """
+
+        bad_pkg10 = """
+            open [email protected],5.11-0
+            add dir path=badfoo/ mode=0755 owner=root group=bin
+            close """
+
+        space_pkg10 = """
+            open [email protected],5.11-0
+            add file tmp/example_file mode=0444 owner=nobody group=sys path='unique/with a space'
+            add dir mode=0755 owner=root group=bin path=unique_dir
+            close """
+
+        cat_pkg10 = """
+            open [email protected],5.11-0
+            add set name=info.classification value=org.opensolaris.category.2008:System/Security value=org.random:Other/Category
+            close """
+
+        cat2_pkg10 = """
+            open [email protected],5.11-0
+            add set name=info.classification value="org.opensolaris.category.2008:Applications/Sound and Video" value=Developer/C
+            close """
+
+        cat3_pkg10 = """
+            open [email protected],5.11-0
+            add set name=info.classification value="org.opensolaris.category.2008:foo/bar/baz/bill/beam/asda"
+            close """
+
+        bad_cat_pkg10 = """
+            open [email protected],5.11-0
+            add set name=info.classification value="TestBad1/TestBad2"
+            close """
+
+        bad_cat2_pkg10 = """
+            open [email protected],5.11-0
+            add set name=info.classification value="org.opensolaris.category.2008:TestBad1:TestBad2"
+            close """
+
+        fat_pkg10 = """
+open [email protected],5.11-0
+add set name=variant.arch value=sparc value=i386
+add set name=description value="i386 variant" variant.arch=i386
+add set name=description value="sparc variant" variant.arch=sparc
+close """
+
+        bogus_pkg10 = """
+set name=pkg.fmri value=pkg:/[email protected],5.11-0:20090326T233451Z
+set name=description value=""validation with simple chains of constraints ""
+set name=pkg.description value="pseudo-hashes as arrays tied to a "type" (list of fields)"
+depend fmri=XML-Atom-Entry
+set name=com.sun.service.incorporated_changes value="6556919 6627937"
+"""
+        bogus_fmri = fmri.PkgFmri("[email protected],5.11-0:20090326T233451Z")
+
+        bug_8492_manf_1 = """
+open [email protected],5.11-0
+add set description="Image Packaging System"
+close """
+
+        bug_8492_manf_2 = """
+open [email protected],5.11-0
+add set description="Image Packaging System"
+close """
+
+        res_8492_1 = set([('pkg:/[email protected]', 'Image Packaging System', 'set name=description value="Image Packaging System"')])
+        res_8492_2 = set([('pkg:/[email protected]', 'Image Packaging System', 'set name=description value="Image Packaging System"')])
+        
+        remote_fmri_string = ('pkg:/[email protected]', 'test/example_pkg',
+            'set name=pkg.fmri value=pkg://test/[email protected],5.11-0:')
+
+        res_remote_pkg = set([
+            remote_fmri_string
+        ])
+
+        res_remote_path = set([
+            ("pkg:/[email protected]", "basename","file a686473102ba73bd7920fc0ab1d97e00a24ed704 chash=f88920ce1f61db185d127ccb32dc8cf401ae7a83 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=30 pkg.size=12")
+        ])
+
+        res_remote_path_of_example_path = set([
+            ("pkg:/[email protected]", "path","file a686473102ba73bd7920fc0ab1d97e00a24ed704 chash=f88920ce1f61db185d127ccb32dc8cf401ae7a83 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=30 pkg.size=12")
+        ])
+
+        res_remote_bin = set([
+            ("pkg:/[email protected]", "path", "dir group=bin mode=0755 owner=root path=bin")
+        ])
+
+        res_remote_openssl = set([
+            ("pkg:/[email protected]", "basename", "dir group=bin mode=0755 owner=root path=usr/lib/python2.6/vendor-packages/OpenSSL")
+        ])
+
+        res_remote_bug_id = set([
+            ("pkg:/[email protected]", "4851433", 'set name=com.sun.service.bug_ids value=4641790 value=4725245 value=4817791 value=4851433 value=4897491 value=4913776 value=6178339 value=6556919 value=6627937')
+        ])
+
+        res_remote_bug_id_4725245 = set([
+            ("pkg:/[email protected]", "4725245", 'set name=com.sun.service.bug_ids value=4641790 value=4725245 value=4817791 value=4851433 value=4897491 value=4913776 value=6178339 value=6556919 value=6627937')
+        ])
+
+
+        res_remote_inc_changes = set([
+            ("pkg:/[email protected]", "6556919 6627937", 'set name=com.sun.service.incorporated_changes value="6556919 6627937"'),
+            ("pkg:/[email protected]", "6556919", 'set name=com.sun.service.bug_ids value=4641790 value=4725245 value=4817791 value=4851433 value=4897491 value=4913776 value=6178339 value=6556919 value=6627937')
+        ])
+
+        res_remote_random_test = set([
+            ("pkg:/[email protected]", "42", "set name=com.sun.service.random_test value=42 value=79")
+        ])
+
+        res_remote_random_test_79 = set([
+            ("pkg:/[email protected]", "79", "set name=com.sun.service.random_test value=42 value=79")
+        ])
+
+        res_remote_keywords = set([
+            ("pkg:/[email protected]", "sort null -n -m -t sort 0x86 separator", 'set name=com.sun.service.keywords value="sort null -n -m -t sort 0x86 separator"')
+        ])
+
+        res_remote_wildcard = res_remote_path.union(set([
+            remote_fmri_string,
+            ('pkg:/[email protected]', 'basename', 'dir group=bin mode=0755 owner=root path=bin/example_dir')
+        ]))
+
+        res_remote_glob = set([
+            remote_fmri_string,
+            ('pkg:/[email protected]', 'path', 'dir group=bin mode=0755 owner=root path=bin/example_dir'),
+            ('pkg:/[email protected]', 'basename', 'dir group=bin mode=0755 owner=root path=bin/example_dir'),
+            ('pkg:/[email protected]', 'path', 'file a686473102ba73bd7920fc0ab1d97e00a24ed704 chash=f88920ce1f61db185d127ccb32dc8cf401ae7a83 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=30 pkg.size=12')
+        ]) | res_remote_path
+
+        res_remote_foo = set([
+            ('pkg:/[email protected]', 'FOOO bAr O OO OOO', 'set name=description value="FOOO bAr O OO OOO" value="whee fun"')
+        ])
+
+        res_remote_weird = set([
+            ('pkg:/[email protected]', '] [ * ?', 'set name=weirdness value="] [ * ?"')
+        ])
+
+        local_fmri_string = ('pkg:/[email protected]', 'test/example_pkg',
+            'set name=pkg.fmri value=pkg://test/[email protected],5.11-0:')
+
+        res_local_pkg = set([
+                local_fmri_string
+                ])
+
+        res_local_path = copy.copy(res_remote_path)
+
+        res_local_bin = copy.copy(res_remote_bin)
+
+        res_local_bug_id = copy.copy(res_remote_bug_id)
+
+        res_local_inc_changes = copy.copy(res_remote_inc_changes)
+
+        res_local_random_test = copy.copy(res_remote_random_test)
+
+        res_local_keywords = copy.copy(res_remote_keywords)
+
+        res_local_wildcard = copy.copy(res_remote_wildcard)
+        res_local_wildcard.add(local_fmri_string)
+
+        res_local_glob = copy.copy(res_remote_glob)
+        res_local_glob.add(local_fmri_string)
+
+        res_local_foo = copy.copy(res_remote_foo)
+
+        res_local_openssl = copy.copy(res_remote_openssl)
+
+        res_local_path_example11 = set([
+            ("pkg:/[email protected]", "basename", "file a686473102ba73bd7920fc0ab1d97e00a24ed704 chash=f88920ce1f61db185d127ccb32dc8cf401ae7a83 group=bin mode=0555 owner=root path=bin/example_path11 pkg.csize=30 pkg.size=12")
+        ])
+
+        res_local_bin_example11 = set([
+            ("pkg:/[email protected]", "path", "dir group=bin mode=0755 owner=root path=bin")
+        ])
+
+        res_local_pkg_example11 = set([
+            ("pkg:/[email protected]", "test/example_pkg", "set name=pkg.fmri value=pkg://test/[email protected],5.11-0:")
+        ])
+
+        res_local_wildcard_example11 = set([
+            ("pkg:/[email protected]", "basename", "file a686473102ba73bd7920fc0ab1d97e00a24ed704 chash=f88920ce1f61db185d127ccb32dc8cf401ae7a83 group=bin mode=0555 owner=root path=bin/example_path11 pkg.csize=30 pkg.size=12"),
+        ]).union(res_local_pkg_example11)
+
+        res_cat_pkg10 = set([
+            ('pkg:/[email protected]', 'System/Security', 'set name=info.classification value=org.opensolaris.category.2008:System/Security value=org.random:Other/Category')
+        ])
+
+        res_cat_pkg10_2 = set([
+            ('pkg:/[email protected]', 'Other/Category', 'set name=info.classification value=org.opensolaris.category.2008:System/Security value=org.random:Other/Category')
+        ])
+
+        res_cat2_pkg10 = set([
+            ('pkg:/[email protected]', 'Applications/Sound and Video', 'set name=info.classification value="org.opensolaris.category.2008:Applications/Sound and Video" value=Developer/C')
+        ])
+
+        res_cat2_pkg10_2 = set([
+            ('pkg:/[email protected]', 'Developer/C', 'set name=info.classification value="org.opensolaris.category.2008:Applications/Sound and Video" value=Developer/C')
+        ])
+
+        res_cat3_pkg10 = set([
+            ('pkg:/[email protected]', 'foo/bar/baz/bill/beam/asda', 'set name=info.classification value=org.opensolaris.category.2008:foo/bar/baz/bill/beam/asda')
+        ])
+
+        res_fat10_i386 = set([
+            ('pkg:/[email protected]', 'i386 variant', 'set name=description value="i386 variant" variant.arch=i386'),
+            ('pkg:/[email protected]', 'i386 variant', 'set name=description value="i386 variant" variant.arch=i386'),
+            ('pkg:/[email protected]', 'i386', 'set name=variant.arch value=sparc value=i386'),
+        ])
+
+        res_fat10_sparc = set([
+            ('pkg:/[email protected]', 'sparc variant', 'set name=description value="sparc variant" variant.arch=sparc'),
+            ('pkg:/[email protected]', 'sparc', 'set name=variant.arch value=sparc value=i386')
+        ])
+
+        fat_10_fmri_string = set([('pkg:/[email protected]', 'test/fat', 'set name=pkg.fmri value=pkg://test/[email protected],5.11-0:')])
+
+        res_remote_fat10_star = fat_10_fmri_string | res_fat10_sparc | res_fat10_i386
+
+        res_local_fat10_i386_star = res_fat10_i386.union(set([
+            ('pkg:/[email protected]', 'sparc', 'set name=variant.arch value=sparc value=i386')
+        ])).union(fat_10_fmri_string)
+
+        res_local_fat10_sparc_star = res_fat10_sparc.union(set([
+            ('pkg:/[email protected]', 'i386', 'set name=variant.arch value=sparc value=i386')
+        ])).union(fat_10_fmri_string)
+
+        res_space_with_star = set([
+            ('pkg:/[email protected]', 'basename', 'file a686473102ba73bd7920fc0ab1d97e00a24ed704 chash=f88920ce1f61db185d127ccb32dc8cf401ae7a83 group=sys mode=0444 owner=nobody path="unique/with a space" pkg.csize=30 pkg.size=12')
+        ])
+
+        res_space_space_star = set([
+            ('pkg:/[email protected]', 'basename', 'file a686473102ba73bd7920fc0ab1d97e00a24ed704 chash=f88920ce1f61db185d127ccb32dc8cf401ae7a83 group=sys mode=0444 owner=nobody path="unique/with a space" pkg.csize=30 pkg.size=12'), ('pkg:/[email protected]', 'path', 'file a686473102ba73bd7920fc0ab1d97e00a24ed704 chash=f88920ce1f61db185d127ccb32dc8cf401ae7a83 group=sys mode=0444 owner=nobody path="unique/with a space" pkg.csize=30 pkg.size=12')
+        ])
+
+        res_space_unique = set([
+            ('pkg:/[email protected]', 'basename', 'dir group=bin mode=0755 owner=root path=unique_dir')
+        ])
+
+        # This is a copy of the 3.81%2C5.11-0.89%3A20080527T163123Z version of
+        # SUNWgmake from ipkg with the file and liscense actions changed so
+        # that they all take /tmp/example file when sending.
+        bug_983_manifest = """
+open [email protected],5.11-0.89
+add dir group=sys mode=0755 owner=root path=usr
+add dir group=bin mode=0755 owner=root path=usr/bin
+add dir group=bin mode=0755 owner=root path=usr/gnu
+add dir group=bin mode=0755 owner=root path=usr/gnu/bin
+add link path=usr/gnu/bin/make target=../../bin/gmake
+add dir group=sys mode=0755 owner=root path=usr/gnu/share
+add dir group=bin mode=0755 owner=root path=usr/gnu/share/man
+add dir group=bin mode=0755 owner=root path=usr/gnu/share/man/man1
+add link path=usr/gnu/share/man/man1/make.1 target=../../../../share/man/man1/gmake.1
+add dir group=bin mode=0755 owner=root path=usr/sfw
+add dir group=bin mode=0755 owner=root path=usr/sfw/bin
+add link path=usr/sfw/bin/gmake target=../../bin/gmake
+add dir group=bin mode=0755 owner=root path=usr/sfw/share
+add dir group=bin mode=0755 owner=root path=usr/sfw/share/man
+add dir group=bin mode=0755 owner=root path=usr/sfw/share/man/man1
+add link path=usr/sfw/share/man/man1/gmake.1 target=../../../../share/man/man1/gmake.1
+add dir group=sys mode=0755 owner=root path=usr/share
+add dir group=bin mode=0755 owner=root path=usr/share/info
+add dir group=bin mode=0755 owner=root path=usr/share/man
+add dir group=bin mode=0755 owner=root path=usr/share/man/man1
+add file tmp/example_file elfarch=i386 elfbits=32 elfhash=68cca393e816e6adcbac1e8ffe9c618de70413e0 group=bin mode=0555 owner=root path=usr/bin/gmake pkg.size=12
+add file tmp/example_file group=bin mode=0444 owner=root path=usr/share/info/make.info pkg.size=12
+add file tmp/example_file group=bin mode=0444 owner=root path=usr/share/info/make.info-1 pkg.size=12
+add file tmp/example_file group=bin mode=0444 owner=root path=usr/share/info/make.info-2 pkg.size=12
+add file tmp/example_file group=bin mode=0444 owner=root path=usr/share/man/man1/gmake.1 pkg.size=12
+add license tmp/example_file license=SUNWgmake.copyright pkg.size=12 transaction_id=1211931083_pkg%3A%2FSUNWgmake%403.81%2C5.11-0.89%3A20080527T163123Z
+add depend fmri=pkg:/[email protected] type=require
+add depend [email protected] type=require
+add depend [email protected] type=incorporate
+add set name=description value="gmake - GNU make"
+add legacy arch=i386 category=system desc="GNU make - A utility used to build software (gmake) 3.81" hotline="Please contact your local service provider" name="gmake - GNU make" pkg=SUNWgmake vendor="Sun Microsystems, Inc." version=11.11.0,REV=2008.04.29.02.08
+close
+"""
+
+        res_bug_983 = set([
+            ("pkg:/[email protected]", "basename", "link path=usr/sfw/bin/gmake target=../../bin/gmake"),
+            ('pkg:/[email protected]', 'basename', 'file a686473102ba73bd7920fc0ab1d97e00a24ed704 chash=f88920ce1f61db185d127ccb32dc8cf401ae7a83 elfarch=i386 elfbits=32 elfhash=68cca393e816e6adcbac1e8ffe9c618de70413e0 group=bin mode=0555 owner=root path=usr/bin/gmake pkg.csize=30 pkg.size=12'),
+            ('pkg:/[email protected]', 'gmake - GNU make', 'set name=description value="gmake - GNU make"')
+        ])
+
+        res_983_csl_dependency = set([
+            ('pkg:/[email protected]', 'require', 'depend fmri=pkg:/[email protected] type=require')
+        ])
+
+        res_983_bar_dependency = set([
+            ('pkg:/[email protected]', 'require', 'depend [email protected] type=require')
+        ])
+
+        res_983_foo_dependency = set([
+            ('pkg:/[email protected]', 'incorporate', 'depend [email protected] type=incorporate')
+        ])
+
+        res_local_pkg_ret_pkg = set([
+            "pkg:/[email protected]"
+        ])
+
+        res_remote_pkg_ret_pkg = set([
+            "pkg:/[email protected]"
+        ])
+
+        res_remote_file = set([
+            ('pkg:/[email protected]',
+             'path',
+             'file a686473102ba73bd7920fc0ab1d97e00a24ed704 chash=f88920ce1f61db185d127ccb32dc8cf401ae7a83 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=30 pkg.size=12'),
+            ('pkg:/[email protected]',
+             'a686473102ba73bd7920fc0ab1d97e00a24ed704',
+             'file a686473102ba73bd7920fc0ab1d97e00a24ed704 chash=f88920ce1f61db185d127ccb32dc8cf401ae7a83 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=30 pkg.size=12')
+        ]) | res_remote_path
+
+        res_remote_url = set([
+            ('pkg:/[email protected]',
+            'http://service.opensolaris.com/xml/pkg/[email protected],5.11-1:20080514I120000Z',
+            'set name=com.sun.service.info_url value=http://service.opensolaris.com/xml/pkg/[email protected],5.11-1:20080514I120000Z'),
+        ])
+
+        res_remote_path_extra = set([
+            ('pkg:/[email protected]',
+             'basename',
+             'file a686473102ba73bd7920fc0ab1d97e00a24ed704 chash=f88920ce1f61db185d127ccb32dc8cf401ae7a83 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=30 pkg.size=12'),
+            ('pkg:/[email protected]',
+             'path',
+             'file a686473102ba73bd7920fc0ab1d97e00a24ed704 chash=f88920ce1f61db185d127ccb32dc8cf401ae7a83 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=30 pkg.size=12'),
+            ('pkg:/[email protected]',
+             'a686473102ba73bd7920fc0ab1d97e00a24ed704',
+             'file a686473102ba73bd7920fc0ab1d97e00a24ed704 chash=f88920ce1f61db185d127ccb32dc8cf401ae7a83 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=30 pkg.size=12')
+        ])
+
+        res_bad_pkg = set([
+            ('pkg:/[email protected]', 'basename',
+             'dir group=bin mode=0755 owner=root path=badfoo/')
+        ])
+
+        fast_add_after_install = set([
+            "VERSION: 2\n",
+            "[email protected],5.11",
+            "[email protected],5.11"
+        ])
+
+        fast_remove_after_install = set([
+            "VERSION: 2\n",
+        ])
+
+        fast_add_after_first_update = set([
+            "VERSION: 2\n",
+            "[email protected],5.11",
+            "[email protected],5.11",
+            "[email protected],5.11",
+            "[email protected],5.11"
+        ])
+
+        fast_remove_after_first_update = set([
+            "VERSION: 2\n",
+            "[email protected],5.11",
+            "[email protected],5.11"
+        ])
+
+        fast_add_after_second_update = set(["VERSION: 2\n"])
+
+        fast_remove_after_second_update = set(["VERSION: 2\n"])
+
+        debug_features = []
+
+        # We wire the contents of the example file to a well known string
+        # so that the hash is also well known.
+        misc_files = { "tmp/example_file" : "magic banana" }
+
+        def setUp(self):
+                pkg5unittest.SingleDepotTestCase.setUp(self,
+                    debug_features=self.debug_features)
+                self.testdata_dir = os.path.join(self.test_root,
+                    "search_results")
+                os.mkdir(self.testdata_dir)
+                self._dir_restore_functions = [self._restore_dir,
+                    self._restore_dir_preserve_hash]
+                self.make_misc_files(self.misc_files)
+
+        def _check(self, proposed_answer, correct_answer):
+                if correct_answer == proposed_answer:
+                        return True
+                else:
+                        self.debug("Proposed Answer: " + str(proposed_answer))
+                        self.debug("Correct Answer : " + str(correct_answer))
+                        if isinstance(correct_answer, set) and \
+                            isinstance(proposed_answer, set):
+                                print >> sys.stderr, "Missing: " + \
+                                    str(correct_answer - proposed_answer)
+                                print >> sys.stderr, "Extra  : " + \
+                                    str(proposed_answer - correct_answer)
+                        self.assert_(correct_answer == proposed_answer)
+
+        @staticmethod
+        def _replace_act(act):
+                if act.startswith('set name=pkg.fmri'):
+                        return act.strip().rsplit(":", 1)[0] + ":"
+                else:
+                        return act.strip()
+
+        @staticmethod
+        def _extract_action_from_res(it):
+                return (
+                    (fmri.PkgFmri(str(pkg_name)).get_short_fmri(), piece,
+                    TestApiSearchBasics._replace_act(act))
+                    for query_num, auth, (version, return_type,
+                    (pkg_name, piece, act))
+                    in it
+                )
+
+        @staticmethod
+        def _extract_package_from_res(it):
+                return (
+                    (fmri.PkgFmri(str(pkg_name)).get_short_fmri())
+                    for query_num, auth, (version, return_type, pkg_name)
+                    in it
+                )
+
+        @staticmethod
+        def _get_lines(fp):
+                fh = open(fp, "rb")
+                lines = fh.readlines()
+                fh.close()
+                return lines
+
+        def _search_op(self, api_obj, remote, token, test_value,
+            case_sensitive=False, return_actions=True, num_to_return=None,
+            start_point=None, servers=None):
+                query = [api.Query(token, case_sensitive, return_actions,
+                    num_to_return, start_point)]
+                self._search_op_common(api_obj, remote, query, test_value,
+                    return_actions, servers)
+
+        def _search_op_multi(self, api_obj, remote, tokens, test_value,
+            case_sensitive=False, return_actions=True, num_to_return=None,
+            start_point=None, servers=None):
+                query = [api.Query(token, case_sensitive, return_actions,
+                    num_to_return, start_point) for token in tokens]
+                self._search_op_common(api_obj, remote, query, test_value,
+                    return_actions, servers)
+
+        def _search_op_common(self, api_obj, remote, query, test_value,
+            return_actions, servers):
+                self.debug("Search for: %s" % " ".join([str(q) for q in query]))
+                search_func = api_obj.local_search
+                if remote:
+                        search_func = lambda x: api_obj.remote_search(x,
+                            servers=servers)
+                init_time = time.time()
+
+                # servers may not be ready immediately - retry search
+                # operation for 5 seconds
+
+                while (time.time() - init_time) < 5:
+                        try:
+                                res = search_func(query)
+                                if return_actions:
+                                        res = self._extract_action_from_res(res)
+                                else:
+                                        res = self._extract_package_from_res(res)
+                                res = set(res)
+                                break
+                        except api_errors.ProblematicSearchServers, e:
+                                pass
+
+                self._check(set(res), test_value)
+
+        def _search_op_slow(self, api_obj, remote, token, test_value,
+            case_sensitive=False, return_actions=True, num_to_return=None,
+            start_point=None):
+                query = [api.Query(token, case_sensitive, return_actions,
+                    num_to_return, start_point)]
+                self._search_op_slow_common(api_obj, query, test_value,
+                    return_actions)
+
+        def _search_op_slow_multi(self, api_obj, remote, tokens, test_value,
+            case_sensitive=False, return_actions=True, num_to_return=None,
+            start_point=None):
+                query = [api.Query(token, case_sensitive, return_actions,
+                    num_to_return, start_point) for token in tokens]
+                self._search_op_slow_common(api_obj, query, test_value,
+                    return_actions)
+
+        def _search_op_slow_common(self, api_obj, query, test_value,
+            return_actions):
+                search_func = api_obj.local_search
+                tmp = search_func(query)
+                res = []
+                ssu = False
+                try:
+                        for i in tmp:
+                                res.append(i)
+                except api_errors.SlowSearchUsed:
+                        ssu = True
+                self.assert_(ssu)
+                if return_actions:
+                        res = self._extract_action_from_res(res)
+                else:
+                        res = self._extract_package_from_res(res)
+                res = set(res)
+                self._check(set(res), test_value)
+
+        def _run_full_remote_tests(self, api_obj):
+                self._search_op(api_obj, True, "example_pkg",
+                    self.res_remote_pkg)
+                self._search_op(api_obj, True, "example_path",
+                    self.res_remote_path)
+                self._search_op(api_obj, True, "(example_path)",
+                    self.res_remote_path)
+                self._search_op(api_obj, True, "<exam*:::>",
+                    self.res_remote_pkg_ret_pkg, return_actions=False)
+                self._search_op(api_obj, True, "::com.sun.service.info_url:",
+                    self.res_remote_url)
+                self._search_op(api_obj, True, ":::e* AND *path",
+                    self.res_remote_path)
+                self._search_op(api_obj, True, "e* AND *path",
+                    self.res_remote_path)
+                self._search_op(api_obj, True, "<e*>",
+                    self.res_remote_pkg_ret_pkg, return_actions=False)
+                self._search_op(api_obj, True, "<e*> AND <e*>",
+                    self.res_remote_pkg_ret_pkg, return_actions=False)
+                self._search_op(api_obj, True, "<e*> OR <e*>",
+                    self.res_remote_pkg_ret_pkg, return_actions=False)
+                self._search_op(api_obj, True, "<exam:::>",
+                    self.res_remote_pkg_ret_pkg, return_actions=False)
+                self._search_op(api_obj, True, "exam:::e*path",
+                    self.res_remote_path)
+                self._search_op(api_obj, True, "exam:::e*path AND e*:::",
+                    self.res_remote_path)
+                self._search_op(api_obj, True, "e*::: AND exam:::*path",
+                    self.res_remote_path_extra)
+                self._search_op(api_obj, True, "example*",
+                    self.res_remote_wildcard)
+                self._search_op(api_obj, True, "/bin", self.res_remote_bin)
+                self._search_op(api_obj, True, "4851433",
+                    self.res_remote_bug_id)
+                self._search_op(api_obj, True, "<4851433> AND <4725245>",
+                    self.res_remote_pkg_ret_pkg, return_actions=False)
+                self._search_op(api_obj, True, "4851433 AND 4725245",
+                    self.res_remote_bug_id)
+                self._search_op(api_obj, True,
+                    "4851433 AND 4725245 OR example_path",
+                    self.res_remote_bug_id)
+                self._search_op(api_obj, True,
+                    "4851433 AND (4725245 OR example_path)",
+                    self.res_remote_bug_id)
+                self._search_op(api_obj, True,
+                    "(4851433 AND 4725245) OR example_path",
+                    self.res_remote_bug_id | self.res_remote_path)
+                self._search_op(api_obj, True, "4851433 OR 4725245",
+                    self.res_remote_bug_id | self.res_remote_bug_id_4725245)
+                self._search_op(api_obj, True, "6556919",
+                    self.res_remote_inc_changes)
+                self._search_op(api_obj, True, "6556?19",
+                    self.res_remote_inc_changes)
+                self._search_op(api_obj, True, "42",
+                    self.res_remote_random_test)
+                self._search_op(api_obj, True, "79",
+                    self.res_remote_random_test_79)
+                self._search_op(api_obj, True, "separator",
+                    self.res_remote_keywords)
+                self._search_op(api_obj, True, "\"sort 0x86\"",
+                    self.res_remote_keywords)
+                self._search_op(api_obj, True, "*example*",
+                    self.res_remote_glob)
+                self._search_op(api_obj, True, "fooo", self.res_remote_foo)
+                self._search_op(api_obj, True, "fo*", self.res_remote_foo)
+                self._search_op(api_obj, True, "bar", self.res_remote_foo)
+                self._search_op(api_obj, True, "openssl",
+                    self.res_remote_openssl)
+                self._search_op(api_obj, True, "OPENSSL",
+                    self.res_remote_openssl)
+                self._search_op(api_obj, True, "OpEnSsL",
+                    self.res_remote_openssl)
+                # Test for bug 11235, case insensitive phrase search, and bug
+                # 11354, mangled fields during phrase search.
+                self._search_op(api_obj, True, "'OpEnSsL'",
+                    self.res_remote_openssl)
+                self._search_op(api_obj, True, "OpEnS*",
+                    self.res_remote_openssl)
+
+                # These tests are included because a specific bug
+                # was found during development. This prevents regression back
+                # to that bug. Exit status of 1 is expected because the
+                # token isn't in the packages.
+                self._search_op(api_obj, True, "a_non_existent_token", set())
+
+                self._search_op(api_obj, True, "42 AND 4641790", set())
+                self.assertRaises(api_errors.BooleanQueryException,
+                    self._search_op, api_obj, True, "<e*> AND e*", set())
+                self.assertRaises(api_errors.BooleanQueryException,
+                    self._search_op, api_obj, True, "e* AND <e*>", set())
+                self.assertRaises(api_errors.BooleanQueryException,
+                    self._search_op, api_obj, True, "<e*> OR e*", set())
+                self.assertRaises(api_errors.BooleanQueryException,
+                    self._search_op, api_obj, True, "e* OR <e*>", set())
+
+        def _run_remote_tests(self, api_obj):
+                self._search_op(api_obj, True, "example_pkg",
+                    self.res_remote_pkg)
+                self._search_op(api_obj, True, "example_path",
+                    self.res_remote_path)
+                self._search_op(api_obj, True, "::com.sun.service.info_url:",
+                    self.res_remote_url)
+                self._search_op(api_obj, True, "<e*>",
+                    self.res_remote_pkg_ret_pkg, return_actions=False)
+                self._search_op(api_obj, True, "<exam:::>",
+                    self.res_remote_pkg_ret_pkg, return_actions=False)
+                self._search_op(api_obj, True, "exam:::e*path",
+                    self.res_remote_path)
+                self._search_op(api_obj, True, "example*",
+                    self.res_remote_wildcard)
+                self._search_op(api_obj, True, "/bin", self.res_remote_bin)
+                self._search_op(api_obj, True, "4851433",
+                    self.res_remote_bug_id)
+                self._search_op(api_obj, True, "4725245",
+                    self.res_remote_bug_id_4725245)
+                self._search_op(api_obj, True, "6556919",
+                    self.res_remote_inc_changes)
+                self._search_op(api_obj, True, "42",
+                    self.res_remote_random_test)
+                self._search_op(api_obj, True, "79",
+                    self.res_remote_random_test_79)
+                self._search_op(api_obj, True, "separator",
+                    self.res_remote_keywords)
+                self._search_op(api_obj, True, "\"sort 0x86\"",
+                    self.res_remote_keywords)
+                self._search_op(api_obj, True, "*example*",
+                    self.res_remote_glob)
+                self._search_op(api_obj, True, "fooo", self.res_remote_foo)
+                self._search_op(api_obj, True, "bar", self.res_remote_foo)
+                self._search_op(api_obj, True, "OpEnSsL",
+                    self.res_remote_openssl)
+
+                # These tests are included because a specific bug
+                # was found during development. This prevents regression back
+                # to that bug.
+                self._search_op(api_obj, True, "a_non_existent_token", set())
+
+        def _run_full_local_tests(self, api_obj):
+                outfile = os.path.join(self.testdata_dir, "res")
+
+                # This finds something because the client side
+                # manifest has had the name of the package inserted
+                # into it.
+
+                self._search_op(api_obj, False, "example_pkg",
+                    self.res_local_pkg)
+                self._search_op(api_obj, False, "example_path",
+                    self.res_local_path)
+                self._search_op(api_obj, False, "(example_path)",
+                    self.res_local_path)
+                self._search_op(api_obj, False, "<exam*:::>",
+                    self.res_local_pkg_ret_pkg, return_actions=False)
+                self._search_op(api_obj, False, "::com.sun.service.info_url:",
+                    self.res_remote_url)
+                self._search_op(api_obj, False, ":::e* AND *path",
+                    self.res_local_path)
+                self._search_op(api_obj, False, "e* AND *path",
+                    self.res_local_path)
+                self._search_op(api_obj, False, "<e*>",
+                    self.res_local_pkg_ret_pkg, return_actions=False)
+                self._search_op(api_obj, False, "<e*> AND <e*>",
+                    self.res_local_pkg_ret_pkg, return_actions=False)
+                self._search_op(api_obj, False, "<e*> OR <e*>",
+                    self.res_local_pkg_ret_pkg, return_actions=False)
+                self._search_op(api_obj, False, "<exam:::>",
+                    self.res_local_pkg_ret_pkg, return_actions=False)
+                self._search_op(api_obj, False, "exam:::e*path",
+                    self.res_local_path)
+                self._search_op(api_obj, False, "exam:::e*path AND e*:::",
+                    self.res_local_path)
+                self._search_op(api_obj, False, "e*::: AND exam:::*path",
+                    self.res_remote_path_extra)
+                self._search_op(api_obj, False, "example*",
+                    self.res_local_wildcard)
+                self._search_op(api_obj, False, "/bin", self.res_local_bin)
+                self._search_op(api_obj, False, "4851433",
+                    self.res_local_bug_id)
+                self._search_op(api_obj, False, "<4851433> AND <4725245>",
+                    self.res_local_pkg_ret_pkg, return_actions=False)
+                self._search_op(api_obj, False, "4851433 AND 4725245",
+                    self.res_local_bug_id)
+                self._search_op(api_obj, False,
+                    "4851433 AND 4725245 OR example_path",
+                    self.res_local_bug_id)
+                self._search_op(api_obj, False,
+                    "4851433 AND (4725245 OR example_path)",
+                    self.res_local_bug_id)
+                self._search_op(api_obj, False,
+                    "(4851433 AND 4725245) OR example_path",
+                    self.res_local_bug_id | self.res_local_path)
+                self._search_op(api_obj, False, "4851433 OR 4725245",
+                    self.res_local_bug_id | self.res_remote_bug_id_4725245)
+                self._search_op(api_obj, False, "6556919",
+                    self.res_local_inc_changes)
+                self._search_op(api_obj, False, "65569??",
+                    self.res_local_inc_changes)
+                self._search_op(api_obj, False, "42",
+                    self.res_local_random_test)
+                self._search_op(api_obj, False, "79",
+                    self.res_remote_random_test_79)
+                self._search_op(api_obj, False, "separator",
+                    self.res_local_keywords)
+                self._search_op(api_obj, False, "\"sort 0x86\"",
+                    self.res_remote_keywords)
+                self._search_op(api_obj, False, "*example*",
+                    self.res_local_glob)
+                self._search_op(api_obj, False, "fooo", self.res_local_foo)
+                self._search_op(api_obj, False, "fo*", self.res_local_foo)
+                self._search_op(api_obj, False, "bar", self.res_local_foo)
+                self._search_op(api_obj, False, "openssl",
+                    self.res_local_openssl)
+                self._search_op(api_obj, False, "OPENSSL",
+                    self.res_local_openssl)
+                self._search_op(api_obj, False, "OpEnSsL",
+                    self.res_local_openssl)
+                # Test for bug 11235, case insensitive phrase search, and bug
+                # 11354, mangled fields during phrase search.
+                self._search_op(api_obj, False, "'OpEnSsL'",
+                    self.res_remote_openssl)
+                self._search_op(api_obj, False, "OpEnS*",
+                    self.res_local_openssl)
+                # These tests are included because a specific bug
+                # was found during development. These tests prevent regression
+                # back to that bug. Exit status of 1 is expected because the
+                # token isn't in the packages.
+                self._search_op(api_obj, False, "a_non_existent_token", set())
+                self._search_op(api_obj, False, "42 AND 4641790", set())
+                self.assertRaises(api_errors.BooleanQueryException,
+                    self._search_op, api_obj, False, "<e*> AND e*", set())
+                self.assertRaises(api_errors.BooleanQueryException,
+                    self._search_op, api_obj, False, "e* AND <e*>", set())
+                self.assertRaises(api_errors.BooleanQueryException,
+                    self._search_op, api_obj, False, "<e*> OR e*", set())
+                self.assertRaises(api_errors.BooleanQueryException,
+                    self._search_op, api_obj, False, "e* OR <e*>", set())
+
+        def _run_local_tests(self, api_obj):
+                outfile = os.path.join(self.testdata_dir, "res")
+
+                # This finds something because the client side
+                # manifest has had the name of the package inserted
+                # into it.
+
+                self._search_op(api_obj, False, "example_pkg",
+                    self.res_local_pkg)
+                self._search_op(api_obj, False, "example_path",
+                    self.res_local_path)
+                self._search_op(api_obj, False, "::com.sun.service.info_url:",
+                    self.res_remote_url)
+                self._search_op(api_obj, False, "<e*>",
+                    self.res_local_pkg_ret_pkg, return_actions=False)
+                self._search_op(api_obj, False, "<exam:::>",
+                    self.res_local_pkg_ret_pkg, return_actions=False)
+                self._search_op(api_obj, False, "exam:::e*path",
+                    self.res_local_path)
+                self._search_op(api_obj, False, "example*",
+                    self.res_local_wildcard)
+                self._search_op(api_obj, False, "/bin", self.res_local_bin)
+                self._search_op(api_obj, False, "4851433",
+                    self.res_local_bug_id)
+                self._search_op(api_obj, False, "4725245",
+                    self.res_remote_bug_id_4725245)
+                self._search_op(api_obj, False, "6556919",
+                    self.res_local_inc_changes)
+                self._search_op(api_obj, False, "42",
+                    self.res_local_random_test)
+                self._search_op(api_obj, False, "79",
+                    self.res_remote_random_test_79)
+                self._search_op(api_obj, False, "separator",
+                    self.res_local_keywords)
+                self._search_op(api_obj, False, "\"sort 0x86\"",
+                    self.res_remote_keywords)
+                self._search_op(api_obj, False, "*example*",
+                    self.res_local_glob)
+                self._search_op(api_obj, False, "fooo", self.res_local_foo)
+                self._search_op(api_obj, False, "bar", self.res_local_foo)
+                self._search_op(api_obj, False, "OpEnSsL",
+                    self.res_local_openssl)
+                # These tests are included because a specific bug
+                # was found during development. These tests prevent regression
+                # back to that bug.
+                self._search_op(api_obj, False, "a_non_existent_token", set())
+
+        def _run_degraded_local_tests(self, api_obj):
+                outfile = os.path.join(self.testdata_dir, "res")
+
+                # This finds something because the client side
+                # manifest has had the name of the package inserted
+                # into it.
+
+                self._search_op_slow(api_obj, False, "example_pkg",
+                    self.res_local_pkg)
+                self._search_op_slow(api_obj, False, "example_path",
+                    self.res_local_path)
+                self._search_op_slow(api_obj, False, "(example_path)",
+                    self.res_local_path)
+                self._search_op_slow(api_obj, False, "<exam*:::>",
+                    self.res_local_pkg_ret_pkg, return_actions=False)
+                self._search_op_slow(api_obj, False,
+                    "::com.sun.service.info_url:",
+                    self.res_remote_url)
+                self._search_op_slow(api_obj, False, ":::e* AND *path",
+                    self.res_local_path)
+                self._search_op_slow(api_obj, False, "e* AND *path",
+                    self.res_local_path)
+                self._search_op_slow(api_obj, False, "<e*>",
+                    self.res_local_pkg_ret_pkg, return_actions=False)
+                self._search_op_slow(api_obj, False, "<e*> AND <e*>",
+                    self.res_local_pkg_ret_pkg, return_actions=False)
+                self._search_op_slow(api_obj, False, "<e*> OR <e*>",
+                    self.res_local_pkg_ret_pkg, return_actions=False)
+                self._search_op_slow(api_obj, False, "<exam:::>",
+                    self.res_local_pkg_ret_pkg, return_actions=False)
+                self._search_op_slow(api_obj, False, "exam:::e*path",
+                    self.res_local_path)
+                self._search_op_slow(api_obj, False, "exam:::e*path AND e*:::",
+                    self.res_local_path)
+                self._search_op_slow(api_obj, False, "e*::: AND exam:::*path",
+                    self.res_remote_path_extra)
+                self._search_op_slow(api_obj, False, "example*",
+                    self.res_local_wildcard)
+                self._search_op_slow(api_obj, False, "/bin", self.res_local_bin)
+                self._search_op_slow(api_obj, False, "4851433",
+                    self.res_local_bug_id)
+                self._search_op_slow(api_obj, False, "<4851433> AND <4725245>",
+                    self.res_local_pkg_ret_pkg, return_actions=False)
+                self._search_op_slow(api_obj, False, "4851433 AND 4725245",
+                    self.res_local_bug_id)
+                self._search_op_slow(api_obj, False,
+                    "4851433 AND 4725245 OR example_path",
+                    self.res_local_bug_id)
+                self._search_op_slow(api_obj, False,
+                    "4851433 AND (4725245 OR example_path)",
+                    self.res_local_bug_id)
+                self._search_op_slow(api_obj, False,
+                    "(4851433 AND 4725245) OR example_path",
+                    self.res_local_bug_id | self.res_local_path)
+                self._search_op_slow(api_obj, False, "4851433 OR 4725245",
+                    self.res_local_bug_id | self.res_remote_bug_id_4725245)
+                self._search_op_slow(api_obj, False, "6556919",
+                    self.res_local_inc_changes)
+                self._search_op_slow(api_obj, False, "65569??",
+                    self.res_local_inc_changes)
+                self._search_op_slow(api_obj, False, "42",
+                    self.res_local_random_test)
+                self._search_op_slow(api_obj, False, "79",
+                    self.res_remote_random_test_79)
+                self._search_op_slow(api_obj, False, "separator",
+                    self.res_local_keywords)
+                self._search_op_slow(api_obj, False, "\"sort 0x86\"",
+                    self.res_remote_keywords)
+                self._search_op_slow(api_obj, False, "*example*",
+                    self.res_local_glob)
+                self._search_op_slow(api_obj, False, "fooo", self.res_local_foo)
+                self._search_op_slow(api_obj, False, "fo*", self.res_local_foo)
+                self._search_op_slow(api_obj, False, "bar", self.res_local_foo)
+                self._search_op_slow(api_obj, False, "openssl",
+                    self.res_local_openssl)
+                self._search_op_slow(api_obj, False, "OPENSSL",
+                    self.res_local_openssl)
+                self._search_op_slow(api_obj, False, "OpEnSsL",
+                    self.res_local_openssl)
+                self._search_op_slow(api_obj, False, "OpEnS*",
+                    self.res_local_openssl)
+                # These tests are included because a specific bug
+                # was found during development. These tests prevent regression
+                # back to that bug. Exit status of 1 is expected because the
+                # token isn't in the packages.
+                self._search_op_slow(api_obj, False, "a_non_existent_token",
+                    set())
+
+        def _run_remove_root_search(self, search_func, remote, api_obj, ip):
+                search_func(api_obj, remote, [ip + "example_pkg"], set())
+                search_func(api_obj, remote, [ip + "bin/example_path"],
+                    self.res_remote_path_of_example_path)
+                search_func(api_obj, remote, ["(%sbin/example_path)" % ip],
+                    self.res_remote_path_of_example_path)
+                search_func(api_obj, remote, ["<%sexam*:::>" % ip],
+                    set(), return_actions=False)
+                search_func(api_obj, remote,
+                    ["::%scom.sun.service.info_url:" % ip], set())
+                search_func(api_obj, remote,
+                    ["%sbin/e* AND %s*path" % (ip, ip)],
+                    self.res_remote_path_of_example_path)
+                search_func(api_obj, remote,
+                    ["(4851433 AND 4725245) OR :file::%sbin/example_path" % ip],
+                    self.res_remote_bug_id |
+                    self.res_remote_path_of_example_path)
+                search_func(api_obj, remote,
+                    [":::%sbin/example_path OR (4851433 AND 4725245)" % ip],
+                    self.res_remote_bug_id |
+                    self.res_remote_path_of_example_path)
+                search_func(api_obj, remote,
+                    ["%sbin/example_path OR %sbin/example_path" % (ip, ip)],
+                    self.res_remote_path_of_example_path)
+                search_func(api_obj, remote,
+                    ["<::path:%sbin/example_path> OR <(a AND b)>" % ip],
+                    self.res_remote_pkg_ret_pkg, return_actions=False)
+                search_func(api_obj, remote,
+                    ["<(a AND b)> OR <%sbin/example_path>" % ip],
+                    self.res_remote_pkg_ret_pkg, return_actions=False)
+                # The tests below here are for testing that multiple queries
+                # to search return the results from both queries (bug 10365)
+                search_func(api_obj, remote,
+                    ["<(a AND b)>",  "example_path"],
+                    self.res_remote_path)
+                search_func(api_obj, remote,
+                    ["example_path", "<(a AND b)>"],
+                    self.res_remote_path)
+                search_func(api_obj, remote,
+                    [":::%sbin/example_path" % ip, "(4851433 AND 4725245)"],
+                    self.res_remote_bug_id |
+                    self.res_remote_path_of_example_path)
+                search_func(api_obj, remote,
+                    ["(4851433 AND 4725245)", ":::%sbin/example_path" % ip],
+                    self.res_remote_bug_id |
+                    self.res_remote_path_of_example_path)
+
+        def _run_local_tests_example11_installed(self, api_obj):
+                outfile = os.path.join(self.testdata_dir, "res")
+
+                # This finds something because the client side
+                # manifest has had the name of the package inserted
+                # into it.
+
+                self._search_op(api_obj, False, "example_pkg",
+                    self.res_local_pkg_example11)
+                self._search_op(api_obj, False, "example_path", set())
+                self._search_op(api_obj, False, "example_path11",
+                    self.res_local_path_example11)
+                self._search_op(api_obj, False, "example*",
+                    self.res_local_wildcard_example11)
+                self._search_op(api_obj, False, "/bin",
+                    self.res_local_bin_example11)
+
+        def _run_local_empty_tests(self, api_obj):
+                self._search_op(api_obj, False, "example_pkg", set())
+                self._search_op(api_obj, False, "example_path", set())
+                self._search_op(api_obj, False, "example*", set())
+                self._search_op(api_obj, False, "/bin", set())
+
+        def _run_remote_empty_tests(self, api_obj):
+                self._search_op(api_obj, True, "example_pkg", set())
+                self._search_op(api_obj, True, "example_path", set())
+                self._search_op(api_obj, True, "example*", set())
+                self._search_op(api_obj, True, "/bin", set())
+                self._search_op(api_obj, True, "*unique*", set())
+
+        @staticmethod
+        def _restore_dir(index_dir, index_dir_tmp):
+                shutil.rmtree(index_dir)
+                shutil.move(index_dir_tmp, index_dir)
+
+        @staticmethod
+        def _restore_dir_preserve_hash(index_dir, index_dir_tmp):
+                tmp_file = "full_fmri_list.hash"
+                portable.remove(os.path.join(index_dir_tmp, tmp_file))
+                shutil.move(os.path.join(index_dir, tmp_file),
+                            index_dir_tmp)
+                fh = open(os.path.join(index_dir_tmp, ss.MAIN_FILE), "r")
+                fh.seek(0)
+                fh.seek(9)
+                ver = fh.read(1)
+                fh.close()
+                fh = open(os.path.join(index_dir_tmp, tmp_file), "r+")
+                fh.seek(0)
+                fh.seek(9)
+                # Overwrite the existing version number.
+                # By definition, the version 0 is never used.
+                fh.write("%s" % ver)
+                shutil.rmtree(index_dir)
+                shutil.move(index_dir_tmp, index_dir)
+
+        def _get_index_dirs(self):
+                index_dir = os.path.join(self.img_path, "var","pkg","index")
+                index_dir_tmp = index_dir + "TMP"
+                return index_dir, index_dir_tmp
+
+        @staticmethod
+        def _overwrite_version_number(file_path):
+                fh = open(file_path, "r+")
+                fh.seek(0)
+                fh.seek(9)
+                # Overwrite the existing version number.
+                # By definition, the version 0 is never used.
+                fh.write("0")
+                fh.close()
+
+        @staticmethod
+        def _overwrite_on_disk_format_version_number(file_path):
+                fh = open(file_path, "r+")
+                fh.seek(0)
+                fh.seek(16)
+                # Overwrite the existing version number.
+                # By definition, the version 0 is never used.
+                fh.write("9")
+                fh.close()
+
+        @staticmethod
+        def _overwrite_on_disk_format_version_number_with_letter(file_path):
+                fh = open(file_path, "r+")
+                fh.seek(0)
+                fh.seek(16)
+                # Overwrite the existing version number.
+                # By definition, the version 0 is never used.
+                fh.write("a")
+                fh.close()
+
+        @staticmethod
+        def _replace_on_disk_format_version(dir):
+                file_path = os.path.join(dir, ss.BYTE_OFFSET_FILE)
+                fh = open(file_path, "r")
+                lst = fh.readlines()
+                fh.close()
+                fh = open(file_path, "w")
+                fh.write(lst[0])
+                for l in lst[2:]:
+                        fh.write(l)
+                fh.close()
+
+        @staticmethod
+        def _overwrite_hash(ffh_path):
+                fd, tmp = tempfile.mkstemp()
+                portable.copyfile(ffh_path, tmp)
+                fh = open(tmp, "r+")
+                fh.seek(0)
+                fh.seek(20)
+                fh.write("*")
+                fh.close()
+                portable.rename(tmp, ffh_path)
+
+        def _check_no_index(self):
+                ind_dir, ind_dir_tmp = self._get_index_dirs()
+                if os.listdir(ind_dir):
+                        self.assert_(0)
+                if os.path.exists(ind_dir_tmp):
+                        self.assert_(0)
+
+        def _do_install(self, api_obj, pkg_list, **kwargs):
+                self.debug("install %s" % " ".join(pkg_list))
+                api_obj.plan_install(pkg_list, **kwargs)
+                self._do_finish(api_obj)
+
+        def _do_uninstall(self, api_obj, pkg_list, **kwargs):
+                self.debug("uninstall %s" % " ".join(pkg_list))
+                api_obj.plan_uninstall(pkg_list, False, **kwargs)
+                self._do_finish(api_obj)
+
+        def _do_image_update(self, api_obj, **kwargs):
+                self.debug("planning image-update")
+                api_obj.plan_update_all(sys.argv[0], verbose=False, **kwargs)
+                self._do_finish(api_obj)
+
+        def _do_finish(self, api_obj):
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+        @staticmethod
+        def validateAssertRaises(ex_type, validate_func, func, *args, **kwargs):
+                try:
+                        func(*args, **kwargs)
+                except ex_type, e:
+                        validate_func(e)
+                else:
+                        raise RuntimeError("Didn't raise expected exception.")
+
+        @staticmethod
+        def _check_err(e, expected_str, expected_code):
+                err = e.read()
+                if expected_code != e.code:
+                        raise RuntimeError("Got wrong code, expected %s got "
+                            "%s" % (expected_code, e.code))
+                if expected_str not in err:
+                        raise RuntimeError("Got unexpected error message of:\n"
+                            "%s" % err)
+
+
+class TestApiSearchBasicsP(TestApiSearchBasics):
+        # Only start/stop the depot once (instead of for every test)
+        persistent_setup = True
+
+        def __init__(self, *args, **kwargs):
+                TestApiSearchBasics.__init__(self, *args, **kwargs)
+                self.sent_pkgs = set()
+
+        def pkgsend_bulk(self, durl, pkg, optional=True):
+                if pkg not in self.sent_pkgs or optional == False:
+                        self.sent_pkgs.add(pkg)
+                        TestApiSearchBasics.pkgsend_bulk(self, durl, pkg)
+
+        def setUp(self):
+                TestApiSearchBasics.setUp(self)
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.example_pkg10)
+                self.pkgsend_bulk(durl, self.fat_pkg10)
+                self.pkgsend_bulk(durl, self.another_pkg10)
+
+        def test_010_remote(self):
+                """Test remote search."""
+                durl = self.dc.get_depot_url()
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+                time.sleep(1)
+                # This should be a full test to test all functionality.
+                self._run_full_remote_tests(api_obj)
+                self._search_op(api_obj, True, ":file::", self.res_remote_file)
+
+        def test_020_local_0(self):
+                """Install one package, and run the search suite."""
+                durl = self.dc.get_depot_url()
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                self._do_install(api_obj, ["example_pkg"])
+
+                self._run_full_local_tests(api_obj)
+
+        def test_030_degraded_local(self):
+                """Install one package, and run the search suite."""
+                durl = self.dc.get_depot_url()
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                self._do_install(api_obj, ["[email protected]"])
+
+                index_dir = os.path.join(self.img_path, "var","pkg","index")
+                shutil.rmtree(index_dir)
+
+                self._run_degraded_local_tests(api_obj)
+
+        def test_040_repeated_install_uninstall(self):
+                """Install and uninstall a package. Checking search both
+                after each change to the image."""
+                # During development, the index could become corrupted by
+                # repeated installing and uninstalling a package. This
+                # tests if that has been fixed.
+                repeat = 3
+
+                durl = self.dc.get_depot_url()
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                self._do_install(api_obj, ["[email protected]"])
+                self._do_uninstall(api_obj, ["example_pkg"])
+
+                for i in range(1, repeat):
+                        self._do_install(api_obj, ["example_pkg"])
+                        self._run_local_tests(api_obj)
+                        self._do_uninstall(api_obj, ["example_pkg"])
+                        api_obj.reset()
+                        self._run_local_empty_tests(api_obj)
+
+        def test_050_local_case_sensitive(self):
+                """Test local case sensitive search"""
+                durl = self.dc.get_depot_url()
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                self._do_install(api_obj, ["[email protected]"])
+                self._search_op(api_obj, False, "fooo", set(), True)
+                self._search_op(api_obj, False, "fo*", set(), True)
+                self._search_op(api_obj, False, "bar", set(), True)
+                self._search_op(api_obj, False, "FOOO", self.res_local_foo,
+                    True)
+                self._search_op(api_obj, False, "bAr", self.res_local_foo, True)
+
+        def test_060_missing_files(self):
+                """Test to check for stack trace when files missing.
+                Bug 2753"""
+                durl = self.dc.get_depot_url()
+
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+                self._do_install(api_obj, ["[email protected]"])
+
+                index_dir = os.path.join(self.img_path, "var","pkg","index")
+
+                first = True
+
+                for d in query_parser.TermQuery._global_data_dict.values():
+                        orig_fn = d.get_file_name()
+                        orig_path = os.path.join(index_dir, orig_fn)
+                        dest_fn = orig_fn + "TMP"
+                        dest_path = os.path.join(index_dir, dest_fn)
+                        portable.rename(orig_path, dest_path)
+                        self.assertRaises(api_errors.InconsistentIndexException,
+                            self._search_op, api_obj, False,
+                            "exam:::example_pkg", [])
+                        if first:
+                                # Run the shell version once to check that no
+                                # stack trace happens.
+                                self.pkg("search -l 'exam:::example_pkg'",
+                                    exit=1)
+                                first = False
+                        portable.rename(dest_path, orig_path)
+                        self._search_op(api_obj, False, "exam:::example_pkg",
+                            self.res_local_pkg)
+
+        def test_070_mismatched_versions(self):
+                """Test to check for stack trace when files missing.
+                Bug 2753"""
+                durl = self.dc.get_depot_url()
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+                self._do_install(api_obj, ["[email protected]"])
+
+                index_dir = os.path.join(self.img_path, "var","pkg","index")
+
+                first = True
+
+                for d in query_parser.TermQuery._global_data_dict.values():
+                        orig_fn = d.get_file_name()
+                        orig_path = os.path.join(index_dir, orig_fn)
+                        dest_fn = orig_fn + "TMP"
+                        dest_path = os.path.join(index_dir, dest_fn)
+                        shutil.copy(orig_path, dest_path)
+                        self._overwrite_version_number(orig_path)
+                        api_obj.reset()
+                        self.assertRaises(api_errors.InconsistentIndexException,
+                            self._search_op, api_obj, False,
+                            "exam:::example_pkg", [])
+                        if first:
+                                # Run the shell version once to check that no
+                                # stack trace happens.
+                                self.pkg("search -l 'exam:::example_pkg'",
+                                    exit=1)
+                                first = False
+                        portable.rename(dest_path, orig_path)
+                        self._search_op(api_obj, False, "example_pkg",
+                            self.res_local_pkg)
+                        self._overwrite_version_number(orig_path)
+                        self.assertRaises(
+                            api_errors.WrapSuccessfulIndexingException,
+                            self._do_uninstall, api_obj, ["example_pkg"])
+                        api_obj.reset()
+                        self._search_op(api_obj, False, "example_pkg", set())
+                        self._overwrite_version_number(orig_path)
+                        self.assertRaises(
+                            api_errors.WrapSuccessfulIndexingException,
+                            self._do_install, api_obj, ["example_pkg"])
+                        api_obj.reset()
+                        self._search_op(api_obj, False, "example_pkg",
+                            self.res_local_pkg)
+
+                ffh = ss.IndexStoreSetHash(ss.FULL_FMRI_HASH_FILE)
+                ffh_path = os.path.join(index_dir, ffh.get_file_name())
+                dest_fh, dest_path = tempfile.mkstemp()
+                shutil.copy(ffh_path, dest_path)
+                self._overwrite_hash(ffh_path)
+                self.assertRaises(api_errors.IncorrectIndexFileHash,
+                    self._search_op, api_obj, False, "example_pkg", set())
+                # Run the shell version of the test to check for a stack trace.
+                self.pkg("search -l 'exam:::example_pkg'", exit=1)
+                portable.rename(dest_path, ffh_path)
+                self._search_op(api_obj, False, "example_pkg",
+                    self.res_local_pkg)
+                self._overwrite_hash(ffh_path)
+                self.assertRaises(api_errors.WrapSuccessfulIndexingException,
+                    self._do_uninstall, api_obj, ["example_pkg"])
+                self._search_op(api_obj, False, "example_pkg", set())
+
+        def test_080_weird_patterns(self):
+                """Test strange patterns to ensure they're handled correctly"""
+                durl = self.dc.get_depot_url()
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                self._search_op(api_obj, True, "[*]", self.res_remote_weird)
+                self._search_op(api_obj, True, "[?]", self.res_remote_weird)
+                self._search_op(api_obj, True, "[[]", self.res_remote_weird)
+                self._search_op(api_obj, True, "[]]", self.res_remote_weird)
+                self._search_op(api_obj, True, "FO[O]O", self.res_remote_foo)
+                self._search_op(api_obj, True, "FO[?O]O", self.res_remote_foo)
+                self._search_op(api_obj, True, "FO[*O]O", self.res_remote_foo)
+                self._search_op(api_obj, True, "FO[]O]O", self.res_remote_foo)
+
+        def test_090_bug_7660(self):
+                """Test that installing a package doesn't prevent searching on
+                package names from working on previously installed packages."""
+                durl = self.dc.get_depot_url()
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                tmp_dir = os.path.join(self.img_path, "var", "pkg", "index",
+                    "TMP")
+                self._do_install(api_obj, ["example_pkg"])
+                api_obj.rebuild_search_index()
+                self._do_install(api_obj, ["fat"])
+                self.assert_(not os.path.exists(tmp_dir))
+                self._run_local_tests(api_obj)
+
+        def test_100_bug_6712_i386(self):
+                """Install one package, and run the search suite."""
+                durl = self.dc.get_depot_url()
+
+                self.image_create(durl,
+                    additional_args="--variant variant.arch=i386")
+
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                remote = True
+
+                self._search_op(api_obj, remote, "fat:::*",
+                    self.res_remote_fat10_star)
+                self._do_install(api_obj, ["fat"])
+                remote = False
+                self._search_op(api_obj, remote, "fat:::*",
+                    self.res_local_fat10_i386_star)
+
+        def test_110_bug_6712_sparc(self):
+                """Install one package, and run the search suite."""
+                durl = self.dc.get_depot_url()
+
+                self.image_create(durl,
+                    additional_args="--variant variant.arch=sparc")
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                remote = True
+
+                self._search_op(api_obj, remote, "fat:::*",
+                    self.res_remote_fat10_star)
+                self._do_install(api_obj, ["fat"])
+                remote = False
+                self._search_op(api_obj, remote, "fat:::*",
+                    self.res_local_fat10_sparc_star)
+
+        def test_120_bug_3046(self):
+                """Checks if directories ending in / break the indexer."""
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.bad_pkg10)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                self._search_op(api_obj, True, "foo", set())
+                self._search_op(api_obj, True, "/", set())
+
+        def test_130_bug_1059(self):
+                """Checks whether the fallback of removing the image root works.
+                Also tests whether multiple queries submitted via the api work.
+                """
+                durl = self.dc.get_depot_url()
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                ip = self.get_img_path()
+                if not ip.endswith("/"):
+                        ip += "/"
+
+                # Do remote searches
+                self._run_remove_root_search(self._search_op_multi, True,
+                    api_obj, ip)
+
+                self._do_install(api_obj, ["example_pkg"])
+                # Do local searches
+                self._run_remove_root_search(self._search_op_multi, False,
+                    api_obj, ip)
+
+                index_dir = os.path.join(self.img_path, "var","pkg","index")
+                shutil.rmtree(index_dir)
+                # Do slow local searches
+                self._run_remove_root_search(self._search_op_slow_multi, False,
+                    api_obj, ip)
+
+        def test_bug_2849(self):
+                """Checks if things with spaces break the indexer."""
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.space_pkg10)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                self._do_install(api_obj, ["space_pkg"])
+                time.sleep(1)
+
+                self.pkgsend_bulk(durl, self.space_pkg10, optional=False)
+                api_obj.refresh(immediate=True)
+
+                self._do_install(api_obj, ["space_pkg"])
+
+                remote = False
+                self._search_op(api_obj, remote, 'with', set())
+                self._search_op(api_obj, remote, 'with*',
+                    self.res_space_with_star)
+                self._search_op(api_obj, remote, '*space',
+                    self.res_space_space_star)
+                self._search_op(api_obj, remote, 'space', set())
+                self._search_op(api_obj, remote, 'unique_dir',
+                    self.res_space_unique)
+                remote = True
+                self._search_op(api_obj, remote, 'with', set())
+                self._search_op(api_obj, remote, 'with*',
+                    self.res_space_with_star)
+                self._search_op(api_obj, remote, '*space',
+                    self.res_space_space_star)
+                self._search_op(api_obj, remote, 'space', set())
+                time.sleep(1)
+                self.pkgsend_bulk(durl, self.space_pkg10, optional=False)
+                # Need to add install of subsequent package and
+                # local side search as well as remote
+                self._search_op(api_obj, remote, 'with', set())
+                self._search_op(api_obj, remote, 'with*',
+                    self.res_space_with_star)
+                self._search_op(api_obj, remote, '*space',
+                    self.res_space_space_star)
+                self._search_op(api_obj, remote, 'space', set())
+                self._search_op(api_obj, remote, 'unique_dir',
+                    self.res_space_unique)
+
+        def test_bug_2863(self):
+                """Check that disabling indexing works as expected"""
+                durl = self.dc.get_depot_url()
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                self._check_no_index()
+                self._do_install(api_obj, ["example_pkg"], update_index=False)
+                self._check_no_index()
+                api_obj.rebuild_search_index()
+                self._run_local_tests(api_obj)
+                self._do_uninstall(api_obj, ["example_pkg"], update_index=False)
+                # Running empty test because search will notice the index
+                # does not match the installed packages and complain.
+                self.assertRaises(api_errors.IncorrectIndexFileHash,
+                    self._search_op, api_obj, False, "example_pkg", set())
+                api_obj.rebuild_search_index()
+                self._run_local_empty_tests(api_obj)
+                self._do_install(api_obj, ["example_pkg"])
+                self._run_local_tests(api_obj)
+                self.pkgsend_bulk(durl, self.example_pkg11)
+                api_obj.refresh(immediate=True)
+                self._do_image_update(api_obj, update_index=False)
+                # Running empty test because search will notice the index
+                # does not match the installed packages and complain.
+                self.assertRaises(api_errors.IncorrectIndexFileHash,
+                    self._search_op, api_obj, False, "example_pkg", set())
+                api_obj.rebuild_search_index()
+                self._run_local_tests_example11_installed(api_obj)
+                self._do_uninstall(api_obj, ["example_pkg"], update_index=False)
+                # Running empty test because search will notice the index
+                # does not match the installed packages and complain.
+                self.assertRaises(api_errors.IncorrectIndexFileHash,
+                    self._search_op, api_obj, False, "example_pkg", set())
+                api_obj.rebuild_search_index()
+                self._run_local_empty_tests(api_obj)
+
+        def test_bug_2989_1(self):
+                durl = self.dc.get_depot_url()
+
+                for f in self._dir_restore_functions:
+                        self.image_create(durl)
+                        progresstracker = progress.NullProgressTracker()
+                        api_obj = api.ImageInterface(self.get_img_path(),
+                            API_VERSION, progresstracker, lambda x: False,
+                            PKG_CLIENT_NAME)
+                        api_obj.rebuild_search_index()
+
+                        index_dir, index_dir_tmp = self._get_index_dirs()
+
+                        shutil.copytree(index_dir, index_dir_tmp)
+
+                        self._do_install(api_obj, ["example_pkg"])
+
+                        f(index_dir, index_dir_tmp)
+
+                        self.assertRaises(
+                            api_errors.WrapSuccessfulIndexingException,
+                            self._do_uninstall, api_obj, ["example_pkg"])
+
+                        self.image_destroy()
+
+        def test_bug_2989_2(self):
+                durl = self.dc.get_depot_url()
+
+                for f in self._dir_restore_functions:
+
+                        self.image_create(durl)
+                        progresstracker = progress.NullProgressTracker()
+                        api_obj = api.ImageInterface(self.get_img_path(),
+                            API_VERSION, progresstracker, lambda x: False,
+                            PKG_CLIENT_NAME)
+                        self._do_install(api_obj, ["example_pkg"])
+
+                        index_dir, index_dir_tmp = self._get_index_dirs()
+
+                        shutil.copytree(index_dir, index_dir_tmp)
+
+                        self._do_install(api_obj, ["another_pkg"])
+
+                        f(index_dir, index_dir_tmp)
+
+                        self.assertRaises(
+                            api_errors.WrapSuccessfulIndexingException,
+                            self._do_uninstall, api_obj, ["another_pkg"])
+
+                        self.image_destroy()
+
+        def test_bug_2989_3(self):
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.example_pkg11)
+
+                for f in self._dir_restore_functions:
+
+                        self.image_create(durl)
+                        progresstracker = progress.NullProgressTracker()
+                        api_obj = api.ImageInterface(self.get_img_path(),
+                            API_VERSION, progresstracker, lambda x: False,
+                            PKG_CLIENT_NAME)
+                        self._do_install(api_obj, ["[email protected],5.11-0"])
+
+                        index_dir, index_dir_tmp = self._get_index_dirs()
+
+                        shutil.copytree(index_dir, index_dir_tmp)
+
+                        self._do_install(api_obj, ["example_pkg"])
+
+                        f(index_dir, index_dir_tmp)
+
+                        self.assertRaises(
+                            api_errors.WrapSuccessfulIndexingException,
+                            self._do_uninstall, api_obj, ["example_pkg"])
+
+                        self.image_destroy()
+
+        def test_bug_2989_4(self):
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.example_pkg11)
+
+                for f in self._dir_restore_functions:
+
+                        self.image_create(durl)
+                        progresstracker = progress.NullProgressTracker()
+                        api_obj = api.ImageInterface(self.get_img_path(),
+                            API_VERSION, progresstracker, lambda x: False,
+                            PKG_CLIENT_NAME)
+                        self._do_install(api_obj, ["another_pkg"])
+
+                        index_dir, index_dir_tmp = self._get_index_dirs()
+
+                        shutil.copytree(index_dir, index_dir_tmp)
+
+                        self._do_install(api_obj, ["[email protected],5.11-0"])
+
+                        f(index_dir, index_dir_tmp)
+
+                        self.assertRaises(
+                            api_errors.WrapSuccessfulIndexingException,
+                            self._do_image_update, api_obj)
+
+                        self.image_destroy()
+
+        def test_bug_4239(self):
+                """Tests whether categories are indexed and searched for
+                correctly."""
+
+                def _run_cat_tests(self, remote):
+                        self._search_op(api_obj, remote, "System",
+                            self.res_cat_pkg10, case_sensitive=False)
+                        self._search_op(api_obj, remote, "Security",
+                            self.res_cat_pkg10, case_sensitive=False)
+                        self._search_op(api_obj, remote, "System/Security",
+                            self.res_cat_pkg10, case_sensitive=False)
+                        self._search_op(api_obj, remote, "Other/Category",
+                            self.res_cat_pkg10_2, case_sensitive=False)
+                        self._search_op(api_obj, remote, "Other",
+                            self.res_cat_pkg10_2, case_sensitive=False)
+                        self._search_op(api_obj, remote, "Category",
+                            self.res_cat_pkg10_2, case_sensitive=False)
+
+                def _run_cat2_tests(self, remote):
+                        self._search_op(api_obj, remote, "Applications",
+                            self.res_cat2_pkg10, case_sensitive=False)
+                        self._search_op(api_obj, True, "Sound",
+                            self.res_cat2_pkg10, case_sensitive=False)
+                        self._search_op(api_obj, remote, "Sound and Video",
+                            self.res_cat2_pkg10, case_sensitive=False)
+                        self._search_op(api_obj, remote, "Sound*",
+                            self.res_cat2_pkg10, case_sensitive=False)
+                        self._search_op(api_obj, remote, "*Video",
+                            self.res_cat2_pkg10, case_sensitive=False)
+                        self._search_op(api_obj, remote,
+                            "'Applications/Sound and Video'",
+                            self.res_cat2_pkg10, case_sensitive=False)
+                        # This is a test for bug 11002 which ensures that the
+                        # unquoting is being performed correctly.
+                        self._search_op(api_obj, remote,
+                            "'Applications/Sound%20and%20Video'",
+                            set(), case_sensitive=False)
+                        self._search_op(api_obj, remote, "Developer/C",
+                            self.res_cat2_pkg10_2, case_sensitive=False)
+                        self._search_op(api_obj, remote, "Developer",
+                            self.res_cat2_pkg10_2, case_sensitive=False)
+                        self._search_op(api_obj, remote, "C",
+                            self.res_cat2_pkg10_2, case_sensitive=False)
+
+                def _run_cat3_tests(self, remote):
+                        self._search_op(api_obj, remote, "foo",
+                            self.res_cat3_pkg10,case_sensitive=False)
+                        self._search_op(api_obj, remote, "baz",
+                            self.res_cat3_pkg10, case_sensitive=False)
+                        self._search_op(api_obj, remote, "asda",
+                            self.res_cat3_pkg10, case_sensitive=False)
+                        self._search_op(api_obj, remote,
+                            "foo/bar/baz/bill/beam/asda", self.res_cat3_pkg10,
+                            case_sensitive=False)
+
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.cat_pkg10)
+                self.pkgsend_bulk(durl, self.cat2_pkg10)
+                self.pkgsend_bulk(durl, self.cat3_pkg10)
+                self.pkgsend_bulk(durl, self.bad_cat_pkg10)
+                self.pkgsend_bulk(durl, self.bad_cat2_pkg10)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                remote = True
+                _run_cat_tests(self, remote)
+                _run_cat2_tests(self, remote)
+                _run_cat3_tests(self, remote)
+
+                remote = False
+                self._do_install(api_obj, ["cat"])
+                _run_cat_tests(self, remote)
+
+                self._do_install(api_obj, ["cat2"])
+                _run_cat2_tests(self, remote)
+
+                self._do_install(api_obj, ["cat3"])
+                _run_cat3_tests(self, remote)
+
+                self._do_install(api_obj, ["badcat"])
+                self._do_install(api_obj, ["badcat2"])
+                _run_cat_tests(self, remote)
+                _run_cat2_tests(self, remote)
+                _run_cat3_tests(self, remote)
+
+        def test_bug_7628(self):
+                """Checks whether incremental update generates wrong
+                additional lines."""
+                durl = self.dc.get_depot_url()
+                depotpath = self.dc.get_repodir()
+                ind_dir = os.path.join(depotpath, "index")
+                tok_file = os.path.join(ind_dir, ss.BYTE_OFFSET_FILE)
+                main_file = os.path.join(ind_dir, ss.MAIN_FILE)
+                self.pkgsend_bulk(durl, self.example_pkg10)
+                time.sleep(1)
+                fh = open(tok_file)
+                tok_1 = fh.readlines()
+                tok_len = len(tok_1)
+                fh.close()
+                fh = open(main_file)
+                main_1 = fh.readlines()
+                main_len = len(main_1)
+                self.pkgsend_bulk(durl, self.example_pkg10, optional=False)
+                time.sleep(1)
+                fh = open(tok_file)
+                tok_2 = fh.readlines()
+                new_tok_len = len(tok_2)
+                fh.close()
+                fh = open(main_file)
+                main_2 = fh.readlines()
+                new_main_len = len(main_2)
+                fh.close()
+                # Since the server now adds a set action for the FMRI to
+                # manifests during publication, there should be one
+                # additional line for the token file.
+                self.assertEqual(new_tok_len, tok_len + 1)
+                self.assertEqual(new_main_len, main_len + 1)
+
+        def test_bug_983(self):
+                """Test for known bug 983."""
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.bug_983_manifest)
+                time.sleep(2)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                self._search_op(api_obj, True, "gmake", self.res_bug_983)
+                self._search_op(api_obj, True, "[email protected]",
+                    self.res_983_csl_dependency)
+                self._search_op(api_obj, True, "SUNWcsl",
+                    self.res_983_csl_dependency)
+                self._search_op(api_obj, True, "[email protected]",
+                    self.res_983_bar_dependency)
+                self._search_op(api_obj, True, "SUNWtestbar",
+                    self.res_983_bar_dependency)
+                self._search_op(api_obj, True, "[email protected]",
+                    self.res_983_foo_dependency)
+                self._search_op(api_obj, True, "SUNWtestfoo",
+                    self.res_983_foo_dependency)
+                self._search_op(api_obj, True, "depend:require:",
+                    self.res_983_csl_dependency | self.res_983_bar_dependency)
+                self._search_op(api_obj, True, "depend:incorporate:",
+                    self.res_983_foo_dependency)
+                self._search_op(api_obj, True, "depend::",
+                    self.res_983_csl_dependency | self.res_983_bar_dependency |
+                    self.res_983_foo_dependency)
+
+        def test_bug_7534(self):
+                """Tests that an automatic reindexing is detected by the test
+                suite."""
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.example_pkg10)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                index_dir = os.path.join(self.img_path, "var","pkg","index")
+
+                orig_fn = os.path.join(index_dir,
+                    query_parser.TermQuery._global_data_dict.values()[0].\
+                    get_file_name())
+                dest_fn = orig_fn + "TMP"
+
+                self._do_install(api_obj, ["example_pkg"])
+                api_obj.rebuild_search_index()
+
+                portable.rename(orig_fn, dest_fn)
+                self.assertRaises(api_errors.WrapSuccessfulIndexingException,
+                    self._do_uninstall, api_obj, ["example_pkg"])
+
+        def test_bug_8492(self):
+                """Tests that field queries and phrase queries work together.
+                """
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.bug_8492_manf_1)
+                self.pkgsend_bulk(durl, self.bug_8492_manf_2)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                self._search_op(api_obj, True, "set::'image packaging'",
+                    self.res_8492_1 | self.res_8492_2)
+                self._search_op(api_obj, True, "b1:set::'image packaging'",
+                    self.res_8492_1)
+
+                self._do_install(api_obj, ["b1", "b2"])
+
+                self._search_op(api_obj, False, "set::'image packaging'",
+                    self.res_8492_1 | self.res_8492_2)
+                self._search_op(api_obj, False, "b2:set::'image packaging'",
+                    self.res_8492_2)
+
+                api_obj.rebuild_search_index()
+
+                self._search_op(api_obj, True, "set::'image packaging'",
+                    self.res_8492_1 | self.res_8492_2)
+                self._search_op(api_obj, True, "b1:set::'image packaging'",
+                    self.res_8492_1)
+
+        def test_bug_9845_01(self):
+                """Test that a corrupt query doesn't break the server."""
+                durl = self.dc.get_depot_url()
+                expected_string = _("A query is expected to have five fields: "
+                    "case sensitivity, return type, number of results to "
+                    "return, the number at which to start returning results, "
+                    "and the text of the query.  The query provided lacked at "
+                    "least one of those fields:")
+                expected_code = 404
+                q_str = "foo"
+                self.validateAssertRaises(urllib2.HTTPError,
+                    lambda x: self._check_err(x, expected_string,
+                        expected_code),
+                    urllib2.urlopen, durl + "/search/1/" + q_str)
+
+        def test_bug_9845_02(self):
+                """Test that a corrupt case_sensitive value doesn't break the "
+                server."""
+                durl = self.dc.get_depot_url()
+                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
+                    "name": "case_sensitive",
+                    "bv": "FAlse"
+                }
+                expected_code = 404
+                q_str = "FAlse_2_None_None_foo"
+                self.validateAssertRaises(urllib2.HTTPError,
+                    lambda x: self._check_err(x, expected_string,
+                        expected_code),
+                    urllib2.urlopen, durl + "/search/1/" + q_str)
+
+        def test_bug_9845_03(self):
+                """Test that a corrupt return_type value doesn't break the "
+                server."""
+                durl = self.dc.get_depot_url()
+                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
+                    "name": "return_type",
+                    "bv": "3"
+                }
+                expected_code = 404
+                q_str = "False_3_None_None_foo"
+                self.validateAssertRaises(urllib2.HTTPError,
+                    lambda x: self._check_err(x, expected_string,
+                        expected_code),
+                    urllib2.urlopen, durl + "/search/1/" + q_str)
+
+        def test_bug_9845_04(self):
+                """Test that a corrupt return_type value doesn't break the "
+                server."""
+                durl = self.dc.get_depot_url()
+                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
+                    "name": "return_type",
+                    "bv": "A"
+                }
+                expected_code = 404
+                q_str = "False_A_None_None_foo"
+                self.validateAssertRaises(urllib2.HTTPError,
+                    lambda x: self._check_err(x, expected_string,
+                        expected_code),
+                    urllib2.urlopen, durl + "/search/1/" + q_str)
+
+        def test_bug_9845_05(self):
+                """Test that a corrupt num_to_return value doesn't break the "
+                server."""
+                durl = self.dc.get_depot_url()
+                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
+                    "name": "num_to_return",
+                    "bv": "NOne"
+                }
+                expected_code = 404
+                q_str = "False_2_NOne_None_foo"
+                self.validateAssertRaises(urllib2.HTTPError,
+                    lambda x: self._check_err(x, expected_string,
+                        expected_code),
+                    urllib2.urlopen, durl + "/search/1/" + q_str)
+
+        def test_bug_9845_06(self):
+                """Test that a corrupt start_point value doesn't break the "
+                server."""
+                durl = self.dc.get_depot_url()
+                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
+                    "name": "start_point",
+                    "bv": "NOne"
+                }
+                expected_code = 404
+                q_str = "False_2_None_NOne_foo"
+                self.validateAssertRaises(urllib2.HTTPError,
+                    lambda x: self._check_err(x, expected_string,
+                        expected_code),
+                    urllib2.urlopen, durl + "/search/1/" + q_str)
+
+        def test_bug_9845_07(self):
+                """Test that a corrupt case_sensitive value doesn't break the "
+                server."""
+                durl = self.dc.get_depot_url()
+                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
+                    "name": "case_sensitive",
+                    "bv": ""
+                }
+                expected_code = 404
+                q_str = "_2_None_None_foo"
+                self.validateAssertRaises(urllib2.HTTPError,
+                    lambda x: self._check_err(x, expected_string,
+                        expected_code),
+                    urllib2.urlopen, durl + "/search/1/" + q_str)
+
+        def test_bug_9845_08(self):
+                """Test that a missing return_type value doesn't break the "
+                server."""
+                durl = self.dc.get_depot_url()
+                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
+                    "name": "return_type",
+                    "bv": ""
+                }
+                expected_code = 404
+                q_str = "False__None_None_foo"
+                self.validateAssertRaises(urllib2.HTTPError,
+                    lambda x: self._check_err(x, expected_string,
+                        expected_code),
+                    urllib2.urlopen, durl + "/search/1/" + q_str)
+
+        def test_bug_9845_09(self):
+                """Test that a missing num_to_return value doesn't break the "
+                server."""
+                durl = self.dc.get_depot_url()
+                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
+                    "name": "num_to_return",
+                    "bv": ""
+                }
+                expected_code = 404
+                q_str = "False_2__None_foo"
+                self.validateAssertRaises(urllib2.HTTPError,
+                    lambda x: self._check_err(x, expected_string,
+                        expected_code),
+                    urllib2.urlopen, durl + "/search/1/" + q_str)
+
+        def test_bug_9845_10(self):
+                """Test that a missing start_point value doesn't break the "
+                server."""
+                durl = self.dc.get_depot_url()
+                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
+                    "name": "start_point",
+                    "bv": ""
+                }
+                expected_code = 404
+                q_str = "False_2_None__foo"
+                self.validateAssertRaises(urllib2.HTTPError,
+                    lambda x: self._check_err(x, expected_string,
+                        expected_code),
+                    urllib2.urlopen, durl + "/search/1/" + q_str)
+
+        def test_bug_9845_11(self):
+                """Test that missing query text doesn't break the server."""
+                durl = self.dc.get_depot_url()
+                expected_string = _("Could not parse query.")
+                expected_code = 400
+                q_str = "False_2_None_None_"
+                self.validateAssertRaises(urllib2.HTTPError,
+                    lambda x: self._check_err(x, expected_string,
+                        expected_code),
+                    urllib2.urlopen, durl + "/search/1/" + q_str)
+
+
+class TestApiSearchBasics_nonP(TestApiSearchBasics):
+        def setUp(self):
+                self.debug_features = ["headers"]
+                TestApiSearchBasics.setUp(self)
+
+        def test_local_image_update(self):
+                """Test that the index gets updated by image-update and
+                that rebuilding the index works after updating the
+                image. Specifically, this tests that rebuilding indexes with
+                gaps in them works correctly."""
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.example_pkg10)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                self._do_install(api_obj, ["example_pkg"])
+
+                self.pkgsend_bulk(durl, self.example_pkg11)
+                api_obj.refresh(immediate=True)
+
+                self._do_image_update(api_obj)
+
+                self._run_local_tests_example11_installed(api_obj)
+
+                api_obj.rebuild_search_index()
+
+                self._run_local_tests_example11_installed(api_obj)
+
+        def test_bug_4048_1(self):
+                """Checks whether the server deals with partial indexing."""
+                durl = self.dc.get_depot_url()
+                depotpath = self.dc.get_repodir()
+                tmp_dir = os.path.join(depotpath, "index", "TMP")
+                os.mkdir(tmp_dir)
+                self.pkgsend_bulk(durl, self.example_pkg10)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+                self._run_remote_empty_tests(api_obj)
+                os.rmdir(tmp_dir)
+                offset = 2
+                depot_logfile = os.path.join(self.test_root,
+                    "depot_logfile%d" % offset)
+                tmp_dc = self.start_depot(12000 + offset, depotpath,
+                    depot_logfile, refresh_index=True)
+                time.sleep(1)
+                # This should do something other than sleep for 1 sec
+                self._run_remote_tests(api_obj)
+                tmp_dc.kill()
+
+        def test_bug_4048_2(self):
+                """Checks whether the server deals with partial indexing."""
+                durl = self.dc.get_depot_url()
+                depotpath = self.dc.get_repodir()
+                tmp_dir = os.path.join(depotpath, "index", "TMP")
+                os.mkdir(tmp_dir)
+                self.pkgsend_bulk(durl, self.space_pkg10)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+                self._run_remote_empty_tests(api_obj)
+                os.rmdir(tmp_dir)
+                self.pkgsend_bulk(durl, self.example_pkg10)
+                time.sleep(1)
+                self._run_remote_tests(api_obj)
+                self._search_op(api_obj, True, "unique_dir",
+                    self.res_space_unique)
+                self._search_op(api_obj, True, "with*",
+                    self.res_space_with_star)
+
+        def __corrupt_depot(self, ind_dir):
+                self.dc.stop()
+                if os.path.exists(os.path.join(ind_dir, ss.MAIN_FILE)):
+                        shutil.move(os.path.join(ind_dir, ss.MAIN_FILE),
+                            os.path.join(ind_dir, "main_dict.ascii.v1"))
+                self.dc.start()
+
+        def __wait_for_indexing(self, d):
+                init_time = time.time()
+                there = True
+                while there and ((time.time() - init_time) < 10):
+                        there = os.path.exists(d)
+                self.assert_(not there)
+                time.sleep(1)
+
+        def test_bug_7358_1(self):
+                """Move files so that an inconsistent index is created and
+                check that the server rebuilds the index when possible, and
+                doesn't stack trace when it can't write to the directory."""
+
+                durl = self.dc.get_depot_url()
+                depotpath = self.dc.get_repodir()
+                ind_dir = os.path.join(depotpath, "index")
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+                # Check when depot is empty.
+                self.__corrupt_depot(ind_dir)
+                self.__wait_for_indexing(os.path.join(ind_dir, "TMP"))
+                # Since the depot is empty, should return no results but
+                # not error.
+                self._search_op(api_obj, True, 'e*', set())
+
+                self.pkgsend_bulk(durl, self.example_pkg10)
+                self.__wait_for_indexing(os.path.join(ind_dir, "TMP"))
+
+                # Check when depot contains a package.
+                self.__corrupt_depot(ind_dir)
+                self.__wait_for_indexing(os.path.join(ind_dir, "TMP"))
+                self._run_remote_tests(api_obj)
+
+        def test_bug_7358_2(self):
+                """Does same check as 7358_1 except it checks for interactions
+                with writable root."""
+
+                durl = self.dc.get_depot_url()
+                depotpath = self.dc.get_repodir()
+                ind_dir = os.path.join(depotpath, "index")
+                shutil.rmtree(ind_dir)
+                writable_root = os.path.join(self.test_root,
+                    "writ_root")
+                writ_dir = os.path.join(writable_root, "index")
+                self.dc.set_writable_root(writable_root)
+
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+
+                # Check when depot is empty.
+                self.__corrupt_depot(writ_dir)
+                # Since the depot is empty, should return no results but
+                # not error.
+                self.assert_(not os.path.isdir(ind_dir))
+                self.__wait_for_indexing(os.path.join(writ_dir, "TMP"))
+                self._search_op(api_obj, True, 'e*', set())
+
+                self.pkgsend_bulk(durl, self.example_pkg10)
+                self.__wait_for_indexing(os.path.join(writ_dir, "TMP"))
+
+                # Check when depot contains a package.
+                self.__corrupt_depot(writ_dir)
+                self.__wait_for_indexing(os.path.join(writ_dir, "TMP"))
+                self.assert_(not os.path.isdir(ind_dir))
+                self._run_remote_tests(api_obj)
+
+        def test_bug_8318(self):
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.example_pkg10)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+                uuids = []
+                for p in api_obj.img.gen_publishers():
+                        uuids.append(p.client_uuid)
+
+                self._search_op(api_obj, True, "example_path",
+                    self.res_remote_path)
+                self._search_op(api_obj, True, "example_path",
+                    self.res_remote_path, servers=[{"origin": durl}])
+                lfh = file(self.dc.get_logpath(), "rb")
+                found = 0
+                num_expected = 8
+                for line in lfh:
+                        if "X-IPKG-UUID:" in line:
+                                tmp = line.split()
+                                s_uuid = tmp[1]
+                                if s_uuid not in uuids:
+                                        raise RuntimeError("Uuid found:%s not "
+                                            "found in list of possible "
+                                            "uuids:%s" % (s_uuid, uuids))
+                                found += 1
+                if found != num_expected:
+                        raise RuntimeError(("Found %s instances of a "
+                            "client uuid, expected to find %s.") %
+                            (found, num_expected))
+
+        def test_bug_9729_1(self):
+                """Test that installing more than
+                indexer.MAX_ADDED_NUMBER_PACKAGES packages at a time doesn't
+                cause any type of indexing error."""
+                durl = self.dc.get_depot_url()
+                pkg_list = []
+                for i in range(0, indexer.MAX_ADDED_NUMBER_PACKAGES + 1):
+                        self.pkgsend_bulk(durl,
+                            "open pkg%[email protected],5.11-0\nclose\n" % i)
+                        pkg_list.append("pkg%s" % i)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+                self._do_install(api_obj, pkg_list)
+
+        def test_bug_9729_2(self):
+                """Test that installing more than
+                indexer.MAX_ADDED_NUMBER_PACKAGES packages one after another
+                doesn't cause any type of indexing error."""
+                def _remove_extra_info(v):
+                        return v.split("-")[0]
+                durl = self.dc.get_depot_url()
+                pkg_list = []
+                for i in range(0, indexer.MAX_ADDED_NUMBER_PACKAGES + 3):
+                        self.pkgsend_bulk(durl,
+                            "open pkg%[email protected],5.11-0\nclose\n" % i)
+                        pkg_list.append("pkg%s" % i)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+                fast_add_loc = os.path.join(self._get_index_dirs()[0],
+                    "fast_add.v1")
+                fast_remove_loc = os.path.join(self._get_index_dirs()[0],
+                    "fast_remove.v1")
+                api_obj.rebuild_search_index()
+                for p in pkg_list:
+                        self._do_install(api_obj, [p])
+                # Test for bug 11104. The fast_add.v1 file was not being updated
+                # correctly by install or image update, it was growing with
+                # each modification.
+                self._check(set((
+                    _remove_extra_info(v)
+                    for v in self._get_lines(fast_add_loc)
+                    )), self.fast_add_after_install)
+                self._check(set((
+                    _remove_extra_info(v)
+                    for v in self._get_lines(fast_remove_loc)
+                    )), self.fast_remove_after_install)
+                # Now check that image update also handles fast_add
+                # appropriately when a small number of packages have changed.
+                for i in range(0, 2):
+                        self.pkgsend_bulk(durl,
+                            "open pkg%[email protected],5.11-0\nclose\n" % i)
+                        pkg_list.append("pkg%s" % i)
+                api_obj.refresh(immediate=True)
+                self._do_image_update(api_obj)
+                self._check(set((
+                    _remove_extra_info(v)
+                    for v in self._get_lines(fast_add_loc)
+                    )), self.fast_add_after_first_update)
+
+                self._check(set((
+                    _remove_extra_info(v)
+                    for v in self._get_lines(fast_remove_loc)
+                    )), self.fast_remove_after_first_update)
+                # Now check that image update also handles fast_add
+                # appropriately when a large number of packages have changed.
+                for i in range(3, indexer.MAX_ADDED_NUMBER_PACKAGES + 3):
+                        self.pkgsend_bulk(durl,
+                            "open pkg%[email protected],5.11-0\nclose\n" % i)
+                        pkg_list.append("pkg%s" % i)
+                api_obj.refresh(immediate=True)
+                self._do_image_update(api_obj)
+                self._check(set((
+                    _remove_extra_info(v)
+                    for v in self._get_lines(fast_add_loc)
+                    )), self.fast_add_after_second_update)
+                self._check(set((
+                    _remove_extra_info(v)
+                    for v in self._get_lines(fast_remove_loc)
+                    )), self.fast_remove_after_second_update)
+
+        def test_bug_13485(self):
+                """Test that indexer.Indexer's check_for_updates function works
+                as excepted. This needs to be a separate test because other
+                tests are likely to conintue working while reindexing more
+                frequently than they should."""
+
+                durl = self.dc.get_depot_url()
+                depotpath = self.dc.get_repodir()
+                ind_dir = os.path.join(depotpath, "index")
+                repo = srepo.Repository(repo_root=depotpath, read_only=True,
+                    fork_allowed=False, refresh_index=False)
+
+                # Check that an empty index works correctly.
+                fmris = indexer.Indexer.check_for_updates(ind_dir, repo.catalog)
+                self.assertEqual(set(), fmris)
+
+                self.pkgsend_bulk(durl, self.example_pkg10)
+                self.__wait_for_indexing(os.path.join(ind_dir, "TMP"))
+                repo = srepo.Repository(repo_root=depotpath, fork_allowed=False)
+                self.assertEqual(len(set(repo.catalog.fmris())), 1)
+                # Check that after publishing one package, no packages need
+                # indexing.
+                fmris = indexer.Indexer.check_for_updates(ind_dir, repo.catalog)
+                self.assertEqual(set(), fmris)
+                
+                back_dir = ind_dir + ".BACKUP"
+                shutil.copytree(ind_dir, back_dir)
+                self.pkgsend_bulk(durl, self.example_pkg10)
+                repo = srepo.Repository(repo_root=depotpath, fork_allowed=False)
+                self.assertEqual(len(set(repo.catalog.fmris())), 2)
+                # Check that publishing a second package also works.
+                fmris = indexer.Indexer.check_for_updates(ind_dir, repo.catalog)
+                self.assertEqual(set(), fmris)
+
+                # Check that a package that was publisher but not index is
+                # reported.
+                fmris = indexer.Indexer.check_for_updates(back_dir,
+                    repo.catalog)
+                self.assertEqual(len(fmris), 1)
+
+
+class TestApiSearchMulti(pkg5unittest.ManyDepotTestCase):
+
+        example_pkg10 = """
+            open [email protected],5.11-0
+            add dir mode=0755 owner=root group=bin path=/bin/example_dir
+            close """
+
+        res_alternate_server_local = set([
+            ('pkg:/[email protected]', 'test2/example_pkg',
+            'set name=pkg.fmri value=pkg://test2/[email protected],5.11-0:')
+        ])
+
+        def _do_install(self, api_obj, pkg_list, **kwargs):
+                self.debug("install %s" % " ".join(pkg_list))
+                api_obj.plan_install(pkg_list, **kwargs)
+                self._do_finish(api_obj)
+
+        def _do_uninstall(self, api_obj, pkg_list, **kwargs):
+                self.debug("uninstall %s" % " ".join(pkg_list))
+                api_obj.plan_uninstall(pkg_list, False, **kwargs)
+                self._do_finish(api_obj)
+
+        def _do_image_update(self, api_obj, **kwargs):
+                self.debug("planning image-update")
+                api_obj.plan_update_all(sys.argv[0], verbose=False, **kwargs)
+                self._do_finish(api_obj)
+
+        def _do_finish(self, api_obj):
+                api_obj.prepare()
+                api_obj.execute_plan()
+                api_obj.reset()
+
+        def setUp(self):
+                pkg5unittest.ManyDepotTestCase.setUp(self, ["test1", "test2",
+                    "test3"], debug_features=["headers"])
+
+                self.durl1 = self.dcs[1].get_depot_url()
+                self.durl2 = self.dcs[2].get_depot_url()
+                self.durl3 = self.dcs[3].get_depot_url()
+                self.pkgsend_bulk(self.durl2, self.example_pkg10)
+
+                self.image_create(self.durl1, prefix="test1")
+                self.pkg("set-publisher -O " + self.durl2 + " test2")
+
+        def _check(self, proposed_answer, correct_answer):
+                if correct_answer == proposed_answer:
+                        return True
+                else:
+                        self.debug("Proposed Answer: " + str(proposed_answer))
+                        self.debug("Correct Answer : " + str(correct_answer))
+                        if isinstance(correct_answer, set) and \
+                            isinstance(proposed_answer, set):
+                                print >> sys.stderr, "Missing: " + \
+                                    str(correct_answer - proposed_answer)
+                                print >> sys.stderr, "Extra  : " + \
+                                    str(proposed_answer - correct_answer)
+                        self.assert_(correct_answer == proposed_answer)
+
+        @staticmethod
+        def _extract_action_from_res(it, err):
+                res = []
+                if err:
+                        try:
+                                for query_num, auth, (version, return_type,
+                                    (pkg_name, piece, act)) in it:
+                                        res.append((fmri.PkgFmri(str(
+                                            pkg_name)).get_short_fmri(), piece,
+                                            TestApiSearchBasics._replace_act(
+                                            act)),)
+                        except err, e:
+                                return res
+                        else:
+                                raise RuntimeError(
+                                    "Didn't get expected error:%s" % err)
+                else:
+                        return TestApiSearchBasics._extract_action_from_res(it)
+                        
+
+        def _search_op(self, api_obj, remote, token, test_value,
+            case_sensitive=False, return_actions=True, num_to_return=None,
+            start_point=None, servers=None, expected_err=None):
+                search_func = api_obj.local_search
+                query = api.Query(token, case_sensitive, return_actions,
+                    num_to_return, start_point)
+                if remote:
+                        search_func = api_obj.remote_search
+                        res = set(self._extract_action_from_res(
+                            search_func([query], servers=servers),
+                            expected_err))
+                else:
+                        res = set(TestApiSearchBasics._extract_action_from_res(
+                            search_func([query])))
+                self._check(set(res), test_value)
+
+        def test_bug_2955(self):
+                """See http://defect.opensolaris.org/bz/show_bug.cgi?id=2955"""
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+                self._do_install(api_obj, ["example_pkg"])
+
+                # Test for bug 10690 by checking whether the fmri names
+                # for packages installed from the non-preferred publisher
+                # are parsed correctly. Specifically, test whether the name
+                # alone is searchable, as well as the publisher/name
+                # combination.
+                self._search_op(api_obj, False, "set::test2/example_pkg",
+                    self.res_alternate_server_local)
+                self._search_op(api_obj, False, "set::example_pkg",
+                    self.res_alternate_server_local)
+                self._search_op(api_obj, False, "set::test2/*",
+                    self.res_alternate_server_local)
+                api_obj.rebuild_search_index()
+                self._search_op(api_obj, False, "set::test2/example_pkg",
+                    self.res_alternate_server_local)
+                self._search_op(api_obj, False, "set::example_pkg",
+                    self.res_alternate_server_local)
+                self._search_op(api_obj, False, "set::test2/*",
+                    self.res_alternate_server_local)
+                self._do_uninstall(api_obj, ["example_pkg"])
+
+        def test_bug_8318(self):
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                self._search_op(api_obj, True,
+                    "this_should_not_match_any_token", set())
+                self._search_op(api_obj, True, "example_path",
+                    set(), servers=[{"origin": self.durl1}])
+                self._search_op(api_obj, True, "example_path",
+                    set(), servers=[{"origin": self.durl3}])
+                num_expected = { 1: 7, 2: 4, 3: 0 }
+                for d in range(1,(len(self.dcs) + 1)):
+                        try:
+                                pub = api_obj.img.get_publisher(
+                                    origin=self.dcs[d].get_depot_url())
+                                c_uuid = pub.client_uuid
+                        except api_errors.UnknownPublisher:
+                                c_uuid = None
+                        lfh = file(self.dcs[d].get_logpath(), "rb")
+                        found = 0
+                        for line in lfh:
+                                if "X-IPKG-UUID:" in line:
+                                        tmp = line.split()
+                                        s_uuid = tmp[1]
+                                        if s_uuid != c_uuid:
+                                                raise RuntimeError(
+                                                    "Found uuid:%s doesn't "
+                                                    "match expected uuid:%s, "
+                                                    "d:%s, durl:%s" %
+                                                    (s_uuid, c_uuid, d,
+                                                    self.dcs[d].get_depot_url()))
+                                        found += 1
+                        if found != num_expected[d]:
+                                raise RuntimeError("d:%s, found %s instances of"
+                                    " a client uuid, expected to find %s." %
+                                    (d, found, num_expected[d]))
+
+        def test_bug_12739(self):
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                self._search_op(api_obj, True, "example_dir",
+                    set([("pkg:/[email protected]", "basename",
+                        "dir group=bin mode=0755 owner=root "
+                        "path=bin/example_dir")]))
+                self.dcs[1].stop()
+                self._search_op(api_obj, True, "example_dir",
+                    set([("pkg:/[email protected]", "basename",
+                        "dir group=bin mode=0755 owner=root "
+                        "path=bin/example_dir")]),
+                        expected_err=api_errors.ProblematicSearchServers)
+                self.pkg("search example_dir", exit=3)
+                
+if __name__ == "__main__":
+        unittest.main()
--- a/src/tests/api/t_bootenv.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_bootenv.py	Sat Jan 30 01:07:14 2010 -0800
@@ -21,23 +21,21 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import unittest
 import os
 import sys
 import pkg.client.bootenv as bootenv
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-import pkg5unittest
-
 class TestBootEnv(pkg5unittest.Pkg5TestCase):
-        def setUp(self):
-                pass
                 
         def test_api_consistency(self):
                 """Make sure every public method in BootEnv exists in
--- a/src/tests/api/t_catalog.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_catalog.py	Sat Jan 30 01:07:14 2010 -0800
@@ -24,6 +24,11 @@
 # Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import datetime
 import errno
 import os
@@ -34,12 +39,6 @@
 import time
 import unittest
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-
-import pkg5unittest
-
 import pkg.actions
 import pkg.fmri as fmri
 import pkg.catalog as catalog
@@ -54,18 +53,9 @@
         """Tests for all catalog functionality."""
 
         def setUp(self):
-                self.pid = os.getpid()
-                self.pwd = os.getcwd()
-
-                self.__test_prefix = os.path.join(tempfile.gettempdir(),
-                    "ips.test.%d" % self.pid)
+                pkg5unittest.Pkg5TestCase.setUp(self)
 
-                try:
-                        os.makedirs(self.__test_prefix, misc.PKG_DIR_MODE)
-                except OSError, e:
-                        if e.errno != errno.EEXIST:
-                                raise e
-                self.paths = [self.__test_prefix]
+                self.paths = [self.test_root]
                 self.c = catalog.Catalog(log_updates=True)
                 self.nversions = 0
 
@@ -104,18 +94,11 @@
 
                 self.npkgs = len(stems)
 
-        def tearDown(self):
-                for path in self.paths:
-                        shutil.rmtree(path)
-
-        def get_test_prefix(self):
-                return self.__test_prefix
-
         def create_test_dir(self, name):
                 """Creates a temporary directory with the specified name for
                 test usage and returns its absolute path."""
 
-                target = os.path.join(self.__test_prefix, name)
+                target = os.path.join(self.test_root, name)
                 try:
                         os.makedirs(target, misc.PKG_DIR_MODE)
                 except OSError, e:
@@ -403,10 +386,6 @@
                 expected = expected_categories(f)
                 self.assertEqual(returned, expected)
 
-        def debug(self, value):
-                import sys
-                print >> sys.__stderr__, value
-
         def test_01_attrs(self):
                 self.assertEqual(self.npkgs, self.c.package_count)
                 self.assertEqual(self.nversions, self.c.package_version_count)
@@ -1015,7 +994,7 @@
                 orig.save()
 
                 # Next, duplicate the original for testing, and load it.
-                dup1_path = os.path.join(self.get_test_prefix(), "test-07-dup1")
+                dup1_path = os.path.join(self.test_root, "test-07-dup1")
                 shutil.copytree(cpath, dup1_path)
                 dup1 = catalog.Catalog(meta_root=dup1_path)
                 dup1.validate()
--- a/src/tests/api/t_client.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_client.py	Sat Jan 30 01:07:14 2010 -0800
@@ -21,20 +21,20 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import logging
 import os
 import sys
 import unittest
 import StringIO
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-
-import pkg5unittest
 from pkg.client import global_settings
 logger = global_settings.logger
 
--- a/src/tests/api/t_dependencies.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_dependencies.py	Sat Jan 30 01:07:14 2010 -0800
@@ -23,9 +23,10 @@
 # Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
-import cli.testutils as testutils
+import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import shutil
@@ -34,12 +35,6 @@
 import tempfile
 import unittest
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-
-import pkg5unittest
-
 import pkg.catalog as catalog
 import pkg.flavor.base as base
 import pkg.flavor.depthlimitedmf as dlmf
@@ -153,70 +148,35 @@
 
         def setUp(self):
                 pkg5unittest.Pkg5TestCase.setUp(self)
-                self.image_dir = None
-                self.pid = os.getpid()
-                self.pwd = os.getcwd()
 
-                self.__test_prefix = os.path.join(tempfile.gettempdir(),
-                    "ips.test.%d" % self.pid)
-                self.proto_dir = os.path.join(self.__test_prefix, "proto")
-                self.manf_dir = os.path.join(self.__test_prefix, "manfs")
+                self.proto_dir = os.path.join(self.test_root, "proto")
                 os.makedirs(self.proto_dir)
-                os.makedirs(self.manf_dir)
 
-        def tearDown(self):
-                pkg5unittest.Pkg5TestCase.tearDown(self)
-                shutil.rmtree(self.__test_prefix)
+        def make_proto_text_file(self, path, contents=""):
+                self.make_misc_files({ path: contents }, prefix="proto")
 
         def make_python_test_files(self, py_version):
                 pdir = "usr/lib/python%s/vendor-packages" % py_version
                 for p in ["pkg_test/indexer_test/foobar",
                     "pkg_test/search_storage_test", "pkg_test/misc_test"]:
-                        self.make_text_file("%s/%s.py" % (pdir, p))
-                self.make_text_file("%s/pkg_test/__init__.py" % pdir,
+                        self.make_proto_text_file("%s/%s.py" % (pdir, p))
+                self.make_proto_text_file("%s/pkg_test/__init__.py" % pdir,
                     "#!/usr/bin/python\n")
-                self.make_text_file("%s/pkg_test/indexer_test/__init__.py" %
+                self.make_proto_text_file("%s/pkg_test/indexer_test/__init__.py" %
                     pdir, "#!/usr/bin/python")
                 
-        def make_manifest(self, str):
-                t_fd, t_path = tempfile.mkstemp(dir=self.manf_dir)
-                t_fh = os.fdopen(t_fd, "w")
-                t_fh.write(str)
-                t_fh.close()
-                return t_path
-
-        def make_text_file(self, o_path, o_text=""):
-                f_path = os.path.join(self.proto_dir, o_path)
-                f_dir = os.path.dirname(f_path)
-                if not os.path.exists(f_dir):
-                        os.makedirs(f_dir)
-
-                fh = open(f_path, "w")
-                fh.write(o_text)
-                fh.close()
-                return f_path
+        def make_elf(self, final_path, static=False):
+                out_file = os.path.join(self.proto_dir, final_path)
 
-        def make_elf(self, final_path, static=False):
-                t_fd, t_path = tempfile.mkstemp(suffix=".c", dir=self.proto_dir)
-                out_file = os.path.join(self.proto_dir, final_path)
-                out_dir = os.path.dirname(out_file)
-                if not os.path.exists(out_dir):
-                        os.makedirs(out_dir)
-                t_fh = os.fdopen(t_fd, "w")
-                t_fh.write("int main(){}\n")
-                t_fh.close()
-                cmd = ["/usr/bin/cc", "-o", out_file]
+                opts = []
+                # In some cases we want to generate an elf binary with no
+                # dependencies of its own.  We use -c (supress linking) for
+                # this purpose.
                 if static:
-                        cmd.append("-static")
-                cmd.append(t_path)
-                s = subprocess.Popen(cmd, stderr=subprocess.PIPE)
-                out, err = s.communicate()
-                rc = s.returncode
-                if rc != 0:
-                        raise RuntimeError("Compile of %s failed.\nCommand "
-                            "was:\n%s\nError was:\n%s" %
-                            (t_path, " ".join(cmd), err))
-                return out_file
+                        opts.extend(["-c"])
+                self.c_compile("int main(){}\n", opts, out_file)
+
+                return out_file[len(self.proto_dir)+1:]
 
         def __path_to_key(self, path):
                 if path == self.paths["libc_path"]:
@@ -264,7 +224,7 @@
                 dependencies is set."""
 
                 t_path = self.make_manifest(self.int_hardlink_manf)
-                self.make_text_file(self.paths["syslog_path"])
+                self.make_proto_text_file(self.paths["syslog_path"])
                 ds, es, ms = \
                     dependencies.list_implicit_deps(t_path, self.proto_dir, {},
                         [])
@@ -308,7 +268,7 @@
                         self.assertEqual(d.action.attrs["path"],
                             self.paths["script_path"])
                 t_path = self.make_manifest(self.ext_script_manf)
-                self.make_text_file(self.paths["script_path"], self.script_text)
+                self.make_proto_text_file(self.paths["script_path"], self.script_text)
                 _check_res(dependencies.list_implicit_deps(t_path,
                     self.proto_dir, {}, []))
                 _check_res(dependencies.list_implicit_deps(t_path,
@@ -321,7 +281,7 @@
 
                 t_path = self.make_manifest(self.int_script_manf)
                 self.make_elf(self.paths["ksh_path"])
-                self.make_text_file(self.paths["script_path"], self.script_text)
+                self.make_proto_text_file(self.paths["script_path"], self.script_text)
                 ds, es, ms = dependencies.list_implicit_deps(t_path,
                     self.proto_dir, {}, [])
                 if es != []:
@@ -396,7 +356,7 @@
                                 raise RuntimeError("Got errors in results:" +
                                     "\n".join([str(s) for s in es]))
                         self.assertEqual(ms, {})
-                        self.assert_(len(ds) == 1)
+                        self.assertEqual(len(ds), 1)
                         d = ds[0]
                         self.assert_(d.is_error())
                         self.assert_(d.dep_vars.is_satisfied())
@@ -464,7 +424,7 @@
                 self.__debug = True
                 t_path = self.make_manifest(self.ext_python_manf)
                 self.make_python_test_files(2.6)
-                self.make_text_file(self.paths["indexer_path"],
+                self.make_proto_text_file(self.paths["indexer_path"],
                     self.python_text)
                 _check_all_res(dependencies.list_implicit_deps(t_path,
                     self.proto_dir, {}, []))
@@ -515,7 +475,7 @@
                 t_path = self.make_manifest(self.ext_python_manf)
                 self.make_python_test_files(2.6)
                 # Check that absolute imports still work.
-                self.make_text_file(self.paths["indexer_path"],
+                self.make_proto_text_file(self.paths["indexer_path"],
                     self.python_abs_text)
                 _check_all_res(dependencies.list_implicit_deps(t_path,
                     self.proto_dir, {}, []))
@@ -563,7 +523,7 @@
                 self.__debug = True
                 t_path = self.make_manifest(self.ext_python_pkg_manf)
                 self.make_python_test_files(2.6)
-                self.make_text_file(self.paths["pkg_path"], self.python_text)
+                self.make_proto_text_file(self.paths["pkg_path"], self.python_text)
                 _check_all_res(dependencies.list_implicit_deps(t_path,
                     self.proto_dir, {}, []))
                 _check_all_res(dependencies.list_implicit_deps(t_path,
@@ -575,7 +535,7 @@
                 for the other set of variants."""
 
                 t_path = self.make_manifest(self.variant_manf_1)
-                self.make_text_file(self.paths["script_path"], self.script_text)
+                self.make_proto_text_file(self.paths["script_path"], self.script_text)
                 self.make_elf(self.paths["ksh_path"])
                 ds, es, ms = dependencies.list_implicit_deps(t_path,
                     self.proto_dir, {}, [])
@@ -618,7 +578,7 @@
                 dependency, an external dependency is not reported."""
 
                 t_path = self.make_manifest(self.variant_manf_2)
-                self.make_text_file(self.paths["script_path"], self.script_text)
+                self.make_proto_text_file(self.paths["script_path"], self.script_text)
                 self.make_elf(self.paths["ksh_path"])
                 ds, es, ms = dependencies.list_implicit_deps(t_path,
                     self.proto_dir, {}, [])    
@@ -667,7 +627,7 @@
                 reported as an external dependency."""
 
                 t_path = self.make_manifest(self.variant_manf_3)
-                self.make_text_file(self.paths["script_path"], self.script_text)
+                self.make_proto_text_file(self.paths["script_path"], self.script_text)
                 self.make_elf(self.paths["ksh_path"])
                 ds, es, ms = dependencies.list_implicit_deps(t_path,
                     self.proto_dir, {}, [])
@@ -740,3 +700,5 @@
                 str(mi)
                 mi.make_package()
                 str(mi)
+if __name__ == "__main__":
+        unittest.main()
--- a/src/tests/api/t_elf.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_elf.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,19 +20,19 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import unittest
 import pkg.elf as elf
 import os
 import sys
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-import pkg5unittest
-
 class TestElf(pkg5unittest.Pkg5TestCase):
 
 	def test_is_elf_object(self):
--- a/src/tests/api/t_file_manager.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_file_manager.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,9 +20,14 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import errno
 import os
 import shutil
@@ -30,33 +35,11 @@
 import tempfile
 import unittest
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-
-import pkg5unittest
-
 import pkg.file_layout.file_manager as file_manager
 import pkg.file_layout.layout as layout
 
 class TestFileManager(pkg5unittest.Pkg5TestCase):
 
-        def setUp(self):
-                self.pid = os.getpid()
-                self.pwd = os.getcwd()
-
-                self.__test_dir = os.path.join(tempfile.gettempdir(),
-                    "ips.test.%d" % self.pid)
-
-                try:
-                        os.makedirs(self.__test_dir, 0755)
-                except OSError, e:
-                        if e.errno != errno.EEXIST:
-                                raise e
-
-        def tearDown(self):
-                shutil.rmtree(self.__test_dir)
-
         @staticmethod
         def old_hash(s):
                 return os.path.join(s[0:2], s[2:8], s)
@@ -64,7 +47,7 @@
         def touch_old_file(self, s, data=None):
                 if data is None:
                         data = s
-                p = os.path.join(self.__test_dir, self.old_hash(s))
+                p = os.path.join(self.test_root, self.old_hash(s))
                 if not os.path.exists(os.path.dirname(p)):
                         os.makedirs(os.path.dirname(p))
                 fh = open(p, "wb")
@@ -116,8 +99,8 @@
 
                 # Test that a read only FileManager won't modify the file
                 # system.
-                fm = file_manager.FileManager(self.__test_dir, readonly=True)
-                self.assertEqual(os.listdir(self.__test_dir), [])
+                fm = file_manager.FileManager(self.test_root, readonly=True)
+                self.assertEqual(os.listdir(self.test_root), [])
 
                 unmoved = "4b7c923af3a047d4685a39ad7bc9b0382ccde671"
 
@@ -128,7 +111,7 @@
                     set([unmoved]))
 
                 # Test a FileManager that can write to the file system.
-                fm = file_manager.FileManager(self.__test_dir, False)
+                fm = file_manager.FileManager(self.test_root, False)
 
                 hash1 = "584b6ab7d7eb446938a02e57101c3a2fecbfb3cb"
                 hash2 = "584b6ab7d7eb446938a02e57101c3a2fecbfb3cc"
@@ -149,7 +132,7 @@
                 self.assert_(os.path.isfile(p1))
                 self.assert_(os.path.isdir(os.path.dirname(p1)))
                 self.assertEqual(fm.lookup(hash1),
-                    os.path.join(self.__test_dir, l.lookup(hash1)))
+                    os.path.join(self.test_root, l.lookup(hash1)))
                 self.assert_(not os.path.exists(p1))
                 self.assert_(not os.path.exists(os.path.dirname(p1)))
                 fm.remove(hash1)
@@ -165,7 +148,7 @@
                 self.assert_(os.path.isfile(p1))
                 self.assert_(os.path.isdir(os.path.dirname(p1)))
                 self.assertEqual(fm.lookup(hash1),
-                    os.path.join(self.__test_dir, l.lookup(hash1)))
+                    os.path.join(self.test_root, l.lookup(hash1)))
                 self.assert_(not os.path.exists(p1))
                 self.assert_(os.path.exists(os.path.dirname(p1)))
                 fm.remove(hash2)
@@ -204,7 +187,7 @@
 
                 # Test that walking with a different set of layouts works as
                 # expected.
-                fm2 = file_manager.FileManager(self.__test_dir, readonly=True,
+                fm2 = file_manager.FileManager(self.test_root, readonly=True,
                     layouts=[layout.get_preferred_layout()])
 
                 fs = set([hash1, hash4, hash3])
@@ -212,13 +195,13 @@
                         for i in fm2.walk():
                                 fs.remove(i)
                 except file_manager.UnrecognizedFilePaths, e:
-                        self.assertEqual(e.fps, [p[len(self.__test_dir) + 1:]])
+                        self.assertEqual(e.fps, [p[len(self.test_root) + 1:]])
                 self.assertEqual(fs, set())
 
                 # Test removing a file works and removes the containing
                 # directory and that remove removes all instances of a hash
                 # from the file manager.
-                hash3_loc = os.path.join(self.__test_dir, l.lookup(hash3))
+                hash3_loc = os.path.join(self.test_root, l.lookup(hash3))
                 v0_hash3_loc = self.touch_old_file(hash3)
 
                 self.assert_(os.path.isfile(hash3_loc))
@@ -231,7 +214,7 @@
                 self.assert_(not os.path.exists(os.path.dirname(v0_hash3_loc)))
                 self.assert_(os.path.isfile(fm.lookup(hash1)))
 
-                rh2_fd, raw_hash_2_loc = tempfile.mkstemp(dir=self.__test_dir)
+                rh2_fd, raw_hash_2_loc = tempfile.mkstemp(dir=self.test_root)
                 rh2_fh = os.fdopen(rh2_fd, "w")
                 rh2_fh.write(hash2)
                 rh2_fh.close()
@@ -277,25 +260,25 @@
                         self.touch_old_file(fhash)
 
                 # Migrate it to the v1 layout.
-                fm = file_manager.FileManager(self.__test_dir, False)
+                fm = file_manager.FileManager(self.test_root, False)
                 for fhash in fm.walk():
                         self.assertEqual(fm.lookup(fhash),
-                            os.path.join(self.__test_dir, l1.lookup(fhash)))
+                            os.path.join(self.test_root, l1.lookup(fhash)))
 
                 # After migration verify that no v0 parent directories remain.
                 for fhash in fm.walk():
                         self.assertFalse(os.path.exists(os.path.dirname(
-                            os.path.join(self.__test_dir, l0.lookup(fhash)))))
+                            os.path.join(self.test_root, l0.lookup(fhash)))))
 
                 # Re-create the FileManager using v0 as the preferred layout.
-                fm = file_manager.FileManager(self.__test_dir, False,
+                fm = file_manager.FileManager(self.test_root, False,
                     layouts=[l0, l1])
 
                 # Test that looking up a file stored under the v1 layout is
                 # correctly moved to the v0 layout.
                 for fhash in fm.walk():
                         self.assertEqual(fm.lookup(fhash),
-                            os.path.join(self.__test_dir, l0.lookup(fhash)))
+                            os.path.join(self.test_root, l0.lookup(fhash)))
 
         def test_3_replace(self):
                 """Verify that insert will replace an existing file even though
@@ -315,10 +298,10 @@
 
                 # Migrate it to the v1 layout and verify that each
                 # file contains the expected data.
-                fm = file_manager.FileManager(self.__test_dir, False)
+                fm = file_manager.FileManager(self.test_root, False)
                 for fhash in fm.walk():
                         loc = fm.lookup(fhash)
-                        self.assertEqual(loc, os.path.join(self.__test_dir,
+                        self.assertEqual(loc, os.path.join(self.test_root,
                             l1.lookup(fhash)))
 
                         f = open(loc, "rb")
@@ -328,10 +311,10 @@
                 # Now replace each file using the old hashnames and verify
                 # that the each contains the expected data.
                 for fhash in fm.walk():
-                        loc = os.path.join(self.__test_dir, l1.lookup(fhash))
+                        loc = os.path.join(self.test_root, l1.lookup(fhash))
                         self.assertTrue(os.path.exists(loc))
 
-                        npath = os.path.join(self.__test_dir, "new-%s" % fhash)
+                        npath = os.path.join(self.test_root, "new-%s" % fhash)
                         nfile = open(npath, "wb")
                         nfile.write("new-%s" % fhash)
                         nfile.close()
@@ -342,3 +325,5 @@
                         self.assertEqual(f.read(), "new-%s" % fhash)
                         f.close()
 
+if __name__ == "__main__":
+        unittest.main()
--- a/src/tests/api/t_fmri.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_fmri.py	Sat Jan 30 01:07:14 2010 -0800
@@ -21,21 +21,21 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import unittest
 import pkg.fmri as fmri
 
 import os
 import sys
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-import pkg5unittest
-
 class TestFMRI(pkg5unittest.Pkg5TestCase):
 
         pkg_name_valid_chars = {
--- a/src/tests/api/t_history.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_history.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,9 +20,14 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import os
 import re
 import shutil
@@ -36,14 +41,9 @@
 import pkg.misc as misc
 import pkg.portable as portable
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-import pkg5unittest
-
 class TestHistory(pkg5unittest.Pkg5TestCase):
         # This is to prevent setup() being called for each test.
-        persistent_depot = True
+        persistent_setup = True
 
         __scratch_dir = None
 
@@ -67,7 +67,9 @@
         def setUp(self):
                 """Prepare the test for execution.
                 """
-                self.__scratch_dir = tempfile.mkdtemp()
+                pkg5unittest.Pkg5TestCase.setUp(self)
+
+                self.__scratch_dir = tempfile.mkdtemp(dir=self.test_root)
                 # Explicitly convert these to strings as they will be
                 # converted by history to deal with minidom issues.
                 self.__userid = str(portable.get_userid())
@@ -75,12 +77,6 @@
                 self.__h = history.History(root_dir=self.__scratch_dir)
                 self.__h.client_name = "pkg-test"
 
-        def tearDown(self):
-                """Cleanup after the test execution.
-                """
-                if self.__scratch_dir:
-                        shutil.rmtree(self.__scratch_dir, ignore_errors=True)
-
         def test_00_valid_operation(self):
                 """Verify that operation information can be stored and
                 retrieved.
--- a/src/tests/api/t_imageconfig.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_imageconfig.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,9 +20,14 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import unittest
 import os
 import shutil
@@ -30,18 +35,10 @@
 import tempfile
 import pkg.client.imageconfig as imageconfig
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-import pkg5unittest
 
 class TestImageConfig(pkg5unittest.Pkg5TestCase):
-        def setUp(self):
-                self.sample_dir = tempfile.mkdtemp()
-                cfgfile = os.path.join(self.sample_dir, imageconfig.CFG_FILE)
-                f = open(cfgfile, "w")
 
-                f.write("""\
+        misc_files = { imageconfig.CFG_FILE : """\
 [policy]
 Display-Copyrights: False
 
@@ -64,19 +61,16 @@
 repo.registration_uri: http://zruty.sfbay:10001/reg.html
 repo.related_uris:
 sort_policy: priority
-""")
-                f.close()
-                self.ic = imageconfig.ImageConfig(self.sample_dir, "publisher")
+""" }
 
-        def tearDown(self):
-                try:
-                        shutil.rmtree(self.sample_dir)
-                except:
-                        pass
+        def setUp(self):
+                pkg5unittest.Pkg5TestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
+                self.ic = imageconfig.ImageConfig(self.test_root, "publisher")
 
         def test_0_read(self):
                 """Verify that read works and that values are read properly."""
-                self.ic.read(self.sample_dir)
+                self.ic.read(self.test_root)
 
                 pub = self.ic.publishers["sfbay.sun.com"]
                 self.assertEqual(pub.alias, "zruty")
@@ -101,7 +95,7 @@
                 self.assertNotEqual(pub.client_uuid, None)
 
         def test_1_unicode(self):
-                self.ic.read(self.sample_dir)
+                self.ic.read(self.test_root)
                 ustr = u'abc\u3041def'
                 self.ic.properties['name'] = ustr
                 newdir = tempfile.mkdtemp()
@@ -116,18 +110,18 @@
                 #
                 #  See what happens if the conf file is missing.
                 #
-                shutil.rmtree(self.sample_dir)
-                self.assertRaises(RuntimeError, self.ic.read, self.sample_dir)
+                shutil.rmtree(self.test_root)
+                self.assertRaises(RuntimeError, self.ic.read, self.test_root)
 
         def test_3_reread(self):
                 """Verify that the uuid determined during the first read is the
                 same as the uuid in the second read."""
-                self.ic.read(self.sample_dir)
+                self.ic.read(self.test_root)
                 pub = self.ic.publishers["sfbay.sun.com"]
                 uuid = pub.client_uuid
 
-                ic2 = imageconfig.ImageConfig(self.sample_dir, "publisher")
-                ic2.read(self.sample_dir)
+                ic2 = imageconfig.ImageConfig(self.test_root, "publisher")
+                ic2.read(self.test_root)
                 pub2 = ic2.publishers["sfbay.sun.com"]
                 self.assertEqual(pub2.client_uuid, uuid)
 
--- a/src/tests/api/t_indexer.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_indexer.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,11 +20,15 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import unittest
-import pkg5unittest
 import pkg.indexer as indexer
 
 import os
@@ -34,15 +38,12 @@
 import shutil
 
 class TestIndexer(pkg5unittest.Pkg5TestCase):
-        def setUp(self):
-            pass
 
         def test_indexworkingsize(self):
             limit = 200
 
-            tmpdir = tempfile.mkdtemp()
-            ind = indexer.Indexer(tmpdir, None,
-                None, sort_file_max_size=limit)
+            ind = indexer.Indexer(self.test_root, None, None,
+                sort_file_max_size=limit)
 
             os.mkdir(ind._tmp_dir)
 
@@ -73,16 +74,13 @@
 
             # Each file should be under the limit
             for file in os.listdir(ind._tmp_dir):
-                assert os.stat(os.path.join(ind._tmp_dir, file)).st_size <= \
-                    limit
-
-            shutil.rmtree(tmpdir)
+                self.assert_(os.stat(os.path.join(ind._tmp_dir, file)).st_size <= \
+                    limit)
 
 
         def test_indexworkingsize0(self):
-            tmpdir = tempfile.mkdtemp()
-            ind = indexer.Indexer(tmpdir, None,
-                None, sort_file_max_size=0)
+            ind = indexer.Indexer(self.test_root, None, None,
+                sort_file_max_size=0)
 
             os.mkdir(ind._tmp_dir)
 
@@ -114,15 +112,13 @@
             # The first file is already opened by us, so it will fail the
             # <= 0 test by indexer, and indexer will create a new one. Hence,
             # sort.0 will be of size 0
-            assert os.stat(os.path.join(ind._tmp_dir , "sort.0")).st_size == 0
+            self.assert_(os.stat(os.path.join(ind._tmp_dir , "sort.0")).st_size == 0)
 
             # Each file should have at most 1 line in it ( the smallest
             # atomic unit  that the indexer can write to a file )
             for file in os.listdir(ind._tmp_dir):
-                assert len(open(os.path.join(ind._tmp_dir, 
-                    file)).readlines()) <= 1
+                self.assert_(len(open(os.path.join(ind._tmp_dir, \
+                    file)).readlines()) <= 1)
 
-            shutil.rmtree(tmpdir)
- 
 if __name__ == "__main__":
         unittest.main()
--- a/src/tests/api/t_manifest.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_manifest.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,7 +20,7 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import unittest
@@ -44,6 +44,8 @@
 class TestManifest(pkg5unittest.Pkg5TestCase):
 
         def setUp(self):
+                pkg5unittest.Pkg5TestCase.setUp(self)
+
                 self.m1 = manifest.Manifest();
                 self.m1_contents = """\
 set com.sun,test=true
--- a/src/tests/api/t_misc.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_misc.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,9 +20,14 @@
 # CDDL HEADER END
 #
 
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import unittest
 import os
 import stat
@@ -33,11 +38,6 @@
 import pkg.misc as misc
 from pkg.actions.generic import Action
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-import pkg5unittest
-
 class TestMisc(pkg5unittest.Pkg5TestCase):
 
         def testMakedirs(self):
@@ -82,6 +82,5 @@
                 self.assertTrue(misc.valid_pub_url(
                     "http://pkg.opensolaris.org/dev"))
 
-
 if __name__ == "__main__":
         unittest.main()
--- a/src/tests/api/t_p5i.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_p5i.py	Sat Jan 30 01:07:14 2010 -0800
@@ -21,10 +21,15 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import errno
 import unittest
 import cStringIO
@@ -40,11 +45,6 @@
 import urllib
 import urlparse
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-import pkg5unittest
-
 class TestP5I(pkg5unittest.Pkg5TestCase):
         """Class to test the functionality of the pkg.p5i module."""
 
@@ -90,32 +90,8 @@
         misc_files = [ "libc.so.1" ]
 
         def setUp(self):
-                self.pid = os.getpid()
-                self.pwd = os.getcwd()
-
-                self.__test_prefix = os.path.join(tempfile.gettempdir(),
-                    "ips.test.%d" % self.pid)
-
-                try:
-                        os.makedirs(self.__test_prefix,
-                            misc.PKG_DIR_MODE)
-                except OSError, e:
-                        if e.errno != errno.EEXIST:
-                                raise e
-
-                for p in self.misc_files:
-                        fpath = os.path.join(self.get_test_prefix(), p)
-                        f = open(fpath, "wb")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(fpath)
-                        f.close()
-
-        def tearDown(self):
-                shutil.rmtree(self.get_test_prefix())
-
-        def get_test_prefix(self):
-                return self.__test_prefix
+                pkg5unittest.Pkg5TestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
 
         def test_parse_write(self):
                 """Verify that the p5i parsing and writing works as expected."""
@@ -181,7 +157,7 @@
                 # Verify that parse returns the expected object and information
                 # when provided a file path.
                 fobj.seek(0)
-                (fd1, path1) = tempfile.mkstemp(dir=self.get_test_prefix())
+                (fd1, path1) = tempfile.mkstemp(dir=self.test_root)
                 os.write(fd1, fobj.read())
                 os.close(fd1)
                 validate_results(p5i.parse(location=path1))
@@ -197,7 +173,7 @@
 
                 # Verify that appropriate exceptions are raised for p5i
                 # information that can't be retrieved (doesn't exist).
-                nefpath = os.path.join(self.get_test_prefix(), "non-existent")
+                nefpath = os.path.join(self.test_root, "non-existent")
                 self.assertRaises(api_errors.RetrievalError,
                     p5i.parse, location="file://%s" % nefpath)
 
@@ -206,7 +182,7 @@
 
                 # Verify that appropriate exceptions are raised for invalid
                 # p5i information.
-                lcpath = os.path.join(self.get_test_prefix(), "libc.so.1")
+                lcpath = os.path.join(self.test_root, "libc.so.1")
                 location = os.path.abspath(lcpath)
                 location = urlparse.urlunparse(("file", "",
                     urllib.pathname2url(location), "", "", ""))
@@ -222,4 +198,3 @@
 
 if __name__ == "__main__":
         unittest.main()
-
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/api/t_pkg_api_install.py	Sat Jan 30 01:07:14 2010 -0800
@@ -0,0 +1,572 @@
+#!/usr/bin/python
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+#
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+
+import testutils
+if __name__ == "__main__":
+	testutils.setup_environment("../../../proto")
+import pkg5unittest
+
+import os
+import time
+import sys
+import unittest
+from stat import *
+import pkg.client.api as api
+import pkg.client.api_errors as api_errors
+import pkg.client.progress as progress
+
+API_VERSION = 31
+PKG_CLIENT_NAME = "pkg"
+
+class TestPkgApiInstall(pkg5unittest.SingleDepotTestCase):
+        # Only start/stop the depot once (instead of for every test)
+        persistent_setup = False
+
+        foo10 = """
+            open [email protected],5.11-0
+            close """
+
+        foo11 = """
+            open [email protected],5.11-0
+            add dir mode=0755 owner=root group=bin path=/lib
+            add file tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1 timestamp="20080731T024051Z"
+            close """
+        foo11_timestamp = 1217472051
+
+        foo12 = """
+            open [email protected],5.11-0
+            add file tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
+            close """
+
+        bar10 = """
+            open [email protected],5.11-0
+            add depend type=require fmri=pkg:/[email protected]
+            add dir mode=0755 owner=root group=bin path=/bin
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            close """
+
+        bar11 = """
+            open [email protected],5.11-0
+            add depend type=require fmri=pkg:/[email protected]
+            add dir mode=0755 owner=root group=bin path=/bin
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            close """
+
+        xfoo10 = """
+            open [email protected],5.11-0
+            close """
+
+        xbar10 = """
+            open [email protected],5.11-0
+            add depend type=require fmri=pkg:/[email protected]
+            add dir mode=0755 owner=root group=bin path=/bin
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            close """
+
+        xbar11 = """
+            open [email protected],5.11-0
+            add depend type=require fmri=pkg:/[email protected]
+            add dir mode=0755 owner=root group=bin path=/bin
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            close """
+
+
+        bar12 = """
+            open [email protected],5.11-0
+            add depend type=require fmri=pkg:/[email protected]
+            add dir mode=0755 owner=root group=bin path=/bin
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat 
+            close """
+
+        baz10 = """
+            open [email protected],5.11-0
+            add depend type=require fmri=pkg:/[email protected]
+            add dir mode=0755 owner=root group=bin path=/bin
+            add file tmp/baz mode=0555 owner=root group=bin path=/bin/baz
+            close """
+
+        deep10 = """
+            open [email protected],5.11-0
+            add depend type=require fmri=pkg:/[email protected]
+            add dir mode=0755 owner=root group=bin path=/bin
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            close """
+        
+        xdeep10 = """
+            open [email protected],5.11-0
+            add depend type=require fmri=pkg:/[email protected]
+            add dir mode=0755 owner=root group=bin path=/bin
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            close """
+
+        ydeep10 = """
+            open [email protected],5.11-0
+            add depend type=require fmri=pkg:/[email protected]
+            add dir mode=0755 owner=root group=bin path=/bin
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            close """
+
+        misc_files = [ "tmp/libc.so.1", "tmp/cat", "tmp/baz" ]
+
+        def setUp(self):
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
+
+        @staticmethod
+        def __do_install(api_obj, fmris):
+                api_obj.reset()
+                api_obj.plan_install(fmris)
+                api_obj.prepare()
+                api_obj.execute_plan()
+
+        @staticmethod
+        def __do_uninstall(api_obj, fmris, recursive_removal=False):
+                api_obj.reset()
+                api_obj.plan_uninstall(fmris, recursive_removal)
+                api_obj.prepare()
+                api_obj.execute_plan()
+
+        def test_basics_1(self):
+                """ Send empty package [email protected], install and uninstall """
+
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.foo10)
+                self.image_create(durl)
+
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+                
+                self.pkg("list -a")
+                self.pkg("list", exit=1)
+
+                self.__do_install(api_obj, ["foo"])
+
+                self.pkg("list")
+                self.pkg("verify")
+
+                api_obj.reset()
+                self.__do_uninstall(api_obj, ["foo"])
+                self.pkg("verify")
+
+        def test_basics_2(self):
+                """ Send package [email protected], containing a directory and a file,
+                    install, search, and uninstall. """
+
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.foo10)
+                self.pkgsend_bulk(durl, self.foo11)
+                self.image_create(durl)
+
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                self.pkg("list -a")
+                self.__do_install(api_obj, ["foo"])
+
+                self.pkg("verify")
+                self.pkg("list")
+
+                self.pkg("search -l /lib/libc.so.1")
+                self.pkg("search -r /lib/libc.so.1")
+                self.pkg("search -l blah", exit = 1)
+                self.pkg("search -r blah", exit = 1)
+
+                # check to make sure timestamp was set to correct value
+
+                libc_path = os.path.join(self.get_img_path(), "lib/libc.so.1")
+                stat = os.stat(libc_path)
+
+                self.assert_(stat[ST_MTIME] == self.foo11_timestamp)
+
+                # check that verify finds changes
+                now = time.time()
+                os.utime(libc_path, (now, now))
+                self.pkg("verify", exit=1)
+
+                api_obj.reset()
+                self.__do_uninstall(api_obj, ["foo"])
+
+                self.pkg("verify")
+                self.pkg("list -a")
+                self.pkg("verify")
+
+        def test_basics_3(self):
+                """ Install [email protected], upgrade to [email protected], uninstall. """
+
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.foo10)
+                self.pkgsend_bulk(durl, self.foo11)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                self.__do_install(api_obj, ["[email protected]"])
+
+                self.pkg("list [email protected]")
+                self.pkg("list [email protected]", exit = 1)
+
+                api_obj.reset()
+                self.__do_install(api_obj, ["[email protected]"])
+                self.pkg("list [email protected]")
+                self.pkg("list [email protected]", exit = 1)
+                self.pkg("list foo@1")
+                self.pkg("verify")
+
+                api_obj.reset()
+                self.__do_uninstall(api_obj, ["foo"])
+                self.pkg("list -a")
+                self.pkg("verify")
+
+        def test_basics_4(self):
+                """ Add [email protected], dependent on [email protected], install, uninstall. """
+
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.foo10)
+                self.pkgsend_bulk(durl, self.foo11)
+                self.pkgsend_bulk(durl, self.bar10)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                self.pkg("list -a")
+                api_obj.reset()
+                self.__do_install(api_obj, ["[email protected]"])
+
+                self.pkg("list")
+                self.pkg("verify")
+                api_obj.reset()
+                self.__do_uninstall(api_obj, ["bar", "foo"])
+
+                # foo and bar should not be installed at this point
+                self.pkg("list bar", exit = 1)
+                self.pkg("list foo", exit = 1)
+                self.pkg("verify")
+
+        def test_image_upgrade(self):
+                """ Send package [email protected], dependent on [email protected].  Install [email protected].
+                    List all packages.  Upgrade image. """
+
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.foo10)
+                self.pkgsend_bulk(durl, self.foo11)
+                self.pkgsend_bulk(durl, self.bar10)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                self.__do_install(api_obj, ["[email protected]"])
+
+                self.pkgsend_bulk(durl, self.foo12)
+                self.pkgsend_bulk(durl, self.bar11)
+
+                self.pkg("contents -H")
+                self.pkg("list")
+                api_obj.refresh(immediate=True)
+
+                self.pkg("list")
+                self.pkg("verify")
+                api_obj.reset()
+                api_obj.plan_update_all(sys.argv[0])
+                api_obj.prepare()
+                api_obj.execute_plan()
+                self.pkg("verify")
+
+                self.pkg("list [email protected]")
+                self.pkg("list [email protected]")
+
+                api_obj.reset()
+                self.__do_uninstall(api_obj, ["bar", "foo"])
+                self.pkg("verify")
+
+
+        def test_recursive_uninstall(self):
+                """Install [email protected], dependent on [email protected], uninstall foo recursively."""
+
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.foo10)
+                self.pkgsend_bulk(durl, self.foo11)
+                self.pkgsend_bulk(durl, self.bar10)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                self.__do_install(api_obj, ["[email protected]"])
+
+                # Here's the real part of the regression test;
+                # at this point foo and bar are installed, and
+                # bar depends on foo.  foo and bar should both
+                # be removed by this action.
+                self.__do_uninstall(api_obj, ["foo"], True)
+                                       
+                self.pkg("list bar", exit = 1)
+                self.pkg("list foo", exit = 1)
+
+        def test_nonrecursive_dependent_uninstall(self):
+                """Trying to remove a package that's a dependency of another
+                package should fail if the uninstall isn't recursive."""
+
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.foo10)
+                self.pkgsend_bulk(durl, self.bar10)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                self.__do_install(api_obj, ["[email protected]"])
+
+                api_obj.reset()
+                self.assertRaises(api_errors.NonLeafPackageException,
+                    self.__do_uninstall, api_obj, ["foo"])
+                self.pkg("list bar")
+                self.pkg("list foo")
+
+        def test_basics_5(self):
+                """ Add [email protected], install [email protected]. """
+
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.xbar11)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                self.assertRaises(api_errors.PlanCreationException,
+                    self.__do_install, api_obj, ["[email protected]"])
+
+        def test_bug_1338(self):
+                """ Add [email protected], dependent on [email protected], install [email protected]. """
+                
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.bar11)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                self.pkg("list -a")
+
+                self.assertRaises(api_errors.PlanCreationException,
+                    self.__do_install, api_obj, ["[email protected]"])
+
+        def test_bug_1338_2(self):
+                """ Add [email protected], dependent on [email protected], and [email protected], dependent
+                    on [email protected], install [email protected] and [email protected]. """
+                
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.bar11)
+                self.pkgsend_bulk(durl, self.baz10)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                self.assertRaises(api_errors.PlanCreationException,
+                    self.__do_install, api_obj, ["[email protected]", "[email protected]"])
+
+        def test_bug_1338_3(self):
+                """ Add [email protected], [email protected]. [email protected] depends on [email protected] which
+                    depends on [email protected], install [email protected]. """
+                
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.xbar10)
+                self.pkgsend_bulk(durl, self.xdeep10)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                self.assertRaises(api_errors.PlanCreationException,
+                    self.__do_install, api_obj, ["[email protected]"])
+
+        def test_bug_1338_4(self):
+                """ Add [email protected]. [email protected] depends on [email protected] which depends
+                on [email protected], install [email protected]. """
+                
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.ydeep10)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                self.assertRaises(api_errors.PlanCreationException,
+                    self.__do_install, api_obj, ["[email protected]"])
+
+        def test_bug_2795(self):
+                """ Try to install two versions of the same package """
+
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.foo11)
+                self.pkgsend_bulk(durl, self.foo12)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                self.assertRaises(api_errors.PlanCreationException,
+                    self.__do_install, api_obj, ["[email protected]", "[email protected]"])
+
+                self.pkg("list foo", exit = 1)
+
+                self.assertRaises(api_errors.PlanCreationException,
+                    self.__do_install, api_obj, ["[email protected]", "[email protected]"])
+
+
+                self.pkg("list foo", exit = 1)
+
+        def test_install_matching(self):
+                """ Try to [un]install packages matching a pattern """
+
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.foo10)
+                self.pkgsend_bulk(durl, self.bar10)
+                self.pkgsend_bulk(durl, self.baz10)
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+                self.__do_install(api_obj, ['ba*'])
+                self.pkg("list [email protected]", exit=0)
+                self.pkg("list [email protected]", exit=0)
+                self.pkg("list [email protected]", exit=0)
+
+                self.__do_uninstall(api_obj, ['ba*'])
+                self.pkg("list [email protected]", exit=0)
+                self.pkg("list [email protected]", exit=1)
+                self.pkg("list [email protected]", exit=1)
+
+        def test_bad_fmris(self):
+                """ Test passing problematic fmris into the api """
+
+                durl = self.dc.get_depot_url()
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                def check_unfound(e):
+                        return e.unmatched_fmris
+
+                def check_illegal(e):
+                        return e.illegal
+
+                def check_missing(e):
+                        return e.missing_matches
+
+
+                pkg5unittest.eval_assert_raises(api_errors.PlanCreationException,
+                    check_unfound, api_obj.plan_install, ["foo"])
+
+                api_obj.reset()
+                pkg5unittest.eval_assert_raises(api_errors.PlanCreationException,
+                    check_missing, api_obj.plan_uninstall, ["foo"], False)
+
+                api_obj.reset()
+                pkg5unittest.eval_assert_raises(api_errors.PlanCreationException,
+                    check_illegal, api_obj.plan_install, ["@/foo"])
+                
+                api_obj.reset()
+                pkg5unittest.eval_assert_raises(api_errors.PlanCreationException,
+                    check_illegal, api_obj.plan_uninstall, ["/foo"], False)
+
+                self.pkgsend_bulk(durl, self.foo10)
+
+                api_obj.refresh(False)
+                pkg5unittest.eval_assert_raises(api_errors.PlanCreationException,
+                    check_missing, api_obj.plan_uninstall, ["foo"], False)
+
+                api_obj.reset()
+                pkg5unittest.eval_assert_raises(api_errors.PlanCreationException,
+                    check_illegal, api_obj.plan_uninstall, ["/foo"], False)
+
+                api_obj.reset()
+                api_obj.refresh(True)
+                self.__do_install(api_obj, ["foo"])
+                self.__do_uninstall(api_obj, ["foo"])
+
+                api_obj.reset()                
+                pkg5unittest.eval_assert_raises(api_errors.PlanCreationException,
+                    check_missing, api_obj.plan_uninstall, ["foo"], False)
+
+        def test_bug_4109(self):
+                durl = self.dc.get_depot_url()
+                self.image_create(durl)
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
+
+                def check_illegal(e):
+                        return e.illegal
+
+                api_obj.reset()
+                pkg5unittest.eval_assert_raises(api_errors.PlanCreationException,
+                    check_illegal, api_obj.plan_install, ["/foo"])
+
+        def test_catalog_v0(self):
+                """Test install from a publisher's repository that only supports
+                catalog v0, and then the transition from v0 to v1."""
+
+                self.dc.stop()
+                self.dc.set_disable_ops(["catalog/1"])
+                self.dc.start()
+
+                durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.foo10)
+                self.image_create(durl)
+
+                progresstracker = progress.NullProgressTracker()
+                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
+                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
+                self.__do_install(api_obj, ["foo"])
+
+                api_obj.reset()
+                self.__do_uninstall(api_obj, ["foo"])
+ 
+                api_obj.reset()
+                self.__do_install(api_obj, ["pkg://test/foo"])
+
+                self.pkgsend_bulk(durl, self.bar10)
+                self.dc.stop()
+                self.dc.unset_disable_ops()
+                self.dc.start()
+
+                api_obj.reset()
+                api_obj.refresh(immediate=True)
+
+                api_obj.reset()
+                self.__do_install(api_obj, ["pkg://test/[email protected]"])
+
+
+if __name__ == "__main__":
+        unittest.main()
--- a/src/tests/api/t_pkgtarfile.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_pkgtarfile.py	Sat Jan 30 01:07:14 2010 -0800
@@ -21,10 +21,15 @@
 #
 
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import unittest
 import sys
 import os
@@ -34,17 +39,13 @@
 import pkg.portable as portable
 import pkg.pkgtarfile as pkgtarfile
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-import pkg5unittest
-
 class TestPkgTarFile(pkg5unittest.Pkg5TestCase):
 
         def setUp(self):
-                self.tpath = tempfile.mkdtemp()
+                pkg5unittest.Pkg5TestCase.setUp(self)
+                self.tpath = tempfile.mkdtemp(dir=self.test_root)
 
-                cpath = tempfile.mkdtemp()
+                cpath = tempfile.mkdtemp(dir=self.test_root)
                 filepath = os.path.join(cpath, "foo/bar")
                 filename = "baz"
                 create_path = os.path.join(filepath, filename)
@@ -61,9 +62,6 @@
                 tarfp.close()
                 shutil.rmtree(cpath)
                 
-        def tearDown(self):
-                shutil.rmtree(self.tpath)
-
         def testerrorlevelIsCorrect(self):
                 p = pkgtarfile.PkgTarFile(self.tarfile, 'r')
 
--- a/src/tests/api/t_plat.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_plat.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,9 +20,14 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import unittest
 import os
 import shutil
@@ -34,14 +39,7 @@
 import pkg.portable.util as util
 import pkg.portable as portable
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-import pkg5unittest
-
 class TestPlat(pkg5unittest.Pkg5TestCase):
-        def setUp(self):
-                pass
                 
         def testbasic(self):
                 portable.get_isainfo()
--- a/src/tests/api/t_publisher.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_publisher.py	Sat Jan 30 01:07:14 2010 -0800
@@ -21,10 +21,15 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import copy
 import errno
 import os
@@ -38,11 +43,6 @@
 import pkg.misc as misc
 
 
-# Set the path so that modules above can be found.
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-import pkg5unittest
-
 class TestPublisher(pkg5unittest.Pkg5TestCase):
         """Class to test the functionality of the pkg.client.publisher module.
         """
@@ -50,39 +50,16 @@
         misc_files = [ "test.cert", "test.key", "test2.cert", "test2.key" ]
 
         def setUp(self):
-                self.pid = os.getpid()
-                self.pwd = os.getcwd()
-
-                self.__test_prefix = os.path.join(tempfile.gettempdir(),
-                    "ips.test.%d" % self.pid)
-
-                try:
-                        os.makedirs(self.__test_prefix, misc.PKG_DIR_MODE)
-                except OSError, e:
-                        if e.errno != errno.EEXIST:
-                                raise e
-
-                for p in self.misc_files:
-                        fpath = os.path.join(self.get_test_prefix(), p)
-                        f = open(fpath, "wb")
-                        # Write the name of the file into the file, so that
-                        # all files have differing contents.
-                        f.write(fpath)
-                        f.close()
-
-        def tearDown(self):
-                shutil.rmtree(self.get_test_prefix())
-
-        def get_test_prefix(self):
-                return self.__test_prefix
+                pkg5unittest.Pkg5TestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
 
         def test_01_repository_uri(self):
                 """Verify that a RepositoryURI object can be created, copied,
                 modified, and used as expected."""
 
-                nsfile = os.path.join(self.get_test_prefix(), "nosuchfile")
-                tcert = os.path.join(self.get_test_prefix(), "test.cert")
-                tkey = os.path.join(self.get_test_prefix(), "test.key")
+                nsfile = os.path.join(self.test_root, "nosuchfile")
+                tcert = os.path.join(self.test_root, "test.cert")
+                tkey = os.path.join(self.test_root, "test.key")
 
                 uprops = {
                     "priority": 1,
@@ -159,11 +136,11 @@
                 """Verify that a Repository object can be created, copied,
                 modified, and used as expected."""
 
-                tcert = os.path.join(self.get_test_prefix(), "test.cert")
-                tkey = os.path.join(self.get_test_prefix(), "test.key")
+                tcert = os.path.join(self.test_root, "test.cert")
+                tkey = os.path.join(self.test_root, "test.key")
 
-                t2cert = os.path.join(self.get_test_prefix(), "test2.cert")
-                t2key = os.path.join(self.get_test_prefix(), "test2.key")
+                t2cert = os.path.join(self.test_root, "test2.cert")
+                t2key = os.path.join(self.test_root, "test2.key")
 
                 rprops = {
                     "collection_type": publisher.REPO_CTYPE_SUPPLEMENTAL,
@@ -358,7 +335,7 @@
                     "alias": "cat",
                     "client_uuid": "2c6a8ff8-20e5-11de-a818-001fd0979039",
                     "disabled": True,
-                    "meta_root": os.path.join(self.get_test_prefix(), "bobcat"),
+                    "meta_root": os.path.join(self.test_root, "bobcat"),
                     "repositories": [robj, r2obj],
                     "selected_repository": r2obj,
                 }
--- a/src/tests/api/t_repositoryconfig.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_repositoryconfig.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,9 +20,14 @@
 # CDDL HEADER END
 #
 
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import unittest
 import copy
 import os
@@ -31,11 +36,6 @@
 
 import pkg.server.repositoryconfig as rcfg
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-import pkg5unittest
-
 class TestRepositoryConfig(pkg5unittest.Pkg5TestCase):
         """Class to test the functionality of RepositoryConfig.
         """
@@ -147,7 +147,9 @@
         def setUp(self):
                 """Setup our tests.
                 """
-                fd, self.sample_conf = tempfile.mkstemp()
+                pkg5unittest.Pkg5TestCase.setUp(self)
+
+                fd, self.sample_conf = tempfile.mkstemp(dir=self.test_root)
                 f = os.fdopen(fd, "w")
 
                 self.remove = [self.sample_conf]
@@ -274,7 +276,7 @@
                 write().  Calling set for a read-only value should raise a
                 ValueError exception.
                 """
-                fd, sample_conf = tempfile.mkstemp()
+                fd, sample_conf = tempfile.mkstemp(dir=self.test_root)
                 self.remove.append(sample_conf)
                 rc = rcfg.RepositoryConfig()
                 props = self.__props
--- a/src/tests/api/t_smf.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_smf.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,46 +20,40 @@
 # CDDL HEADER END
 #
 
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import unittest
 import tempfile
 import os
 import sys
 import pkg.smf as smf
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-import pkg5unittest
-
 class TestSMF(pkg5unittest.Pkg5TestCase):
 
-	def setUp(self):
-		fd_passwd, self.passwd_tmp = tempfile.mkstemp()
-		fd_xml, self.xml_tmp = tempfile.mkstemp()
-		fd_s1, self.smf1_tmp = tempfile.mkstemp()
-		fd_s2, self.smf2_tmp = tempfile.mkstemp()
+        misc_files = { "passwd" : """\
+root:x:0:0:Super-User:/:/bin/bash
+daemon:x:1:1::/:
+""",
 
-                f = os.fdopen(fd_passwd, "w")
-		f.write("root:x:0:0:Super-User:/:/bin/bash\n")
-		f.write("daemon:x:1:1::/:")
-		f.close()
-
-                f = os.fdopen(fd_xml, "w")
-		f.write("""<?xml version="1.0" encoding="ISO-8859-1"?>
+            "helloworld.xml" : """\
+<?xml version="1.0" encoding="ISO-8859-1"?>
 <?xml-stylesheet type="text/xsl" href="HelloWorld.xsl" ?>
 <!-- Hello World in XML -->
-<text><string>Hello, World</string></text>""")
-		f.close()
+<text><string>Hello, World</string></text>
+""",
 
-		#
-		# This is a single-instance SMF manifest with pseudo contents;
-		# we can process this with get_info and easily test the results
-		#
-                f = os.fdopen(fd_s1, "w")
-		f.write("""<?xml version="1.0"?>
+	    #
+            # This is a single-instance SMF manifest with pseudo
+            # contents; we can process this with get_info and easily
+            # test the results
+	    #
+            "sample_mfst1.xml" : """<?xml version="1.0"?>
 <!DOCTYPE service_bundle SYSTEM
     "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
 <service_bundle type='manifest' name='test'>
@@ -87,15 +81,14 @@
 	<service_fmri value='svc:/milestone/multi-user' />
 </dependent>
 </service>
-</service_bundle>""")
-		f.close()
+</service_bundle>""",
 
-		#
-		# This is a multi-instance SMF manifest with pseudo contents;
-		# we can process this with get_info and easily test the results
-		#
-                f = os.fdopen(fd_s2, "w")
-		f.write("""<?xml version="1.0"?>
+	    #
+            # This is a multi-instance SMF manifest with pseudo
+            # contents; we can process this with get_info and easily
+            # test the results
+	    #
+            "sample_mfst2.xml" : """<?xml version="1.0"?>
 <!DOCTYPE service_bundle SYSTEM
     "/usr/share/lib/xml/dtd/service_bundle.dtd.1">
 <service_bundle type='manifest' name='test'>
@@ -146,33 +139,32 @@
 	</dependent>
 </instance>
 </service>
-</service_bundle>""")
-		f.close()
-
+</service_bundle>""" }
 
-	def tearDown(self):
-		os.remove(self.passwd_tmp)
-		os.remove(self.xml_tmp)
-		os.remove(self.smf1_tmp)
-		os.remove(self.smf2_tmp)
+	def setUp(self):
+                pkg5unittest.Pkg5TestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
 
-
+                self.passwd = os.path.join(self.test_root, "passwd")
+                self.xml = os.path.join(self.test_root, "helloworld.xml")
+                self.smf1 = os.path.join(self.test_root, "sample_mfst1.xml")
+                self.smf2 = os.path.join(self.test_root, "sample_mfst2.xml")
 
 	def test_is_smf_manifest1(self):
 		""" ASSERT: a miscellaneous text file is not a manifest """
-		self.assertEqual(smf.is_smf_manifest(self.passwd_tmp), False)
+		self.assertEqual(smf.is_smf_manifest(self.passwd), False)
 
 	def test_is_smf_manifest2(self):
 		""" ASSERT: a miscellaneous xml file is not a manifest """
-		self.assertEqual(smf.is_smf_manifest(self.xml_tmp), False)
+		self.assertEqual(smf.is_smf_manifest(self.xml), False)
 
 	def test_is_smf_manifest3(self):
 		""" ASSERT: an single-instance manifest is identified """
-		self.assertEqual(smf.is_smf_manifest(self.smf1_tmp), True)
+		self.assertEqual(smf.is_smf_manifest(self.smf1), True)
 
 	def test_is_smf_manifest3(self):
 		""" ASSERT: an multi-instance manifest is identified """
-		self.assertEqual(smf.is_smf_manifest(self.smf2_tmp), True)
+		self.assertEqual(smf.is_smf_manifest(self.smf2), True)
 
 # XXX not sure what the desired behaviour is.  Currently it throws an
 # exception.  Is that ok?
@@ -187,7 +179,7 @@
 		""" ASSERT: get_info returns values corresponding to sample
 		    manifest """
 
-		info = smf.get_info(self.smf1_tmp)
+		info = smf.get_info(self.smf1)
 		self.assertEqual(info,
 		    {'imposes':
 		        [('optional_all', ['svc:/milestone/multi-user'])],
@@ -199,7 +191,7 @@
                     })
 
 	#
-	# Even though smf2_tmp provides multiple services, the
+	# Even though smf2 provides multiple services, the
 	# "info" object should compact the set of things which
 	# are imposed and required.
 
@@ -207,7 +199,7 @@
 #	def test_get_info_2(self):
 #		""" ASSERT: get_info weeds out duplicated information """
 #
-#		info = smf.get_info(self.smf2_tmp)
+#		info = smf.get_info(self.smf2)
 #		self.assertEqual(info,
 #		    {'imposes':
 #		        [('optional_all', ['svc:/milestone/multi-user'])],
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/api/t_solver.py	Sat Jan 30 01:07:14 2010 -0800
@@ -0,0 +1,2216 @@
+#!/usr/bin/python
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+
+import pkg5unittest
+import pkg.solver as solver
+import os
+import sys
+
+class TestSolver(pkg5unittest.Pkg5TestCase):
+
+        def test_no_solution(self):
+                cnf_test(failing_test_case.splitlines())
+
+        def test_solution(self):
+                cnf_test(working_test_case.splitlines())
+
+def cnf_test(lines):
+        s = solver.msat_solver()
+        
+        for l in lines:
+                if l and l[0] in 'pc%0':
+                        pass # comment
+                else:
+                        # skip trailing 0
+                        cl = [int(i) for i in l.split()[0:-1]]
+                        if cl and not s.add_clause(cl):
+                                return False
+        # create new copy of solver instance to test copy code
+        n = solver.msat_solver(s)
+        del s # force gc of old solver instance
+        return n.solve([])
+
+
+failing_test_case = """
+c This Formular is generated by mcnf
+c
+c    horn? no
+c    forced? no
+c    mixed sat? no
+c    clause length = 3
+c
+p cnf 250  1065
+ -128 -209 148 0
+2 196 -115 0
+-66 -189 -241 0
+-84 -132 -93 0
+214 179 66 0
+203 132 -237 0
+164 -13 -172 0
+-157 198 160 0
+-91 -164 235 0
+-70 -116 54 0
+-164 171 -189 0
+126 -184 211 0
+-19 118 41 0
+32 105 -33 0
+-141 -108 50 0
+-1 156 -188 0
+138 -181 142 0
+-191 -247 -220 0
+-101 -207 -88 0
+68 114 -234 0
+134 -57 -131 0
+-30 -133 116 0
+-24 -173 92 0
+226 -4 -224 0
+-190 204 61 0
+148 205 -174 0
+213 -56 53 0
+174 -250 206 0
+32 219 -112 0
+203 -222 202 0
+130 42 226 0
+222 33 58 0
+58 35 34 0
+-121 80 245 0
+-231 38 -248 0
+-205 -179 184 0
+-182 -204 -36 0
+23 35 -181 0
+82 -168 -59 0
+103 132 -182 0
+-243 -18 -160 0
+-180 130 95 0
+111 -140 -107 0
+19 28 -72 0
+-222 207 -103 0
+134 -50 -184 0
+185 155 -11 0
+-102 230 -18 0
+-112 39 242 0
+154 -87 53 0
+173 -123 -159 0
+-238 -101 -40 0
+-126 -232 -139 0
+107 -51 197 0
+-194 -138 -150 0
+106 -66 -11 0
+-150 -159 -27 0
+-98 -32 138 0
+144 -32 128 0
+153 74 -249 0
+-190 -175 -208 0
+-127 88 -38 0
+-59 125 -225 0
+-23 4 181 0
+12 247 -133 0
+151 -238 127 0
+237 -65 -154 0
+-218 -26 -55 0
+91 -245 169 0
+-81 -156 10 0
+166 -66 -45 0
+109 -162 47 0
+-193 153 40 0
+162 -186 -7 0
+93 38 -58 0
+-159 -167 -39 0
+-187 68 124 0
+247 23 212 0
+49 182 -243 0
+206 -105 -237 0
+236 116 154 0
+236 -6 182 0
+-168 236 35 0
+-186 70 -236 0
+127 80 103 0
+100 79 -176 0
+117 -88 -1 0
+60 -115 -224 0
+-148 181 -65 0
+-132 235 19 0
+-44 -197 190 0
+-214 67 129 0
+-203 175 -191 0
+-172 166 -115 0
+-176 -180 207 0
+-56 -208 -1 0
+-37 140 -19 0
+-242 -55 58 0
+-116 -153 241 0
+-203 64 -219 0
+-214 64 90 0
+-166 96 155 0
+68 -2 63 0
+-200 49 196 0
+-230 -232 -148 0
+-81 105 219 0
+187 -236 -123 0
+-99 237 136 0
+-205 61 -118 0
+-235 -230 128 0
+38 -9 -124 0
+-34 -116 179 0
+-40 -55 -85 0
+244 170 6 0
+-7 -54 -236 0
+153 -223 173 0
+-219 -13 -217 0
+244 -210 -228 0
+23 -128 -113 0
+35 -245 -235 0
+184 31 143 0
+-207 -24 135 0
+97 -165 -14 0
+-17 15 26 0
+61 78 -8 0
+215 -30 -166 0
+229 93 -246 0
+-167 -113 80 0
+78 205 -87 0
+117 -144 207 0
+-10 153 -84 0
+-147 238 61 0
+-58 -17 -190 0
+209 -25 -81 0
+-175 244 -57 0
+185 127 -147 0
+237 199 -144 0
+124 148 -10 0
+190 244 231 0
+-185 214 -101 0
+-237 31 -94 0
+-39 36 -94 0
+-175 206 81 0
+141 -209 -109 0
+228 -165 -112 0
+-45 142 238 0
+-34 -64 -71 0
+-60 170 -109 0
+6 245 87 0
+12 -93 -231 0
+80 216 28 0
+-103 137 116 0
+-77 -73 -30 0
+-63 219 -129 0
+-215 -94 86 0
+81 46 221 0
+161 -215 -212 0
+-137 -215 48 0
+-50 211 229 0
+172 74 154 0
+-14 -100 166 0
+59 -119 -243 0
+244 -31 -96 0
+51 -247 205 0
+-90 97 -139 0
+113 118 -7 0
+57 -161 -84 0
+180 -174 -9 0
+-19 16 -202 0
+-39 -134 224 0
+84 240 195 0
+-55 75 -207 0
+116 54 60 0
+80 98 40 0
+-159 109 217 0
+-210 -119 82 0
+-201 -14 174 0
+43 -19 -100 0
+-126 223 26 0
+-249 163 -205 0
+-58 -4 109 0
+-239 109 -82 0
+210 -58 -2 0
+238 -36 117 0
+109 -199 32 0
+-54 221 -80 0
+230 99 97 0
+45 221 169 0
+191 17 114 0
+-177 -138 -12 0
+35 -5 145 0
+-102 -147 103 0
+-59 3 84 0
+-56 240 -130 0
+-233 -223 -47 0
+169 216 -3 0
+-68 -182 67 0
+34 -189 27 0
+230 -222 66 0
+19 123 84 0
+64 35 231 0
+236 165 242 0
+77 -119 -61 0
+-179 215 198 0
+-105 -93 211 0
+-204 221 -112 0
+-244 23 -125 0
+-107 152 78 0
+144 -183 28 0
+-179 -32 194 0
+217 174 72 0
+-38 101 -132 0
+-122 193 108 0
+12 3 -44 0
+140 -23 -2 0
+185 -129 145 0
+-116 -245 -102 0
+203 -29 -131 0
+-172 239 243 0
+-186 -167 109 0
+158 -184 149 0
+-53 56 100 0
+-92 5 35 0
+-212 -236 250 0
+-42 137 -193 0
+171 231 127 0
+176 -85 -122 0
+32 81 -178 0
+78 -14 -227 0
+104 -10 -65 0
+239 -81 -118 0
+182 76 -235 0
+-226 -132 54 0
+145 25 120 0
+49 205 99 0
+250 240 -89 0
+17 37 -65 0
+226 -66 -47 0
+136 -112 19 0
+-94 -32 74 0
+200 144 -65 0
+27 29 207 0
+6 112 53 0
+-170 -192 -65 0
+-18 206 8 0
+-158 245 147 0
+222 34 24 0
+69 182 -121 0
+-22 -202 -232 0
+-213 -82 173 0
+78 -176 -151 0
+245 215 242 0
+-126 -96 243 0
+-164 -220 205 0
+-60 128 162 0
+-237 -126 -20 0
+105 -144 -165 0
+-158 76 -38 0
+153 -236 206 0
+187 -191 247 0
+-192 159 171 0
+162 -151 -213 0
+19 155 238 0
+-43 207 -46 0
+117 250 118 0
+159 40 -199 0
+149 -163 -145 0
+23 7 46 0
+71 106 56 0
+-43 220 -118 0
+-200 242 6 0
+143 219 -168 0
+-179 102 -163 0
+-74 183 -82 0
+248 92 -154 0
+81 202 229 0
+92 243 19 0
+165 -210 199 0
+-54 -8 244 0
+-70 -135 -223 0
+-80 -89 -189 0
+-7 182 -16 0
+172 53 8 0
+114 -107 197 0
+-135 -35 -239 0
+-214 -10 137 0
+136 -131 151 0
+15 -37 -89 0
+-234 -7 97 0
+118 191 101 0
+215 123 185 0
+-230 202 -190 0
+211 -59 210 0
+200 -162 116 0
+158 12 212 0
+-56 229 196 0
+-50 -52 218 0
+164 -142 -71 0
+233 -140 159 0
+119 93 65 0
+155 -156 -57 0
+117 -197 180 0
+-97 -100 -2 0
+165 206 83 0
+-127 173 -110 0
+20 158 116 0
+-205 -125 -209 0
+-244 -57 -246 0
+-139 -173 21 0
+89 -150 149 0
+-51 60 -224 0
+-81 -193 195 0
+-208 -209 83 0
+-141 70 -223 0
+200 -121 99 0
+-207 201 -61 0
+167 157 -71 0
+200 78 182 0
+82 171 -183 0
+4 -33 -85 0
+-103 87 186 0
+41 183 169 0
+84 244 -116 0
+128 -108 -67 0
+24 165 181 0
+94 118 -148 0
+-41 -71 -98 0
+248 15 -135 0
+10 -157 -17 0
+-225 241 93 0
+217 -192 227 0
+28 -11 78 0
+-16 218 24 0
+59 -91 -210 0
+4 141 166 0
+-204 12 -206 0
+187 153 -186 0
+23 -43 -124 0
+100 2 -46 0
+-236 -80 -102 0
+165 129 159 0
+-45 245 -187 0
+137 31 -7 0
+214 -178 200 0
+222 107 -74 0
+-37 -161 -129 0
+-202 -214 99 0
+69 3 78 0
+-7 -217 51 0
+215 -99 96 0
+124 41 195 0
+-233 -223 206 0
+233 197 87 0
+-102 33 70 0
+175 241 162 0
+86 -202 83 0
+137 -214 64 0
+-111 -204 197 0
+-23 12 -121 0
+101 28 -95 0
+-206 57 220 0
+-122 -2 -125 0
+75 -241 86 0
+-72 185 77 0
+-125 210 -143 0
+106 36 54 0
+136 142 -93 0
+-142 -180 214 0
+44 -22 -60 0
+-235 88 -130 0
+-124 -162 245 0
+19 -121 156 0
+84 -23 -191 0
+-173 -43 -163 0
+151 148 213 0
+-239 147 -180 0
+-247 -92 -36 0
+163 37 -188 0
+-245 -7 -231 0
+-32 -139 41 0
+-13 -157 211 0
+-107 136 126 0
+-58 201 -115 0
+-184 -48 -205 0
+57 -237 -80 0
+160 -243 155 0
+154 -42 -179 0
+-107 -242 -167 0
+169 170 -19 0
+-65 -140 -209 0
+143 146 182 0
+90 -170 158 0
+-235 54 83 0
+-122 193 239 0
+112 130 -212 0
+-9 -167 93 0
+-57 54 -28 0
+-55 -56 29 0
+-206 -79 245 0
+-16 -81 -190 0
+174 160 131 0
+-125 156 -148 0
+-128 174 -25 0
+-209 -16 60 0
+-13 -225 109 0
+167 -124 168 0
+142 -16 173 0
+8 -45 216 0
+13 160 -41 0
+-101 125 -225 0
+-218 244 -49 0
+153 -183 204 0
+117 230 167 0
+-108 24 -27 0
+149 -198 13 0
+48 124 -84 0
+-35 -162 58 0
+110 -103 9 0
+-143 -43 169 0
+-91 -87 -70 0
+11 -117 244 0
+-141 37 -177 0
+238 126 -215 0
+157 103 -27 0
+-133 134 -3 0
+112 -107 -113 0
+-225 -104 26 0
+109 -220 -174 0
+58 -140 -86 0
+1 97 14 0
+249 161 -217 0
+99 -242 33 0
+172 2 -235 0
+-79 -132 107 0
+43 -217 -169 0
+-166 218 -128 0
+63 178 135 0
+110 224 30 0
+-62 147 -237 0
+-241 -103 -169 0
+125 -75 -106 0
+146 20 -112 0
+59 226 -136 0
+-194 132 -101 0
+133 -41 -14 0
+190 74 -247 0
+230 221 224 0
+-3 -61 -65 0
+93 15 194 0
+-155 105 117 0
+-146 -127 -35 0
+170 -173 213 0
+-13 -234 -117 0
+-244 -225 15 0
+-41 151 -185 0
+-196 -2 114 0
+-220 111 -238 0
+234 134 146 0
+100 -29 -4 0
+-195 -6 151 0
+-116 109 -9 0
+45 -58 -61 0
+195 224 66 0
+119 174 129 0
+122 233 100 0
+30 -227 -120 0
+238 1 16 0
+231 229 -46 0
+188 226 23 0
+-181 247 -216 0
+233 84 97 0
+8 41 71 0
+37 52 56 0
+-227 58 84 0
+116 48 -95 0
+-58 233 36 0
+210 11 -116 0
+-107 -103 242 0
+21 -161 169 0
+202 25 82 0
+248 163 65 0
+-108 26 -78 0
+-162 163 -248 0
+-14 -95 92 0
+218 -151 -26 0
+-132 -195 44 0
+14 85 -136 0
+-236 219 -105 0
+164 136 -25 0
+7 36 124 0
+-163 -216 -15 0
+-66 176 -76 0
+-144 -3 -101 0
+-178 -149 -108 0
+175 -161 210 0
+-118 106 -11 0
+-124 128 98 0
+-81 -223 117 0
+154 149 -1 0
+-186 26 66 0
+-190 192 -114 0
+-122 -197 -52 0
+-84 -226 105 0
+52 61 225 0
+206 -7 -101 0
+-29 93 -116 0
+67 -164 135 0
+1 -217 -5 0
+-180 218 222 0
+230 -225 -50 0
+4 -25 45 0
+-57 234 -1 0
+-221 -103 100 0
+137 234 -109 0
+20 -227 -202 0
+-103 -247 198 0
+-29 -148 -35 0
+-191 102 18 0
+-52 -195 18 0
+61 5 -247 0
+165 -207 -217 0
+-147 -207 27 0
+100 117 -129 0
+-152 -83 132 0
+-190 53 -121 0
+156 230 181 0
+2 -239 -65 0
+-55 -20 -107 0
+-119 -39 -221 0
+-116 147 16 0
+-211 238 -60 0
+249 -111 141 0
+-54 -193 -81 0
+49 -245 -5 0
+-233 110 -109 0
+-79 -56 180 0
+-41 196 150 0
+242 -63 231 0
+39 22 100 0
+5 23 204 0
+-55 -100 105 0
+-22 -28 247 0
+-209 200 67 0
+-46 59 62 0
+-239 -107 -125 0
+242 25 -246 0
+-148 -30 -11 0
+-148 160 -169 0
+5 145 249 0
+168 -28 -207 0
+-188 212 -201 0
+-166 205 -239 0
+145 -246 -100 0
+3 215 -93 0
+101 -198 -160 0
+-233 178 -90 0
+-143 -26 -102 0
+-72 -97 -195 0
+-119 -163 -120 0
+93 13 98 0
+-131 -53 15 0
+-118 129 151 0
+168 81 199 0
+-17 121 -21 0
+-36 -175 196 0
+-221 57 68 0
+111 145 -183 0
+114 -31 24 0
+-170 159 -146 0
+123 -80 152 0
+-84 -184 -134 0
+-206 30 -55 0
+81 -154 198 0
+129 135 248 0
+-2 198 122 0
+230 101 -18 0
+25 208 216 0
+-247 176 160 0
+34 -159 9 0
+-74 184 31 0
+29 -66 -148 0
+-233 204 -107 0
+204 -30 -127 0
+-237 8 -65 0
+79 112 181 0
+157 -85 83 0
+204 113 -216 0
+-11 -15 27 0
+44 114 8 0
+105 188 -158 0
+-51 204 -48 0
+145 211 40 0
+-107 -31 -114 0
+-134 212 -105 0
+188 -174 -151 0
+58 -9 -151 0
+33 -37 -119 0
+172 -3 169 0
+-26 -21 48 0
+-94 -99 -41 0
+192 1 -7 0
+250 -138 185 0
+-6 -131 -83 0
+11 191 -240 0
+-175 -163 -249 0
+-214 -98 193 0
+120 190 -185 0
+-135 -64 -24 0
+-187 249 -129 0
+76 -232 112 0
+-17 -161 117 0
+-6 250 246 0
+85 -188 117 0
+-47 91 -103 0
+-123 -92 142 0
+3 -183 -249 0
+-175 148 -129 0
+223 172 119 0
+194 76 -114 0
+206 123 -222 0
+-186 -110 -71 0
+-63 152 -110 0
+-122 -44 -119 0
+-14 76 -224 0
+-8 -77 -97 0
+-116 110 63 0
+148 106 192 0
+204 -168 -56 0
+-221 173 -13 0
+168 57 -211 0
+218 151 245 0
+70 -234 -143 0
+24 194 106 0
+16 -236 -187 0
+162 97 43 0
+8 79 228 0
+-39 -179 48 0
+-119 213 -231 0
+-239 57 -232 0
+-161 247 8 0
+30 -127 197 0
+72 168 -233 0
+-157 -217 -135 0
+134 180 233 0
+27 -14 -64 0
+153 247 -60 0
+-154 -76 -106 0
+-59 -100 170 0
+120 -121 -41 0
+-169 13 158 0
+-166 199 120 0
+164 202 -199 0
+-223 148 -242 0
+4 211 100 0
+188 -231 -98 0
+218 129 -93 0
+-211 18 -93 0
+51 -10 -78 0
+22 -155 -130 0
+207 -135 -172 0
+199 197 14 0
+182 -245 -135 0
+-204 181 -32 0
+-18 -237 80 0
+-96 69 193 0
+-98 245 -91 0
+71 -24 93 0
+48 -131 194 0
+29 144 -12 0
+128 15 -71 0
+125 58 -238 0
+-84 111 38 0
+224 168 246 0
+-82 -188 -33 0
+-67 98 242 0
+34 248 -112 0
+217 95 59 0
+56 245 13 0
+72 129 -245 0
+82 134 -61 0
+-128 55 -183 0
+-187 42 38 0
+90 -102 54 0
+-159 224 229 0
+-117 -158 -180 0
+113 108 5 0
+239 34 -122 0
+-85 -118 -19 0
+-240 129 -145 0
+-15 149 129 0
+-144 -189 217 0
+228 -223 97 0
+16 -84 -242 0
+206 -212 91 0
+-71 -194 21 0
+59 -31 37 0
+-89 156 -243 0
+60 21 75 0
+14 12 -8 0
+-227 -183 131 0
+-95 -190 -49 0
+-151 -54 -133 0
+-134 49 -157 0
+6 -114 224 0
+201 -195 -17 0
+-99 -36 88 0
+123 -67 105 0
+142 -94 49 0
+58 106 234 0
+22 -18 -86 0
+201 -245 71 0
+-220 -228 227 0
+-117 31 -212 0
+-177 -140 -59 0
+229 233 150 0
+47 -36 103 0
+-239 102 -241 0
+-35 194 208 0
+199 -37 -180 0
+140 -176 -123 0
+148 -36 243 0
+14 141 227 0
+-182 -141 248 0
+178 85 144 0
+247 231 15 0
+77 -168 -40 0
+-194 -181 -83 0
+-225 116 -79 0
+-80 182 -50 0
+63 -36 -122 0
+82 231 -59 0
+-64 -244 157 0
+-86 140 -207 0
+-129 -192 -143 0
+-69 227 216 0
+-83 137 -101 0
+117 -71 145 0
+115 -53 199 0
+-32 96 -1 0
+104 93 -142 0
+190 116 83 0
+191 -124 -161 0
+144 11 -181 0
+-151 113 243 0
+-66 -141 -108 0
+-153 -149 7 0
+-75 -129 137 0
+113 -107 43 0
+-191 99 237 0
+199 67 163 0
+-198 -177 -21 0
+217 -236 88 0
+-136 -84 158 0
+52 68 -204 0
+-61 200 21 0
+95 -204 -221 0
+-75 -125 118 0
+213 113 173 0
+-226 -92 118 0
+-134 -189 67 0
+-198 7 -26 0
+-49 197 57 0
+-5 -72 -146 0
+226 167 -27 0
+211 -229 94 0
+-101 -80 -12 0
+58 -47 -80 0
+148 -217 -9 0
+229 -120 -117 0
+161 -174 191 0
+10 -51 -154 0
+-155 235 -198 0
+-171 247 127 0
+-130 19 140 0
+-209 -185 -25 0
+-223 -199 -27 0
+-28 124 187 0
+135 -28 31 0
+-31 88 89 0
+22 -43 -47 0
+21 165 -184 0
+-250 69 -27 0
+221 -177 162 0
+-72 -218 207 0
+23 -159 83 0
+-54 225 -190 0
+-140 -21 49 0
+-50 -177 -18 0
+80 -250 172 0
+-77 183 -218 0
+184 55 -146 0
+-104 181 -188 0
+243 146 -70 0
+-215 -187 -247 0
+-196 -50 90 0
+-84 143 -146 0
+147 119 -118 0
+227 14 -110 0
+44 238 -153 0
+197 -69 -176 0
+127 65 27 0
+208 190 -162 0
+-39 250 -196 0
+114 -89 206 0
+142 75 -148 0
+-202 237 -194 0
+-21 216 -177 0
+114 -80 -200 0
+-27 91 -84 0
+-63 249 -36 0
+89 -18 -133 0
+-19 -17 -107 0
+145 62 -227 0
+-89 -148 -44 0
+-133 -192 -149 0
+-65 240 -233 0
+-88 -40 -245 0
+92 -129 4 0
+22 -62 -21 0
+216 116 -93 0
+79 100 234 0
+39 134 44 0
+-226 -170 -157 0
+104 9 -191 0
+26 -39 40 0
+113 232 -174 0
+-101 81 -104 0
+173 90 101 0
+-208 173 -97 0
+-72 209 -111 0
+-51 -93 108 0
+-248 216 181 0
+-65 -170 212 0
+-102 -161 146 0
+-72 -28 -25 0
+-117 -18 229 0
+-52 163 -79 0
+94 120 79 0
+105 116 -227 0
+67 186 -211 0
+-226 -235 196 0
+-67 -11 23 0
+-55 -85 -197 0
+-200 -245 -76 0
+109 -61 -127 0
+-248 127 -229 0
+53 148 -197 0
+151 -98 -24 0
+-58 180 -158 0
+74 214 -200 0
+-31 241 172 0
+26 219 -56 0
+1 110 -18 0
+156 19 -89 0
+112 87 204 0
+-5 151 -59 0
+34 -149 100 0
+83 248 220 0
+31 2 -78 0
+110 -152 -37 0
+-132 -217 -57 0
+-71 176 79 0
+31 -98 -75 0
+-60 229 -171 0
+87 207 112 0
+30 151 -41 0
+17 162 109 0
+-172 111 -221 0
+166 170 -147 0
+-48 143 -201 0
+233 -46 -122 0
+207 -149 -124 0
+-188 -166 -65 0
+-76 -77 -96 0
+-216 211 45 0
+137 -103 -106 0
+220 -82 -136 0
+47 -84 -44 0
+-37 67 -32 0
+33 -5 156 0
+-137 58 127 0
+229 -36 -84 0
+243 175 63 0
+242 -73 -121 0
+219 237 164 0
+149 -201 -142 0
+27 172 243 0
+-90 29 45 0
+206 57 153 0
+-235 -49 -94 0
+233 71 108 0
+82 -122 223 0
+-195 -71 37 0
+-70 179 -159 0
+-79 -240 -38 0
+-79 -121 30 0
+-238 -78 -246 0
+218 96 48 0
+107 -154 -199 0
+4 -205 194 0
+1 -205 -203 0
+-155 129 -26 0
+-128 57 22 0
+-195 -168 -10 0
+97 -186 -90 0
+122 227 171 0
+22 163 191 0
+-223 191 -85 0
+100 -59 -63 0
+245 49 -181 0
+-51 210 -135 0
+-34 55 54 0
+2 74 -57 0
+233 168 -230 0
+-40 22 230 0
+128 -157 27 0
+-154 -161 -114 0
+-74 -136 38 0
+51 -205 23 0
+-212 40 -71 0
+9 -138 -83 0
+-95 54 121 0
+-174 -85 140 0
+66 16 67 0
+-137 -8 105 0
+-133 -206 -3 0
+175 86 -206 0
+-50 -217 51 0
+51 244 31 0
+184 -218 84 0
+-153 58 -237 0
+56 -198 63 0
+228 -42 74 0
+43 -32 245 0
+-150 82 -44 0
+-14 -22 25 0
+228 -232 -245 0
+-147 -221 29 0
+-222 41 -40 0
+42 -13 -20 0
+53 9 161 0
+125 236 69 0
+-105 -172 32 0
+-142 114 -71 0
+-120 -122 -197 0
+-29 9 -200 0
+26 210 -193 0
+-155 183 140 0
+216 -208 -146 0
+-220 -8 98 0
+109 175 -63 0
+-16 -139 -108 0
+176 137 -119 0
+-97 39 142 0
+218 -44 -37 0
+-119 -69 -107 0
+-79 142 109 0
+-123 25 227 0
+177 -187 -89 0
+-99 -147 -207 0
+-68 81 236 0
+145 90 3 0
+93 -149 -127 0
+-120 -67 154 0
+121 234 -229 0
+-245 186 21 0
+92 5 -121 0
+197 -100 -46 0
+-40 -39 -3 0
+25 -117 -121 0
+-194 -189 175 0
+246 10 40 0
+13 50 147 0
+-243 163 105 0
+132 -131 -218 0
+-241 78 101 0
+-200 -38 -29 0
+-36 -166 183 0
+248 -216 218 0
+-203 92 204 0
+-83 -84 -165 0
+-202 -197 -244 0
+112 -221 63 0
+100 151 -1 0
+141 -206 -52 0
+181 -208 -229 0
+53 93 173 0
+193 -184 -79 0
+41 -78 -133 0
+1 -35 -90 0
+-198 -60 174 0
+152 207 -157 0
+183 -196 -163 0
+-244 242 218 0
+11 32 146 0
+-66 -32 -84 0
+-54 -109 -195 0
+190 -116 144 0
+-242 -122 86 0
+-71 7 -150 0
+241 -173 -15 0
+62 -217 81 0
+205 -116 130 0
+193 -209 128 0
+146 -240 -132 0
+29 197 161 0
+15 83 -39 0
+-109 -44 81 0
+244 85 -7 0
+-246 9 165 0
+115 -83 67 0
+-98 -141 170 0
+-102 94 -52 0
+-231 -74 -28 0
+162 191 -149 0
+197 -183 -35 0
+102 -56 50 0
+30 -45 -129 0
+25 -207 -33 0
+192 -106 -169 0
+43 -129 -169 0
+237 244 182 0
+-72 -44 -168 0
+-158 -150 102 0
+168 -143 151 0
+-72 26 212 0
+116 -89 98 0
+171 -197 156 0
+233 -54 -181 0
+129 -161 25 0
+113 69 -33 0
+179 -175 224 0
+138 -143 -46 0
+75 213 -246 0
+-137 -175 -150 0
+-169 -67 215 0
+86 69 -199 0
+-159 233 63 0
+-145 101 6 0
+129 -243 -227 0
+-175 72 -247 0
+163 -109 207 0
+31 77 33 0
+-136 175 160 0
+-192 -193 -7 0
+99 145 232 0
+-233 198 114 0
+240 -89 -108 0
+-81 -67 -63 0
+5 149 69 0
+-172 166 -184 0
+158 -244 -166 0
+-53 -172 -62 0
+49 25 61 0
+237 19 -166 0
+94 202 -148 0
+-246 13 152 0
+-135 -86 -5 0
+-190 -44 -223 0
+-17 -141 6 0
+165 39 237 0
+221 -62 -104 0
+-206 107 -223 0
+-159 -243 -13 0
+118 -9 57 0
+%
+0
+"""
+working_test_case = """
+c This Formular is generated by mcnf
+c
+c    horn? no
+c    forced? no
+c    mixed sat? no
+c    clause length = 3
+c
+p cnf 250  1065
+ -108 246 59 0
+-161 -43 234 0
+7 41 -88 0
+26 178 -41 0
+-7 -145 -33 0
+206 18 -136 0
+-15 173 -213 0
+31 -91 215 0
+3 216 196 0
+234 -85 179 0
+155 -195 106 0
+-211 -223 -41 0
+97 2 -217 0
+-81 -122 27 0
+-149 34 239 0
+69 -216 183 0
+-69 148 -92 0
+-89 -120 184 0
+231 110 -213 0
+67 173 -195 0
+132 155 183 0
+-115 83 4 0
+173 163 -242 0
+-198 43 90 0
+71 -116 37 0
+-232 52 28 0
+21 -230 -124 0
+-146 -108 -110 0
+-116 163 214 0
+69 -143 128 0
+228 141 -99 0
+-47 75 -193 0
+-118 -244 -235 0
+148 -246 -112 0
+124 19 -76 0
+-49 102 -125 0
+110 155 3 0
+-180 -192 -94 0
+-114 -67 -219 0
+-159 53 187 0
+219 -102 162 0
+21 -109 -173 0
+-124 90 189 0
+-191 117 175 0
+77 -250 -155 0
+-74 203 60 0
+-4 65 166 0
+174 -212 -165 0
+-220 119 -35 0
+-247 105 126 0
+-110 -192 63 0
+-227 181 172 0
+-219 -31 -221 0
+51 113 19 0
+212 -4 151 0
+197 -14 -211 0
+117 159 -69 0
+48 -19 207 0
+-168 203 -212 0
+-232 250 -222 0
+151 34 139 0
+249 -159 229 0
+-243 244 -48 0
+48 180 -153 0
+-227 -98 190 0
+-73 -130 60 0
+33 239 -11 0
+41 -48 -201 0
+-39 43 143 0
+131 -28 106 0
+-97 49 -215 0
+7 42 -194 0
+-224 -94 46 0
+137 -220 -84 0
+-38 41 -163 0
+-229 208 -187 0
+149 -120 238 0
+-90 111 135 0
+176 -171 -36 0
+144 -238 237 0
+-194 111 -55 0
+76 203 -38 0
+-105 134 34 0
+55 -194 -239 0
+37 -95 177 0
+-121 -94 -169 0
+-93 49 -175 0
+54 -217 102 0
+-155 11 63 0
+83 -138 109 0
+-68 -30 103 0
+-208 -48 -125 0
+-100 230 -204 0
+-70 222 171 0
+146 -198 158 0
+13 24 98 0
+191 217 100 0
+52 -198 5 0
+166 219 -43 0
+107 -247 105 0
+-83 -13 86 0
+232 -68 -61 0
+-107 185 -112 0
+-106 225 -226 0
+48 71 238 0
+144 -83 -135 0
+-56 -27 -39 0
+243 94 55 0
+38 139 35 0
+-146 -127 180 0
+182 -83 84 0
+45 211 -70 0
+31 -91 72 0
+-146 -232 244 0
+-39 140 -200 0
+219 205 -220 0
+-94 -65 -87 0
+-143 180 -24 0
+70 161 -201 0
+136 128 85 0
+-223 64 62 0
+-69 209 147 0
+88 -15 -225 0
+80 48 -149 0
+224 246 -117 0
+-166 -53 -26 0
+-59 -63 -100 0
+-1 -55 -237 0
+214 246 13 0
+-101 249 -118 0
+-180 -222 -250 0
+-97 -7 58 0
+-169 -213 -80 0
+-120 152 242 0
+5 115 15 0
+70 -12 -43 0
+65 63 -248 0
+-148 177 173 0
+-224 201 12 0
+-231 -88 -141 0
+66 29 -233 0
+99 163 12 0
+-56 -183 197 0
+89 133 229 0
+126 79 149 0
+-238 -139 -137 0
+-170 -95 -148 0
+-202 -246 115 0
+-176 -63 158 0
+216 38 -83 0
+221 41 44 0
+-91 181 135 0
+171 -63 71 0
+-60 136 107 0
+222 5 57 0
+210 -89 -151 0
+-44 36 -91 0
+3 -194 -15 0
+-117 38 -110 0
+242 226 155 0
+158 -240 110 0
+218 -37 90 0
+11 217 57 0
+250 -157 73 0
+-9 -122 53 0
+185 -76 73 0
+-99 -101 102 0
+52 -171 33 0
+-143 195 228 0
+42 -63 -229 0
+-178 -160 224 0
+-65 -54 208 0
+232 -43 -38 0
+85 43 -178 0
+-171 -50 45 0
+47 71 -180 0
+127 135 -187 0
+-201 33 222 0
+-221 -131 -165 0
+-131 114 221 0
+195 60 185 0
+-8 206 -140 0
+124 -240 223 0
+-217 198 149 0
+52 -227 -206 0
+136 -96 29 0
+-76 -228 64 0
+-157 -47 93 0
+148 -108 17 0
+139 40 -89 0
+63 198 86 0
+199 94 -33 0
+-116 216 -2 0
+27 242 -1 0
+-156 177 28 0
+234 -83 37 0
+-124 -123 -149 0
+112 -1 173 0
+7 235 10 0
+245 -184 -224 0
+-112 -161 77 0
+203 104 124 0
+-59 -123 -10 0
+250 -242 -203 0
+56 243 164 0
+24 126 -2 0
+-101 227 86 0
+-233 138 -218 0
+-211 -119 -196 0
+143 -183 -186 0
+-148 236 76 0
+-131 -187 -77 0
+62 -144 -43 0
+-232 96 -30 0
+121 -152 89 0
+7 105 37 0
+182 135 -58 0
+-164 -162 -112 0
+-118 173 93 0
+-54 220 -2 0
+-193 32 65 0
+-101 46 203 0
+-127 -219 -215 0
+235 -42 -77 0
+-179 -242 -145 0
+-140 77 203 0
+-23 157 -112 0
+-28 -193 134 0
+-147 -166 100 0
+148 171 -31 0
+-214 241 -166 0
+-217 204 93 0
+-219 -211 -142 0
+107 57 50 0
+227 220 119 0
+-234 62 24 0
+-131 -223 24 0
+232 133 -4 0
+74 200 -201 0
+211 6 220 0
+-113 -9 102 0
+-207 39 -80 0
+24 244 -125 0
+171 190 -167 0
+122 24 -201 0
+-132 216 -235 0
+-90 58 -181 0
+161 62 185 0
+-3 -9 242 0
+115 2 -78 0
+42 -225 -145 0
+168 -46 55 0
+-40 -126 -154 0
+26 164 -1 0
+-71 199 -133 0
+-78 55 -201 0
+219 249 -203 0
+116 137 -43 0
+11 -137 -118 0
+143 224 -150 0
+-2 -199 218 0
+108 -140 -47 0
+228 28 -30 0
+224 58 -27 0
+-42 -211 153 0
+104 -238 -222 0
+-120 47 -33 0
+61 85 223 0
+230 -78 -77 0
+185 -210 106 0
+111 4 80 0
+226 195 -66 0
+-204 172 8 0
+195 -241 191 0
+166 182 -69 0
+-114 -130 223 0
+213 -189 243 0
+-201 151 26 0
+70 21 28 0
+-119 -208 -207 0
+-156 94 106 0
+-177 250 -6 0
+24 -227 -103 0
+87 4 -200 0
+139 133 -200 0
+-71 226 23 0
+-244 -32 60 0
+202 225 -63 0
+-233 -111 1 0
+175 -114 -147 0
+54 -30 193 0
+-137 -199 78 0
+31 -149 3 0
+90 186 138 0
+105 -43 -227 0
+-218 220 -216 0
+206 -182 119 0
+62 158 -215 0
+-92 -91 -103 0
+92 35 -13 0
+-4 -148 -219 0
+-119 125 8 0
+214 -160 -39 0
+120 -1 59 0
+190 216 -43 0
+-11 -5 119 0
+-118 -36 -187 0
+-200 -152 98 0
+194 -50 -8 0
+32 88 -154 0
+-45 106 159 0
+-226 202 112 0
+-101 28 -201 0
+-206 -209 180 0
+152 244 165 0
+210 112 -115 0
+195 -1 -151 0
+104 -14 5 0
+185 -167 -229 0
+192 31 184 0
+-116 -46 -113 0
+178 -108 140 0
+56 17 67 0
+80 6 195 0
+-250 -61 -106 0
+184 31 -236 0
+185 188 -7 0
+-127 -72 187 0
+-221 212 -13 0
+240 -19 192 0
+36 -135 -139 0
+-170 -116 87 0
+96 66 173 0
+40 -229 16 0
+184 -134 55 0
+233 13 141 0
+19 -204 -188 0
+-208 226 -192 0
+-185 48 178 0
+236 -34 -204 0
+-46 141 -194 0
+-8 -30 181 0
+72 -92 37 0
+-212 157 -92 0
+-210 -92 -225 0
+95 176 23 0
+-16 120 -63 0
+7 -136 40 0
+-88 -110 168 0
+121 208 -115 0
+228 215 171 0
+35 -19 -151 0
+45 222 -101 0
+95 103 108 0
+-35 -152 -64 0
+144 -226 -149 0
+-95 11 -170 0
+211 -152 106 0
+-59 80 223 0
+22 126 -156 0
+-19 -167 128 0
+-68 76 -114 0
+-121 32 122 0
+96 152 187 0
+-72 -90 -152 0
+129 193 93 0
+-109 -177 -149 0
+193 35 2 0
+172 -106 246 0
+134 -245 152 0
+212 100 -19 0
+127 -214 -56 0
+-245 -128 3 0
+89 -114 119 0
+147 -105 37 0
+-125 -102 -108 0
+22 33 177 0
+46 52 -240 0
+-62 -136 45 0
+222 -117 120 0
+16 -40 111 0
+86 206 49 0
+123 -78 -158 0
+44 188 90 0
+-103 89 176 0
+232 -112 130 0
+-109 70 19 0
+-15 204 128 0
+-127 -110 192 0
+-26 52 -147 0
+-41 5 105 0
+234 206 -160 0
+-52 128 195 0
+-184 -176 121 0
+184 167 -120 0
+-74 158 -148 0
+-18 62 200 0
+169 115 -190 0
+-124 229 164 0
+-63 37 221 0
+-76 190 245 0
+-217 136 -134 0
+-228 231 62 0
+156 -218 -85 0
+124 -25 225 0
+-182 32 -31 0
+-250 -221 35 0
+-80 114 -78 0
+248 186 139 0
+-19 -128 125 0
+85 154 113 0
+14 -80 -88 0
+-145 -43 88 0
+145 181 55 0
+134 31 -187 0
+-89 -109 -62 0
+-68 237 -222 0
+-130 -180 -227 0
+-86 48 90 0
+-199 -215 -132 0
+44 60 -14 0
+-248 -79 224 0
+-154 114 189 0
+-39 167 -139 0
+230 -5 -184 0
+17 184 -215 0
+-17 37 54 0
+-249 159 -151 0
+-29 -78 -148 0
+136 186 209 0
+-224 64 33 0
+-163 111 108 0
+-4 99 23 0
+137 -64 138 0
+-237 -116 29 0
+44 158 -139 0
+147 -8 -92 0
+-118 -228 42 0
+201 19 141 0
+-182 -39 -238 0
+-36 27 -79 0
+-157 249 -181 0
+-191 121 132 0
+-59 212 32 0
+72 -233 122 0
+230 -229 -132 0
+-231 60 -233 0
+-66 -249 106 0
+-210 -40 -79 0
+-75 61 111 0
+-51 -98 -32 0
+-166 137 245 0
+-134 113 52 0
+-107 19 72 0
+-64 85 -121 0
+227 82 -87 0
+-194 180 -128 0
+241 -211 38 0
+-74 -56 115 0
+206 -54 -210 0
+-66 -204 72 0
+144 156 16 0
+-197 84 54 0
+-80 199 59 0
+69 49 103 0
+19 190 -34 0
+-176 235 -151 0
+33 -202 -78 0
+-90 -15 -151 0
+198 28 -43 0
+-131 -74 -108 0
+159 89 -184 0
+-54 -62 141 0
+-83 -238 91 0
+227 -84 -76 0
+187 -15 205 0
+-243 -87 -207 0
+115 200 -48 0
+-82 -163 184 0
+221 -122 153 0
+-178 77 -52 0
+-250 113 -65 0
+-192 -153 -161 0
+185 -240 153 0
+187 -133 171 0
+-127 -108 139 0
+-158 -240 -121 0
+183 -137 -62 0
+-84 -60 210 0
+-35 -115 -5 0
+-16 81 41 0
+163 -167 -20 0
+192 -71 -102 0
+-223 -248 -37 0
+54 -18 79 0
+242 -238 114 0
+64 55 -39 0
+-48 30 -248 0
+-126 -6 -159 0
+-127 242 -160 0
+238 42 120 0
+224 -138 -66 0
+-189 -18 -183 0
+99 -43 -220 0
+149 -82 -59 0
+-25 239 60 0
+99 -201 137 0
+-50 188 -223 0
+84 147 157 0
+240 -183 -212 0
+239 243 -149 0
+119 217 162 0
+46 126 21 0
+204 196 21 0
+-174 26 53 0
+-45 63 -15 0
+155 -229 -99 0
+-149 29 -51 0
+43 250 -107 0
+-183 -34 -169 0
+7 -214 -55 0
+154 -61 -143 0
+-176 -25 -155 0
+-138 235 201 0
+137 -231 95 0
+48 -223 -227 0
+-16 -147 193 0
+-34 75 94 0
+140 -189 21 0
+-152 70 49 0
+-9 173 -238 0
+118 -39 129 0
+-129 -230 -101 0
+7 -58 89 0
+-96 50 -92 0
+-158 54 -139 0
+126 -156 -201 0
+-31 94 127 0
+32 72 103 0
+-142 195 51 0
+200 -246 -150 0
+-1 17 94 0
+-98 -52 -152 0
+20 213 -38 0
+-123 -225 -81 0
+-19 -158 165 0
+-107 -246 73 0
+-9 45 145 0
+-127 39 164 0
+-34 95 130 0
+-226 -210 213 0
+-250 -201 -91 0
+209 -191 -78 0
+-245 -248 192 0
+208 -191 -157 0
+136 123 169 0
+-117 -17 -74 0
+-140 174 162 0
+121 -37 119 0
+124 -152 217 0
+-240 -125 237 0
+33 90 -20 0
+-77 -187 -160 0
+-109 24 -239 0
+-3 -209 85 0
+84 -229 -199 0
+74 170 12 0
+-79 102 -245 0
+-191 -197 172 0
+-111 -176 -216 0
+-19 229 184 0
+-139 -123 240 0
+-208 45 -116 0
+100 -224 151 0
+-28 -13 -249 0
+-198 -226 -122 0
+-201 -81 43 0
+205 -189 53 0
+-23 240 -60 0
+-246 38 -224 0
+138 229 156 0
+-179 -60 -221 0
+204 -98 32 0
+-46 -228 -178 0
+-215 25 112 0
+96 -34 198 0
+32 -203 -225 0
+231 -156 -232 0
+130 -224 -197 0
+196 156 209 0
+99 210 -49 0
+91 95 143 0
+-199 79 -250 0
+150 221 152 0
+-31 223 249 0
+4 -127 -73 0
+-244 13 231 0
+-231 -27 -156 0
+159 -107 -217 0
+-153 -234 -216 0
+15 227 122 0
+-223 -23 -56 0
+-31 139 160 0
+-183 28 -223 0
+142 -241 -159 0
+-102 -157 -109 0
+17 -216 160 0
+206 -200 207 0
+-232 -70 -104 0
+131 -110 182 0
+171 70 -230 0
+167 -58 189 0
+145 -86 -57 0
+177 -183 -13 0
+-221 18 90 0
+-225 228 -127 0
+177 -174 226 0
+222 -144 -191 0
+-222 -171 -74 0
+214 172 229 0
+-111 49 12 0
+-155 179 -192 0
+-236 14 86 0
+-68 -13 -1 0
+103 210 -123 0
+-116 124 -244 0
+145 -14 -174 0
+28 129 230 0
+-192 123 35 0
+143 -118 241 0
+-211 -64 -128 0
+201 -85 -1 0
+91 198 24 0
+-92 -2 -201 0
+-158 87 83 0
+152 63 94 0
+17 218 119 0
+-162 183 237 0
+-13 -95 -49 0
+179 129 -79 0
+-42 -178 242 0
+169 -224 227 0
+76 152 1 0
+-109 98 99 0
+-150 240 -198 0
+-158 -43 152 0
+-159 -97 82 0
+-203 210 223 0
+208 132 -157 0
+127 -189 -208 0
+-48 -74 -1 0
+-57 132 -26 0
+-210 -220 -120 0
+-241 -131 23 0
+115 -64 -250 0
+31 -185 -239 0
+-210 190 94 0
+144 -38 80 0
+-155 211 134 0
+-238 222 134 0
+-153 74 205 0
+-103 64 28 0
+-57 -193 143 0
+139 110 -73 0
+-93 25 -153 0
+-247 164 20 0
+40 157 -189 0
+172 160 -180 0
+-177 -185 245 0
+180 49 56 0
+28 -22 232 0
+172 13 193 0
+97 1 206 0
+-161 -242 -185 0
+-186 170 -190 0
+59 28 -236 0
+76 246 222 0
+64 -202 51 0
+-20 138 107 0
+96 -228 16 0
+-249 28 44 0
+-193 -143 -113 0
+215 -224 -170 0
+-131 -12 35 0
+84 61 54 0
+-116 94 50 0
+-26 -21 -9 0
+107 -150 -143 0
+-174 45 147 0
+34 -116 174 0
+-109 -80 -113 0
+25 -14 -212 0
+203 9 -46 0
+-231 -209 4 0
+-239 200 151 0
+181 146 -195 0
+-234 79 195 0
+-91 -65 -105 0
+96 141 98 0
+135 -6 215 0
+150 -98 -147 0
+-26 124 -30 0
+-66 160 206 0
+-60 -142 6 0
+-173 -126 -28 0
+138 -60 -43 0
+235 -179 57 0
+156 -215 34 0
+-227 195 -221 0
+6 -25 -87 0
+228 49 -57 0
+203 68 139 0
+-133 237 -1 0
+-247 74 -80 0
+179 62 206 0
+12 73 -165 0
+-28 45 -65 0
+-203 186 -132 0
+-88 99 53 0
+99 246 171 0
+172 23 -88 0
+-84 119 224 0
+-44 -237 211 0
+-155 -28 -163 0
+-67 44 -224 0
+3 19 7 0
+-19 189 -216 0
+-18 130 -237 0
+-42 -210 -204 0
+-183 -233 192 0
+-141 222 -59 0
+-244 80 -102 0
+-210 90 68 0
+123 110 -82 0
+-226 -246 -231 0
+206 -43 -172 0
+178 -184 -63 0
+217 103 224 0
+-157 -172 -152 0
+-236 -223 211 0
+166 96 155 0
+-70 38 -28 0
+-18 34 23 0
+-33 -224 -242 0
+149 -197 213 0
+-222 -79 198 0
+-220 235 -95 0
+-167 -135 194 0
+10 159 -235 0
+-241 242 143 0
+55 -72 133 0
+-59 -168 -33 0
+64 81 -35 0
+18 30 -70 0
+198 -22 153 0
+146 29 75 0
+76 -89 189 0
+10 55 -184 0
+205 79 233 0
+186 29 35 0
+-91 14 37 0
+187 -118 -155 0
+-228 236 201 0
+115 235 -90 0
+-111 193 199 0
+-153 122 80 0
+-6 223 -239 0
+57 -76 -200 0
+18 -101 -214 0
+-28 -59 -165 0
+42 107 67 0
+-243 -52 -77 0
+-196 20 -249 0
+125 -45 87 0
+-60 -179 93 0
+-169 196 -154 0
+-89 60 -1 0
+88 -237 233 0
+-73 7 -53 0
+193 -154 133 0
+-82 46 232 0
+-184 119 -109 0
+-148 -121 136 0
+-138 -30 24 0
+145 -130 -23 0
+63 -247 -195 0
+-94 166 93 0
+-103 -247 -246 0
+6 -14 -232 0
+-148 98 -50 0
+69 -187 -212 0
+237 76 -108 0
+-205 130 204 0
+-152 -124 93 0
+54 -51 143 0
+68 39 -204 0
+222 39 11 0
+-37 72 169 0
+-69 173 160 0
+206 -110 112 0
+116 30 -121 0
+4 29 210 0
+-53 -144 -149 0
+-7 202 -93 0
+228 -69 -9 0
+171 32 1 0
+-212 104 -87 0
+-249 -170 -89 0
+-68 146 175 0
+59 -39 105 0
+39 48 -53 0
+-98 -50 7 0
+-129 221 -44 0
+190 186 -79 0
+151 -155 179 0
+27 11 -104 0
+-233 147 -242 0
+-113 -210 183 0
+-89 -118 237 0
+-58 -132 -236 0
+-42 -163 218 0
+87 -225 -164 0
+-40 -76 -204 0
+24 -71 -249 0
+91 46 -111 0
+-33 -73 -161 0
+-17 -54 127 0
+-174 -172 -167 0
+9 -168 -219 0
+237 19 1 0
+95 -128 105 0
+157 144 127 0
+124 247 180 0
+-188 -134 -241 0
+112 -127 187 0
+-145 68 158 0
+-73 228 179 0
+-207 -135 249 0
+-210 113 -6 0
+119 -130 -23 0
+-87 -138 -63 0
+-30 -210 112 0
+-210 116 -7 0
+81 -211 43 0
+233 30 -191 0
+250 -171 -71 0
+196 -194 168 0
+-179 111 -191 0
+-116 -150 153 0
+-220 -219 -93 0
+-94 224 99 0
+122 232 207 0
+115 -218 219 0
+-247 -19 -187 0
+214 147 143 0
+234 150 -90 0
+95 -185 -107 0
+-160 -88 113 0
+167 140 -33 0
+-27 2 -106 0
+35 42 61 0
+249 219 59 0
+2 180 120 0
+-129 225 -151 0
+-121 104 -192 0
+-138 -57 -41 0
+-73 179 -133 0
+164 -36 -83 0
+-45 -28 -116 0
+135 60 47 0
+76 173 125 0
+-31 194 233 0
+-67 239 -53 0
+-40 67 -231 0
+-98 -148 229 0
+213 -50 187 0
+141 197 2 0
+-140 177 66 0
+145 115 -155 0
+44 117 65 0
+-36 223 88 0
+30 200 31 0
+-212 237 174 0
+-49 -177 167 0
+-218 63 -148 0
+-25 46 23 0
+25 -54 226 0
+163 -88 21 0
+98 -41 -9 0
+-98 -181 18 0
+-182 -194 -137 0
+-230 214 -46 0
+240 182 9 0
+93 -116 41 0
+57 -228 186 0
+165 154 -49 0
+42 88 -202 0
+8 33 -152 0
+17 -136 -35 0
+-62 45 141 0
+-102 33 -18 0
+138 -126 214 0
+-59 -221 39 0
+-130 4 -218 0
+-78 123 250 0
+83 221 -151 0
+-225 8 110 0
+-194 156 43 0
+65 -245 34 0
+-238 -237 217 0
+106 -37 -56 0
+240 111 184 0
+-172 -243 185 0
+245 40 -45 0
+122 60 -189 0
+-174 -152 181 0
+155 -147 -178 0
+117 -168 -219 0
+-102 -127 234 0
+99 26 -114 0
+181 36 -62 0
+178 169 116 0
+81 -123 -30 0
+-243 -26 -38 0
+-31 20 217 0
+55 239 -116 0
+-85 -27 49 0
+62 212 177 0
+3 -4 127 0
+-233 -9 68 0
+-28 208 -114 0
+23 159 240 0
+125 171 83 0
+152 16 97 0
+-77 -39 -84 0
+-19 -15 195 0
+95 -180 177 0
+204 -125 -207 0
+-130 78 235 0
+-51 182 79 0
+122 -95 -80 0
+85 -72 -167 0
+48 -109 -41 0
+-223 -25 -44 0
+248 -51 -81 0
+-141 57 -2 0
+208 -207 -50 0
+41 15 -63 0
+48 -242 -232 0
+240 196 -32 0
+-227 -163 -23 0
+207 -90 102 0
+210 5 84 0
+-230 -134 95 0
+-193 214 239 0
+-192 -11 173 0
+-109 -196 145 0
+30 -161 -113 0
+216 164 83 0
+103 67 21 0
+102 -233 66 0
+-79 56 -250 0
+-82 -45 112 0
+-144 -124 208 0
+33 -37 -149 0
+-109 230 173 0
+-229 82 -174 0
+179 137 -235 0
+84 -225 -16 0
+123 233 235 0
+-211 144 92 0
+-2 46 -177 0
+115 -202 -119 0
+241 75 174 0
+-205 238 -105 0
+-53 219 34 0
+-239 103 -148 0
+147 -143 123 0
+-214 -232 188 0
+10 -193 41 0
+6 185 18 0
+141 -68 -222 0
+209 -129 -143 0
+-194 -108 116 0
+-184 5 -46 0
+23 -125 -113 0
+-159 54 -8 0
+130 -50 119 0
+156 -74 120 0
+-124 139 -119 0
+-97 -134 112 0
+-150 -82 -79 0
+148 91 219 0
+-30 19 -172 0
+-13 164 -15 0
+-119 -179 -11 0
+5 -38 -15 0
+-4 94 -66 0
+-71 140 -198 0
+-119 -51 -151 0
+9 50 162 0
+-203 35 88 0
+192 122 -127 0
+-187 -164 -126 0
+121 -25 -215 0
+-5 -167 -196 0
+216 138 -11 0
+-86 46 250 0
+199 239 -8 0
+-238 244 188 0
+98 -19 -11 0
+19 -151 -83 0
+-158 40 232 0
+1 200 -23 0
+171 -11 -139 0
+-203 60 173 0
+-160 -122 -8 0
+-179 -58 1 0
+-194 -216 -202 0
+-111 144 -237 0
+153 -206 9 0
+-182 79 -233 0
+-150 -249 -191 0
+153 102 121 0
+79 -178 -239 0
+14 -79 196 0
+133 84 193 0
+-248 173 -13 0
+-93 225 22 0
+58 -158 -16 0
+-36 236 -20 0
+96 140 7 0
+53 -2 202 0
+235 -32 249 0
+94 53 -234 0
+50 134 -191 0
+-243 -211 88 0
+-28 52 94 0
+3 101 65 0
+78 200 -112 0
+-16 -108 -93 0
+-154 -169 242 0
+-196 220 -177 0
+-177 187 24 0
+5 242 -195 0
+81 157 -247 0
+-191 -3 123 0
+-16 115 10 0
+-152 -217 33 0
+-7 -149 67 0
+105 45 23 0
+-55 -23 109 0
+-217 -220 -144 0
+73 -63 149 0
+-180 -245 -191 0
+-113 -50 199 0
+242 -205 52 0
+129 98 -226 0
+205 146 -200 0
+145 -180 -182 0
+-240 -39 176 0
+217 166 -31 0
+-24 -144 9 0
+137 -120 -228 0
+-24 -117 158 0
+%
+0
+"""
+
+if __name__ == "__main__":
+        unittest.main()
--- a/src/tests/api/t_unix_usergrp.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_unix_usergrp.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,9 +20,14 @@
 # CDDL HEADER END
 #
 
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import unittest
 import os
 import shutil
@@ -30,25 +35,17 @@
 import tempfile
 import pkg.portable as portable
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-import pkg5unittest
-
 class TestUserGroup(pkg5unittest.Pkg5TestCase):
 
         def setUp(self):
-                self.tempdir = tempfile.mkdtemp()
-                os.makedirs(os.path.join(self.tempdir, "etc"))
-
-        def tearDown(self):
-                shutil.rmtree(self.tempdir)
+                pkg5unittest.Pkg5TestCase.setUp(self)
+                os.makedirs(os.path.join(self.test_root, "etc"))
 
         def testGroup1(self):
                 if not os.path.exists("/etc/group"):
                         return
 
-                grpfile = file(os.path.join(self.tempdir, "etc", "group"), "w")
+                grpfile = file(os.path.join(self.test_root, "etc", "group"), "w")
                 grpfile.write( \
 """root::0:
 gk::0:
@@ -62,15 +59,15 @@
                 grpfile.close()
 
                 self.assertRaises(KeyError, portable.get_group_by_name,
-                    "ThisShouldNotExist", self.tempdir, True)
+                    "ThisShouldNotExist", self.test_root, True)
 
                 self.assert_(0 == \
-                    portable.get_group_by_name("root", self.tempdir, True))
+                    portable.get_group_by_name("root", self.test_root, True))
                 self.assert_(0 == \
-                    portable.get_group_by_name("gk", self.tempdir, True))
+                    portable.get_group_by_name("gk", self.test_root, True))
 
                 self.assertRaises(KeyError, portable.get_name_by_gid,
-                    12345, self.tempdir, True)
+                    12345, self.test_root, True)
 
         def testGroup2(self):
                 """ Test with a missing group file """
@@ -78,21 +75,21 @@
                         return
 
                 self.assertRaises(KeyError, portable.get_group_by_name,
-                    "ThisShouldNotExist", self.tempdir, True)
+                    "ThisShouldNotExist", self.test_root, True)
 
                 # This should work on unix systems, since we'll "bootstrap"
                 # out to the OS's version.  And AFAIK all unix systems have
                 # a group with gid 0.
-                grpname = portable.get_name_by_gid(0, self.tempdir, True)
+                grpname = portable.get_name_by_gid(0, self.test_root, True)
                 self.assert_(0 == \
-                    portable.get_group_by_name(grpname, self.tempdir, True))
+                    portable.get_group_by_name(grpname, self.test_root, True))
 
         def testGroup3(self):
                 """ Test with corrupt/oddball group file """
                 if not os.path.exists("/etc/group"):
                         return
 
-                grpfile = file(os.path.join(self.tempdir, "etc", "group"), "w")
+                grpfile = file(os.path.join(self.test_root, "etc", "group"), "w")
                 grpfile.write( \
 """root::0:
 blorg
@@ -107,22 +104,22 @@
 +""")
                 grpfile.close()
                 self.assert_("root" == \
-                    portable.get_name_by_gid(0, self.tempdir, True))
+                    portable.get_name_by_gid(0, self.test_root, True))
                 self.assert_(0 == \
-                    portable.get_group_by_name("root", self.tempdir, True))
+                    portable.get_group_by_name("root", self.test_root, True))
                 self.assert_(0 == \
-                    portable.get_group_by_name("gk", self.tempdir, True))
+                    portable.get_group_by_name("gk", self.test_root, True))
                 self.assert_(7 == \
-                    portable.get_group_by_name("tty", self.tempdir, True))
+                    portable.get_group_by_name("tty", self.test_root, True))
 
                 self.assertRaises(KeyError, portable.get_group_by_name,
-                    "ThisShouldNotExist", self.tempdir, True)
+                    "ThisShouldNotExist", self.test_root, True)
 
                 self.assertRaises(KeyError, portable.get_group_by_name,
-                    "corrupt", self.tempdir, True)
+                    "corrupt", self.test_root, True)
 
                 self.assertRaises(KeyError, portable.get_group_by_name,
-                    570, self.tempdir, True)
+                    570, self.test_root, True)
 
         def testGroup4(self):
                 """ Test with a group name line in the group file that
@@ -130,7 +127,7 @@
                 if not os.path.exists("/etc/group"):
                         return
 
-                grpfile = file(os.path.join(self.tempdir, "etc", "group"), "w")
+                grpfile = file(os.path.join(self.test_root, "etc", "group"), "w")
                 grpfile.write( \
 """root::0:
 gk::0:
@@ -143,23 +140,23 @@
 +""")
                 grpfile.close()
                 self.assert_("root" == \
-                    portable.get_name_by_gid(0, self.tempdir, True))
+                    portable.get_name_by_gid(0, self.test_root, True))
                 self.assert_(0 == \
-                    portable.get_group_by_name("root", self.tempdir, True))
+                    portable.get_group_by_name("root", self.test_root, True))
                 self.assert_(0 == \
-                    portable.get_group_by_name("gk", self.tempdir, True))
+                    portable.get_group_by_name("gk", self.test_root, True))
                 self.assert_(7 == \
-                    portable.get_group_by_name("tty", self.tempdir, True))
+                    portable.get_group_by_name("tty", self.test_root, True))
 
                 self.assertRaises(KeyError, portable.get_group_by_name,
-                    "plusgrp", self.tempdir, True)
+                    "plusgrp", self.test_root, True)
 
 
         def testUser1(self):
                 if not os.path.exists("/etc/passwd"):
                         return
 
-                passwd = file(os.path.join(self.tempdir, "etc", "passwd"), "w")
+                passwd = file(os.path.join(self.test_root, "etc", "passwd"), "w")
                 passwd.write( \
 """root:x:0:0::/root:/usr/bin/bash
 gk:x:0:0::/root:/usr/bin/bash
@@ -173,17 +170,17 @@
                 passwd.close()
 
                 self.assertRaises(KeyError, portable.get_user_by_name,
-                    "ThisShouldNotExist", self.tempdir, True)
+                    "ThisShouldNotExist", self.test_root, True)
 
                 self.assert_(0 == \
-                    portable.get_user_by_name("root", self.tempdir, True))
+                    portable.get_user_by_name("root", self.test_root, True))
                 self.assert_(0 == \
-                    portable.get_user_by_name("gk", self.tempdir, True))
+                    portable.get_user_by_name("gk", self.test_root, True))
                 self.assert_(999 == \
-                    portable.get_user_by_name("moop", self.tempdir, True))
+                    portable.get_user_by_name("moop", self.test_root, True))
 
                 self.assertRaises(KeyError, portable.get_name_by_uid,
-                    12345, self.tempdir, True)
+                    12345, self.test_root, True)
 
 
         def testUser2(self):
@@ -192,14 +189,14 @@
                         return
 
                 self.assertRaises(KeyError, portable.get_user_by_name,
-                    "ThisShouldNotExist", self.tempdir, True)
+                    "ThisShouldNotExist", self.test_root, True)
 
                 # This should work on unix systems, since we'll "bootstrap"
                 # out to the OS's version.
                 self.assert_(0 == \
-                    portable.get_user_by_name("root", self.tempdir, True))
+                    portable.get_user_by_name("root", self.test_root, True))
                 self.assert_("root" == \
-                    portable.get_name_by_uid(0, self.tempdir, True))
+                    portable.get_name_by_uid(0, self.test_root, True))
 
 
         def testUser3(self):
@@ -207,7 +204,7 @@
                 if not os.path.exists("/etc/passwd"):
                         return
 
-                passwd = file(os.path.join(self.tempdir, "etc", "passwd"), "w")
+                passwd = file(os.path.join(self.test_root, "etc", "passwd"), "w")
                 passwd.write( \
 """root:x:0:0::/root:/usr/bin/bash
 daemon:x:1:1::/:
@@ -224,20 +221,20 @@
 +""")
                 passwd.close()
                 self.assert_(0 == \
-                    portable.get_user_by_name("root", self.tempdir, True))
+                    portable.get_user_by_name("root", self.test_root, True))
                 self.assert_(0 == \
-                    portable.get_user_by_name("gk", self.tempdir, True))
+                    portable.get_user_by_name("gk", self.test_root, True))
                 self.assert_("uucp" == \
-                    portable.get_name_by_uid(5, self.tempdir, True))
+                    portable.get_name_by_uid(5, self.test_root, True))
 
                 self.assertRaises(KeyError, portable.get_user_by_name,
-                    "ThisShouldNotExist", self.tempdir, True)
+                    "ThisShouldNotExist", self.test_root, True)
 
                 self.assertRaises(KeyError, portable.get_user_by_name,
-                    "corrupt", self.tempdir, True)
+                    "corrupt", self.test_root, True)
 
                 self.assertRaises(KeyError, portable.get_user_by_name,
-                    999, self.tempdir, True)
+                    999, self.test_root, True)
 
         def testUser4(self):
                 """ Test with a user name line in the passwd file that
@@ -245,7 +242,7 @@
                 if not os.path.exists("/etc/passwd"):
                         return
 
-                passwd = file(os.path.join(self.tempdir, "etc", "passwd"), "w")
+                passwd = file(os.path.join(self.test_root, "etc", "passwd"), "w")
                 passwd.write( \
 """root:x:0:0::/root:/usr/bin/bash
 gk:x:0:0::/root:/usr/bin/bash
@@ -259,16 +256,16 @@
 +""")
                 passwd.close()
                 self.assert_(0 == \
-                    portable.get_user_by_name("root", self.tempdir, True))
+                    portable.get_user_by_name("root", self.test_root, True))
                 self.assert_(0 == \
-                    portable.get_user_by_name("gk", self.tempdir, True))
+                    portable.get_user_by_name("gk", self.test_root, True))
                 self.assert_("root" == \
-                    portable.get_name_by_uid(0, self.tempdir, True))
+                    portable.get_name_by_uid(0, self.test_root, True))
                 self.assert_("uucp" == \
-                    portable.get_name_by_uid(5, self.tempdir, True))
+                    portable.get_name_by_uid(5, self.test_root, True))
 
                 self.assertRaises(KeyError, portable.get_user_by_name,
-                    "plususer", self.tempdir, True)
+                    "plususer", self.test_root, True)
 
 
 if __name__ == "__main__":
--- a/src/tests/api/t_variant.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_variant.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,9 +20,14 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import itertools
 import datetime
 import os
@@ -33,12 +38,6 @@
 import time
 import unittest
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-
-import pkg5unittest
-
 import pkg.variant as variant
 
 class TestVariants(pkg5unittest.Pkg5TestCase):
@@ -89,3 +88,5 @@
                 v1.remove_identical(v5)
                 self.__check_equal(v1, dict([(3, ["b", "c"])]))
 
+if __name__ == "__main__":
+        unittest.main()
--- a/src/tests/api/t_version.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/api/t_version.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,20 +20,20 @@
 # CDDL HEADER END
 #
 
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import unittest
 import pkg.version as version
 import datetime
 import os
 import sys
 
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-import pkg5unittest
-
 class TestVersion(pkg5unittest.Pkg5TestCase):
         def setUp(self):
                 self.d1 = version.DotSequence("1.1.3")
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/api/testutils.py	Sat Jan 30 01:07:14 2010 -0800
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+
+import os
+import sys
+
+# Set the path so that modules can be found
+path_to_parent = os.path.join(os.path.dirname(__file__), "..")
+sys.path.insert(0, path_to_parent)
+
+import pkg5testenv
+
+def setup_environment(proto):
+        pkg5testenv.setup_environment(proto)
--- a/src/tests/baseline.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/baseline.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,68 +20,59 @@
 # CDDL HEADER END
 #
 
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import os
 import sys
 import unittest
 
+BASELINE_MATCH=0
+BASELINE_MISMATCH=1
+
 class BaseLine(object):
-        """Test result baseline for determining which tests failed against
-        the current state of the source tree.
-        """
-
+        """Test result baseline recording and checking. """
         sep1 = '=' * 70
         sep2 = '-' * 70
 
-        # dict of "test name" -> "result"
-        results = {}
-
-        # Filename to store the results
-        filename = ""
+        def __init__(self, filename="baseline.txt", generate=False):
 
-        # 'generating' keeps track of whether we are currently generating
-        # a baseline or not: if either the baseline doesn't exist or the
-        # "-g" option is specified on the commandline.
-        #
-        generating = False     
+                # filename from which to get or store baseline results
+                self.__filename = filename
+                # 'generating' keeps track of whether we are currently
+                # generating a baseline or not: if either the baseline doesn't
+                # exist or the "-g" option is specified on the commandline.
+                self.__generating = generate
+                # List of tuples (name, result) for failed tests
+                self.__failed_list = []
+                # dict of "test name" -> "result"
+                self.__results = {}
 
-        # List of tuples (name, result) for failed tests
-        failed_list = []
-
-        def __init__(self, filename="baseline.txt", generate=False):
-                self.filename = filename
-                self.generating = generate
-
-        def handleresult(self, name, result):
+        def handleresult(self, name, actualresult):
                 """Add a result if we're generating the baseline file,
-                otherwise check it against the current result set."""
-                rv = True
-                if self.generating:
-                        self.results[name] = result
-                else:
-                        rv = self.checkresult(name, result)
-                        if rv != True:
-                                self.failed_list.append((name, result))
-                return rv
+                otherwise check it against the current result set.
+                Returns a value to indicate whether the result matched
+                the baseline."""
+
+                if self.__generating:
+                        self.__results[name] = actualresult
+                        return BASELINE_MATCH
 
-        def getresult(self, name):
-                """Retrieve a result by test name."""
-                return self.results.get(name, None)
+                if self.expectedresult(name) != actualresult:
+                        self.__failed_list.append((name, actualresult))
+                        return BASELINE_MISMATCH
+                return BASELINE_MATCH
 
-        def checkresult(self, name, result):
-                """Check a name/result pair against the current result set,
-                adding this test to the list of failures if it doesn't
-                match."""
-                if self.generating:
-                        return True
-                res = self.getresult(name)
-                return (cmp(res, result) == 0)
+        def expectedresult(self, name):
+                # The assumption if we're generating, or if we don't
+                # have a result in baseline, is that the test should pass.
+                if self.__generating:
+                        return "pass"
+                return self.__results.get(name, "pass")
 
         def getfailures(self):
                 """Return the list of failed tests."""
-                return self.failed_list
+                return self.__failed_list
 
         def reportfailures(self):
                 """Display all test cases that failed to match the baseline
@@ -102,40 +93,40 @@
         def store(self):
                 """Store the result set."""
                 # Only store the result set if we're generating a baseline
-                if not self.generating:
+                if not self.__generating:
                         return
                 try:
-                        f = file(self.filename, "w")
+                        f = file(self.__filename, "w")
                 except IOError, (err, msg):
                         print >> sys.stderr, "ERROR: storing baseline:"
                         print >> sys.stderr, "Failed to open %s: %s" % \
-                                (self.filename, msg)
+                                (self.__filename, msg)
                         return 
 
 		# Sort the results to make baseline diffs easier
-		results_sorted = self.results.keys()
+		results_sorted = self.__results.keys()
 		results_sorted.sort()
-	
+                print >> sys.stderr, "# Writing baseline to %s." % self.__filename	
                 for s in results_sorted:
                         f.write("%s|%s%s" %
-                            (s, self.results[s], os.linesep))
+                            (s, self.__results[s], os.linesep))
                 f.flush()
                 f.close()
 
         def load(self):
                 """Load the result set."""
-                if not os.path.exists(self.filename):
-                        self.generating = True
+                if not os.path.exists(self.__filename):
+                        self.__generating = True
                         return
 
                 try:
-                        f = file(self.filename, "r")
+                        f = file(self.__filename, "r")
                 except IOError, (err, msg):
                         print >> sys.stderr, "ERROR: loading baseline:"
                         print >> sys.stderr, "Failed to open %s: %s" % \
-                                (self.filename, msg)
+                                (self.__filename, msg)
                         return
                 for line in f.readlines():
                         n, r = line.split('|')
-                        self.results[n] = r.rstrip('\n')
+                        self.__results[n] = r.rstrip('\n')
                 f.close()
--- a/src/tests/baseline.txt	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/baseline.txt	Sat Jan 30 01:07:14 2010 -0800
@@ -249,50 +249,50 @@
 cli.t_api_list.py TestApiList.test_list_06_upgradable|pass
 cli.t_api_list.py TestApiList.test_list_07_get_pkg_categories|pass
 cli.t_api_list.py TestApiList.test_list_08_patterns|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_010_remote|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_020_local_0|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_030_degraded_local|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_040_repeated_install_uninstall|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_050_local_case_sensitive|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_060_missing_files|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_070_mismatched_versions|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_080_weird_patterns|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_090_bug_7660|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_100_bug_6712_i386|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_110_bug_6712_sparc|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_120_bug_3046|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_130_bug_1059|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_2849|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_2863|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_2989_1|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_2989_2|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_2989_3|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_2989_4|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_4239|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_7534|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_7628|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_8492|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_9729_1|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_9729_2|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_983|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_9845_01|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_9845_02|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_9845_03|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_9845_04|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_9845_05|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_9845_06|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_9845_07|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_9845_08|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_9845_09|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_9845_10|pass
-cli.t_api_search.py TestApiSearchBasicsPersistentDepot.test_bug_9845_11|pass
-cli.t_api_search.py TestApiSearchBasicsRestartingDepot.test_bug_13485|pass
-cli.t_api_search.py TestApiSearchBasicsRestartingDepot.test_bug_4048_1|pass
-cli.t_api_search.py TestApiSearchBasicsRestartingDepot.test_bug_4048_2|pass
-cli.t_api_search.py TestApiSearchBasicsRestartingDepot.test_bug_7358_1|pass
-cli.t_api_search.py TestApiSearchBasicsRestartingDepot.test_bug_7358_2|pass
-cli.t_api_search.py TestApiSearchBasicsRestartingDepot.test_bug_8318|pass
-cli.t_api_search.py TestApiSearchBasicsRestartingDepot.test_local_image_update|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_010_remote|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_020_local_0|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_030_degraded_local|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_040_repeated_install_uninstall|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_050_local_case_sensitive|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_060_missing_files|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_070_mismatched_versions|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_080_weird_patterns|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_090_bug_7660|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_100_bug_6712_i386|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_110_bug_6712_sparc|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_120_bug_3046|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_130_bug_1059|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_2849|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_2863|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_2989_1|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_2989_2|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_2989_3|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_2989_4|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_4239|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_7534|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_7628|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_8492|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_9729_1|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_9729_2|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_983|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_9845_01|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_9845_02|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_9845_03|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_9845_04|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_9845_05|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_9845_06|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_9845_07|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_9845_08|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_9845_09|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_9845_10|pass
+cli.t_api_search.py TestApiSearchBasicsP.test_bug_9845_11|pass
+cli.t_api_search.py TestApiSearchBasics_nonP.test_bug_13485|pass
+cli.t_api_search.py TestApiSearchBasics_nonP.test_bug_4048_1|pass
+cli.t_api_search.py TestApiSearchBasics_nonP.test_bug_4048_2|pass
+cli.t_api_search.py TestApiSearchBasics_nonP.test_bug_7358_1|pass
+cli.t_api_search.py TestApiSearchBasics_nonP.test_bug_7358_2|pass
+cli.t_api_search.py TestApiSearchBasics_nonP.test_bug_8318|pass
+cli.t_api_search.py TestApiSearchBasics_nonP.test_local_image_update|pass
 cli.t_api_search.py TestApiSearchMulti.test_bug_12739|pass
 cli.t_api_search.py TestApiSearchMulti.test_bug_2955|pass
 cli.t_api_search.py TestApiSearchMulti.test_bug_8318|pass
@@ -643,3 +643,13 @@
 gui.t_pm_rmrepo.py TestPkgGuiRmRepoBasics.testRmRepository|pass
 gui.t_pm_start.py TestPkgGuiStartBasics.testStartPackagemanager|pass
 gui.t_pm_uninstall.py TestPkgGuiUninstallBasics.testUninstallSimplePackage|pass
+testsuite.t_setup_teardown.py TestSetupFailing.test_shoulderror1|error
+testsuite.t_setup_teardown.py TestSetupFailing.test_shoulderror2|error
+testsuite.t_setup_teardown.py TestSetupFailingEarly.test_shoulderror1|error
+testsuite.t_setup_teardown.py TestSetupFailingP.test_shoulderror1|error
+testsuite.t_setup_teardown.py TestSetupFailingP.test_shoulderror2|error
+testsuite.t_setup_teardown.py TestSetupFailingEarlyP.test_shoulderror1|error
+testsuite.t_setup_teardown.py TestTeardownFailing.test_shoulderror1|error
+testsuite.t_setup_teardown.py TestTeardownFailing.test_shoulderror2|error
+testsuite.t_setup_teardown.py TestTeardownFailingP.test_shouldpass1|pass
+testsuite.t_setup_teardown.py TestTeardownFailingP.test_shouldpass2|pass
--- a/src/tests/cli/t_actuators.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_actuators.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,12 +20,13 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import unittest
@@ -33,11 +34,12 @@
 
 from pkg import misc
 
-class TestPkgActuators(testutils.SingleDepotTestCase):
+class TestPkgActuators(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
-        svcprop_enabled_data = \
+        misc_files = { \
+                "svcprop_enabled" :
 """general/enabled boolean true
 general/entity_stability astring Unstable
 general/single_instance boolean true
@@ -67,8 +69,9 @@
 stop/exec astring :true
 stop/timeout_seconds count 0
 stop/type astring method
-"""
-        svcprop_disabled_data = \
+""",
+
+                "svcprop_disabled" :
 """general/enabled boolean false
 general/entity_stability astring Unstable
 general/single_instance boolean true
@@ -98,8 +101,9 @@
 stop/exec astring :true
 stop/timeout_seconds count 0
 stop/type astring method
-"""
-        svcprop_temp_enabled_data = \
+""",
+
+                "svcprop_temp_enabled" :
 """general/enabled boolean false
 general/entity_stability astring Unstable
 general/single_instance boolean true
@@ -130,8 +134,8 @@
 stop/exec astring :true
 stop/timeout_seconds count 0
 stop/type astring method
-"""
-        svcprop_temp_disabled_data = \
+""",
+                "svcprop_temp_disabled" :
 """general/enabled boolean true
 general/entity_stability astring Unstable
 general/single_instance boolean true
@@ -162,78 +166,63 @@
 stop/exec astring :true
 stop/timeout_seconds count 0
 stop/type astring method
-"""
-        empty_data = ""
+""",
 
-        svcprop_data = \
+                "empty": "",
+                "usr/bin/svcprop" :
 """#!/bin/sh
 cat $PKG_TEST_DIR/$PKG_SVCPROP_OUTPUT
 exit $PKG_SVCPROP_EXIT_CODE
-"""
-        svcadm_data = \
+""",
+                "usr/sbin/svcadm" : \
 """#!/bin/sh
 echo $0 "$@" >> $PKG_TEST_DIR/svcadm_arguments
 exit $PKG_SVCADM_EXIT_CODE
 """
-
-
-        misc_files = [ "svcprop_enabled", "svcprop_disabled", "svcprop_temp_enabled", "empty",
-                       "svcprop_temp_enabled", "usr/bin/svcprop", "usr/sbin/svcadm"]
+}
 
         testdata_dir = None
 
         def setUp(self):
 
-                testutils.SingleDepotTestCase.setUp(self)
-                tp = self.get_test_prefix()
-                self.testdata_dir = os.path.join(tp, "testdata")
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                self.testdata_dir = os.path.join(self.test_root, "testdata")
                 os.mkdir(self.testdata_dir)
+
                 self.pkg_list = []
 
                 self.pkg_list+= ["""
                     open [email protected],5.11-0
-                    add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=sys path=/test_restart restart_fmri=svc:system/test_restart_svc
+                    add file testdata/empty mode=0644 owner=root group=sys path=/test_restart restart_fmri=svc:system/test_restart_svc
                     close """]
 
                 self.pkg_list+= ["""
                     open [email protected],5.11-0
-                    add file """ + self.testdata_dir + """/empty mode=0655 owner=root group=sys path=/test_restart restart_fmri=svc:system/test_restart_svc
+                    add file testdata/empty mode=0655 owner=root group=sys path=/test_restart restart_fmri=svc:system/test_restart_svc
                     close """]
 
                 self.pkg_list+= ["""
                     open [email protected],5.11-0
-                    add file """ + self.testdata_dir + """/empty mode=0646 owner=root group=sys path=/test_restart restart_fmri=svc:system/test_restart_svc
+                    add file testdata/empty mode=0646 owner=root group=sys path=/test_restart restart_fmri=svc:system/test_restart_svc
                     close """]
 
                 self.pkg_list+= ["""
                     open [email protected],5.11-0
-                    add file """ + self.testdata_dir + """/empty mode=0657 owner=root group=sys path=/test_restart refresh_fmri=svc:system/test_refresh_svc
+                    add file testdata/empty mode=0657 owner=root group=sys path=/test_restart refresh_fmri=svc:system/test_refresh_svc
                     close """]
 
                 self.pkg_list+= ["""
                     open [email protected],5.11-0
-                    add file """ + self.testdata_dir + """/empty mode=0667 owner=root group=sys path=/test_restart suspend_fmri=svc:system/test_suspend_svc
+                    add file testdata/empty mode=0667 owner=root group=sys path=/test_restart suspend_fmri=svc:system/test_suspend_svc
                     close """]
 
                 self.pkg_list+= ["""
                     open [email protected],5.11-0
-                    add file """ + self.testdata_dir + """/empty mode=0677 owner=root group=sys path=/test_restart suspend_fmri=svc:system/test_suspend_svc disable_fmri=svc:system/test_disable_svc
+                    add file testdata/empty mode=0677 owner=root group=sys path=/test_restart suspend_fmri=svc:system/test_suspend_svc disable_fmri=svc:system/test_disable_svc
                     close """]
 
-                for f in self.misc_files:
-                        filename = os.path.join(self.testdata_dir, f)
-                        if not os.path.exists(os.path.dirname(filename)):
-                                os.makedirs(os.path.dirname(filename))
-                        file_handle = open(filename, 'wb')
-                        data = "self.%s_data" % os.path.basename(f)
-                        file_handle.write(eval(data))
-                        file_handle.close()
-                        os.chmod(filename, misc.PKG_DIR_MODE)
-
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-                if self.testdata_dir:
-                        shutil.rmtree(self.testdata_dir)
+                self.make_misc_files(self.misc_files, prefix="testdata",
+                     mode=0755)
 
         def test_actuators(self):
                 """test actuators"""
--- a/src/tests/cli/t_api.py	Fri Jan 29 13:24:14 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,934 +0,0 @@
-#!/usr/bin/python
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-import testutils
-if __name__ == "__main__":
-	testutils.setup_environment("../../../proto")
-
-import cStringIO
-import os
-import pkg.client.api as api
-import pkg.client.api_errors as api_errors
-import pkg.client.progress as progress
-import pkg.fmri as fmri
-import sys
-import tempfile
-import time
-import unittest
-
-API_VERSION = 31
-PKG_CLIENT_NAME = "pkg"
-
-class TestPkgApi(testutils.SingleDepotTestCase):
-        # restart the depot for every test
-        persistent_depot = False
-
-        foo10 = """
-            open [email protected],5.11-0
-            close """
-
-        foo12 = """
-            open [email protected],5.11-0
-            add file $test_prefix/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
-            close """
-
-        bar10 = """
-            open [email protected],5.11-0
-            close """
-
-        baz10 = """
-            open [email protected],5.11-0
-            add license $test_prefix/copyright.baz license=copyright.baz
-            close """
-
-        quux10 = """
-            open [email protected],5.11-0
-            add depend type=require [email protected]
-            close """
-
-        # First iteration has just a copyright.
-        licensed10 = """
-            open [email protected],5.11-0
-            add depend type=require [email protected]
-            add license $test_prefix/copyright.licensed license=copyright.licensed
-            close """
-
-        # Second iteration has copyright that must-display and a new license
-        # that doesn't require acceptance.
-        licensed12 = """
-            open [email protected],5.11-0
-            add depend type=require [email protected]
-            add file $test_prefix/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
-            add license $test_prefix/copyright.licensed license=copyright.licensed must-display=True
-            add license $test_prefix/license.licensed license=license.licensed
-            close """
-
-        # Third iteration now requires acceptance of license.
-        licensed13 = """
-            open [email protected],5.11-0
-            add depend type=require [email protected]
-            add file $test_prefix/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
-            add license $test_prefix/copyright.licensed license=copyright.licensed must-display=True
-            add license $test_prefix/license.licensed license=license.licensed must-accept=True
-            close """
-
-        p5i_bobcat = """{
-  "packages": [
-    "pkg:/[email protected],5.11-0", 
-    "baz"
-  ], 
-  "publishers": [
-    {
-      "alias": "cat", 
-      "name": "bobcat", 
-      "packages": [
-        "pkg:/[email protected],5.11-0"
-      ], 
-      "repositories": [
-        {
-          "collection_type": "core", 
-          "description": "xkcd.net/325", 
-          "legal_uris": [
-            "http://xkcd.com/license.html"
-          ], 
-          "mirrors": [], 
-          "name": "source", 
-          "origins": [
-            "http://localhost:12001/"
-          ], 
-          "refresh_seconds": 43200, 
-          "registration_uri": "", 
-          "related_uris": []
-        }
-      ]
-    }
-  ], 
-  "version": 1
-}
-"""
-
-
-        misc_files = ["copyright.baz", "copyright.licensed", "libc.so.1",
-            "license.licensed", "license.licensed.addendum"]
-
-        def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self, publisher="bobcat")
-
-                for p in ("foo12", "baz10", "licensed10", "licensed12",
-                    "licensed13"):
-                        val = getattr(self, p).replace("$test_prefix",
-                            self.get_test_prefix())
-                        setattr(self, p, val)
-
-                for p in self.misc_files:
-                        fpath = os.path.join(self.get_test_prefix(), p)
-                        f = open(fpath, "wb")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(fpath)
-                        f.close()
-                        self.debug("wrote %s" % fpath)
-
-        def tearDown(self):
-                #for p in self.misc_files:
-                #        os.remove(os.path.join(self.get_test_prefix(), p))
-                testutils.SingleDepotTestCase.tearDown(self)
-
-        def __try_bad_installs(self, api_obj):
-
-                self.assertRaises(api_errors.PlanExistsException,
-                    api_obj.plan_install,["foo"])
-
-                self.assertRaises(api_errors.PlanExistsException,
-                    api_obj.plan_uninstall,["foo"], False)
-                self.assertRaises(api_errors.PlanExistsException,
-                    api_obj.plan_update_all, sys.argv[0])
-                try:
-                        api_obj.plan_update_all(sys.argv[0])
-                except api_errors.PlanExistsException:
-                        pass
-                else:
-                        assert 0
-
-        def __try_bad_combinations_and_complete(self, api_obj):
-                self.__try_bad_installs(api_obj)
-
-                self.assertRaises(api_errors.PrematureExecutionException,
-                    api_obj.execute_plan)
-
-                api_obj.prepare()
-                self.__try_bad_installs(api_obj)
-
-                self.assertRaises(api_errors.AlreadyPreparedException,
-                    api_obj.prepare)
-
-                api_obj.execute_plan()
-                self.__try_bad_installs(api_obj)
-                self.assertRaises(api_errors.AlreadyPreparedException,
-                    api_obj.prepare)
-                self.assertRaises(api_errors.AlreadyExecutedException,
-                    api_obj.execute_plan)
-
-        def test_bad_orderings(self):
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.foo10)
-                self.image_create(durl, prefix="bobcat")
-
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                self.assert_(api_obj.describe() is None)
-
-                self.assertRaises(api_errors.PlanMissingException,
-                    api_obj.prepare)
-
-                api_obj.plan_install(["foo"])
-                self.__try_bad_combinations_and_complete(api_obj)
-                api_obj.reset()
-
-                self.assertRaises(api_errors.PlanMissingException,
-                    api_obj.prepare)
-
-                self.assert_(api_obj.describe() is None)
-
-                self.pkgsend_bulk(durl, self.foo12)
-                api_obj.refresh(immediate=True)
-
-                api_obj.plan_update_all(sys.argv[0])
-                self.__try_bad_combinations_and_complete(api_obj)
-                api_obj.reset()
-
-                self.assertRaises(api_errors.PlanMissingException,
-                    api_obj.prepare)
-                self.assert_(api_obj.describe() is None)
-
-                api_obj.plan_uninstall(["foo"], False)
-                self.__try_bad_combinations_and_complete(api_obj)
-                api_obj.reset()
-
-                self.assertRaises(api_errors.PlanMissingException,
-                    api_obj.prepare)
-                self.assert_(api_obj.describe() is None)
-
-        def test_reset(self):
-                """ Send empty package [email protected], install and uninstall """
-
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.foo10)
-                self.image_create(durl, prefix="bobcat")
-
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                recursive_removal = False
-
-                api_obj.plan_install(["foo"])
-                self.assert_(api_obj.describe() is not None)
-                api_obj.reset()
-                self.assert_(api_obj.describe() is None)
-                api_obj.plan_install(["foo"])
-                self.assert_(api_obj.describe() is not None)
-                api_obj.prepare()
-                api_obj.reset()
-                self.assert_(api_obj.describe() is None)
-                api_obj.plan_install(["foo"])
-                self.assert_(api_obj.describe() is not None)
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-                self.assert_(api_obj.describe() is None)
-
-                self.pkg("list")
-                self.pkg("verify")
-
-                self.pkgsend_bulk(durl, self.foo12)
-                api_obj.refresh(immediate=True)
-
-                api_obj.plan_update_all(sys.argv[0])
-                self.assert_(api_obj.describe() is not None)
-                api_obj.reset()
-                self.assert_(api_obj.describe() is None)
-                api_obj.plan_update_all(sys.argv[0])
-                self.assert_(api_obj.describe() is not None)
-                api_obj.prepare()
-                api_obj.reset()
-                self.assert_(api_obj.describe() is None)
-                api_obj.plan_update_all(sys.argv[0])
-                self.assert_(api_obj.describe() is not None)
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-                self.assert_(api_obj.describe() is None)
-
-                self.pkg("list")
-                self.pkg("verify")
-
-                api_obj.plan_uninstall(["foo"], recursive_removal)
-                self.assert_(api_obj.describe() is not None)
-                api_obj.reset()
-                self.assert_(api_obj.describe() is None)
-                api_obj.plan_uninstall(["foo"], recursive_removal)
-                self.assert_(api_obj.describe() is not None)
-                api_obj.prepare()
-                api_obj.reset()
-                self.assert_(api_obj.describe() is None)
-                api_obj.plan_uninstall(["foo"], recursive_removal)
-                self.assert_(api_obj.describe() is not None)
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-                self.assert_(api_obj.describe() is None)
-
-                self.pkg("verify")
-
-        def test_refresh_transition(self):
-                """Verify that refresh works for a v0 catalog source and that
-                if the client transitions from v0 to v1 or back that the correct
-                state information is recorded in the image catalog."""
-
-                # First create the image and get v1 catalog.
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.foo10 + self.quux10)
-                self.image_create(durl, prefix="bobcat")
-
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-                img = api_obj.img
-                kcat = img.get_catalog(img.IMG_CATALOG_KNOWN)
-                entry = [e for f, e in kcat.entries()][0]
-                states = entry["metadata"]["states"]
-                self.assert_(img.PKG_STATE_V1 in states)
-                self.assert_(img.PKG_STATE_V0 not in states)
-
-                # Next, disable v1 catalog for the depot and force a client
-                # refresh.  Only v0 state should be present.
-                self.dc.set_disable_ops(["catalog/1"])
-                self.dc.stop()
-                self.dc.start()
-                api_obj.refresh(immediate=True)
-                api_obj.reset()
-                img = api_obj.img
-
-                kcat = img.get_catalog(img.IMG_CATALOG_KNOWN)
-                entry = [e for f, e in kcat.entries()][0]
-                states = entry["metadata"]["states"]
-                self.assert_(img.PKG_STATE_V1 not in states)
-                self.assert_(img.PKG_STATE_V0 in states)
-
-                # Verify that there is no dependency information present
-                # in the known or installed catalog.
-                icat = img.get_catalog(img.IMG_CATALOG_INSTALLED)
-                for cat in kcat, icat:
-                        dpart = cat.get_part("catalog.dependency.C")
-                        dep_acts = [
-                            acts
-                            for t, entry in dpart.tuple_entries()
-                            for acts in entry.get("actions", [])
-                        ]
-                        self.assertEqual(dep_acts, [])
-
-                # Now install a package, and verify that the entries in the
-                # known catalog for installed packages exist in the installed
-                # catalog and are identical.
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-                img = api_obj.img
-
-                # Get image catalogs.
-                kcat = img.get_catalog(img.IMG_CATALOG_KNOWN)
-                icat = img.get_catalog(img.IMG_CATALOG_INSTALLED)
-
-                # Verify quux package is only in known catalog.
-                self.assertTrue("quux" in kcat.names())
-                self.assertTrue("foo" in kcat.names())
-                self.assertTrue("quux" not in icat.names())
-                self.assertTrue("foo" not in icat.names())
-
-                # Install the packages.
-                api_obj.plan_install(["[email protected]"])
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-                # Get image catalogs.
-                kcat = img.get_catalog(img.IMG_CATALOG_KNOWN)
-                icat = img.get_catalog(img.IMG_CATALOG_INSTALLED)
-
-                # Verify quux package is in both catalogs.
-                self.assertTrue("quux" in kcat.names())
-                self.assertTrue("foo" in kcat.names())
-                self.assertTrue("quux" in icat.names())
-                self.assertTrue("foo" in icat.names())
-
-                # Verify state info.
-                for cat in kcat, icat:
-                        entry = [e for f, e in cat.entries()][0]
-                        states = entry["metadata"]["states"]
-                        self.assert_(img.PKG_STATE_INSTALLED in states)
-                        self.assert_(img.PKG_STATE_V0 in states)
-
-                # Finally, transition back to v1 catalog.  This requires
-                # creating a new api object since transport will think that
-                # v1 catalogs are still unsupported.
-                self.dc.unset_disable_ops()
-                self.dc.stop()
-                self.dc.start()
-
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-                api_obj.refresh(immediate=True)
-                img = api_obj.img
-
-                # Get image catalogs.
-                kcat = img.get_catalog(img.IMG_CATALOG_KNOWN)
-                icat = img.get_catalog(img.IMG_CATALOG_INSTALLED)
-
-                # Verify quux package is in both catalogs.
-                self.assertTrue("quux" in kcat.names())
-                self.assertTrue("foo" in kcat.names())
-                self.assertTrue("quux" in icat.names())
-                self.assertTrue("foo" in icat.names())
-
-                # Verify state info.
-                for f, entry in kcat.entries():
-                        states = entry["metadata"]["states"]
-                        self.assert_(img.PKG_STATE_V1 in states)
-                        self.assert_(img.PKG_STATE_V0 not in states)
-
-                # Verify that there is dependency information present
-                # in the known and installed catalog.
-                for cat in kcat, icat:
-                        dpart = cat.get_part("catalog.dependency.C")
-                        entries = [(t, entry) for t, entry in dpart.tuple_entries()]
-                        dep_acts = [
-                            acts
-                            for t, entry in dpart.tuple_entries()
-                            for acts in entry.get("actions", [])
-                            if t[1] == "quux"
-                        ]
-                        self.assertNotEqual(dep_acts, [])
-
-                # Verify that every installed package is in known and has
-                # identical entries and that every installed package in
-                # the installed catalog is in the known catalog and has
-                # entries.
-                for src, dest in ((kcat, icat), (icat, kcat)):
-                        src_base = src.get_part("catalog.base.C",
-                            must_exist=True)
-                        self.assertNotEqual(src_base, None)
-
-                        for f, bentry in src_base.entries():
-                                states = bentry["metadata"]["states"]
-                                if img.PKG_STATE_INSTALLED not in states:
-                                        continue
-
-                                for name in src.parts:
-                                        spart = src.get_part(name,
-                                            must_exist=True)
-                                        self.assertNotEqual(spart, None)
-
-                                        dpart = dest.get_part(name,
-                                            must_exist=True)
-                                        self.assertNotEqual(dpart, None)
-
-                                        sentry = spart.get_entry(pfmri=f)
-                                        dentry = dpart.get_entry(pfmri=f)
-                                        self.assertEqual(sentry, dentry)
-
-        def test_properties(self):
-                """Verify that properties of the ImageInterface api object are
-                accessible and return expected values."""
-
-                durl = self.dc.get_depot_url()
-                self.image_create(durl, prefix="bobcat")
-
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                self.assertEqual(api_obj.root, self.img_path)
-
-        def test_publisher_apis(self):
-                """Verify that the publisher api methods work as expected.
-
-                Note that not all methods are tested here as this would be
-                redundant since other tests for the client will use those
-                methods indirectly."""
-
-                durl = self.dc.get_depot_url()
-                plist = self.pkgsend_bulk(durl, self.foo10 + self.bar10)
-                self.image_create(durl, prefix="bobcat")
-
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                # Verify that existence tests succeed.
-                self.assertTrue(api_obj.has_publisher("bobcat"))
-
-                # Verify preferred publisher prefix is returned correctly.
-                self.assertEqual(api_obj.get_preferred_publisher(), "bobcat")
-
-                # Verify that get_publisher returned the correct publisher object.
-                pub = api_obj.get_publisher(prefix="bobcat")
-                self.assertEqual(pub.prefix, "bobcat")
-
-                # Verify that not specifying matching criteria for get_publisher
-                # raises a UnknownPublisher exception.
-                self.assertRaises(api_errors.UnknownPublisher,
-                    api_obj.get_publisher, "zuul")
-                self.assertRaises(api_errors.UnknownPublisher,
-                    api_obj.get_publisher)
-
-                # Verify that publisher objects returned from get_publishers
-                # match those returned by get_publisher.
-                pubs = api_obj.get_publishers()
-                self.assertEqual(pub.prefix, pubs[0].prefix)
-                self.assertEqual(id(pub), id(pubs[0]))
-
-                # Verify that duplicate actually creates duplicates.
-                cpub = api_obj.get_publisher(prefix="bobcat", duplicate=True)
-                self.assertNotEqual(id(pub), id(cpub))
-
-                # Now modify publisher information and update.
-                cpub.alias = "cat"
-                repo = cpub.selected_repository
-                repo.name = "source"
-                repo.description = "xkcd.net/325"
-                repo.legal_uris = ["http://xkcd.com/license.html"]
-                repo.refresh_seconds = 43200
-                repo.registered = False
-                api_obj.update_publisher(cpub)
-
-                # Verify that the update happened.
-                pub = api_obj.get_publisher(prefix="bobcat")
-                self.assertEqual(pub.alias, "cat")
-                repo = pub.selected_repository
-                self.assertEqual(repo.name, "source")
-                self.assertEqual(repo.description, "xkcd.net/325")
-                self.assertEqual(repo.legal_uris[0],
-                    "http://xkcd.com/license.html")
-                self.assertEqual(repo.refresh_seconds, 43200)
-                self.assertEqual(repo.registered, False)
-
-                # Verify that duplicates match their original.
-                cpub = api_obj.get_publisher(alias=pub.alias, duplicate=True)
-                for p in ("alias", "prefix", "meta_root"):
-                        self.assertEqual(getattr(pub, p), getattr(cpub, p))
-
-                for p in ("collection_type", "description", "legal_uris",
-                    "mirrors", "name", "origins", "refresh_seconds",
-                    "registered", "registration_uri", "related_uris",
-                    "sort_policy"):
-                        srepo = pub.selected_repository
-                        crepo = cpub.selected_repository
-                        self.assertEqual(getattr(srepo, p), getattr(crepo, p))
-                cpub = None
-
-                cpubs = api_obj.get_publishers(duplicate=True)
-                self.assertNotEqual(id(pub), id(cpubs[0]))
-                cpubs = None
-
-                # Verify that publisher_last_update_time returns a value.
-                self.assertTrue(
-                    api_obj.get_publisher_last_update_time("bobcat"))
-
-                # Verify that p5i export and parse works as expected.
-
-                # Ensure that PackageInfo, PkgFmri, and strings are all
-                # supported properly.
-
-                # Strip timestamp information so that comparison with
-                # pre-generated test data will succeed.
-                ffoo = fmri.PkgFmri(plist[0])
-                sfoo = str(ffoo).replace(":%s" % ffoo.version.timestr, "")
-                ffoo = fmri.PkgFmri(sfoo)
-                sfoo = ffoo.get_fmri(anarchy=True)
-
-                fbar = fmri.PkgFmri(plist[1])
-                sbar = str(fbar).replace(":%s" % fbar.version.timestr, "")
-                fbar = fmri.PkgFmri(sbar)
-                sbar = fbar.get_fmri(anarchy=True)
-
-                # Build a simple list of packages.
-                pnames = {
-                    "bobcat": (api.PackageInfo(ffoo),),
-                    "": [fbar, "baz"],
-                }
-
-                # Dump the p5i data.
-                fobj = cStringIO.StringIO()
-                api_obj.write_p5i(fobj, pkg_names=pnames, pubs=[pub])
-
-                # Verify that output matches expected output.
-                fobj.seek(0)
-                output = fobj.read()
-                self.assertEqual(output, self.p5i_bobcat)
-
-                def validate_results(results):
-                        # First result should be 'bobcat' publisher and its
-                        # pkg_names.
-                        pub, pkg_names = results[0]
-
-                        self.assertEqual(pub.prefix, "bobcat")
-                        self.assertEqual(pub.alias, "cat")
-                        repo = pub.selected_repository
-                        self.assertEqual(repo.name, "source")
-                        self.assertEqual(repo.description, "xkcd.net/325")
-                        self.assertEqual(repo.legal_uris[0],
-                            "http://xkcd.com/license.html")
-                        self.assertEqual(repo.refresh_seconds, 43200)
-                        self.assertEqual(pkg_names, [sfoo])
-
-                        # Last result should be no publisher and a list of
-                        # pkg_names.
-                        pub, pkg_names = results[1]
-                        self.assertEqual(pub, None)
-                        self.assertEqual(pkg_names, [sbar, "baz"])
-
-                # Verify that parse returns the expected object and information
-                # when provided a fileobj.
-                fobj.seek(0)
-                validate_results(api_obj.parse_p5i(fileobj=fobj))
-
-                # Verify that an add of the parsed object works (the name has to
-                # be changed to prevent a duplicate error here).
-                fobj.seek(0)
-                results = api_obj.parse_p5i(fileobj=fobj)
-                pub, pkg_names = results[0]
-
-                pub.prefix = "p5icat"
-                pub.alias = "copycat"
-                api_obj.add_publisher(pub, refresh_allowed=False)
-
-                # Now verify that we can retrieve the added publisher.
-                api_obj.get_publisher(prefix=pub.prefix)
-                cpub = api_obj.get_publisher(alias=pub.alias, duplicate=True)
-
-                # Now update the publisher and set it to disabled, to verify
-                # that api functions still work as expected.
-                cpub.disabled = True
-                api_obj.update_publisher(cpub)
-
-                cpub = api_obj.get_publisher(alias=cpub.alias, duplicate=True)
-                self.assertTrue(cpub.disabled)
-
-                self.assertTrue(api_obj.has_publisher(prefix=cpub.prefix))
-
-                # Now attempt to update the disabled publisher.
-                cpub = api_obj.get_publisher(alias=cpub.alias, duplicate=True)
-                cpub.alias = "copycopycat"
-                api_obj.update_publisher(cpub)
-                cpub = None
-
-                # Verify that parse returns the expected object and information
-                # when provided a file path.
-                fobj.seek(0)
-                (fd1, path1) = tempfile.mkstemp(dir=self.get_test_prefix())
-                os.write(fd1, fobj.read())
-                validate_results(api_obj.parse_p5i(location=path1))
-
-                # Verify that parse returns the expected object and information
-                # when provided a file URI.
-                validate_results(api_obj.parse_p5i(location="file://" + path1))
-                fobj.close()
-                fobj = None
-
-                # Verify that appropriate exceptions are raised for p5i
-                # information that can't be retrieved (doesn't exist).
-                nefpath = os.path.join(self.get_test_prefix(), "non-existent")
-                self.assertRaises(api_errors.RetrievalError,
-                    api_obj.parse_p5i, location="file://%s" % nefpath)
-
-                self.assertRaises(api_errors.RetrievalError,
-                    api_obj.parse_p5i, location=nefpath)
-
-                # Verify that appropriate exceptions are raised for invalid
-                # p5i information.
-                lcpath = os.path.join(self.get_test_prefix(), "libc.so.1")
-                self.assertRaises(api_errors.InvalidP5IFile, api_obj.parse_p5i,
-                    location="file://%s" % lcpath)
-
-                self.assertRaises(api_errors.InvalidP5IFile, api_obj.parse_p5i,
-                    location=lcpath)
-
-        def test_license(self):
-                """ Send various packages and then verify that install and
-                update operations will raise the correct exceptions or
-                enforce the requirements of the license actions within. """
-
-                durl = self.dc.get_depot_url()
-                plist = self.pkgsend_bulk(durl, self.licensed10 + \
-                    self.licensed12 + self.licensed13 + self.bar10 + self.baz10)
-                self.image_create(durl, prefix="bobcat")
-
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                # First, test the basic install case to see if expected license
-                # data is returned.
-                api_obj.plan_install(["[email protected]"])
-
-                def lic_sort(a, b):
-                        adest = a[2]
-                        bdest = b[2]
-                        return cmp(adest.license, bdest.license)
-
-                plan = api_obj.describe()
-                lics = sorted(plan.get_licenses(), cmp=lic_sort)
-
-                # Expect one license action for each package: "licensed", and
-                # its dependency "baz".
-                self.assertEqual(len(lics), 2)
-
-                # Now verify license entry for "[email protected]" and "[email protected]".
-                for i, p in enumerate([plist[4], plist[0]]):
-                        pfmri = fmri.PkgFmri(p)
-                        dest_fmri, src, dest, accepted, displayed = lics[i]
-
-                        # Expect license information to be for this package.
-                        self.assertEqual(pfmri, dest_fmri)
-
-                        # This is an install, not an update, so there should be
-                        # no src.
-                        self.assertEqual(src, None)
-
-                        # dest should be a LicenseInfo object.
-                        self.assertEqual(type(dest), api.LicenseInfo)
-
-                        # Verify the identity of the LicenseInfo objects.
-                        self.assertEqual(dest.license,
-                            "copyright.%s" % pfmri.pkg_name)
-
-                        # The license hasn't been accepted yet.
-                        self.assertEqual(accepted, False)
-
-                        # The license hasn't beend displayed yet.
-                        self.assertEqual(displayed, False)
-
-                        # The license action doesn't require acceptance.
-                        self.assertEqual(dest.must_accept, False)
-
-                        # The license action doesn't require display.
-                        self.assertEqual(dest.must_display, False)
-
-                        # Verify license text.
-                        text = os.path.join(self.get_test_prefix(),
-                            dest.license)
-                        self.assertEqual(dest.get_text(), text)
-
-                # Install the packages.
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-                # Next, check that an upgrade produces expected license data.
-                api_obj.plan_install(["[email protected]"])
-
-                plan = api_obj.describe()
-                lics = sorted(plan.get_licenses(), cmp=lic_sort)
-
-                # Expect two license actions, both of which should be for the
-                # [email protected] package.
-                self.assertEqual(len(lics), 2)
-
-                # Now verify license entries for "[email protected]".
-                pfmri = fmri.PkgFmri(plist[1])
-                for dest_fmri, src, dest, accepted, displayed in lics:
-                        # License information should only be for "[email protected]".
-                        self.assertEqual(pfmri, dest_fmri)
-
-                        must_accept = False
-                        must_display = False
-                        if dest.license.startswith("copyright"):
-                                # This is an an update, so src should be a
-                                # LicenseInfo object.
-                                self.assertEqual(type(src), api.LicenseInfo)
-
-                                # In this version, copyright must be displayed
-                                # for dest.
-                                must_display = True
-
-                        # dest should be a LicenseInfo object.
-                        self.assertEqual(type(dest), api.LicenseInfo)
-
-                        # Verify LicenseInfo attributes.
-                        self.assertEqual(accepted, False)
-                        self.assertEqual(displayed, False)
-                        self.assertEqual(dest.must_accept, must_accept)
-                        self.assertEqual(dest.must_display, must_display)
-
-                        # Verify license text.
-                        text = os.path.join(self.get_test_prefix(),
-                            dest.license)
-                        self.assertEqual(dest.get_text(), text)
-
-                # Attempt to prepare plan; this should raise a license
-                # exception.
-                self.assertRaises(api_errors.PlanLicenseErrors,
-                    api_obj.prepare)
-
-                # Plan will have to be re-created first before continuing.
-                api_obj.reset()
-                api_obj.plan_install(["[email protected]"])
-                plan = api_obj.describe()
-
-                # Set the copyright as having been displayed.
-                api_obj.set_plan_license_status(pfmri, "copyright.licensed",
-                    displayed=True)
-                lics = sorted(plan.get_licenses(pfmri=pfmri), cmp=lic_sort)
-
-                # Verify displayed was updated and accepted remains False.
-                dest_fmri, src, dest, accepted, displayed = lics[0]
-                self.assertEqual(src.license, "copyright.licensed")
-                self.assertEqual(accepted, False)
-                self.assertEqual(displayed, True)
-
-                # Prepare should succeed this time; so execute afterwards.
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-                # Next, check that an image-update produces expected license
-                # data.
-                api_obj.plan_update_all(sys.argv[0])
-
-                plan = api_obj.describe()
-                lics = sorted(plan.get_licenses(), cmp=lic_sort)
-
-                # Expect two license actions, both of which should be for the
-                # [email protected] package.
-                self.assertEqual(len(lics), 2)
-
-                # Now verify license entries for "[email protected]".
-                pfmri = fmri.PkgFmri(plist[2])
-                for dest_fmri, src, dest, accepted, displayed in lics:
-                        # License information should only be for "[email protected]".
-                        self.assertEqual(pfmri, dest_fmri)
-
-                        must_accept = False
-                        must_display = False
-
-                        # This is an an update, so src should be a LicenseInfo
-                        # object.
-                        self.assertEqual(type(src), api.LicenseInfo)
-
-                        if dest.license.startswith("copyright."):
-                                # copyright must be displayed for dest.
-                                must_display = True
-                        elif dest.license.startswith("license."):
-                                # license must be accepted for dest.
-                                must_accept = True
-
-                        # dest should be a LicenseInfo object.
-                        self.assertEqual(type(dest), api.LicenseInfo)
-
-                        # Verify LicenseInfo attributes.
-                        self.assertEqual(accepted, False)
-                        self.assertEqual(displayed, False)
-                        self.assertEqual(dest.must_accept, must_accept)
-                        self.assertEqual(dest.must_display, must_display)
-
-                        # Verify license text.
-                        text = os.path.join(self.get_test_prefix(),
-                            dest.license)
-                        self.assertEqual(dest.get_text(), text)
-
-                # Attempt to prepare plan; this should raise a license
-                # exception.
-                self.assertRaises(api_errors.PlanLicenseErrors,
-                    api_obj.prepare)
-
-                # Plan will have to be re-created first before continuing.
-                api_obj.reset()
-                api_obj.plan_update_all(sys.argv[0])
-                plan = api_obj.describe()
-                lics = sorted(plan.get_licenses(pfmri=pfmri), cmp=lic_sort)
-
-                # Set the license status of only one license.
-                api_obj.set_plan_license_status(pfmri, "license.licensed",
-                    accepted=True)
-                lics = sorted(plan.get_licenses(pfmri=pfmri), cmp=lic_sort)
-
-                # Verify only license.licensed was updated.
-                dest_fmri, src, dest, accepted, displayed = lics[0]
-                self.assertEqual(src.license, "copyright.licensed")
-                self.assertEqual(accepted, False)
-                self.assertEqual(displayed, False)
-
-                dest_fmri, src, dest, accepted, displayed = lics[1]
-                self.assertEqual(src.license, "license.licensed")
-                self.assertEqual(accepted, True)
-                self.assertEqual(displayed, False)
-
-                # Attempt to prepare plan; this should raise a license
-                # exception since the copyright wasn't displayed.
-                self.assertRaises(api_errors.PlanLicenseErrors,
-                    api_obj.prepare)
-
-                # Plan will have to be re-created first before continuing.
-                api_obj.reset()
-                api_obj.plan_update_all(sys.argv[0])
-                plan = api_obj.describe()
-
-                # Set the correct license status for all licenses.
-                api_obj.set_plan_license_status(pfmri, "copyright.licensed",
-                    displayed=True)
-                api_obj.set_plan_license_status(pfmri, "license.licensed",
-                    accepted=True)
-                lics = sorted(plan.get_licenses(pfmri=pfmri), cmp=lic_sort)
-
-                # Verify status for both license actions.
-                dest_fmri, src, dest, accepted, displayed = lics[0]
-                self.assertEqual(src.license, "copyright.licensed")
-                self.assertEqual(accepted, False)
-                self.assertEqual(displayed, True)
-
-                dest_fmri, src, dest, accepted, displayed = lics[1]
-                self.assertEqual(src.license, "license.licensed")
-                self.assertEqual(accepted, True)
-                self.assertEqual(displayed, False)
-
-                # Prepare should succeed this time; so execute afterwards.
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-                # Finally, verify that an uninstall won't trigger license
-                # errors as acceptance should never be applied to it.
-                api_obj.plan_uninstall(["*"], False)
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-
--- a/src/tests/cli/t_api_info.py	Fri Jan 29 13:24:14 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,311 +0,0 @@
-#!/usr/bin/python
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-import testutils
-if __name__ == "__main__":
-	testutils.setup_environment("../../../proto")
-
-import unittest
-import os
-import re
-import shutil
-import difflib
-import time
-
-import pkg.client.api as api
-import pkg.client.api_errors as api_errors
-import pkg.client.progress as progress
-
-API_VERSION = 31
-PKG_CLIENT_NAME = "pkg"
-
-class TestApiInfo(testutils.SingleDepotTestCase):
-        # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
-
-        def test_info_local_remote(self):
-                self.image_create(self.dc.get_depot_url())
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                self.assertRaises(api_errors.NoPackagesInstalledException,
-                    api_obj.info, [], True, api.PackageInfo.ALL_OPTIONS -
-                    (frozenset([api.PackageInfo.LICENSES]) |
-                    api.PackageInfo.ACTION_OPTIONS))
-
-                self.assertRaises(api_errors.UnrecognizedOptionsToInfo,
-                    api_obj.info, [], True, set([-1]))
-                self.assertRaises(api_errors.UnrecognizedOptionsToInfo,
-                    api_obj.info, [], True, set('a'))
-
-                misc_files = ["/tmp/copyright1", "/tmp/example_file"]
-                for p in misc_files:
-                        f = open(p, "w")
-                        f.write(p)
-                        f.close()
-
-                pkg1 = """
-                    open [email protected],5.11-0
-                    add dir mode=0755 owner=root group=bin path=/bin
-                    add set name=info.classification value="org.opensolaris.category.2008:Applications/Sound and Video"
-                    close
-                """
-
-                pkg2 = """
-                    open [email protected],5.11-0
-                    add dir mode=0755 owner=root group=bin path=/bin
-                    add set name=info.classification value=org.opensolaris.category.2008:System/Security/Foo/bar/Baz
-                    close
-                """
-
-                pkg3 = """
-                    open [email protected],5.11-0
-                    close
-                """
-
-                pkg4 = """
-                    open [email protected],5.11-0
-                    add depend fmri=pkg:/[email protected] type=require
-                    add dir mode=0755 owner=root group=bin path=/bin
-                    add file /tmp/example_file mode=0555 owner=root group=bin path=/bin/example_path
-                    add hardlink path=/bin/example_path2 target=/bin/example_path
-                    add link path=/bin/example_path3 target=/bin/example_path
-                    add set description='FOOO bAr O OO OOO'
-                    add license /tmp/copyright1 license=copyright
-                    add set name=info.classification value=org.opensolaris.category.2008:System/Security/Foo/bar/Baz
-                    add set pkg.description="DESCRIPTION 1"
-                    close """
-
-                pkg5 = """
-                    open [email protected],5.11-0
-                    add dir mode=0755 owner=root group=bin path=/bin
-                    add set pkg.summary='SUMMARY: Example Package 5'
-                    add set pkg.description="DESCRIPTION 2"
-                    close
-                """
-
-                pkg6 = """
-                    open [email protected],5.11-0
-                    add dir mode=0755 owner=root group=bin path=/bin
-                    add set description='DESCRIPTION: Example Package 6'
-                    add set pkg.summary='SUMMARY: Example Package 6'
-                    add set pkg.description="DESCRIPTION 3"
-                    close
-                """
-
-                durl = self.dc.get_depot_url()
-
-                self.pkgsend_bulk(durl, pkg1)
-                self.pkgsend_bulk(durl, pkg2)
-                self.pkgsend_bulk(durl, pkg4)
-                self.pkgsend_bulk(durl, pkg5)
-                self.pkgsend_bulk(durl, pkg6)
-
-                self.image_create(durl)
-
-                local = True
-                get_license = False
-
-                info_needed = api.PackageInfo.ALL_OPTIONS - \
-                    (api.PackageInfo.ACTION_OPTIONS |
-                    frozenset([api.PackageInfo.LICENSES]))
-                
-                ret = api_obj.info(["jade"], local, info_needed)
-                self.assert_(not ret[api.ImageInterface.INFO_FOUND])
-                self.assert_(len(ret[api.ImageInterface.INFO_MISSING]) == 1)
-                
-                api_obj.plan_install(["jade"])
-                api_obj.prepare()
-                api_obj.execute_plan()
-
-                self.pkg("verify -v")
-                
-                ret = api_obj.info(["jade", "turquoise", "emerald"],
-                    local, info_needed)
-                pis = ret[api.ImageInterface.INFO_FOUND]
-                notfound = ret[api.ImageInterface.INFO_MISSING]
-                illegals = ret[api.ImageInterface.INFO_ILLEGALS]
-                self.assert_(len(pis) == 1)
-                self.assert_(api.PackageInfo.INSTALLED in pis[0].states)
-                self.assert_(pis[0].pkg_stem == 'jade')
-                self.assert_(len(notfound) == 2)
-                self.assert_(len(illegals) == 0)
-                self.assert_(len(pis[0].category_info_list) == 1)
-
-                ret = api_obj.info(["j*"], local, info_needed)
-                pis = ret[api.ImageInterface.INFO_FOUND]
-                notfound = ret[api.ImageInterface.INFO_MISSING]
-                illegals = ret[api.ImageInterface.INFO_ILLEGALS]
-                self.assert_(len(pis))
-
-                ret = api_obj.info(["*a*"], local, info_needed)
-                pis = ret[api.ImageInterface.INFO_FOUND]
-                notfound = ret[api.ImageInterface.INFO_MISSING]
-                illegals = ret[api.ImageInterface.INFO_ILLEGALS]
-                self.assert_(len(pis))
-
-                local = False
-
-                ret = api_obj.info(["jade"], local, info_needed)
-                pis = ret[api.ImageInterface.INFO_FOUND]
-                notfound = ret[api.ImageInterface.INFO_MISSING]
-                illegals = ret[api.ImageInterface.INFO_ILLEGALS]
-                self.assert_(len(pis) == 1)
-                self.assert_(api.PackageInfo.INSTALLED in pis[0].states)
-                self.assert_(len(pis[0].category_info_list) == 1)
-
-                ret = api_obj.info(["turquoise"], local, info_needed)
-                pis = ret[api.ImageInterface.INFO_FOUND]
-                notfound = ret[api.ImageInterface.INFO_MISSING]
-                illegals = ret[api.ImageInterface.INFO_ILLEGALS]
-                self.assert_(len(pis) == 1)
-                self.assert_(api.PackageInfo.INSTALLED not in pis[0].states)
-                self.assert_(len(pis[0].category_info_list) == 1)
-
-                ret = api_obj.info(["example_pkg"], local,
-                    api.PackageInfo.ALL_OPTIONS)
-                pis = ret[api.ImageInterface.INFO_FOUND]
-                self.assert_(len(pis) == 1)
-                res = pis[0]
-                self.assert_(api.PackageInfo.INSTALLED not in res.states)
-                self.assert_(len(res.category_info_list) == 1)
-
-                self.assert_(res.pkg_stem is not None)
-                self.assert_(res.summary is not None)
-                self.assert_(res.publisher is not None)
-                self.assert_(res.preferred_publisher is not None)
-                self.assert_(res.version is not None)
-                self.assert_(res.build_release is not None)
-                self.assert_(res.branch is not None)
-                self.assert_(res.packaging_date is not None)
-                total_size = 0
-                for p in misc_files:
-                        total_size += len(p)
-                self.assertEqual(res.size, total_size)
-                self.assert_(res.licenses is not None)
-                self.assert_(res.links is not None)
-                self.assert_(res.hardlinks is not None)
-                self.assert_(res.files is not None)
-                self.assert_(res.dirs is not None)
-                self.assert_(res.dependencies is not None)
-                # A test for bug 8868 which ensures the pkg.description field
-                # is as exected.
-                self.assertEqual(res.description, "DESCRIPTION 1")
-
-                ret = api_obj.info(["emerald"], local, info_needed)
-                pis = ret[api.ImageInterface.INFO_FOUND]
-                notfound = ret[api.ImageInterface.INFO_MISSING]
-                illegals = ret[api.ImageInterface.INFO_ILLEGALS]
-                self.assert_(len(notfound) == 1)
-
-                local = True
-                get_license = False
-                get_action_info = True
-
-                info_needed = api.PackageInfo.ALL_OPTIONS - \
-                    frozenset([api.PackageInfo.LICENSES])
-                
-                ret = api_obj.info(["jade"],
-                    local, info_needed)
-                pis = ret[api.ImageInterface.INFO_FOUND]
-                notfound = ret[api.ImageInterface.INFO_MISSING]
-                illegals = ret[api.ImageInterface.INFO_ILLEGALS]
-                self.assert_(len(pis) == 1)
-                self.assert_(len(pis[0].dirs) == 1)
-                
-                ret = api_obj.info(["jade"], local, set())
-                pis = ret[api.ImageInterface.INFO_FOUND]
-                self.assert_(len(pis) == 1)
-                res = pis[0]
-                self.assert_(res.pkg_stem is None)
-                self.assert_(res.summary is None)
-                self.assertEqual(res.category_info_list, [])
-                self.assertEqual(res.states, set())
-                self.assert_(res.publisher is None)
-                self.assert_(res.preferred_publisher is None)
-                self.assert_(res.version is None)
-                self.assert_(res.build_release is None)
-                self.assert_(res.branch is None)
-                self.assert_(res.packaging_date is None)
-                self.assert_(res.size is None)
-                self.assert_(res.licenses is None)
-                self.assert_(res.links is None)
-                self.assert_(res.hardlinks is None)
-                self.assert_(res.files is None)
-                self.assert_(res.dirs is None)
-                self.assert_(res.dependencies is None)
-                
-                local = False
-
-                ret = api_obj.info(["jade"],
-                    local, info_needed)
-                pis = ret[api.ImageInterface.INFO_FOUND]
-                notfound = ret[api.ImageInterface.INFO_MISSING]
-                illegals = ret[api.ImageInterface.INFO_ILLEGALS]
-                self.assert_(len(pis) == 1)
-                self.assert_(len(pis[0].dirs) == 1)
-
-                self.assertRaises(api_errors.UnrecognizedOptionsToInfo,
-                    api_obj.info, ["jade"], local, set([-1]))
-                self.assertRaises(api_errors.UnrecognizedOptionsToInfo,
-                    api_obj.info, ["jade"], local, set('a'))
-
-                self.assertRaises(api_errors.UnrecognizedOptionsToInfo,
-                    api_obj.info, ["foo"], local, set([-1]))
-                self.assertRaises(api_errors.UnrecognizedOptionsToInfo,
-                    api_obj.info, ["foo"], local, set('a'))
-
-                # Test if the package summary has been correctly set if just
-                # a pkg.summary had been set in the package.
-                # See bug #4395 and bug #8829 for more details.
-                ret = api_obj.info(["example_pkg5"], local,
-                    api.PackageInfo.ALL_OPTIONS)
-                pis = ret[api.ImageInterface.INFO_FOUND]
-                self.assert_(len(pis) == 1)
-                res = pis[0]
-                self.assert_(res.summary == "SUMMARY: Example Package 5")
-                # A test for bug 8868 which ensures the pkg.description field
-                # is as exected.
-                self.assertEqual(res.description, "DESCRIPTION 2")
-
-                # Test if the package summary has been correctly set if both
-                # a pkg.summary and a description had been set in the package.
-                # See bug #4395 and bug #8829 for more details.
-                ret = api_obj.info(["example_pkg6"], local,
-                    api.PackageInfo.ALL_OPTIONS)
-                pis = ret[api.ImageInterface.INFO_FOUND]
-                self.assert_(len(pis) == 1)
-                res = pis[0]
-                self.assert_(res.summary == "SUMMARY: Example Package 6")
-                # A test for bug 8868 which ensures the pkg.description field
-                # is as exected.
-                self.assertEqual(res.description, "DESCRIPTION 3")
-
-
-if __name__ == "__main__":
-        unittest.main()
--- a/src/tests/cli/t_api_list.py	Fri Jan 29 13:24:14 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,1387 +0,0 @@
-#!/usr/bin/python
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-import testutils
-if __name__ == "__main__":
-        testutils.setup_environment("../../../proto")
-
-import calendar
-import difflib
-import os
-import platform
-import pprint
-import re
-import shutil
-import simplejson as json
-import unittest
-
-import pkg.client.api as api
-import pkg.client.api_errors as api_errors
-import pkg.client.progress as progress
-import pkg.fmri as fmri
-import pkg.misc as misc
-import pkg.version as version
-
-API_VERSION = 31
-PKG_CLIENT_NAME = "pkg"
-
-class TestApiList(testutils.ManyDepotTestCase):
-        # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
-
-        packages = [
-            "apple@1,5.11-0",
-            "[email protected],5.11-0",
-            "[email protected],5.11-0",
-            "[email protected],5.11-0",
-            "[email protected],5.11-0",
-            "[email protected],5.11-0",
-            "[email protected],5.11-1",
-            "bat/[email protected],5.11-0",
-            "[email protected]",
-            "[email protected]",
-            "[email protected]",
-            "[email protected]",
-            "[email protected]",
-            "[email protected]",
-            "[email protected]",
-            "[email protected]",
-            "[email protected]",
-            "[email protected]",
-            "[email protected]",
-        ]
-
-        @staticmethod
-        def __tuple_order(a, b):
-                apub, astem, aver = a
-                bpub, bstem, bver = b
-                rval = cmp(astem, bstem)
-                if rval != 0:
-                        return rval
-                rval = cmp(apub, bpub)
-                if rval != 0:
-                        return rval
-                aver = version.Version(aver, "5.11")
-                bver = version.Version(bver, "5.11")
-                return cmp(aver, bver) * -1
-
-        @staticmethod
-        def __get_pkg_arch(stem, ver):
-                # Attempt to determine current arch and opposite arch.
-                # This is so that the tests will see the set of packages
-                # they expect to be omitted.
-                parch = platform.processor()
-                if parch == "i386":
-                        oparch = "sparc"
-                else:
-                        oparch = "i386"
-
-                if stem == "apple":
-                        return [parch]
-                elif stem in ("entire", "bat/bar", "obsolete"):
-                        return
-                elif stem in ("corge", "grault", "qux", "quux"):
-                        return [parch, oparch]
-                return [oparch]
-
-        @staticmethod
-        def __get_pkg_cats(stem, ver):
-                if stem == "apple":
-                        return [
-                            "fruit",
-                            "org.opensolaris.category.2008:"
-                            "Applications/Sound and Video"
-                        ]
-                elif stem == "bat/bar":
-                        return [
-                            "food",
-                            "org.opensolaris.category.2008:"
-                            "Development/Python"
-                        ]
-                return []
-
-        @staticmethod
-        def __get_pkg_summ_desc(stem, ver):
-                summ = "Summ. is %s %s" % (stem, ver)
-                desc = "Desc. is %s %s" % (stem, ver)
-                return summ, desc
-
-        def __get_pkg_states(self, pub, stem, ver, installed=False):
-                states = [api.PackageInfo.KNOWN]
-                if installed:
-                        states.append(api.PackageInfo.INSTALLED)
-                if stem == "apple":
-                        # Compare with newest version entry for this stem.
-                        if ver != str(self.dlist1[6].version):
-                                states.append(api.PackageInfo.UPGRADABLE)
-                elif stem == "baz":
-                        # Compare with newest version entry for this stem.
-                        if ver != str(self.dlist1[10].version):
-                                states.append(api.PackageInfo.UPGRADABLE)
-                elif stem == "corge":
-                        # Compare with newest version entry for this stem.
-                        nver = str(self.dlist1[12].version)
-                        if ver != nver:
-                                states.append(api.PackageInfo.UPGRADABLE)
-                        if ver == nver:
-                                states.append(api.PackageInfo.RENAMED)
-                elif stem == "obsolete":
-                        states.append(api.PackageInfo.OBSOLETE)
-                elif stem == "qux":
-                        # Compare with newest version entry for this stem.
-                        nver = str(self.dlist1[18].version)
-                        if ver != nver:
-                                states.append(api.PackageInfo.UPGRADABLE)
-                        if ver == nver:
-                                states.append(api.PackageInfo.RENAMED)
-                return frozenset(states)
-
-        def __get_pub_entry(self, pub, idx, name, ver):
-                if pub == "test1":
-                        l = self.dlist1
-                else:
-                        l = self.dlist2
-
-                f = l[idx]
-                self.assertEqual(f.pkg_name, name)
-                v = str(f.version)
-                try:
-                        self.assertTrue(v.startswith(ver + ":"))
-                except AssertionError:
-                        self.debug("\n%s does not start with %s:" % (v, ver))
-                        raise
-                return f, v
-
-        def __get_exp_pub_entry(self, pub, idx, name, ver, installed=False):
-                f, v = self.__get_pub_entry(pub, idx, name, ver)
-                return self.__get_expected_entry(pub, name, v,
-                    installed=installed)
-
-        def setUp(self):
-                testutils.ManyDepotTestCase.setUp(self, ["test1", "test2",
-                    "test3"])
-
-                pkg_data = ""
-                for p in self.packages:
-                        pkg_data += p
-                        stem, ver = p.split("@")
-
-                        # XXX version should not require 5.11
-                        sver = version.Version(ver, "5.11")
-                        sver = str(sver).split(":", 1)[0]
-
-                        summ, desc = self.__get_pkg_summ_desc(stem, sver)
-                        pkg_data += """
-open %(stem)s@%(ver)s
-add set name=pkg.summary value="%(summ)s"
-add set name=pkg.description value="%(desc)s"
-""" % { "stem": stem, "ver": ver, "summ": summ, "desc": desc }
-
-                        cats = self.__get_pkg_cats(stem, sver)
-                        if cats:
-                                pkg_data += "add set name=info.classification"
-                                for cat in cats:
-                                        pkg_data += ' value="%s"' % cat
-                                pkg_data += "\n"
-
-                        arch = self.__get_pkg_arch(stem, sver)
-                        if arch:
-                                adata = "value="
-                                adata += " value=".join(arch)
-                                pkg_data += "add set name=variant.arch " \
-                                    "%s\n" % adata
-
-                        if stem == "corge" and sver.startswith("1.0"):
-                                pkg_data += "add set name=pkg.renamed " \
-                                    "value=true\n"
-                                pkg_data += "add depend type=require " \
-                                    "fmri=grault\n"
-                        elif stem == "entire":
-                                pkg_data += "add depend type=incorporate " \
-                                    "[email protected]\n"
-                                pkg_data += "add depend type=incorporate " \
-                                    "[email protected]\n"
-                                pkg_data += "add depend type=incorporate " \
-                                    "[email protected]\n"
-                        elif stem == "obsolete":
-                                pkg_data += "add set name=pkg.obsolete " \
-                                    "value=true\n"
-                        elif stem == "qux" and sver.startswith("1.0"):
-                                pkg_data += "add set name=pkg.renamed " \
-                                    "value=true\n"
-                                pkg_data += "add depend type=require " \
-                                    "fmri=quux\n"
-
-                        pkg_data += "close\n"
-
-                durl1 = self.dcs[1].get_depot_url()
-                plist = self.pkgsend_bulk(durl1, pkg_data)
-                durl2 = self.dcs[2].get_depot_url()
-
-                # Ensure that the second repo's packages have exactly the same
-                # timestamps as those in the first ... by copying the repo over.
-                self.dcs[2].stop()
-                d1dir = self.dcs[1].get_repodir()
-                d2dir = self.dcs[2].get_repodir()
-                self.copy_repository(d1dir, "test1", d2dir, "test2")
-
-                self.dlist1 = []
-                self.dlist2 = []
-                for e in plist:
-                        # Unique FMRI object is needed for each list.
-                        f = fmri.PkgFmri(str(e))
-                        self.dlist1.append(f)
-
-                        f = fmri.PkgFmri(str(e))
-                        f.set_publisher("test2")
-                        self.dlist2.append(f)
-
-                self.dlist1.sort()
-                self.dlist2.sort()
-
-                # The new repository won't have a catalog, so set the depot
-                # server to rebuild it.
-                self.dcs[2].set_rebuild()
-                self.dcs[2].start()
-                self.dcs[2].set_norebuild()
-
-                # The third repository should remain empty and not be
-                # published to.
-
-                # Next, create the image and configure publishers.
-                self.image_create(durl1, prefix="test1")
-                self.pkg("set-publisher -g " + durl2 + " test2")
-
-        def assertPrettyEqual(self, actual, expected):
-                if actual == expected:
-                        return
-
-                actual = pprint.pformat(actual, indent=2)
-                expected = pprint.pformat(expected, indent=2)
-
-                self.assertEqual(expected, actual,
-                    "Actual output differed from expected output.\n" +
-                    "\n".join(difflib.unified_diff(
-                        expected.splitlines(), actual.splitlines(),
-                        "Expected output", "Actual output", lineterm="")))
-                raise AssertionError(output)
-
-        def __get_expected_entry(self, pub, stem, ver, installed=False):
-                states = self.__get_pkg_states(pub, stem, ver,
-                    installed=installed)
-
-                sver = ver.split(":", 1)[0]
-                raw_cats = self.__get_pkg_cats(stem, sver)
-                summ, desc = self.__get_pkg_summ_desc(stem, sver)
-
-                scheme = None
-                cat = None
-                pcats = []
-                for e in raw_cats:
-                        if e and ":" in e:
-                                scheme, cat = e.split(":", 1)
-                        else:
-                                scheme = ""
-                                cat = e
-                        pcats.append((scheme, cat))
-                return ((pub, stem, ver), summ, pcats, states)
-
-        def __get_expected(self, pkg_list, cats=None, pubs=misc.EmptyI,
-            variants=False):
-                nlist = {}
-                newest = pkg_list == api.ImageInterface.LIST_NEWEST
-                if newest:
-                        # Get the newest FMRI for each unique package stem on
-                        # a per-publisher basis.
-                        for plist in (self.dlist1, self.dlist2):
-                                for f in plist:
-                                        pstem = f.get_pkg_stem()
-                                        if pstem not in nlist:
-                                                nlist[pstem] = f
-                                        elif f.version > nlist[pstem]:
-                                                nlist[pstem] = f
-                nlist = sorted(nlist.values())
-
-                expected = []
-                for plist in (self.dlist1, self.dlist2):
-                        for f in plist:
-                                pub, stem, ver = f.tuple()
-                                ver = str(f.version)
-                                if pubs and pub not in pubs:
-                                        continue
-
-                                sver = ver.split(":", 1)[0]
-                                arch = self.__get_pkg_arch(stem, sver)
-                                parch = platform.processor()
-                                if not variants and arch and parch not in arch:
-                                        continue
-
-                                if newest and f not in nlist:
-                                        continue
-
-                                t, summ, pcats, states = \
-                                    self.__get_expected_entry(pub, stem, ver)
-                                if cats is not None:
-                                        if not cats:
-                                                if pcats:
-                                                        # Want packages with no
-                                                        # category.
-                                                        continue
-                                        elif not \
-                                            [sc for sc in cats if sc in pcats]:
-                                                # Doesn't match specified
-                                                # categories.
-                                                continue
-
-                                expected.append((t, summ, pcats, states))
-
-                def pkg_list_order(a, b):
-                        at = a[0]
-                        bt = b[0]
-                        return self.__tuple_order(at, bt)
-                expected.sort(cmp=pkg_list_order)
-                return expected
-
-        def __get_returned(self, pkg_list, api_obj=None, cats=None,
-            num_expected=None, patterns=misc.EmptyI,
-            pubs=misc.EmptyI, variants=False):
-
-                if not api_obj:
-                        progresstracker = progress.NullProgressTracker()
-                        api_obj = api.ImageInterface(self.get_img_path(),
-                            API_VERSION, progresstracker, lambda x: False,
-                            PKG_CLIENT_NAME)
-
-                # Set of states exposed by the API.
-                exp_states = set([api.PackageInfo.FROZEN,
-                    api.PackageInfo.INCORPORATED, api.PackageInfo.EXCLUDES,
-                    api.PackageInfo.KNOWN, api.PackageInfo.INSTALLED,
-                    api.PackageInfo.UPGRADABLE, api.PackageInfo.OBSOLETE,
-                    api.PackageInfo.RENAMED])
-
-                # Get ordered list of all packages.
-                returned = []
-                for entry in api_obj.get_pkg_list(pkg_list, cats=cats,
-                    patterns=patterns, pubs=pubs, variants=variants):
-                        (pub, stem, ver), summ, pcats, raw_states = entry
-
-                        sver = ver.split(":", 1)[0]
-
-                        # Eliminate states not exposed by the api.
-                        states = raw_states.intersection(exp_states)
-                        returned.append(((pub, stem, ver), summ, pcats, states))
-                return returned
-
-        def __test_list(self, pkg_list, api_obj=None,
-            cats=None, num_expected=None, pubs=misc.EmptyI,
-            variants=False):
-
-                # Get package list.
-                returned = self.__get_returned(pkg_list, api_obj=api_obj,
-                    cats=cats, pubs=pubs, variants=variants)
-
-                # Now generate expected list.
-                expected = self.__get_expected(pkg_list, cats=cats,
-                    pubs=pubs, variants=variants)
-
-                # Compare returned and expected.
-                self.assertPrettyEqual(returned, expected)
-
-                if num_expected is not None:
-                        self.assertEqual(len(returned), num_expected)
-
-        def test_list_01_full(self):
-                """Verify the sort order and content of a full list and
-                combinations thereof."""
-
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                # First check all variants case.
-                returned = self.__get_returned(api_obj.LIST_ALL,
-                    api_obj=api_obj, variants=True)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 6, "apple",
-                        "1.2.1,5.11-1"),
-                    self.__get_exp_pub_entry("test1", 5, "apple",
-                        "1.2.1,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 4, "apple",
-                        "1.2.1,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 3, "apple",
-                        "1.2.0,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 2, "apple", "1.1,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 1, "apple", "1.0,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 0, "apple", "1,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 6, "apple",
-                        "1.2.1,5.11-1"),
-                    self.__get_exp_pub_entry("test2", 5, "apple",
-                        "1.2.1,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 4, "apple",
-                        "1.2.1,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 3, "apple",
-                        "1.2.0,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 2, "apple", "1.1,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 1, "apple", "1.0,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 0, "apple", "1,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 10, "baz", "1.3,5.11"),
-                    self.__get_exp_pub_entry("test1", 9, "baz", "1.0.1,5.11"),
-                    self.__get_exp_pub_entry("test1", 8, "baz", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 10, "baz", "1.3,5.11"),
-                    self.__get_exp_pub_entry("test2", 9, "baz", "1.0.1,5.11"),
-                    self.__get_exp_pub_entry("test2", 8, "baz", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 11, "corge", "0.9,5.11"),
-                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 11, "corge", "0.9,5.11"),
-                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 13, "entire", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 16, "quux", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 18, "qux", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 17, "qux", "0.9,5.11"),
-                    self.__get_exp_pub_entry("test2", 18, "qux", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 17, "qux", "0.9,5.11"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 38)
-
-                # Next, check no variants case (which has to be done
-                # programatically to deal with unit test running on
-                # different platforms).
-                self.__test_list(api.ImageInterface.LIST_ALL, api_obj=api_obj,
-                    num_expected=32, variants=False)
-
-        def test_list_02_newest(self):
-                """Verify the sort order and content of a list excluding
-                packages not for the current image variant, and all but
-                the newest versions of each package for each publisher."""
-
-                self.__test_list(api.ImageInterface.LIST_NEWEST,
-                    num_expected=16, variants=False)
-
-        def test_list_03_cats(self):
-                """Verify the sort order and content of a list excluding
-                packages not for the current image variant, and packages
-                that don't match the specified scheme, category
-                combinations."""
-
-                combos = [
-                    ([
-                        ("", "fruit"),
-                        ("org.opensolaris.category.2008",
-                        "Applications/Sound and Video"),
-                        ("", "food"),
-                        ("org.opensolaris.category.2008",
-                        "Development/Python")
-                    ], 16),
-                    ([
-                        ("org.opensolaris.category.2008",
-                        "Development/Python")
-                    ], 2),
-                    ([
-                        ("org.opensolaris.category.2008",
-                        "Applications/Sound and Video"),
-                        ("", "food")
-                    ], 16),
-                    ([
-                        ("", "fruit")
-                    ], 14),
-                    ([
-                        ("", "food")
-                    ], 2),
-                    ([], 16) # Only packages with no category assigned.
-                ]
-
-                for combo, expected in combos:
-                        self.__test_list(api.ImageInterface.LIST_ALL,
-                            cats=combo, num_expected=expected, variants=False)
-
-        def test_list_04_pubs(self):
-                """Verify the sort order and content of list filtered using
-                various publisher and variant combinations."""
-
-                combos = [
-                    (["test1", "test2"], 32, False),
-                    (["test1", "test2"], 38, True),
-                    (["test2"], 16, False),
-                    (["test2"], 19, True),
-                    (["test1"], 16, False),
-                    (["test1"], 19, True),
-                    (["test3"], 0, False),
-                    (["test3"], 0, True),
-                    ([], 32, False),
-                    ([], 38, True)
-                ]
-
-                for combo, expected, variants in combos:
-                        self.__test_list(api.ImageInterface.LIST_ALL,
-                            num_expected=expected, pubs=combo,
-                            variants=variants)
-
-        def test_list_05_installed(self):
-                """Verify the sort order and content of a list containing
-                only installed packages and combinations thereof."""
-
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                # Verify no installed packages case.
-                returned = self.__get_returned(api_obj.LIST_INSTALLED,
-                    api_obj=api_obj)
-                self.assertEqual(len(returned), 0)
-
-                # Test results after installing packages and only listing the
-                # installed packages.  Note that the 'obsolete' package here
-                # won't be installed since it has no dependencies.
-                af = self.__get_pub_entry("test1", 3, "apple",
-                    "1.2.0,5.11-0")[0]
-                api_obj.plan_install(["entire", af.get_fmri(), "corge",
-                    "obsolete", "qux"])
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-                # Verify the results for LIST_INSTALLED.
-                returned = self.__get_returned(api_obj.LIST_INSTALLED,
-                    api_obj=api_obj)
-                self.assertEqual(len(returned), 6)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 3, "apple",
-                        "1.2.0,5.11-0", installed=True),
-                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11",
-                        installed=True),
-                    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.assertPrettyEqual(returned, expected)
-
-                # Verify the results for LIST_INSTALLED_NEWEST.
-                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
-                    api_obj=api_obj)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 3, "apple",
-                        "1.2.0,5.11-0", installed=True),
-                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "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.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 10)
-
-                # Re-test, including variants.
-                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
-                    api_obj=api_obj, variants=True)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 3, "apple",
-                        "1.2.0,5.11-0", installed=True),
-                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,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", 12, "corge", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "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.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 12)
-
-                # Verify results of LIST_INSTALLED_NEWEST when not including
-                # the publisher of installed packages.
-                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
-                    api_obj=api_obj, pubs=["test2"])
-
-                expected = [
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "1.0,5.11"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 2)
-
-                # Verify the results for LIST_INSTALLED_NEWEST after
-                # uninstalling 'qux'.  'qux' should not be listed as
-                # its replacement is incorporated.
-                api_obj.plan_uninstall(["qux"], False)
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
-                    api_obj=api_obj)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 3, "apple",
-                        "1.2.0,5.11-0", installed=True),
-                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11",
-                        installed=True),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 9)
-
-                # Verify the results for LIST_INSTALLED_NEWEST after
-                # uninstalling 'quux' and 'qux'.
-                api_obj.plan_uninstall(["quux"], False)
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
-                    api_obj=api_obj)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 3, "apple",
-                        "1.2.0,5.11-0", installed=True),
-                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 9)
-
-                # Verify the results for LIST_INSTALLED_NEWEST after
-                # all packages have been uninstalled.
-                api_obj.plan_uninstall(["entire", "corge", "apple",
-                    "grault"], False)
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
-                    api_obj=api_obj)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 6, "apple",
-                        "1.2.1,5.11-1"),
-                    self.__get_exp_pub_entry("test2", 6, "apple",
-                        "1.2.1,5.11-1"),
-                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 13, "entire", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 16, "quux", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 18, "qux", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 18, "qux", "1.0,5.11"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 16)
-
-                # Re-test, including variants.
-                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
-                    api_obj=api_obj, variants=True)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 6, "apple",
-                        "1.2.1,5.11-1"),
-                    self.__get_exp_pub_entry("test2", 6, "apple",
-                        "1.2.1,5.11-1"),
-                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,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", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 13, "entire",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 13, "entire", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 16, "quux", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 18, "qux", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 18, "qux", "1.0,5.11"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 18)
-
-                # 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]
-                api_obj.plan_install([af.get_fmri(), "[email protected]", "[email protected]"])
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-                # Verify the results for LIST_INSTALLED and
-                # LIST_INSTALLED_NEWEST when future versions
-                # are renamed and current versions are not
-                # incorporated.
-                returned = self.__get_returned(api_obj.LIST_INSTALLED,
-                    api_obj=api_obj)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 1, "apple", "1.0,5.11-0",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 11, "corge", "0.9,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 17, "qux", "0.9,5.11",
-                        installed=True),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 3)
-
-                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
-                    api_obj=api_obj)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 1, "apple", "1.0,5.11-0",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 11, "corge", "0.9,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 13, "entire", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 17, "qux", "0.9,5.11",
-                        installed=True),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 9)
-
-                # Remove corge, install grault, retest for
-                # LIST_INSTALLED_NEWEST.  corge, grault, qux, and
-                # quux should be listed since none of them are
-                # listed in an installed incorporation.
-
-                # XXX due to bug 12898 attempting to install
-                # any more packages after this would result
-                # in quux being installed even when the
-                # requested packages do not have quux as a
-                # dependency.  As such, uninstall all packages
-                # here and then install apple, qux and grault.
-                api_obj.plan_uninstall(["*"], False)
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-                af = self.__get_pub_entry("test1", 1, "apple", "1.0,5.11-0")[0]
-                api_obj.plan_install([af.get_fmri(), "[email protected]",
-                    "pkg://test2/grault"])
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
-                    api_obj=api_obj)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 1, "apple", "1.0,5.11-0",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 13, "entire", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 17, "qux", "0.9,5.11",
-                        installed=True),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 11)
-
-                # Now verify that publisher search order determines the entries
-                # that are listed when those entries are part of an installed
-                # incorporation.
-                api_obj.plan_uninstall(["*"], False)
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-                api_obj.plan_install(["entire"])
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-                # In this case, any packages present in an installed
-                # incorporation and that are not installed should be
-                # listed using the highest ranked publisher (test1).
-                # Only apple and quux are incorporated, and build
-                # 0 of apple should be listed here instead of build 1
-                # since the installed incorporation doesn't allow the
-                # build 1 version.
-                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
-                    api_obj=api_obj)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 5, "apple",
-                        "1.2.1,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 11)
-
-                # Re-test, only including test1's packages.
-                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
-                    api_obj=api_obj, pubs=["test1"])
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 5, "apple",
-                        "1.2.1,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 7)
-
-                # Re-test, only including test2's packages.  Since none of
-                # the other packages are installed for test1, and they meet
-                # the requirements of the installed incorporations, this is
-                # the expected result.
-                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
-                    api_obj=api_obj, pubs=["test2"])
-
-                expected = [
-                    self.__get_exp_pub_entry("test2", 5, "apple",
-                        "1.2.1,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 16, "quux", "1.0,5.11"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 6)
-
-                # Change test2 to be ranked higher than test1.
-                api_obj.set_pub_search_before("test2", "test1")
-
-                # Re-test; test2 should now have its entries listed in place
-                # of test1's for the non-filtered case.
-                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
-                    api_obj=api_obj)
-
-                expected = [
-                    self.__get_exp_pub_entry("test2", 5, "apple",
-                        "1.2.1,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 16, "quux", "1.0,5.11"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 11)
-
-                # Now install one of the incorporated packages and check
-                # that test2 is still listed for the remaining package
-                # for the non-filtered case.
-                api_obj.plan_install(["apple"])
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
-                    api_obj=api_obj)
-
-                expected = [
-                    self.__get_exp_pub_entry("test2", 5, "apple",
-                        "1.2.1,5.11-0", installed=True),
-                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 16, "quux", "1.0,5.11"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 11)
-
-                # Reset publisher search order and re-test.
-                api_obj.set_pub_search_before("test1", "test2")
-
-                returned = self.__get_returned(api_obj.LIST_INSTALLED_NEWEST,
-                    api_obj=api_obj)
-
-                expected = [
-                    self.__get_exp_pub_entry("test2", 5, "apple",
-                        "1.2.1,5.11-0", installed=True),
-                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 12, "corge", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 13, "entire", "1.0,5.11",
-                        installed=True),
-                    self.__get_exp_pub_entry("test1", 14, "grault", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 14, "grault", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 16, "quux", "1.0,5.11"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 11)
-
-                # Reset image state for following tests.
-                api_obj.plan_uninstall(["*"], False)
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-        def test_list_06_upgradable(self):
-                """Verify the sort order and content of a list containing
-                only upgradable packages and combinations thereof."""
-
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                # Verify no installed packages case.
-                returned = self.__get_returned(api_obj.LIST_UPGRADABLE,
-                    api_obj=api_obj)
-                self.assertEqual(len(returned), 0)
-
-                # Test results after installing packages and only listing the
-                # installed, upgradable packages.
-                af = self.__get_pub_entry("test1", 3, "apple",
-                    "1.2.0,5.11-0")[0]
-                api_obj.plan_install([af.get_fmri(), "bat/bar", "qux"])
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-                # Verify the results for LIST_UPGRADABLE.
-                returned = self.__get_returned(api_obj.LIST_UPGRADABLE,
-                    api_obj=api_obj)
-                self.assertEqual(len(returned), 1)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 3, "apple",
-                        "1.2.0,5.11-0", installed=True),
-                ]
-                self.assertPrettyEqual(returned, expected)
-
-                # Reset image state for following tests.
-                api_obj.plan_uninstall(["*"], False)
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-        def test_list_07_get_pkg_categories(self):
-                """Verify that get_pkg_categories returns expected results."""
-
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                # Verify no installed packages case.
-                returned = api_obj.get_pkg_categories(installed=True)
-                self.assertEqual(len(returned), 0)
-
-                def get_pkg_cats(p):
-                        stem, ver = p.split("@")
-
-                        # XXX version should not require 5.11
-                        sver = version.Version(ver, "5.11")
-                        sver = str(sver).split(":", 1)[0]
-                        raw_cats = self.__get_pkg_cats(stem, sver)
-
-                        pcats = []
-                        for e in raw_cats:
-                                if e and ":" in e:
-                                        scheme, cat = e.split(":", 1)
-                                else:
-                                        scheme = ""
-                                        cat = e
-                                pcats.append((scheme, cat))
-                        return pcats
-
-                # Verify all case.
-                returned = api_obj.get_pkg_categories()
-                all_pkgs = self.packages
-                all_cats = sorted(set(
-                    sc
-                    for p in all_pkgs
-                    for sc in get_pkg_cats(p)
-                ))
-                self.assertPrettyEqual(returned, all_cats)
-
-                # Verify all case with a few different pub combos.
-                combos = [
-                    (["test1", "test2"], all_cats),
-                    (["test1"], all_cats),
-                    (["test2"], all_cats),
-                    (["test3"], []),
-                    ([], all_cats),
-                ]
-
-                for combo, expected in combos:
-                        returned = api_obj.get_pkg_categories(pubs=combo)
-                        self.assertPrettyEqual(returned, expected)
-
-                # Now install different sets of packages and ensure the
-                # results match what is expected.
-                combos = [
-                    [
-                        self.dlist1[6], # "[email protected],5.11-1"
-                        self.dlist1[7], # "[email protected],5.11-0"
-                    ],
-                    [
-                        self.dlist1[12], # "[email protected]"
-                        self.dlist1[14], # "[email protected]"
-                    ],
-                    [
-                        self.dlist1[16], # "[email protected]"
-                    ],
-                ]
-
-                for combo in combos:
-                        import time
-                        self.debug("combo: %s, time: %s" % (combo, time.ctime()))
-                        pkgs = [
-                            f.get_fmri(anarchy=True, include_scheme=False)
-                            for f in combo
-                        ]
-                        self.debug("plan install: %s" % time.ctime())
-                        api_obj.plan_install(pkgs)
-                        self.debug("prepare install: %s" % time.ctime())
-                        api_obj.prepare()
-                        self.debug("execute install: %s" % time.ctime())
-                        api_obj.execute_plan()
-                        self.debug("1reset: %s" % time.ctime())
-                        api_obj.reset()
-
-                        returned = api_obj.get_pkg_categories(installed=True)
-                        expected = sorted(set(
-                            sc
-                            for p in pkgs
-                            for sc in get_pkg_cats(p)
-                        ))
-                        self.assertPrettyEqual(returned, expected)
-
-                        # Prepare for next test.
-                        self.debug("plan uninstall: %s" % time.ctime())
-                        api_obj.plan_uninstall(pkgs, False)
-                        self.debug("prepare uninstall: %s" % time.ctime())
-                        api_obj.prepare()
-                        self.debug("execute uninstall: %s" % time.ctime())
-                        api_obj.execute_plan()
-                        self.debug("2reset: %s" % time.ctime())
-                        api_obj.reset()
-                self.debug("test finished: %s" % time.ctime())
-
-        def test_list_08_patterns(self):
-                """Verify that pattern filtering works as expected."""
-
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                # First, check all variants, but with multiple patterns for the
-                # partial, exact, and wildcard match cases.
-                patterns = ["bar", "pkg:/baz", "*obs*"]
-                returned = self.__get_returned(api_obj.LIST_ALL,
-                    api_obj=api_obj, patterns=patterns, variants=True)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test1", 10, "baz", "1.3,5.11"),
-                    self.__get_exp_pub_entry("test1", 9, "baz", "1.0.1,5.11"),
-                    self.__get_exp_pub_entry("test1", 8, "baz", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 10, "baz", "1.3,5.11"),
-                    self.__get_exp_pub_entry("test2", 9, "baz", "1.0.1,5.11"),
-                    self.__get_exp_pub_entry("test2", 8, "baz", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "1.0,5.11"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 10)
-
-                # Next, check all variants, but with exact and partial match.
-                patterns = ["pkg:/bar", "obsolete"]
-                returned = self.__get_returned(api_obj.LIST_ALL,
-                    api_obj=api_obj, patterns=patterns, variants=True)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 15, "obsolete",
-                        "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 15, "obsolete",
-                        "1.0,5.11"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 2)
-
-                # Next, check all variants, but for publisher and exact
-                # match case only.
-                patterns = ["pkg://test2/bat/bar"]
-                returned = self.__get_returned(api_obj.LIST_ALL,
-                    api_obj=api_obj, patterns=patterns, variants=True)
-
-                expected = [
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 1)
-
-                # Should return no matches.
-                patterns = ["pkg://test2/bar"]
-                returned = self.__get_returned(api_obj.LIST_ALL,
-                    api_obj=api_obj, patterns=patterns, variants=True)
-                expected = []
-                self.assertPrettyEqual(returned, expected)
-
-                # Next, check all variants, but for exact match case only.
-                patterns = ["pkg:/bat/bar"]
-                returned = self.__get_returned(api_obj.LIST_ALL,
-                    api_obj=api_obj, patterns=patterns, variants=True)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 7, "bat/bar",
-                        "1.2,5.11-0"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 2)
-
-                # Next, check version matching for a single pattern.
-                patterns = ["[email protected]"]
-                returned = self.__get_returned(api_obj.LIST_ALL,
-                    api_obj=api_obj, patterns=patterns, variants=True)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 3, "apple",
-                        "1.2.0,5.11-0"),
-                    self.__get_exp_pub_entry("test2", 3, "apple",
-                        "1.2.0,5.11-0"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 2)
-
-                patterns = ["[email protected]"]
-                returned = self.__get_returned(api_obj.LIST_ALL,
-                    api_obj=api_obj, patterns=patterns, 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.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 2)
-
-                patterns = ["apple@*,*-1"]
-                returned = self.__get_returned(api_obj.LIST_ALL,
-                    api_obj=api_obj, patterns=patterns, variants=True)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 6, "apple",
-                        "1.2.1,5.11-1"),
-                    self.__get_exp_pub_entry("test2", 6, "apple",
-                        "1.2.1,5.11-1"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 2)
-
-                # Next, check version matching for multiple patterns.
-                patterns = ["[email protected]", "pkg:/[email protected]",
-                    "pkg://test1/[email protected]"]
-                returned = self.__get_returned(api_obj.LIST_ALL,
-                    api_obj=api_obj, patterns=patterns, variants=True)
-
-                expected = [
-                    self.__get_exp_pub_entry("test1", 9, "baz", "1.0.1,5.11"),
-                    self.__get_exp_pub_entry("test1", 8, "baz", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test2", 9, "baz", "1.0.1,5.11"),
-                    self.__get_exp_pub_entry("test2", 8, "baz", "1.0,5.11"),
-                    self.__get_exp_pub_entry("test1", 17, "qux", "0.9,5.11"),
-                ]
-                self.assertPrettyEqual(returned, expected)
-                self.assertEqual(len(returned), 5)
-
-                # Finally, verify that specifying an illegal pattern will
-                # raise an InventoryException.
-                patterns = ["baz@1.*.a", "baz@*-1"]
-                try:
-                        returned = self.__get_returned(api_obj.LIST_ALL,
-                            api_obj=api_obj, patterns=patterns, variants=True)
-                except api_errors.InventoryException, e:
-                        self.assertEqual(e.illegal, patterns)
-                else:
-                        raise RuntimeError("InventoryException not raised!")
-
-
-if __name__ == "__main__":
-        unittest.main()
--- a/src/tests/cli/t_api_search.py	Fri Jan 29 13:24:14 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2521 +0,0 @@
-#!/usr/bin/python
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-
-import testutils
-if __name__ == "__main__":
-	testutils.setup_environment("../../../proto")
-
-import copy
-import difflib
-import os
-import re
-import shutil
-import sys
-import tempfile
-import time
-import unittest
-import urllib2
-
-import pkg.client.api as api
-import pkg.client.api_errors as api_errors
-import pkg.client.query_parser as query_parser
-import pkg.client.progress as progress
-import pkg.fmri as fmri
-import pkg.indexer as indexer
-import pkg.portable as portable
-import pkg.search_storage as ss
-import pkg.server.repository as srepo
-
-API_VERSION = 31
-PKG_CLIENT_NAME = "pkg"
-
-class TestApiSearchBasics(testutils.SingleDepotTestCase):
-
-        example_pkg10 = """
-            open [email protected],5.11-0
-            add dir mode=0755 owner=root group=bin path=/bin
-            add dir mode=0755 owner=root group=bin path=/bin/example_dir
-            add dir mode=0755 owner=root group=bin path=/usr/lib/python2.6/vendor-packages/OpenSSL
-            add file /tmp/example_file mode=0555 owner=root group=bin path=/bin/example_path
-            add set name=com.sun.service.incorporated_changes value="6556919 6627937"
-            add set name=com.sun.service.random_test value=42 value=79
-            add set name=com.sun.service.bug_ids value=4641790 value=4725245 value=4817791 value=4851433 value=4897491 value=4913776 value=6178339 value=6556919 value=6627937
-            add set name=com.sun.service.keywords value="sort null -n -m -t sort 0x86 separator"
-            add set name=com.sun.service.info_url value=http://service.opensolaris.com/xml/pkg/[email protected],5.11-1:20080514I120000Z
-            add set name=description value='FOOO bAr O OO OOO' value="whee fun"
-            add set name='weirdness' value='] [ * ?'
-            add signature pkg.sig_bit1=sig_bit_val1 pkg.sig_bit2=sig_bit_val2
-            close """
-
-        example_pkg11 = """
-            open [email protected],5.11-0
-            add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/example_file mode=0555 owner=root group=bin path=/bin/example_path11
-            close """
-
-        another_pkg10 = """
-            open [email protected],5.11-0
-            add dir mode=0755 owner=root group=bin path=/bin
-            add dir mode=0755 owner=root group=bin path=/bin/another_dir
-            add file /tmp/example_file mode=0555 owner=root group=bin path=/bin/another_path
-            add set name=com.sun.service.incorporated_changes value="6556919 6627937"
-            add set name=com.sun.service.random_test value=42 value=79
-            add set name=com.sun.service.bug_ids value="4641790 4725245 4817791 4851433 4897491 4913776 6178339 6556919 6627937"
-            add set name=com.sun.service.keywords value="sort null -n -m -t sort 0x86 separator"
-            add set name=com.sun.service.info_url value=http://service.opensolaris.com/xml/pkg/[email protected],5.11-1:20080514I120000Z
-            close """
-
-        bad_pkg10 = """
-            open [email protected],5.11-0
-            add dir path=badfoo/ mode=0755 owner=root group=bin
-            close """
-
-        space_pkg10 = """
-            open [email protected],5.11-0
-            add file /tmp/example_file mode=0444 owner=nobody group=sys path='unique/with a space'
-            add dir mode=0755 owner=root group=bin path=unique_dir
-            close """
-
-        cat_pkg10 = """
-            open [email protected],5.11-0
-            add set name=info.classification value=org.opensolaris.category.2008:System/Security value=org.random:Other/Category
-            close """
-
-        cat2_pkg10 = """
-            open [email protected],5.11-0
-            add set name=info.classification value="org.opensolaris.category.2008:Applications/Sound and Video" value=Developer/C
-            close """
-
-        cat3_pkg10 = """
-            open [email protected],5.11-0
-            add set name=info.classification value="org.opensolaris.category.2008:foo/bar/baz/bill/beam/asda"
-            close """
-
-        bad_cat_pkg10 = """
-            open [email protected],5.11-0
-            add set name=info.classification value="TestBad1/TestBad2"
-            close """
-
-        bad_cat2_pkg10 = """
-            open [email protected],5.11-0
-            add set name=info.classification value="org.opensolaris.category.2008:TestBad1:TestBad2"
-            close """
-
-        fat_pkg10 = """
-open [email protected],5.11-0
-add set name=variant.arch value=sparc value=i386
-add set name=description value="i386 variant" variant.arch=i386
-add set name=description value="sparc variant" variant.arch=sparc
-close """
-
-        bogus_pkg10 = """
-set name=pkg.fmri value=pkg:/[email protected],5.11-0:20090326T233451Z
-set name=description value=""validation with simple chains of constraints ""
-set name=pkg.description value="pseudo-hashes as arrays tied to a "type" (list of fields)"
-depend fmri=XML-Atom-Entry
-set name=com.sun.service.incorporated_changes value="6556919 6627937"
-"""
-        bogus_fmri = fmri.PkgFmri("[email protected],5.11-0:20090326T233451Z")
-
-        bug_8492_manf_1 = """
-open [email protected],5.11-0
-add set description="Image Packaging System"
-close """
-
-        bug_8492_manf_2 = """
-open [email protected],5.11-0
-add set description="Image Packaging System"
-close """
-
-        res_8492_1 = set([('pkg:/[email protected]', 'Image Packaging System', 'set name=description value="Image Packaging System"')])
-        res_8492_2 = set([('pkg:/[email protected]', 'Image Packaging System', 'set name=description value="Image Packaging System"')])
-        
-        remote_fmri_string = ('pkg:/[email protected]', 'test/example_pkg',
-            'set name=pkg.fmri value=pkg://test/[email protected],5.11-0:')
-
-        res_remote_pkg = set([
-            remote_fmri_string
-        ])
-
-        res_remote_path = set([
-            ("pkg:/[email protected]", "basename","file 820157a2043e3135f342b238129b556aade20347 chash=bfa46fc98d1ca97f1260090797d35a35e76096a3 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=38 pkg.size=18")
-        ])
-
-        res_remote_path_of_example_path = set([
-            ("pkg:/[email protected]", "path","file 820157a2043e3135f342b238129b556aade20347 chash=bfa46fc98d1ca97f1260090797d35a35e76096a3 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=38 pkg.size=18")
-        ])
-
-        res_remote_bin = set([
-            ("pkg:/[email protected]", "path", "dir group=bin mode=0755 owner=root path=bin")
-        ])
-
-        res_remote_openssl = set([
-            ("pkg:/[email protected]", "basename", "dir group=bin mode=0755 owner=root path=usr/lib/python2.6/vendor-packages/OpenSSL")
-        ])
-
-        res_remote_bug_id = set([
-            ("pkg:/[email protected]", "4851433", 'set name=com.sun.service.bug_ids value=4641790 value=4725245 value=4817791 value=4851433 value=4897491 value=4913776 value=6178339 value=6556919 value=6627937')
-        ])
-
-        res_remote_bug_id_4725245 = set([
-            ("pkg:/[email protected]", "4725245", 'set name=com.sun.service.bug_ids value=4641790 value=4725245 value=4817791 value=4851433 value=4897491 value=4913776 value=6178339 value=6556919 value=6627937')
-        ])
-
-
-        res_remote_inc_changes = set([
-            ("pkg:/[email protected]", "6556919 6627937", 'set name=com.sun.service.incorporated_changes value="6556919 6627937"'),
-            ("pkg:/[email protected]", "6556919", 'set name=com.sun.service.bug_ids value=4641790 value=4725245 value=4817791 value=4851433 value=4897491 value=4913776 value=6178339 value=6556919 value=6627937')
-        ])
-
-        res_remote_random_test = set([
-            ("pkg:/[email protected]", "42", "set name=com.sun.service.random_test value=42 value=79")
-        ])
-
-        res_remote_random_test_79 = set([
-            ("pkg:/[email protected]", "79", "set name=com.sun.service.random_test value=42 value=79")
-        ])
-
-        res_remote_keywords = set([
-            ("pkg:/[email protected]", "sort null -n -m -t sort 0x86 separator", 'set name=com.sun.service.keywords value="sort null -n -m -t sort 0x86 separator"')
-        ])
-
-        res_remote_wildcard = res_remote_path.union(set([
-            remote_fmri_string,
-            ('pkg:/[email protected]', 'basename', 'dir group=bin mode=0755 owner=root path=bin/example_dir')
-        ]))
-
-        res_remote_glob = set([
-            remote_fmri_string,
-            ('pkg:/[email protected]', 'path', 'dir group=bin mode=0755 owner=root path=bin/example_dir'),
-            ('pkg:/[email protected]', 'basename', 'dir group=bin mode=0755 owner=root path=bin/example_dir'),
-            ('pkg:/[email protected]', 'path', 'file 820157a2043e3135f342b238129b556aade20347 chash=bfa46fc98d1ca97f1260090797d35a35e76096a3 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=38 pkg.size=18')
-        ]) | res_remote_path
-
-        res_remote_foo = set([
-            ('pkg:/[email protected]', 'FOOO bAr O OO OOO', 'set name=description value="FOOO bAr O OO OOO" value="whee fun"')
-        ])
-
-        res_remote_weird = set([
-            ('pkg:/[email protected]', '] [ * ?', 'set name=weirdness value="] [ * ?"')
-        ])
-
-        local_fmri_string = ('pkg:/[email protected]', 'test/example_pkg',
-            'set name=pkg.fmri value=pkg://test/[email protected],5.11-0:')
-
-        res_local_pkg = set([
-                local_fmri_string
-                ])
-
-        res_local_path = copy.copy(res_remote_path)
-
-        res_local_bin = copy.copy(res_remote_bin)
-
-        res_local_bug_id = copy.copy(res_remote_bug_id)
-
-        res_local_inc_changes = copy.copy(res_remote_inc_changes)
-
-        res_local_random_test = copy.copy(res_remote_random_test)
-
-        res_local_keywords = copy.copy(res_remote_keywords)
-
-        res_local_wildcard = copy.copy(res_remote_wildcard)
-        res_local_wildcard.add(local_fmri_string)
-
-        res_local_glob = copy.copy(res_remote_glob)
-        res_local_glob.add(local_fmri_string)
-
-        res_local_foo = copy.copy(res_remote_foo)
-
-        res_local_openssl = copy.copy(res_remote_openssl)
-
-        res_local_path_example11 = set([
-            ("pkg:/[email protected]", "basename", "file 820157a2043e3135f342b238129b556aade20347 chash=bfa46fc98d1ca97f1260090797d35a35e76096a3 group=bin mode=0555 owner=root path=bin/example_path11 pkg.csize=38 pkg.size=18")
-        ])
-
-        res_local_bin_example11 = set([
-            ("pkg:/[email protected]", "path", "dir group=bin mode=0755 owner=root path=bin")
-        ])
-
-        res_local_pkg_example11 = set([
-            ("pkg:/[email protected]", "test/example_pkg", "set name=pkg.fmri value=pkg://test/[email protected],5.11-0:")
-        ])
-
-        res_local_wildcard_example11 = set([
-            ("pkg:/[email protected]", "basename", "file 820157a2043e3135f342b238129b556aade20347 chash=bfa46fc98d1ca97f1260090797d35a35e76096a3 group=bin mode=0555 owner=root path=bin/example_path11 pkg.csize=38 pkg.size=18"),
-        ]).union(res_local_pkg_example11)
-
-        res_cat_pkg10 = set([
-            ('pkg:/[email protected]', 'System/Security', 'set name=info.classification value=org.opensolaris.category.2008:System/Security value=org.random:Other/Category')
-        ])
-
-        res_cat_pkg10_2 = set([
-            ('pkg:/[email protected]', 'Other/Category', 'set name=info.classification value=org.opensolaris.category.2008:System/Security value=org.random:Other/Category')
-        ])
-
-        res_cat2_pkg10 = set([
-            ('pkg:/[email protected]', 'Applications/Sound and Video', 'set name=info.classification value="org.opensolaris.category.2008:Applications/Sound and Video" value=Developer/C')
-        ])
-
-        res_cat2_pkg10_2 = set([
-            ('pkg:/[email protected]', 'Developer/C', 'set name=info.classification value="org.opensolaris.category.2008:Applications/Sound and Video" value=Developer/C')
-        ])
-
-        res_cat3_pkg10 = set([
-            ('pkg:/[email protected]', 'foo/bar/baz/bill/beam/asda', 'set name=info.classification value=org.opensolaris.category.2008:foo/bar/baz/bill/beam/asda')
-        ])
-
-        res_fat10_i386 = set([
-            ('pkg:/[email protected]', 'i386 variant', 'set name=description value="i386 variant" variant.arch=i386'),
-            ('pkg:/[email protected]', 'i386 variant', 'set name=description value="i386 variant" variant.arch=i386'),
-            ('pkg:/[email protected]', 'i386', 'set name=variant.arch value=sparc value=i386'),
-        ])
-
-        res_fat10_sparc = set([
-            ('pkg:/[email protected]', 'sparc variant', 'set name=description value="sparc variant" variant.arch=sparc'),
-            ('pkg:/[email protected]', 'sparc', 'set name=variant.arch value=sparc value=i386')
-        ])
-
-        fat_10_fmri_string = set([('pkg:/[email protected]', 'test/fat', 'set name=pkg.fmri value=pkg://test/[email protected],5.11-0:')])
-
-        res_remote_fat10_star = fat_10_fmri_string | res_fat10_sparc | res_fat10_i386
-
-        res_local_fat10_i386_star = res_fat10_i386.union(set([
-            ('pkg:/[email protected]', 'sparc', 'set name=variant.arch value=sparc value=i386')
-        ])).union(fat_10_fmri_string)
-
-        res_local_fat10_sparc_star = res_fat10_sparc.union(set([
-            ('pkg:/[email protected]', 'i386', 'set name=variant.arch value=sparc value=i386')
-        ])).union(fat_10_fmri_string)
-
-        res_space_with_star = set([
-            ('pkg:/[email protected]', 'basename', 'file 820157a2043e3135f342b238129b556aade20347 chash=bfa46fc98d1ca97f1260090797d35a35e76096a3 group=sys mode=0444 owner=nobody path="unique/with a space" pkg.csize=38 pkg.size=18')
-        ])
-
-        res_space_space_star = set([
-            ('pkg:/[email protected]', 'basename', 'file 820157a2043e3135f342b238129b556aade20347 chash=bfa46fc98d1ca97f1260090797d35a35e76096a3 group=sys mode=0444 owner=nobody path="unique/with a space" pkg.csize=38 pkg.size=18'), ('pkg:/[email protected]', 'path', 'file 820157a2043e3135f342b238129b556aade20347 chash=bfa46fc98d1ca97f1260090797d35a35e76096a3 group=sys mode=0444 owner=nobody path="unique/with a space" pkg.csize=38 pkg.size=18')
-        ])
-
-        res_space_unique = set([
-            ('pkg:/[email protected]', 'basename', 'dir group=bin mode=0755 owner=root path=unique_dir')
-        ])
-
-        misc_files = ['/tmp/example_file']
-
-        # This is a copy of the 3.81%2C5.11-0.89%3A20080527T163123Z version of
-        # SUNWgmake from ipkg with the file and liscense actions changed so
-        # that they all take /tmp/example file when sending.
-        bug_983_manifest = """
-open [email protected],5.11-0.89
-add dir group=sys mode=0755 owner=root path=usr
-add dir group=bin mode=0755 owner=root path=usr/bin
-add dir group=bin mode=0755 owner=root path=usr/gnu
-add dir group=bin mode=0755 owner=root path=usr/gnu/bin
-add link path=usr/gnu/bin/make target=../../bin/gmake
-add dir group=sys mode=0755 owner=root path=usr/gnu/share
-add dir group=bin mode=0755 owner=root path=usr/gnu/share/man
-add dir group=bin mode=0755 owner=root path=usr/gnu/share/man/man1
-add link path=usr/gnu/share/man/man1/make.1 target=../../../../share/man/man1/gmake.1
-add dir group=bin mode=0755 owner=root path=usr/sfw
-add dir group=bin mode=0755 owner=root path=usr/sfw/bin
-add link path=usr/sfw/bin/gmake target=../../bin/gmake
-add dir group=bin mode=0755 owner=root path=usr/sfw/share
-add dir group=bin mode=0755 owner=root path=usr/sfw/share/man
-add dir group=bin mode=0755 owner=root path=usr/sfw/share/man/man1
-add link path=usr/sfw/share/man/man1/gmake.1 target=../../../../share/man/man1/gmake.1
-add dir group=sys mode=0755 owner=root path=usr/share
-add dir group=bin mode=0755 owner=root path=usr/share/info
-add dir group=bin mode=0755 owner=root path=usr/share/man
-add dir group=bin mode=0755 owner=root path=usr/share/man/man1
-add file /tmp/example_file elfarch=i386 elfbits=32 elfhash=68cca393e816e6adcbac1e8ffe9c618de70413e0 group=bin mode=0555 owner=root path=usr/bin/gmake pkg.size=18
-add file /tmp/example_file group=bin mode=0444 owner=root path=usr/share/info/make.info pkg.size=18
-add file /tmp/example_file group=bin mode=0444 owner=root path=usr/share/info/make.info-1 pkg.size=18
-add file /tmp/example_file group=bin mode=0444 owner=root path=usr/share/info/make.info-2 pkg.size=18
-add file /tmp/example_file group=bin mode=0444 owner=root path=usr/share/man/man1/gmake.1 pkg.size=18
-add license /tmp/example_file license=SUNWgmake.copyright pkg.size=18 transaction_id=1211931083_pkg%3A%2FSUNWgmake%403.81%2C5.11-0.89%3A20080527T163123Z
-add depend fmri=pkg:/[email protected] type=require
-add depend [email protected] type=require
-add depend [email protected] type=incorporate
-add set name=description value="gmake - GNU make"
-add legacy arch=i386 category=system desc="GNU make - A utility used to build software (gmake) 3.81" hotline="Please contact your local service provider" name="gmake - GNU make" pkg=SUNWgmake vendor="Sun Microsystems, Inc." version=11.11.0,REV=2008.04.29.02.08
-close
-"""
-
-        res_bug_983 = set([
-            ("pkg:/[email protected]", "basename", "link path=usr/sfw/bin/gmake target=../../bin/gmake"),
-            ('pkg:/[email protected]', 'basename', 'file 820157a2043e3135f342b238129b556aade20347 chash=bfa46fc98d1ca97f1260090797d35a35e76096a3 elfarch=i386 elfbits=32 elfhash=68cca393e816e6adcbac1e8ffe9c618de70413e0 group=bin mode=0555 owner=root path=usr/bin/gmake pkg.csize=38 pkg.size=18'),
-            ('pkg:/[email protected]', 'gmake - GNU make', 'set name=description value="gmake - GNU make"')
-        ])
-
-        res_983_csl_dependency = set([
-            ('pkg:/[email protected]', 'require', 'depend fmri=pkg:/[email protected] type=require')
-        ])
-
-        res_983_bar_dependency = set([
-            ('pkg:/[email protected]', 'require', 'depend [email protected] type=require')
-        ])
-
-        res_983_foo_dependency = set([
-            ('pkg:/[email protected]', 'incorporate', 'depend [email protected] type=incorporate')
-        ])
-
-        res_local_pkg_ret_pkg = set([
-            "pkg:/[email protected]"
-        ])
-
-        res_remote_pkg_ret_pkg = set([
-            "pkg:/[email protected]"
-        ])
-
-        res_remote_file = set([
-            ('pkg:/[email protected]',
-             'path',
-             'file 820157a2043e3135f342b238129b556aade20347 chash=bfa46fc98d1ca97f1260090797d35a35e76096a3 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=38 pkg.size=18'),
-            ('pkg:/[email protected]',
-             '820157a2043e3135f342b238129b556aade20347',
-             'file 820157a2043e3135f342b238129b556aade20347 chash=bfa46fc98d1ca97f1260090797d35a35e76096a3 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=38 pkg.size=18')
-        ]) | res_remote_path
-
-        res_remote_url = set([
-            ('pkg:/[email protected]',
-            'http://service.opensolaris.com/xml/pkg/[email protected],5.11-1:20080514I120000Z',
-            'set name=com.sun.service.info_url value=http://service.opensolaris.com/xml/pkg/[email protected],5.11-1:20080514I120000Z')
-        ])
-
-        res_remote_path_extra = set([
-            ('pkg:/[email protected]',
-             'basename',
-             'file 820157a2043e3135f342b238129b556aade20347 chash=bfa46fc98d1ca97f1260090797d35a35e76096a3 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=38 pkg.size=18'),
-            ('pkg:/[email protected]',
-             'path',
-             'file 820157a2043e3135f342b238129b556aade20347 chash=bfa46fc98d1ca97f1260090797d35a35e76096a3 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=38 pkg.size=18'),
-            ('pkg:/[email protected]',
-             '820157a2043e3135f342b238129b556aade20347',
-             'file 820157a2043e3135f342b238129b556aade20347 chash=bfa46fc98d1ca97f1260090797d35a35e76096a3 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=38 pkg.size=18')
-        ])
-
-        res_bad_pkg = set([
-            ('pkg:/[email protected]', 'basename',
-             'dir group=bin mode=0755 owner=root path=badfoo/')
-        ])
-
-        fast_add_after_install = set([
-            "VERSION: 2\n",
-            "[email protected],5.11",
-            "[email protected],5.11"
-        ])
-
-        fast_remove_after_install = set([
-            "VERSION: 2\n",
-        ])
-
-        fast_add_after_first_update = set([
-            "VERSION: 2\n",
-            "[email protected],5.11",
-            "[email protected],5.11",
-            "[email protected],5.11",
-            "[email protected],5.11"
-        ])
-
-        fast_remove_after_first_update = set([
-            "VERSION: 2\n",
-            "[email protected],5.11",
-            "[email protected],5.11"
-        ])
-
-        fast_add_after_second_update = set(["VERSION: 2\n"])
-
-        fast_remove_after_second_update = set(["VERSION: 2\n"])
-
-        debug_features = []
-
-        def setUp(self):
-                for p in self.misc_files:
-                        f = open(p, "w")
-                        # Write the name of the file into the file, so that
-                        # all files have differing contents.
-                        f.write(p + "\n")
-                        f.close()
-                testutils.SingleDepotTestCase.setUp(self,
-                    debug_features=self.debug_features)
-                tp = self.get_test_prefix()
-                self.testdata_dir = os.path.join(tp, "search_results")
-                os.mkdir(self.testdata_dir)
-                self._dir_restore_functions = [self._restore_dir,
-                    self._restore_dir_preserve_hash]
-
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-                for p in self.misc_files:
-                        os.remove(p)
-                shutil.rmtree(self.testdata_dir)
-
-        def _check(self, proposed_answer, correct_answer):
-                if correct_answer == proposed_answer:
-                        return True
-                else:
-                        self.debug("Proposed Answer: " + str(proposed_answer))
-                        self.debug("Correct Answer : " + str(correct_answer))
-                        if isinstance(correct_answer, set) and \
-                            isinstance(proposed_answer, set):
-                                print >> sys.stderr, "Missing: " + \
-                                    str(correct_answer - proposed_answer)
-                                print >> sys.stderr, "Extra  : " + \
-                                    str(proposed_answer - correct_answer)
-                        self.assert_(correct_answer == proposed_answer)
-
-        @staticmethod
-        def _replace_act(act):
-                if act.startswith('set name=pkg.fmri'):
-                        return act.strip().rsplit(":", 1)[0] + ":"
-                else:
-                        return act.strip()
-
-        @staticmethod
-        def _extract_action_from_res(it):
-                return (
-                    (fmri.PkgFmri(str(pkg_name)).get_short_fmri(), piece,
-                    TestApiSearchBasics._replace_act(act))
-                    for query_num, auth, (version, return_type,
-                    (pkg_name, piece, act))
-                    in it
-                )
-
-        @staticmethod
-        def _extract_package_from_res(it):
-                return (
-                    (fmri.PkgFmri(str(pkg_name)).get_short_fmri())
-                    for query_num, auth, (version, return_type, pkg_name)
-                    in it
-                )
-
-        @staticmethod
-        def _get_lines(fp):
-                fh = open(fp, "rb")
-                lines = fh.readlines()
-                fh.close()
-                return lines
-
-        def _search_op(self, api_obj, remote, token, test_value,
-            case_sensitive=False, return_actions=True, num_to_return=None,
-            start_point=None, servers=None):
-                query = [api.Query(token, case_sensitive, return_actions,
-                    num_to_return, start_point)]
-                self._search_op_common(api_obj, remote, query, test_value,
-                    return_actions, servers)
-
-        def _search_op_multi(self, api_obj, remote, tokens, test_value,
-            case_sensitive=False, return_actions=True, num_to_return=None,
-            start_point=None, servers=None):
-                query = [api.Query(token, case_sensitive, return_actions,
-                    num_to_return, start_point) for token in tokens]
-                self._search_op_common(api_obj, remote, query, test_value,
-                    return_actions, servers)
-
-        def _search_op_common(self, api_obj, remote, query, test_value,
-            return_actions, servers):
-                search_func = api_obj.local_search
-                if remote:
-                        search_func = lambda x: api_obj.remote_search(x,
-                            servers=servers)
-                init_time = time.time()
-
-                # servers may not be ready immediately - retry search
-                # operation for 5 seconds
-
-                while (time.time() - init_time) < 5:
-                        try:
-                                res = search_func(query)
-                                if return_actions:
-                                        res = self._extract_action_from_res(res)
-                                else:
-                                        res = self._extract_package_from_res(res)
-                                res = set(res)
-                                break
-                        except api_errors.ProblematicSearchServers, e:
-                                pass
-
-                self._check(set(res), test_value)
-
-        def _search_op_slow(self, api_obj, remote, token, test_value,
-            case_sensitive=False, return_actions=True, num_to_return=None,
-            start_point=None):
-                query = [api.Query(token, case_sensitive, return_actions,
-                    num_to_return, start_point)]
-                self._search_op_slow_common(api_obj, query, test_value,
-                    return_actions)
-
-        def _search_op_slow_multi(self, api_obj, remote, tokens, test_value,
-            case_sensitive=False, return_actions=True, num_to_return=None,
-            start_point=None):
-                query = [api.Query(token, case_sensitive, return_actions,
-                    num_to_return, start_point) for token in tokens]
-                self._search_op_slow_common(api_obj, query, test_value,
-                    return_actions)
-
-        def _search_op_slow_common(self, api_obj, query, test_value,
-            return_actions):
-                search_func = api_obj.local_search
-                tmp = search_func(query)
-                res = []
-                ssu = False
-                try:
-                        for i in tmp:
-                                res.append(i)
-                except api_errors.SlowSearchUsed:
-                        ssu = True
-                self.assert_(ssu)
-                if return_actions:
-                        res = self._extract_action_from_res(res)
-                else:
-                        res = self._extract_package_from_res(res)
-                res = set(res)
-                self._check(set(res), test_value)
-
-        def _run_full_remote_tests(self, api_obj):
-                self._search_op(api_obj, True, "example_pkg",
-                    self.res_remote_pkg)
-                self._search_op(api_obj, True, "example_path",
-                    self.res_remote_path)
-                self._search_op(api_obj, True, "(example_path)",
-                    self.res_remote_path)
-                self._search_op(api_obj, True, "<exam*:::>",
-                    self.res_remote_pkg_ret_pkg, return_actions=False)
-                self._search_op(api_obj, True, "::com.sun.service.info_url:",
-                    self.res_remote_url)
-                self._search_op(api_obj, True, ":::e* AND *path",
-                    self.res_remote_path)
-                self._search_op(api_obj, True, "e* AND *path",
-                    self.res_remote_path)
-                self._search_op(api_obj, True, "<e*>",
-                    self.res_remote_pkg_ret_pkg, return_actions=False)
-                self._search_op(api_obj, True, "<e*> AND <e*>",
-                    self.res_remote_pkg_ret_pkg, return_actions=False)
-                self._search_op(api_obj, True, "<e*> OR <e*>",
-                    self.res_remote_pkg_ret_pkg, return_actions=False)
-                self._search_op(api_obj, True, "<exam:::>",
-                    self.res_remote_pkg_ret_pkg, return_actions=False)
-                self._search_op(api_obj, True, "exam:::e*path",
-                    self.res_remote_path)
-                self._search_op(api_obj, True, "exam:::e*path AND e*:::",
-                    self.res_remote_path)
-                self._search_op(api_obj, True, "e*::: AND exam:::*path",
-                    self.res_remote_path_extra)
-                self._search_op(api_obj, True, "example*",
-                    self.res_remote_wildcard)
-                self._search_op(api_obj, True, "/bin", self.res_remote_bin)
-                self._search_op(api_obj, True, "4851433",
-                    self.res_remote_bug_id)
-                self._search_op(api_obj, True, "<4851433> AND <4725245>",
-                    self.res_remote_pkg_ret_pkg, return_actions=False)
-                self._search_op(api_obj, True, "4851433 AND 4725245",
-                    self.res_remote_bug_id)
-                self._search_op(api_obj, True,
-                    "4851433 AND 4725245 OR example_path",
-                    self.res_remote_bug_id)
-                self._search_op(api_obj, True,
-                    "4851433 AND (4725245 OR example_path)",
-                    self.res_remote_bug_id)
-                self._search_op(api_obj, True,
-                    "(4851433 AND 4725245) OR example_path",
-                    self.res_remote_bug_id | self.res_remote_path)
-                self._search_op(api_obj, True, "4851433 OR 4725245",
-                    self.res_remote_bug_id | self.res_remote_bug_id_4725245)
-                self._search_op(api_obj, True, "6556919",
-                    self.res_remote_inc_changes)
-                self._search_op(api_obj, True, "6556?19",
-                    self.res_remote_inc_changes)
-                self._search_op(api_obj, True, "42",
-                    self.res_remote_random_test)
-                self._search_op(api_obj, True, "79",
-                    self.res_remote_random_test_79)
-                self._search_op(api_obj, True, "separator",
-                    self.res_remote_keywords)
-                self._search_op(api_obj, True, "\"sort 0x86\"",
-                    self.res_remote_keywords)
-                self._search_op(api_obj, True, "*example*",
-                    self.res_remote_glob)
-                self._search_op(api_obj, True, "fooo", self.res_remote_foo)
-                self._search_op(api_obj, True, "fo*", self.res_remote_foo)
-                self._search_op(api_obj, True, "bar", self.res_remote_foo)
-                self._search_op(api_obj, True, "openssl",
-                    self.res_remote_openssl)
-                self._search_op(api_obj, True, "OPENSSL",
-                    self.res_remote_openssl)
-                self._search_op(api_obj, True, "OpEnSsL",
-                    self.res_remote_openssl)
-                # Test for bug 11235, case insensitive phrase search, and bug
-                # 11354, mangled fields during phrase search.
-                self._search_op(api_obj, True, "'OpEnSsL'",
-                    self.res_remote_openssl)
-                self._search_op(api_obj, True, "OpEnS*",
-                    self.res_remote_openssl)
-
-                # These tests are included because a specific bug
-                # was found during development. This prevents regression back
-                # to that bug. Exit status of 1 is expected because the
-                # token isn't in the packages.
-                self._search_op(api_obj, True, "a_non_existent_token", set())
-
-                self._search_op(api_obj, True, "42 AND 4641790", set())
-                self.assertRaises(api_errors.BooleanQueryException,
-                    self._search_op, api_obj, True, "<e*> AND e*", set())
-                self.assertRaises(api_errors.BooleanQueryException,
-                    self._search_op, api_obj, True, "e* AND <e*>", set())
-                self.assertRaises(api_errors.BooleanQueryException,
-                    self._search_op, api_obj, True, "<e*> OR e*", set())
-                self.assertRaises(api_errors.BooleanQueryException,
-                    self._search_op, api_obj, True, "e* OR <e*>", set())
-
-        def _run_remote_tests(self, api_obj):
-                self._search_op(api_obj, True, "example_pkg",
-                    self.res_remote_pkg)
-                self._search_op(api_obj, True, "example_path",
-                    self.res_remote_path)
-                self._search_op(api_obj, True, "::com.sun.service.info_url:",
-                    self.res_remote_url)
-                self._search_op(api_obj, True, "<e*>",
-                    self.res_remote_pkg_ret_pkg, return_actions=False)
-                self._search_op(api_obj, True, "<exam:::>",
-                    self.res_remote_pkg_ret_pkg, return_actions=False)
-                self._search_op(api_obj, True, "exam:::e*path",
-                    self.res_remote_path)
-                self._search_op(api_obj, True, "example*",
-                    self.res_remote_wildcard)
-                self._search_op(api_obj, True, "/bin", self.res_remote_bin)
-                self._search_op(api_obj, True, "4851433",
-                    self.res_remote_bug_id)
-                self._search_op(api_obj, True, "4725245",
-                    self.res_remote_bug_id_4725245)
-                self._search_op(api_obj, True, "6556919",
-                    self.res_remote_inc_changes)
-                self._search_op(api_obj, True, "42",
-                    self.res_remote_random_test)
-                self._search_op(api_obj, True, "79",
-                    self.res_remote_random_test_79)
-                self._search_op(api_obj, True, "separator",
-                    self.res_remote_keywords)
-                self._search_op(api_obj, True, "\"sort 0x86\"",
-                    self.res_remote_keywords)
-                self._search_op(api_obj, True, "*example*",
-                    self.res_remote_glob)
-                self._search_op(api_obj, True, "fooo", self.res_remote_foo)
-                self._search_op(api_obj, True, "bar", self.res_remote_foo)
-                self._search_op(api_obj, True, "OpEnSsL",
-                    self.res_remote_openssl)
-
-                # These tests are included because a specific bug
-                # was found during development. This prevents regression back
-                # to that bug.
-                self._search_op(api_obj, True, "a_non_existent_token", set())
-
-        def _run_full_local_tests(self, api_obj):
-                outfile = os.path.join(self.testdata_dir, "res")
-
-                # This finds something because the client side
-                # manifest has had the name of the package inserted
-                # into it.
-
-                self._search_op(api_obj, False, "example_pkg",
-                    self.res_local_pkg)
-                self._search_op(api_obj, False, "example_path",
-                    self.res_local_path)
-                self._search_op(api_obj, False, "(example_path)",
-                    self.res_local_path)
-                self._search_op(api_obj, False, "<exam*:::>",
-                    self.res_local_pkg_ret_pkg, return_actions=False)
-                self._search_op(api_obj, False, "::com.sun.service.info_url:",
-                    self.res_remote_url)
-                self._search_op(api_obj, False, ":::e* AND *path",
-                    self.res_local_path)
-                self._search_op(api_obj, False, "e* AND *path",
-                    self.res_local_path)
-                self._search_op(api_obj, False, "<e*>",
-                    self.res_local_pkg_ret_pkg, return_actions=False)
-                self._search_op(api_obj, False, "<e*> AND <e*>",
-                    self.res_local_pkg_ret_pkg, return_actions=False)
-                self._search_op(api_obj, False, "<e*> OR <e*>",
-                    self.res_local_pkg_ret_pkg, return_actions=False)
-                self._search_op(api_obj, False, "<exam:::>",
-                    self.res_local_pkg_ret_pkg, return_actions=False)
-                self._search_op(api_obj, False, "exam:::e*path",
-                    self.res_local_path)
-                self._search_op(api_obj, False, "exam:::e*path AND e*:::",
-                    self.res_local_path)
-                self._search_op(api_obj, False, "e*::: AND exam:::*path",
-                    self.res_remote_path_extra)
-                self._search_op(api_obj, False, "example*",
-                    self.res_local_wildcard)
-                self._search_op(api_obj, False, "/bin", self.res_local_bin)
-                self._search_op(api_obj, False, "4851433",
-                    self.res_local_bug_id)
-                self._search_op(api_obj, False, "<4851433> AND <4725245>",
-                    self.res_local_pkg_ret_pkg, return_actions=False)
-                self._search_op(api_obj, False, "4851433 AND 4725245",
-                    self.res_local_bug_id)
-                self._search_op(api_obj, False,
-                    "4851433 AND 4725245 OR example_path",
-                    self.res_local_bug_id)
-                self._search_op(api_obj, False,
-                    "4851433 AND (4725245 OR example_path)",
-                    self.res_local_bug_id)
-                self._search_op(api_obj, False,
-                    "(4851433 AND 4725245) OR example_path",
-                    self.res_local_bug_id | self.res_local_path)
-                self._search_op(api_obj, False, "4851433 OR 4725245",
-                    self.res_local_bug_id | self.res_remote_bug_id_4725245)
-                self._search_op(api_obj, False, "6556919",
-                    self.res_local_inc_changes)
-                self._search_op(api_obj, False, "65569??",
-                    self.res_local_inc_changes)
-                self._search_op(api_obj, False, "42",
-                    self.res_local_random_test)
-                self._search_op(api_obj, False, "79",
-                    self.res_remote_random_test_79)
-                self._search_op(api_obj, False, "separator",
-                    self.res_local_keywords)
-                self._search_op(api_obj, False, "\"sort 0x86\"",
-                    self.res_remote_keywords)
-                self._search_op(api_obj, False, "*example*",
-                    self.res_local_glob)
-                self._search_op(api_obj, False, "fooo", self.res_local_foo)
-                self._search_op(api_obj, False, "fo*", self.res_local_foo)
-                self._search_op(api_obj, False, "bar", self.res_local_foo)
-                self._search_op(api_obj, False, "openssl",
-                    self.res_local_openssl)
-                self._search_op(api_obj, False, "OPENSSL",
-                    self.res_local_openssl)
-                self._search_op(api_obj, False, "OpEnSsL",
-                    self.res_local_openssl)
-                # Test for bug 11235, case insensitive phrase search, and bug
-                # 11354, mangled fields during phrase search.
-                self._search_op(api_obj, False, "'OpEnSsL'",
-                    self.res_remote_openssl)
-                self._search_op(api_obj, False, "OpEnS*",
-                    self.res_local_openssl)
-                # These tests are included because a specific bug
-                # was found during development. These tests prevent regression
-                # back to that bug. Exit status of 1 is expected because the
-                # token isn't in the packages.
-                self._search_op(api_obj, False, "a_non_existent_token", set())
-                self._search_op(api_obj, False, "42 AND 4641790", set())
-                self.assertRaises(api_errors.BooleanQueryException,
-                    self._search_op, api_obj, False, "<e*> AND e*", set())
-                self.assertRaises(api_errors.BooleanQueryException,
-                    self._search_op, api_obj, False, "e* AND <e*>", set())
-                self.assertRaises(api_errors.BooleanQueryException,
-                    self._search_op, api_obj, False, "<e*> OR e*", set())
-                self.assertRaises(api_errors.BooleanQueryException,
-                    self._search_op, api_obj, False, "e* OR <e*>", set())
-
-        def _run_local_tests(self, api_obj):
-                outfile = os.path.join(self.testdata_dir, "res")
-
-                # This finds something because the client side
-                # manifest has had the name of the package inserted
-                # into it.
-
-                self._search_op(api_obj, False, "example_pkg",
-                    self.res_local_pkg)
-                self._search_op(api_obj, False, "example_path",
-                    self.res_local_path)
-                self._search_op(api_obj, False, "::com.sun.service.info_url:",
-                    self.res_remote_url)
-                self._search_op(api_obj, False, "<e*>",
-                    self.res_local_pkg_ret_pkg, return_actions=False)
-                self._search_op(api_obj, False, "<exam:::>",
-                    self.res_local_pkg_ret_pkg, return_actions=False)
-                self._search_op(api_obj, False, "exam:::e*path",
-                    self.res_local_path)
-                self._search_op(api_obj, False, "example*",
-                    self.res_local_wildcard)
-                self._search_op(api_obj, False, "/bin", self.res_local_bin)
-                self._search_op(api_obj, False, "4851433",
-                    self.res_local_bug_id)
-                self._search_op(api_obj, False, "4725245",
-                    self.res_remote_bug_id_4725245)
-                self._search_op(api_obj, False, "6556919",
-                    self.res_local_inc_changes)
-                self._search_op(api_obj, False, "42",
-                    self.res_local_random_test)
-                self._search_op(api_obj, False, "79",
-                    self.res_remote_random_test_79)
-                self._search_op(api_obj, False, "separator",
-                    self.res_local_keywords)
-                self._search_op(api_obj, False, "\"sort 0x86\"",
-                    self.res_remote_keywords)
-                self._search_op(api_obj, False, "*example*",
-                    self.res_local_glob)
-                self._search_op(api_obj, False, "fooo", self.res_local_foo)
-                self._search_op(api_obj, False, "bar", self.res_local_foo)
-                self._search_op(api_obj, False, "OpEnSsL",
-                    self.res_local_openssl)
-                # These tests are included because a specific bug
-                # was found during development. These tests prevent regression
-                # back to that bug.
-                self._search_op(api_obj, False, "a_non_existent_token", set())
-
-        def _run_degraded_local_tests(self, api_obj):
-                outfile = os.path.join(self.testdata_dir, "res")
-
-                # This finds something because the client side
-                # manifest has had the name of the package inserted
-                # into it.
-
-                self._search_op_slow(api_obj, False, "example_pkg",
-                    self.res_local_pkg)
-                self._search_op_slow(api_obj, False, "example_path",
-                    self.res_local_path)
-                self._search_op_slow(api_obj, False, "(example_path)",
-                    self.res_local_path)
-                self._search_op_slow(api_obj, False, "<exam*:::>",
-                    self.res_local_pkg_ret_pkg, return_actions=False)
-                self._search_op_slow(api_obj, False,
-                    "::com.sun.service.info_url:",
-                    self.res_remote_url)
-                self._search_op_slow(api_obj, False, ":::e* AND *path",
-                    self.res_local_path)
-                self._search_op_slow(api_obj, False, "e* AND *path",
-                    self.res_local_path)
-                self._search_op_slow(api_obj, False, "<e*>",
-                    self.res_local_pkg_ret_pkg, return_actions=False)
-                self._search_op_slow(api_obj, False, "<e*> AND <e*>",
-                    self.res_local_pkg_ret_pkg, return_actions=False)
-                self._search_op_slow(api_obj, False, "<e*> OR <e*>",
-                    self.res_local_pkg_ret_pkg, return_actions=False)
-                self._search_op_slow(api_obj, False, "<exam:::>",
-                    self.res_local_pkg_ret_pkg, return_actions=False)
-                self._search_op_slow(api_obj, False, "exam:::e*path",
-                    self.res_local_path)
-                self._search_op_slow(api_obj, False, "exam:::e*path AND e*:::",
-                    self.res_local_path)
-                self._search_op_slow(api_obj, False, "e*::: AND exam:::*path",
-                    self.res_remote_path_extra)
-                self._search_op_slow(api_obj, False, "example*",
-                    self.res_local_wildcard)
-                self._search_op_slow(api_obj, False, "/bin", self.res_local_bin)
-                self._search_op_slow(api_obj, False, "4851433",
-                    self.res_local_bug_id)
-                self._search_op_slow(api_obj, False, "<4851433> AND <4725245>",
-                    self.res_local_pkg_ret_pkg, return_actions=False)
-                self._search_op_slow(api_obj, False, "4851433 AND 4725245",
-                    self.res_local_bug_id)
-                self._search_op_slow(api_obj, False,
-                    "4851433 AND 4725245 OR example_path",
-                    self.res_local_bug_id)
-                self._search_op_slow(api_obj, False,
-                    "4851433 AND (4725245 OR example_path)",
-                    self.res_local_bug_id)
-                self._search_op_slow(api_obj, False,
-                    "(4851433 AND 4725245) OR example_path",
-                    self.res_local_bug_id | self.res_local_path)
-                self._search_op_slow(api_obj, False, "4851433 OR 4725245",
-                    self.res_local_bug_id | self.res_remote_bug_id_4725245)
-                self._search_op_slow(api_obj, False, "6556919",
-                    self.res_local_inc_changes)
-                self._search_op_slow(api_obj, False, "65569??",
-                    self.res_local_inc_changes)
-                self._search_op_slow(api_obj, False, "42",
-                    self.res_local_random_test)
-                self._search_op_slow(api_obj, False, "79",
-                    self.res_remote_random_test_79)
-                self._search_op_slow(api_obj, False, "separator",
-                    self.res_local_keywords)
-                self._search_op_slow(api_obj, False, "\"sort 0x86\"",
-                    self.res_remote_keywords)
-                self._search_op_slow(api_obj, False, "*example*",
-                    self.res_local_glob)
-                self._search_op_slow(api_obj, False, "fooo", self.res_local_foo)
-                self._search_op_slow(api_obj, False, "fo*", self.res_local_foo)
-                self._search_op_slow(api_obj, False, "bar", self.res_local_foo)
-                self._search_op_slow(api_obj, False, "openssl",
-                    self.res_local_openssl)
-                self._search_op_slow(api_obj, False, "OPENSSL",
-                    self.res_local_openssl)
-                self._search_op_slow(api_obj, False, "OpEnSsL",
-                    self.res_local_openssl)
-                self._search_op_slow(api_obj, False, "OpEnS*",
-                    self.res_local_openssl)
-                # These tests are included because a specific bug
-                # was found during development. These tests prevent regression
-                # back to that bug. Exit status of 1 is expected because the
-                # token isn't in the packages.
-                self._search_op_slow(api_obj, False, "a_non_existent_token",
-                    set())
-
-        def _run_remove_root_search(self, search_func, remote, api_obj, ip):
-                search_func(api_obj, remote, [ip + "example_pkg"], set())
-                search_func(api_obj, remote, [ip + "bin/example_path"],
-                    self.res_remote_path_of_example_path)
-                search_func(api_obj, remote, ["(%sbin/example_path)" % ip],
-                    self.res_remote_path_of_example_path)
-                search_func(api_obj, remote, ["<%sexam*:::>" % ip],
-                    set(), return_actions=False)
-                search_func(api_obj, remote,
-                    ["::%scom.sun.service.info_url:" % ip], set())
-                search_func(api_obj, remote,
-                    ["%sbin/e* AND %s*path" % (ip, ip)],
-                    self.res_remote_path_of_example_path)
-                search_func(api_obj, remote,
-                    ["(4851433 AND 4725245) OR :file::%sbin/example_path" % ip],
-                    self.res_remote_bug_id |
-                    self.res_remote_path_of_example_path)
-                search_func(api_obj, remote,
-                    [":::%sbin/example_path OR (4851433 AND 4725245)" % ip],
-                    self.res_remote_bug_id |
-                    self.res_remote_path_of_example_path)
-                search_func(api_obj, remote,
-                    ["%sbin/example_path OR %sbin/example_path" % (ip, ip)],
-                    self.res_remote_path_of_example_path)
-                search_func(api_obj, remote,
-                    ["<::path:%sbin/example_path> OR <(a AND b)>" % ip],
-                    self.res_remote_pkg_ret_pkg, return_actions=False)
-                search_func(api_obj, remote,
-                    ["<(a AND b)> OR <%sbin/example_path>" % ip],
-                    self.res_remote_pkg_ret_pkg, return_actions=False)
-                # The tests below here are for testing that multiple queries
-                # to search return the results from both queries (bug 10365)
-                search_func(api_obj, remote,
-                    ["<(a AND b)>",  "example_path"],
-                    self.res_remote_path)
-                search_func(api_obj, remote,
-                    ["example_path", "<(a AND b)>"],
-                    self.res_remote_path)
-                search_func(api_obj, remote,
-                    [":::%sbin/example_path" % ip, "(4851433 AND 4725245)"],
-                    self.res_remote_bug_id |
-                    self.res_remote_path_of_example_path)
-                search_func(api_obj, remote,
-                    ["(4851433 AND 4725245)", ":::%sbin/example_path" % ip],
-                    self.res_remote_bug_id |
-                    self.res_remote_path_of_example_path)
-
-        def _run_local_tests_example11_installed(self, api_obj):
-                outfile = os.path.join(self.testdata_dir, "res")
-
-                # This finds something because the client side
-                # manifest has had the name of the package inserted
-                # into it.
-
-                self._search_op(api_obj, False, "example_pkg",
-                    self.res_local_pkg_example11)
-                self._search_op(api_obj, False, "example_path", set())
-                self._search_op(api_obj, False, "example_path11",
-                    self.res_local_path_example11)
-                self._search_op(api_obj, False, "example*",
-                    self.res_local_wildcard_example11)
-                self._search_op(api_obj, False, "/bin",
-                    self.res_local_bin_example11)
-
-        def _run_local_empty_tests(self, api_obj):
-                self._search_op(api_obj, False, "example_pkg", set())
-                self._search_op(api_obj, False, "example_path", set())
-                self._search_op(api_obj, False, "example*", set())
-                self._search_op(api_obj, False, "/bin", set())
-
-        def _run_remote_empty_tests(self, api_obj):
-                self._search_op(api_obj, True, "example_pkg", set())
-                self._search_op(api_obj, True, "example_path", set())
-                self._search_op(api_obj, True, "example*", set())
-                self._search_op(api_obj, True, "/bin", set())
-                self._search_op(api_obj, True, "*unique*", set())
-
-        @staticmethod
-        def _restore_dir(index_dir, index_dir_tmp):
-                shutil.rmtree(index_dir)
-                shutil.move(index_dir_tmp, index_dir)
-
-        @staticmethod
-        def _restore_dir_preserve_hash(index_dir, index_dir_tmp):
-                tmp_file = "full_fmri_list.hash"
-                portable.remove(os.path.join(index_dir_tmp, tmp_file))
-                shutil.move(os.path.join(index_dir, tmp_file),
-                            index_dir_tmp)
-                fh = open(os.path.join(index_dir_tmp, ss.MAIN_FILE), "r")
-                fh.seek(0)
-                fh.seek(9)
-                ver = fh.read(1)
-                fh.close()
-                fh = open(os.path.join(index_dir_tmp, tmp_file), "r+")
-                fh.seek(0)
-                fh.seek(9)
-                # Overwrite the existing version number.
-                # By definition, the version 0 is never used.
-                fh.write("%s" % ver)
-                shutil.rmtree(index_dir)
-                shutil.move(index_dir_tmp, index_dir)
-
-        def _get_index_dirs(self):
-                index_dir = os.path.join(self.img_path, "var","pkg","index")
-                index_dir_tmp = index_dir + "TMP"
-                return index_dir, index_dir_tmp
-
-        @staticmethod
-        def _overwrite_version_number(file_path):
-                fh = open(file_path, "r+")
-                fh.seek(0)
-                fh.seek(9)
-                # Overwrite the existing version number.
-                # By definition, the version 0 is never used.
-                fh.write("0")
-                fh.close()
-
-        @staticmethod
-        def _overwrite_on_disk_format_version_number(file_path):
-                fh = open(file_path, "r+")
-                fh.seek(0)
-                fh.seek(16)
-                # Overwrite the existing version number.
-                # By definition, the version 0 is never used.
-                fh.write("9")
-                fh.close()
-
-        @staticmethod
-        def _overwrite_on_disk_format_version_number_with_letter(file_path):
-                fh = open(file_path, "r+")
-                fh.seek(0)
-                fh.seek(16)
-                # Overwrite the existing version number.
-                # By definition, the version 0 is never used.
-                fh.write("a")
-                fh.close()
-
-        @staticmethod
-        def _replace_on_disk_format_version(dir):
-                file_path = os.path.join(dir, ss.BYTE_OFFSET_FILE)
-                fh = open(file_path, "r")
-                lst = fh.readlines()
-                fh.close()
-                fh = open(file_path, "w")
-                fh.write(lst[0])
-                for l in lst[2:]:
-                        fh.write(l)
-                fh.close()
-
-        @staticmethod
-        def _overwrite_hash(ffh_path):
-                fd, tmp = tempfile.mkstemp()
-                portable.copyfile(ffh_path, tmp)
-                fh = open(tmp, "r+")
-                fh.seek(0)
-                fh.seek(20)
-                fh.write("*")
-                fh.close()
-                portable.rename(tmp, ffh_path)
-
-        def _check_no_index(self):
-                ind_dir, ind_dir_tmp = self._get_index_dirs()
-                if os.listdir(ind_dir):
-                        self.assert_(0)
-                if os.path.exists(ind_dir_tmp):
-                        self.assert_(0)
-
-        @staticmethod
-        def _do_install(api_obj, pkg_list, **kwargs):
-                api_obj.plan_install(pkg_list, **kwargs)
-                TestApiSearchBasics._do_finish(api_obj)
-
-        @staticmethod
-        def _do_uninstall(api_obj, pkg_list, **kwargs):
-                api_obj.plan_uninstall(pkg_list, False, **kwargs)
-                TestApiSearchBasics._do_finish(api_obj)
-
-        @staticmethod
-        def _do_image_update(api_obj, **kwargs):
-                api_obj.plan_update_all(sys.argv[0], **kwargs)
-                TestApiSearchBasics._do_finish(api_obj)
-
-        @staticmethod
-        def _do_finish(api_obj):
-                api_obj.prepare()
-                api_obj.execute_plan()
-                api_obj.reset()
-
-        @staticmethod
-        def validateAssertRaises(ex_type, validate_func, func, *args, **kwargs):
-                try:
-                        func(*args, **kwargs)
-                except ex_type, e:
-                        validate_func(e)
-                else:
-                        raise RuntimeError("Didn't raise expected exception.")
-
-        @staticmethod
-        def _check_err(e, expected_str, expected_code):
-                err = e.read()
-                if expected_code != e.code:
-                        raise RuntimeError("Got wrong code, expected %s got "
-                            "%s" % (expected_code, e.code))
-                if expected_str not in err:
-                        raise RuntimeError("Got unexpected error message of:\n"
-                            "%s" % err)
-
-
-class TestApiSearchBasicsPersistentDepot(TestApiSearchBasics):
-        # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
-
-        def __init__(self, *args, **kwargs):
-                TestApiSearchBasics.__init__(self, *args, **kwargs)
-                self.sent_pkgs = set()
-
-        def pkgsend_bulk(self, durl, pkg, optional=True):
-                if pkg not in self.sent_pkgs or optional == False:
-                        self.sent_pkgs.add(pkg)
-                        TestApiSearchBasics.pkgsend_bulk(self, durl, pkg)
-
-        def test_010_remote(self):
-                """Test remote search."""
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-                time.sleep(1)
-                # This should be a full test to test all functionality.
-                self._run_full_remote_tests(api_obj)
-                self._search_op(api_obj, True, ":file::", self.res_remote_file)
-
-        def test_020_local_0(self):
-                """Install one package, and run the search suite."""
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                self._do_install(api_obj, ["example_pkg"])
-
-                self._run_full_local_tests(api_obj)
-
-        def test_030_degraded_local(self):
-                """Install one package, and run the search suite."""
-                durl = self.dc.get_depot_url()
-                fmris = self.pkgsend_bulk(durl, self.example_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                self._do_install(api_obj, ["example_pkg"])
-
-                index_dir = os.path.join(self.img_path, "var","pkg","index")
-                shutil.rmtree(index_dir)
-
-                self._run_degraded_local_tests(api_obj)
-
-        def test_040_repeated_install_uninstall(self):
-                """Install and uninstall a package. Checking search both
-                after each change to the image."""
-                # During development, the index could become corrupted by
-                # repeated installing and uninstalling a package. This
-                # tests if that has been fixed.
-                repeat = 3
-
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                self._do_install(api_obj, ["example_pkg"])
-                self._do_uninstall(api_obj, ["example_pkg"])
-
-                for i in range(1, repeat):
-                        self._do_install(api_obj, ["example_pkg"])
-                        self._run_local_tests(api_obj)
-                        self._do_uninstall(api_obj, ["example_pkg"])
-                        api_obj.reset()
-                        self._run_local_empty_tests(api_obj)
-
-        def test_050_local_case_sensitive(self):
-                """Test local case sensitive search"""
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                self._do_install(api_obj, ["example_pkg"])
-                self._search_op(api_obj, False, "fooo", set(), True)
-                self._search_op(api_obj, False, "fo*", set(), True)
-                self._search_op(api_obj, False, "bar", set(), True)
-                self._search_op(api_obj, False, "FOOO", self.res_local_foo,
-                    True)
-                self._search_op(api_obj, False, "bAr", self.res_local_foo, True)
-
-        def test_060_missing_files(self):
-                """Test to check for stack trace when files missing.
-                Bug 2753"""
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.example_pkg10)
-
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-                self._do_install(api_obj, ["example_pkg"])
-
-                index_dir = os.path.join(self.img_path, "var","pkg","index")
-
-                first = True
-
-                for d in query_parser.TermQuery._global_data_dict.values():
-                        orig_fn = d.get_file_name()
-                        orig_path = os.path.join(index_dir, orig_fn)
-                        dest_fn = orig_fn + "TMP"
-                        dest_path = os.path.join(index_dir, dest_fn)
-                        portable.rename(orig_path, dest_path)
-                        self.assertRaises(api_errors.InconsistentIndexException,
-                            self._search_op, api_obj, False,
-                            "exam:::example_pkg", [])
-                        if first:
-                                # Run the shell version once to check that no
-                                # stack trace happens.
-                                self.pkg("search -l 'exam:::example_pkg'",
-                                    exit=1)
-                                first = False
-                        portable.rename(dest_path, orig_path)
-                        self._search_op(api_obj, False, "exam:::example_pkg",
-                            self.res_local_pkg)
-
-        def test_070_mismatched_versions(self):
-                """Test to check for stack trace when files missing.
-                Bug 2753"""
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-                self._do_install(api_obj, ["example_pkg"])
-
-                index_dir = os.path.join(self.img_path, "var","pkg","index")
-
-                first = True
-
-                for d in query_parser.TermQuery._global_data_dict.values():
-                        orig_fn = d.get_file_name()
-                        orig_path = os.path.join(index_dir, orig_fn)
-                        dest_fn = orig_fn + "TMP"
-                        dest_path = os.path.join(index_dir, dest_fn)
-                        shutil.copy(orig_path, dest_path)
-                        self._overwrite_version_number(orig_path)
-                        api_obj.reset()
-                        self.assertRaises(api_errors.InconsistentIndexException,
-                            self._search_op, api_obj, False,
-                            "exam:::example_pkg", [])
-                        if first:
-                                # Run the shell version once to check that no
-                                # stack trace happens.
-                                self.pkg("search -l 'exam:::example_pkg'",
-                                    exit=1)
-                                first = False
-                        portable.rename(dest_path, orig_path)
-                        self._search_op(api_obj, False, "example_pkg",
-                            self.res_local_pkg)
-                        self._overwrite_version_number(orig_path)
-                        self.assertRaises(
-                            api_errors.WrapSuccessfulIndexingException,
-                            self._do_uninstall, api_obj, ["example_pkg"])
-                        api_obj.reset()
-                        self._search_op(api_obj, False, "example_pkg", set())
-                        self._overwrite_version_number(orig_path)
-                        self.assertRaises(
-                            api_errors.WrapSuccessfulIndexingException,
-                            self._do_install, api_obj, ["example_pkg"])
-                        api_obj.reset()
-                        self._search_op(api_obj, False, "example_pkg",
-                            self.res_local_pkg)
-
-                ffh = ss.IndexStoreSetHash(ss.FULL_FMRI_HASH_FILE)
-                ffh_path = os.path.join(index_dir, ffh.get_file_name())
-                dest_fh, dest_path = tempfile.mkstemp()
-                shutil.copy(ffh_path, dest_path)
-                self._overwrite_hash(ffh_path)
-                self.assertRaises(api_errors.IncorrectIndexFileHash,
-                    self._search_op, api_obj, False, "example_pkg", set())
-                # Run the shell version of the test to check for a stack trace.
-                self.pkg("search -l 'exam:::example_pkg'", exit=1)
-                portable.rename(dest_path, ffh_path)
-                self._search_op(api_obj, False, "example_pkg",
-                    self.res_local_pkg)
-                self._overwrite_hash(ffh_path)
-                self.assertRaises(api_errors.WrapSuccessfulIndexingException,
-                    self._do_uninstall, api_obj, ["example_pkg"])
-                self._search_op(api_obj, False, "example_pkg", set())
-
-        def test_080_weird_patterns(self):
-                """Test strange patterns to ensure they're handled correctly"""
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                self._search_op(api_obj, True, "[*]", self.res_remote_weird)
-                self._search_op(api_obj, True, "[?]", self.res_remote_weird)
-                self._search_op(api_obj, True, "[[]", self.res_remote_weird)
-                self._search_op(api_obj, True, "[]]", self.res_remote_weird)
-                self._search_op(api_obj, True, "FO[O]O", self.res_remote_foo)
-                self._search_op(api_obj, True, "FO[?O]O", self.res_remote_foo)
-                self._search_op(api_obj, True, "FO[*O]O", self.res_remote_foo)
-                self._search_op(api_obj, True, "FO[]O]O", self.res_remote_foo)
-
-        def test_090_bug_7660(self):
-                """Test that installing a package doesn't prevent searching on
-                package names from working on previously installed packages."""
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.pkgsend_bulk(durl, self.fat_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                tmp_dir = os.path.join(self.img_path, "var", "pkg", "index",
-                    "TMP")
-                self._do_install(api_obj, ["example_pkg"])
-                api_obj.rebuild_search_index()
-                self._do_install(api_obj, ["fat"])
-                self.assert_(not os.path.exists(tmp_dir))
-                self._run_local_tests(api_obj)
-
-        def test_100_bug_6712_i386(self):
-                """Install one package, and run the search suite."""
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.fat_pkg10)
-
-                self.image_create(durl,
-                    additional_args="--variant variant.arch=i386")
-
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                remote = True
-
-                self._search_op(api_obj, remote, "fat:::*",
-                    self.res_remote_fat10_star)
-                self._do_install(api_obj, ["fat"])
-                remote = False
-                self._search_op(api_obj, remote, "fat:::*",
-                    self.res_local_fat10_i386_star)
-
-        def test_110_bug_6712_sparc(self):
-                """Install one package, and run the search suite."""
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.fat_pkg10)
-
-                self.image_create(durl,
-                    additional_args="--variant variant.arch=sparc")
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                remote = True
-
-                self._search_op(api_obj, remote, "fat:::*",
-                    self.res_remote_fat10_star)
-                self._do_install(api_obj, ["fat"])
-                remote = False
-                self._search_op(api_obj, remote, "fat:::*",
-                    self.res_local_fat10_sparc_star)
-
-        def test_120_bug_3046(self):
-                """Checks if directories ending in / break the indexer."""
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.bad_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                self._search_op(api_obj, True, "foo", set())
-                self._search_op(api_obj, True, "/", set())
-
-        def test_130_bug_1059(self):
-                """Checks whether the fallback of removing the image root works.
-                Also tests whether multiple queries submitted via the api work.
-                """
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                ip = self.get_img_path()
-                if not ip.endswith("/"):
-                        ip += "/"
-
-                # Do remote searches
-                self._run_remove_root_search(self._search_op_multi, True,
-                    api_obj, ip)
-
-                self._do_install(api_obj, ["example_pkg"])
-                # Do local searches
-                self._run_remove_root_search(self._search_op_multi, False,
-                    api_obj, ip)
-
-                index_dir = os.path.join(self.img_path, "var","pkg","index")
-                shutil.rmtree(index_dir)
-                # Do slow local searches
-                self._run_remove_root_search(self._search_op_slow_multi, False,
-                    api_obj, ip)
-
-        def test_bug_2849(self):
-                """Checks if things with spaces break the indexer."""
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.space_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                self._do_install(api_obj, ["space_pkg"])
-                time.sleep(1)
-
-                self.pkgsend_bulk(durl, self.space_pkg10, optional=False)
-                api_obj.refresh(immediate=True)
-
-                self._do_install(api_obj, ["space_pkg"])
-
-                remote = False
-                self._search_op(api_obj, remote, 'with', set())
-                self._search_op(api_obj, remote, 'with*',
-                    self.res_space_with_star)
-                self._search_op(api_obj, remote, '*space',
-                    self.res_space_space_star)
-                self._search_op(api_obj, remote, 'space', set())
-                self._search_op(api_obj, remote, 'unique_dir',
-                    self.res_space_unique)
-                remote = True
-                self._search_op(api_obj, remote, 'with', set())
-                self._search_op(api_obj, remote, 'with*',
-                    self.res_space_with_star)
-                self._search_op(api_obj, remote, '*space',
-                    self.res_space_space_star)
-                self._search_op(api_obj, remote, 'space', set())
-                time.sleep(1)
-                self.pkgsend_bulk(durl, self.space_pkg10, optional=False)
-                # Need to add install of subsequent package and
-                # local side search as well as remote
-                self._search_op(api_obj, remote, 'with', set())
-                self._search_op(api_obj, remote, 'with*',
-                    self.res_space_with_star)
-                self._search_op(api_obj, remote, '*space',
-                    self.res_space_space_star)
-                self._search_op(api_obj, remote, 'space', set())
-                self._search_op(api_obj, remote, 'unique_dir',
-                    self.res_space_unique)
-
-        def test_bug_2863(self):
-                """Check that disabling indexing works as expected"""
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                self._check_no_index()
-                self._do_install(api_obj, ["example_pkg"], update_index=False)
-                self._check_no_index()
-                api_obj.rebuild_search_index()
-                self._run_local_tests(api_obj)
-                self._do_uninstall(api_obj, ["example_pkg"], update_index=False)
-                # Running empty test because search will notice the index
-                # does not match the installed packages and complain.
-                self.assertRaises(api_errors.IncorrectIndexFileHash,
-                    self._search_op, api_obj, False, "example_pkg", set())
-                api_obj.rebuild_search_index()
-                self._run_local_empty_tests(api_obj)
-                self._do_install(api_obj, ["example_pkg"])
-                self._run_local_tests(api_obj)
-                self.pkgsend_bulk(durl, self.example_pkg11)
-                api_obj.refresh(immediate=True)
-                self._do_image_update(api_obj, update_index=False)
-                # Running empty test because search will notice the index
-                # does not match the installed packages and complain.
-                self.assertRaises(api_errors.IncorrectIndexFileHash,
-                    self._search_op, api_obj, False, "example_pkg", set())
-                api_obj.rebuild_search_index()
-                self._run_local_tests_example11_installed(api_obj)
-                self._do_uninstall(api_obj, ["example_pkg"], update_index=False)
-                # Running empty test because search will notice the index
-                # does not match the installed packages and complain.
-                self.assertRaises(api_errors.IncorrectIndexFileHash,
-                    self._search_op, api_obj, False, "example_pkg", set())
-                api_obj.rebuild_search_index()
-                self._run_local_empty_tests(api_obj)
-
-        def test_bug_2989_1(self):
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.example_pkg10)
-
-                for f in self._dir_restore_functions:
-                        self.image_create(durl)
-                        progresstracker = progress.NullProgressTracker()
-                        api_obj = api.ImageInterface(self.get_img_path(),
-                            API_VERSION, progresstracker, lambda x: False,
-                            PKG_CLIENT_NAME)
-                        api_obj.rebuild_search_index()
-
-                        index_dir, index_dir_tmp = self._get_index_dirs()
-
-                        shutil.copytree(index_dir, index_dir_tmp)
-
-                        self._do_install(api_obj, ["example_pkg"])
-
-                        f(index_dir, index_dir_tmp)
-
-                        self.assertRaises(
-                            api_errors.WrapSuccessfulIndexingException,
-                            self._do_uninstall, api_obj, ["example_pkg"])
-
-                        self.image_destroy()
-
-        def test_bug_2989_2(self):
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.pkgsend_bulk(durl, self.another_pkg10)
-
-                for f in self._dir_restore_functions:
-
-                        self.image_create(durl)
-                        progresstracker = progress.NullProgressTracker()
-                        api_obj = api.ImageInterface(self.get_img_path(),
-                            API_VERSION, progresstracker, lambda x: False,
-                            PKG_CLIENT_NAME)
-                        self._do_install(api_obj, ["example_pkg"])
-
-                        index_dir, index_dir_tmp = self._get_index_dirs()
-
-                        shutil.copytree(index_dir, index_dir_tmp)
-
-                        self._do_install(api_obj, ["another_pkg"])
-
-                        f(index_dir, index_dir_tmp)
-
-                        self.assertRaises(
-                            api_errors.WrapSuccessfulIndexingException,
-                            self._do_uninstall, api_obj, ["another_pkg"])
-
-                        self.image_destroy()
-
-        def test_bug_2989_3(self):
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.pkgsend_bulk(durl, self.example_pkg11)
-
-                for f in self._dir_restore_functions:
-
-                        self.image_create(durl)
-                        progresstracker = progress.NullProgressTracker()
-                        api_obj = api.ImageInterface(self.get_img_path(),
-                            API_VERSION, progresstracker, lambda x: False,
-                            PKG_CLIENT_NAME)
-                        self._do_install(api_obj, ["[email protected],5.11-0"])
-
-                        index_dir, index_dir_tmp = self._get_index_dirs()
-
-                        shutil.copytree(index_dir, index_dir_tmp)
-
-                        self._do_install(api_obj, ["example_pkg"])
-
-                        f(index_dir, index_dir_tmp)
-
-                        self.assertRaises(
-                            api_errors.WrapSuccessfulIndexingException,
-                            self._do_uninstall, api_obj, ["example_pkg"])
-
-                        self.image_destroy()
-
-        def test_bug_2989_4(self):
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.another_pkg10)
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.pkgsend_bulk(durl, self.example_pkg11)
-
-                for f in self._dir_restore_functions:
-
-                        self.image_create(durl)
-                        progresstracker = progress.NullProgressTracker()
-                        api_obj = api.ImageInterface(self.get_img_path(),
-                            API_VERSION, progresstracker, lambda x: False,
-                            PKG_CLIENT_NAME)
-                        self._do_install(api_obj, ["another_pkg"])
-
-                        index_dir, index_dir_tmp = self._get_index_dirs()
-
-                        shutil.copytree(index_dir, index_dir_tmp)
-
-                        self._do_install(api_obj, ["[email protected],5.11-0"])
-
-                        f(index_dir, index_dir_tmp)
-
-                        self.assertRaises(
-                            api_errors.WrapSuccessfulIndexingException,
-                            self._do_image_update, api_obj)
-
-                        self.image_destroy()
-
-
-        def test_bug_4239(self):
-                """Tests whether categories are indexed and searched for
-                correctly."""
-
-                def _run_cat_tests(self, remote):
-                        self._search_op(api_obj, remote, "System",
-                            self.res_cat_pkg10, case_sensitive=False)
-                        self._search_op(api_obj, remote, "Security",
-                            self.res_cat_pkg10, case_sensitive=False)
-                        self._search_op(api_obj, remote, "System/Security",
-                            self.res_cat_pkg10, case_sensitive=False)
-                        self._search_op(api_obj, remote, "Other/Category",
-                            self.res_cat_pkg10_2, case_sensitive=False)
-                        self._search_op(api_obj, remote, "Other",
-                            self.res_cat_pkg10_2, case_sensitive=False)
-                        self._search_op(api_obj, remote, "Category",
-                            self.res_cat_pkg10_2, case_sensitive=False)
-
-                def _run_cat2_tests(self, remote):
-                        self._search_op(api_obj, remote, "Applications",
-                            self.res_cat2_pkg10, case_sensitive=False)
-                        self._search_op(api_obj, True, "Sound",
-                            self.res_cat2_pkg10, case_sensitive=False)
-                        self._search_op(api_obj, remote, "Sound and Video",
-                            self.res_cat2_pkg10, case_sensitive=False)
-                        self._search_op(api_obj, remote, "Sound*",
-                            self.res_cat2_pkg10, case_sensitive=False)
-                        self._search_op(api_obj, remote, "*Video",
-                            self.res_cat2_pkg10, case_sensitive=False)
-                        self._search_op(api_obj, remote,
-                            "'Applications/Sound and Video'",
-                            self.res_cat2_pkg10, case_sensitive=False)
-                        # This is a test for bug 11002 which ensures that the
-                        # unquoting is being performed correctly.
-                        self._search_op(api_obj, remote,
-                            "'Applications/Sound%20and%20Video'",
-                            set(), case_sensitive=False)
-                        self._search_op(api_obj, remote, "Developer/C",
-                            self.res_cat2_pkg10_2, case_sensitive=False)
-                        self._search_op(api_obj, remote, "Developer",
-                            self.res_cat2_pkg10_2, case_sensitive=False)
-                        self._search_op(api_obj, remote, "C",
-                            self.res_cat2_pkg10_2, case_sensitive=False)
-
-                def _run_cat3_tests(self, remote):
-                        self._search_op(api_obj, remote, "foo",
-                            self.res_cat3_pkg10,case_sensitive=False)
-                        self._search_op(api_obj, remote, "baz",
-                            self.res_cat3_pkg10, case_sensitive=False)
-                        self._search_op(api_obj, remote, "asda",
-                            self.res_cat3_pkg10, case_sensitive=False)
-                        self._search_op(api_obj, remote,
-                            "foo/bar/baz/bill/beam/asda", self.res_cat3_pkg10,
-                            case_sensitive=False)
-
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.cat_pkg10)
-                self.pkgsend_bulk(durl, self.cat2_pkg10)
-                self.pkgsend_bulk(durl, self.cat3_pkg10)
-                self.pkgsend_bulk(durl, self.bad_cat_pkg10)
-                self.pkgsend_bulk(durl, self.bad_cat2_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                remote = True
-                _run_cat_tests(self, remote)
-                _run_cat2_tests(self, remote)
-                _run_cat3_tests(self, remote)
-
-                remote = False
-                self._do_install(api_obj, ["cat"])
-                _run_cat_tests(self, remote)
-
-                self._do_install(api_obj, ["cat2"])
-                _run_cat2_tests(self, remote)
-
-                self._do_install(api_obj, ["cat3"])
-                _run_cat3_tests(self, remote)
-
-                self._do_install(api_obj, ["badcat"])
-                self._do_install(api_obj, ["badcat2"])
-                _run_cat_tests(self, remote)
-                _run_cat2_tests(self, remote)
-                _run_cat3_tests(self, remote)
-
-        def test_bug_7628(self):
-                """Checks whether incremental update generates wrong
-                additional lines."""
-                durl = self.dc.get_depot_url()
-                depotpath = self.dc.get_repodir()
-                ind_dir = os.path.join(depotpath, "index")
-                tok_file = os.path.join(ind_dir, ss.BYTE_OFFSET_FILE)
-                main_file = os.path.join(ind_dir, ss.MAIN_FILE)
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                time.sleep(1)
-                fh = open(tok_file)
-                tok_1 = fh.readlines()
-                tok_len = len(tok_1)
-                fh.close()
-                fh = open(main_file)
-                main_1 = fh.readlines()
-                main_len = len(main_1)
-                self.pkgsend_bulk(durl, self.example_pkg10, optional=False)
-                time.sleep(1)
-                fh = open(tok_file)
-                tok_2 = fh.readlines()
-                new_tok_len = len(tok_2)
-                fh.close()
-                fh = open(main_file)
-                main_2 = fh.readlines()
-                new_main_len = len(main_2)
-                fh.close()
-                # Since the server now adds a set action for the FMRI to
-                # manifests during publication, there should be one
-                # additional line for the token file.
-                self.assertEqual(new_tok_len, tok_len + 1)
-                self.assertEqual(new_main_len, main_len + 1)
-
-        def test_bug_983(self):
-                """Test for known bug 983."""
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.bug_983_manifest)
-                time.sleep(2)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                self._search_op(api_obj, True, "gmake", self.res_bug_983)
-                self._search_op(api_obj, True, "[email protected]",
-                    self.res_983_csl_dependency)
-                self._search_op(api_obj, True, "SUNWcsl",
-                    self.res_983_csl_dependency)
-                self._search_op(api_obj, True, "[email protected]",
-                    self.res_983_bar_dependency)
-                self._search_op(api_obj, True, "SUNWtestbar",
-                    self.res_983_bar_dependency)
-                self._search_op(api_obj, True, "[email protected]",
-                    self.res_983_foo_dependency)
-                self._search_op(api_obj, True, "SUNWtestfoo",
-                    self.res_983_foo_dependency)
-                self._search_op(api_obj, True, "depend:require:",
-                    self.res_983_csl_dependency | self.res_983_bar_dependency)
-                self._search_op(api_obj, True, "depend:incorporate:",
-                    self.res_983_foo_dependency)
-                self._search_op(api_obj, True, "depend::",
-                    self.res_983_csl_dependency | self.res_983_bar_dependency |
-                    self.res_983_foo_dependency)
-
-        def test_bug_7534(self):
-                """Tests that an automatic reindexing is detected by the test
-                suite."""
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                index_dir = os.path.join(self.img_path, "var","pkg","index")
-
-                orig_fn = os.path.join(index_dir,
-                    query_parser.TermQuery._global_data_dict.values()[0].\
-                    get_file_name())
-                dest_fn = orig_fn + "TMP"
-
-                self._do_install(api_obj, ["example_pkg"])
-                api_obj.rebuild_search_index()
-
-                portable.rename(orig_fn, dest_fn)
-                self.assertRaises(api_errors.WrapSuccessfulIndexingException,
-                    self._do_uninstall, api_obj, ["example_pkg"])
-
-        def test_bug_8492(self):
-                """Tests that field queries and phrase queries work together.
-                """
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.bug_8492_manf_1)
-                self.pkgsend_bulk(durl, self.bug_8492_manf_2)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                self._search_op(api_obj, True, "set::'image packaging'",
-                    self.res_8492_1 | self.res_8492_2)
-                self._search_op(api_obj, True, "b1:set::'image packaging'",
-                    self.res_8492_1)
-
-                self._do_install(api_obj, ["b1", "b2"])
-
-                self._search_op(api_obj, False, "set::'image packaging'",
-                    self.res_8492_1 | self.res_8492_2)
-                self._search_op(api_obj, False, "b2:set::'image packaging'",
-                    self.res_8492_2)
-
-                api_obj.rebuild_search_index()
-
-                self._search_op(api_obj, True, "set::'image packaging'",
-                    self.res_8492_1 | self.res_8492_2)
-                self._search_op(api_obj, True, "b1:set::'image packaging'",
-                    self.res_8492_1)
-
-        def test_bug_9729_1(self):
-                """Test that installing more than
-                indexer.MAX_ADDED_NUMBER_PACKAGES packages at a time doesn't
-                cause any type of indexing error."""
-                durl = self.dc.get_depot_url()
-                pkg_list = []
-                for i in range(0, indexer.MAX_ADDED_NUMBER_PACKAGES + 1):
-                        self.pkgsend_bulk(durl,
-                            "open pkg%[email protected],5.11-0\nclose\n" % i)
-                        pkg_list.append("pkg%s" % i)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-                self._do_install(api_obj, pkg_list)
-
-        def test_bug_9729_2(self):
-                """Test that installing more than
-                indexer.MAX_ADDED_NUMBER_PACKAGES packages one after another
-                doesn't cause any type of indexing error."""
-                def _remove_extra_info(v):
-                        return v.split("-")[0]
-                durl = self.dc.get_depot_url()
-                pkg_list = []
-                for i in range(0, indexer.MAX_ADDED_NUMBER_PACKAGES + 3):
-                        self.pkgsend_bulk(durl,
-                            "open pkg%[email protected],5.11-0\nclose\n" % i)
-                        pkg_list.append("pkg%s" % i)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-                fast_add_loc = os.path.join(self._get_index_dirs()[0],
-                    "fast_add.v1")
-                fast_remove_loc = os.path.join(self._get_index_dirs()[0],
-                    "fast_remove.v1")
-                api_obj.rebuild_search_index()
-                for p in pkg_list:
-                        self._do_install(api_obj, [p])
-                # Test for bug 11104. The fast_add.v1 file was not being updated
-                # correctly by install or image update, it was growing with
-                # each modification.
-                self._check(set((
-                    _remove_extra_info(v)
-                    for v in self._get_lines(fast_add_loc)
-                    )), self.fast_add_after_install)
-                self._check(set((
-                    _remove_extra_info(v)
-                    for v in self._get_lines(fast_remove_loc)
-                    )), self.fast_remove_after_install)
-                # Now check that image update also handles fast_add
-                # appropriately when a small number of packages have changed.
-                for i in range(0, 2):
-                        self.pkgsend_bulk(durl,
-                            "open pkg%[email protected],5.11-0\nclose\n" % i)
-                        pkg_list.append("pkg%s" % i)
-                api_obj.refresh(immediate=True)
-                self._do_image_update(api_obj)
-                self._check(set((
-                    _remove_extra_info(v)
-                    for v in self._get_lines(fast_add_loc)
-                    )), self.fast_add_after_first_update)
-
-                self._check(set((
-                    _remove_extra_info(v)
-                    for v in self._get_lines(fast_remove_loc)
-                    )), self.fast_remove_after_first_update)
-                # Now check that image update also handles fast_add
-                # appropriately when a large number of packages have changed.
-                for i in range(3, indexer.MAX_ADDED_NUMBER_PACKAGES + 3):
-                        self.pkgsend_bulk(durl,
-                            "open pkg%[email protected],5.11-0\nclose\n" % i)
-                        pkg_list.append("pkg%s" % i)
-                api_obj.refresh(immediate=True)
-                self._do_image_update(api_obj)
-                self._check(set((
-                    _remove_extra_info(v)
-                    for v in self._get_lines(fast_add_loc)
-                    )), self.fast_add_after_second_update)
-                self._check(set((
-                    _remove_extra_info(v)
-                    for v in self._get_lines(fast_remove_loc)
-                    )), self.fast_remove_after_second_update)
-
-        def test_bug_9845_01(self):
-                """Test that a corrupt query doesn't break the server."""
-                durl = self.dc.get_depot_url()
-                expected_string = _("A query is expected to have five fields: "
-                    "case sensitivity, return type, number of results to "
-                    "return, the number at which to start returning results, "
-                    "and the text of the query.  The query provided lacked at "
-                    "least one of those fields:")
-                expected_code = 404
-                q_str = "foo"
-                self.validateAssertRaises(urllib2.HTTPError,
-                    lambda x: self._check_err(x, expected_string,
-                        expected_code),
-                    urllib2.urlopen, durl + "/search/1/" + q_str)
-
-        def test_bug_9845_02(self):
-                """Test that a corrupt case_sensitive value doesn't break the "
-                server."""
-                durl = self.dc.get_depot_url()
-                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
-                    "name": "case_sensitive",
-                    "bv": "FAlse"
-                }
-                expected_code = 404
-                q_str = "FAlse_2_None_None_foo"
-                self.validateAssertRaises(urllib2.HTTPError,
-                    lambda x: self._check_err(x, expected_string,
-                        expected_code),
-                    urllib2.urlopen, durl + "/search/1/" + q_str)
-
-        def test_bug_9845_03(self):
-                """Test that a corrupt return_type value doesn't break the "
-                server."""
-                durl = self.dc.get_depot_url()
-                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
-                    "name": "return_type",
-                    "bv": "3"
-                }
-                expected_code = 404
-                q_str = "False_3_None_None_foo"
-                self.validateAssertRaises(urllib2.HTTPError,
-                    lambda x: self._check_err(x, expected_string,
-                        expected_code),
-                    urllib2.urlopen, durl + "/search/1/" + q_str)
-
-        def test_bug_9845_04(self):
-                """Test that a corrupt return_type value doesn't break the "
-                server."""
-                durl = self.dc.get_depot_url()
-                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
-                    "name": "return_type",
-                    "bv": "A"
-                }
-                expected_code = 404
-                q_str = "False_A_None_None_foo"
-                self.validateAssertRaises(urllib2.HTTPError,
-                    lambda x: self._check_err(x, expected_string,
-                        expected_code),
-                    urllib2.urlopen, durl + "/search/1/" + q_str)
-
-        def test_bug_9845_05(self):
-                """Test that a corrupt num_to_return value doesn't break the "
-                server."""
-                durl = self.dc.get_depot_url()
-                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
-                    "name": "num_to_return",
-                    "bv": "NOne"
-                }
-                expected_code = 404
-                q_str = "False_2_NOne_None_foo"
-                self.validateAssertRaises(urllib2.HTTPError,
-                    lambda x: self._check_err(x, expected_string,
-                        expected_code),
-                    urllib2.urlopen, durl + "/search/1/" + q_str)
-
-        def test_bug_9845_06(self):
-                """Test that a corrupt start_point value doesn't break the "
-                server."""
-                durl = self.dc.get_depot_url()
-                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
-                    "name": "start_point",
-                    "bv": "NOne"
-                }
-                expected_code = 404
-                q_str = "False_2_None_NOne_foo"
-                self.validateAssertRaises(urllib2.HTTPError,
-                    lambda x: self._check_err(x, expected_string,
-                        expected_code),
-                    urllib2.urlopen, durl + "/search/1/" + q_str)
-
-        def test_bug_9845_07(self):
-                """Test that a corrupt case_sensitive value doesn't break the "
-                server."""
-                durl = self.dc.get_depot_url()
-                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
-                    "name": "case_sensitive",
-                    "bv": ""
-                }
-                expected_code = 404
-                q_str = "_2_None_None_foo"
-                self.validateAssertRaises(urllib2.HTTPError,
-                    lambda x: self._check_err(x, expected_string,
-                        expected_code),
-                    urllib2.urlopen, durl + "/search/1/" + q_str)
-
-        def test_bug_9845_08(self):
-                """Test that a missing return_type value doesn't break the "
-                server."""
-                durl = self.dc.get_depot_url()
-                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
-                    "name": "return_type",
-                    "bv": ""
-                }
-                expected_code = 404
-                q_str = "False__None_None_foo"
-                self.validateAssertRaises(urllib2.HTTPError,
-                    lambda x: self._check_err(x, expected_string,
-                        expected_code),
-                    urllib2.urlopen, durl + "/search/1/" + q_str)
-
-        def test_bug_9845_09(self):
-                """Test that a missing num_to_return value doesn't break the "
-                server."""
-                durl = self.dc.get_depot_url()
-                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
-                    "name": "num_to_return",
-                    "bv": ""
-                }
-                expected_code = 404
-                q_str = "False_2__None_foo"
-                self.validateAssertRaises(urllib2.HTTPError,
-                    lambda x: self._check_err(x, expected_string,
-                        expected_code),
-                    urllib2.urlopen, durl + "/search/1/" + q_str)
-
-        def test_bug_9845_10(self):
-                """Test that a missing start_point value doesn't break the "
-                server."""
-                durl = self.dc.get_depot_url()
-                expected_string = _("%(name)s had a bad value of '%(bv)s'") % {
-                    "name": "start_point",
-                    "bv": ""
-                }
-                expected_code = 404
-                q_str = "False_2_None__foo"
-                self.validateAssertRaises(urllib2.HTTPError,
-                    lambda x: self._check_err(x, expected_string,
-                        expected_code),
-                    urllib2.urlopen, durl + "/search/1/" + q_str)
-
-        def test_bug_9845_11(self):
-                """Test that missing query text doesn't break the server."""
-                durl = self.dc.get_depot_url()
-                expected_string = _("Could not parse query.")
-                expected_code = 400
-                q_str = "False_2_None_None_"
-                self.validateAssertRaises(urllib2.HTTPError,
-                    lambda x: self._check_err(x, expected_string,
-                        expected_code),
-                    urllib2.urlopen, durl + "/search/1/" + q_str)
-
-
-class TestApiSearchBasicsRestartingDepot(TestApiSearchBasics):
-        def setUp(self):
-                self.debug_features = ["headers"]
-                TestApiSearchBasics.setUp(self)
-
-        def test_local_image_update(self):
-                """Test that the index gets updated by image-update and
-                that rebuilding the index works after updating the
-                image. Specifically, this tests that rebuilding indexes with
-                gaps in them works correctly."""
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                self._do_install(api_obj, ["example_pkg"])
-
-                self.pkgsend_bulk(durl, self.example_pkg11)
-                api_obj.refresh(immediate=True)
-
-                self._do_image_update(api_obj)
-
-                self._run_local_tests_example11_installed(api_obj)
-
-                api_obj.rebuild_search_index()
-
-                self._run_local_tests_example11_installed(api_obj)
-
-        def test_bug_4048_1(self):
-                """Checks whether the server deals with partial indexing."""
-                durl = self.dc.get_depot_url()
-                depotpath = self.dc.get_repodir()
-                tmp_dir = os.path.join(depotpath, "index", "TMP")
-                os.mkdir(tmp_dir)
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-                self._run_remote_empty_tests(api_obj)
-                os.rmdir(tmp_dir)
-                offset = 2
-                depot_logfile = os.path.join(self.get_test_prefix(),
-                    self.id(), "depot_logfile%d" % offset)
-                tmp_dc = self.start_depot(12000 + offset, depotpath,
-                    depot_logfile, refresh_index=True)
-                time.sleep(1)
-                # This should do something other than sleep for 1 sec
-                self._run_remote_tests(api_obj)
-                tmp_dc.kill()
-
-        def test_bug_4048_2(self):
-                """Checks whether the server deals with partial indexing."""
-                durl = self.dc.get_depot_url()
-                depotpath = self.dc.get_repodir()
-                tmp_dir = os.path.join(depotpath, "index", "TMP")
-                os.mkdir(tmp_dir)
-                self.pkgsend_bulk(durl, self.space_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-                self._run_remote_empty_tests(api_obj)
-                os.rmdir(tmp_dir)
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                time.sleep(1)
-                self._run_remote_tests(api_obj)
-                self._search_op(api_obj, True, "unique_dir",
-                    self.res_space_unique)
-                self._search_op(api_obj, True, "with*",
-                    self.res_space_with_star)
-
-        def __corrupt_depot(self, ind_dir):
-                self.dc.stop()
-                if os.path.exists(os.path.join(ind_dir, ss.MAIN_FILE)):
-                        shutil.move(os.path.join(ind_dir, ss.MAIN_FILE),
-                            os.path.join(ind_dir, "main_dict.ascii.v1"))
-                self.dc.start()
-
-        def __wait_for_indexing(self, d):
-                init_time = time.time()
-                there = True
-                while there and ((time.time() - init_time) < 10):
-                        there = os.path.exists(d)
-                self.assert_(not there)
-                time.sleep(1)
-
-        def test_bug_7358_1(self):
-                """Move files so that an inconsistent index is created and
-                check that the server rebuilds the index when possible, and
-                doesn't stack trace when it can't write to the directory."""
-
-                durl = self.dc.get_depot_url()
-                depotpath = self.dc.get_repodir()
-                ind_dir = os.path.join(depotpath, "index")
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-                # Check when depot is empty.
-                self.__corrupt_depot(ind_dir)
-                self.__wait_for_indexing(os.path.join(ind_dir, "TMP"))
-                # Since the depot is empty, should return no results but
-                # not error.
-                self._search_op(api_obj, True, 'e*', set())
-
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.__wait_for_indexing(os.path.join(ind_dir, "TMP"))
-
-                # Check when depot contains a package.
-                self.__corrupt_depot(ind_dir)
-                self.__wait_for_indexing(os.path.join(ind_dir, "TMP"))
-                self._run_remote_tests(api_obj)
-
-        def test_bug_7358_2(self):
-                """Does same check as 7358_1 except it checks for interactions
-                with writable root."""
-
-                durl = self.dc.get_depot_url()
-                depotpath = self.dc.get_repodir()
-                ind_dir = os.path.join(depotpath, "index")
-                shutil.rmtree(ind_dir)
-                writable_root = os.path.join(self.get_test_prefix(),
-                    "writ_root")
-                writ_dir = os.path.join(writable_root, "index")
-                self.dc.set_writable_root(writable_root)
-
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-
-                # Check when depot is empty.
-                self.__corrupt_depot(writ_dir)
-                # Since the depot is empty, should return no results but
-                # not error.
-                self.assert_(not os.path.isdir(ind_dir))
-                self.__wait_for_indexing(os.path.join(writ_dir, "TMP"))
-                self._search_op(api_obj, True, 'e*', set())
-
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.__wait_for_indexing(os.path.join(writ_dir, "TMP"))
-
-                # Check when depot contains a package.
-                self.__corrupt_depot(writ_dir)
-                self.__wait_for_indexing(os.path.join(writ_dir, "TMP"))
-                self.assert_(not os.path.isdir(ind_dir))
-                self._run_remote_tests(api_obj)
-
-        def test_bug_8318(self):
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-                uuids = []
-                for p in api_obj.img.gen_publishers():
-                        uuids.append(p.client_uuid)
-
-                self._search_op(api_obj, True, "example_path",
-                    self.res_remote_path)
-                self._search_op(api_obj, True, "example_path",
-                    self.res_remote_path, servers=[{"origin": durl}])
-                lfh = file(self.dc.get_logpath(), "rb")
-                found = 0
-                num_expected = 8
-                for line in lfh:
-                        if "X-IPKG-UUID:" in line:
-                                tmp = line.split()
-                                s_uuid = tmp[1]
-                                if s_uuid not in uuids:
-                                        raise RuntimeError("Uuid found:%s not "
-                                            "found in list of possible "
-                                            "uuids:%s" % (s_uuid, uuids))
-                                found += 1
-                if found != num_expected:
-                        raise RuntimeError(("Found %s instances of a "
-                            "client uuid, expected to find %s.") %
-                            (found, num_expected))
-
-        def test_bug_13485(self):
-                """Test that indexer.Indexer's check_for_updates function works
-                as excepted. This needs to be a separate test because other
-                tests are likely to conintue working while reindexing more
-                frequently than they should."""
-
-                durl = self.dc.get_depot_url()
-                depotpath = self.dc.get_repodir()
-                ind_dir = os.path.join(depotpath, "index")
-                repo = srepo.Repository(repo_root=depotpath, read_only=True,
-                    fork_allowed=False, refresh_index=False)
-
-                # Check that an empty index works correctly.
-                fmris = indexer.Indexer.check_for_updates(ind_dir, repo.catalog)
-                self.assertEqual(set(), fmris)
-
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                self.__wait_for_indexing(os.path.join(ind_dir, "TMP"))
-                repo = srepo.Repository(repo_root=depotpath, fork_allowed=False)
-                self.assertEqual(len(set(repo.catalog.fmris())), 1)
-                # Check that after publishing one package, no packages need
-                # indexing.
-                fmris = indexer.Indexer.check_for_updates(ind_dir, repo.catalog)
-                self.assertEqual(set(), fmris)
-                
-                back_dir = ind_dir + ".BACKUP"
-                shutil.copytree(ind_dir, back_dir)
-                self.pkgsend_bulk(durl, self.example_pkg10)
-                repo = srepo.Repository(repo_root=depotpath, fork_allowed=False)
-                self.assertEqual(len(set(repo.catalog.fmris())), 2)
-                # Check that publishing a second package also works.
-                fmris = indexer.Indexer.check_for_updates(ind_dir, repo.catalog)
-                self.assertEqual(set(), fmris)
-
-                # Check that a package that was publisher but not index is
-                # reported.
-                fmris = indexer.Indexer.check_for_updates(back_dir,
-                    repo.catalog)
-                self.assertEqual(len(fmris), 1)
-
-class TestApiSearchMulti(testutils.ManyDepotTestCase):
-
-        example_pkg10 = """
-            open [email protected],5.11-0
-            add dir mode=0755 owner=root group=bin path=/bin/example_dir
-            close """
-
-        res_alternate_server_local = set([
-            ('pkg:/[email protected]', 'test2/example_pkg',
-            'set name=pkg.fmri value=pkg://test2/[email protected],5.11-0:')
-        ])
-
-        def setUp(self):
-                testutils.ManyDepotTestCase.setUp(self, ["test1", "test2",
-                    "test3"], debug_features=["headers"])
-
-                self.durl1 = self.dcs[1].get_depot_url()
-                self.durl2 = self.dcs[2].get_depot_url()
-                self.durl3 = self.dcs[3].get_depot_url()
-                self.pkgsend_bulk(self.durl2, self.example_pkg10)
-
-                self.image_create(self.durl1, prefix="test1")
-                self.pkg("set-publisher -O " + self.durl2 + " test2")
-
-        def _check(self, proposed_answer, correct_answer):
-                if correct_answer == proposed_answer:
-                        return True
-                else:
-                        self.debug("Proposed Answer: " + str(proposed_answer))
-                        self.debug("Correct Answer : " + str(correct_answer))
-                        if isinstance(correct_answer, set) and \
-                            isinstance(proposed_answer, set):
-                                print >> sys.stderr, "Missing: " + \
-                                    str(correct_answer - proposed_answer)
-                                print >> sys.stderr, "Extra  : " + \
-                                    str(proposed_answer - correct_answer)
-                        self.assert_(correct_answer == proposed_answer)
-
-        @staticmethod
-        def _extract_action_from_res(it, err):
-                res = []
-                if err:
-                        try:
-                                for query_num, auth, (version, return_type,
-                                    (pkg_name, piece, act)) in it:
-                                        res.append((fmri.PkgFmri(str(
-                                            pkg_name)).get_short_fmri(), piece,
-                                            TestApiSearchBasics._replace_act(
-                                            act)),)
-                        except err, e:
-                                return res
-                        else:
-                                raise RuntimeError(
-                                    "Didn't get expected error:%s" % err)
-                else:
-                        return TestApiSearchBasics._extract_action_from_res(it)
-                        
-
-        def _search_op(self, api_obj, remote, token, test_value,
-            case_sensitive=False, return_actions=True, num_to_return=None,
-            start_point=None, servers=None, expected_err=None):
-                search_func = api_obj.local_search
-                query = api.Query(token, case_sensitive, return_actions,
-                    num_to_return, start_point)
-                if remote:
-                        search_func = api_obj.remote_search
-                        res = set(self._extract_action_from_res(
-                            search_func([query], servers=servers),
-                            expected_err))
-                else:
-                        res = set(TestApiSearchBasics._extract_action_from_res(
-                            search_func([query])))
-                self._check(set(res), test_value)
-
-        def test_bug_2955(self):
-                """See http://defect.opensolaris.org/bz/show_bug.cgi?id=2955"""
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-                TestApiSearchBasics._do_install(api_obj, ["example_pkg"])
-                # Test for bug 10690 by checking whether the fmri names
-                # for packages installed from the non-preferred publisher
-                # are parsed correctly. Specifically, test whether the name
-                # alone is searchable, as well as the publisher/name
-                # combination.
-                self._search_op(api_obj, False, "set::test2/example_pkg",
-                    self.res_alternate_server_local)
-                self._search_op(api_obj, False, "set::example_pkg",
-                    self.res_alternate_server_local)
-                self._search_op(api_obj, False, "set::test2/*",
-                    self.res_alternate_server_local)
-                api_obj.rebuild_search_index()
-                self._search_op(api_obj, False, "set::test2/example_pkg",
-                    self.res_alternate_server_local)
-                self._search_op(api_obj, False, "set::example_pkg",
-                    self.res_alternate_server_local)
-                self._search_op(api_obj, False, "set::test2/*",
-                    self.res_alternate_server_local)
-                TestApiSearchBasics._do_uninstall(api_obj, ["example_pkg"])
-
-        def test_bug_8318(self):
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                self._search_op(api_obj, True,
-                    "this_should_not_match_any_token", set())
-                self._search_op(api_obj, True, "example_path",
-                    set(), servers=[{"origin": self.durl1}])
-                self._search_op(api_obj, True, "example_path",
-                    set(), servers=[{"origin": self.durl3}])
-                num_expected = { 1: 7, 2: 4, 3: 0 }
-                for d in range(1,(len(self.dcs) + 1)):
-                        try:
-                                pub = api_obj.img.get_publisher(
-                                    origin=self.dcs[d].get_depot_url())
-                                c_uuid = pub.client_uuid
-                        except api_errors.UnknownPublisher:
-                                c_uuid = None
-                        lfh = file(self.dcs[d].get_logpath(), "rb")
-                        found = 0
-                        for line in lfh:
-                                if "X-IPKG-UUID:" in line:
-                                        tmp = line.split()
-                                        s_uuid = tmp[1]
-                                        if s_uuid != c_uuid:
-                                                raise RuntimeError(
-                                                    "Found uuid:%s doesn't "
-                                                    "match expected uuid:%s, "
-                                                    "d:%s, durl:%s" %
-                                                    (s_uuid, c_uuid, d,
-                                                    self.dcs[d].get_depot_url()))
-                                        found += 1
-                        if found != num_expected[d]:
-                                raise RuntimeError("d:%s, found %s instances of"
-                                    " a client uuid, expected to find %s." %
-                                    (d, found, num_expected[d]))
-
-        def test_bug_12739(self):
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                self._search_op(api_obj, True, "example_dir",
-                    set([("pkg:/[email protected]", "basename",
-                        "dir group=bin mode=0755 owner=root "
-                        "path=bin/example_dir")]))
-                self.dcs[1].stop()
-                self._search_op(api_obj, True, "example_dir",
-                    set([("pkg:/[email protected]", "basename",
-                        "dir group=bin mode=0755 owner=root "
-                        "path=bin/example_dir")]),
-                        expected_err=api_errors.ProblematicSearchServers)
-                self.pkg("search example_dir", exit=3)
-                
-if __name__ == "__main__":
-        unittest.main()
--- a/src/tests/cli/t_change_facet.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_change_facet.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,12 +20,13 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import re
@@ -38,47 +39,33 @@
 
 
 
-class TestPkgChangeFacet(testutils.SingleDepotTestCase):
+class TestPkgChangeFacet(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         pkg_A = """
         open [email protected],5.11-0
-        add file /tmp/facets_0 mode=0555 owner=root group=bin path=0         
-        add file /tmp/facets_1 mode=0555 owner=root group=bin path=1 facet.locale.fr=True
-        add file /tmp/facets_2 mode=0555 owner=root group=bin path=2 facet.locale.fr_FR=True
-        add file /tmp/facets_3 mode=0555 owner=root group=bin path=3 facet.locale.fr_CA=True
-        add file /tmp/facets_4 mode=0555 owner=root group=bin path=4 facet.locale.fr_CA=True facet.locale.nl_ZA=True
-        add file /tmp/facets_5 mode=0555 owner=root group=bin path=5 facet.locale.nl=True
-        add file /tmp/facets_6 mode=0555 owner=root group=bin path=6 facet.locale.nl_NA=True
-        add file /tmp/facets_7 mode=0555 owner=root group=bin path=7 facet.locale.nl_ZA=True
+        add file tmp/facets_0 mode=0555 owner=root group=bin path=0         
+        add file tmp/facets_1 mode=0555 owner=root group=bin path=1 facet.locale.fr=True
+        add file tmp/facets_2 mode=0555 owner=root group=bin path=2 facet.locale.fr_FR=True
+        add file tmp/facets_3 mode=0555 owner=root group=bin path=3 facet.locale.fr_CA=True
+        add file tmp/facets_4 mode=0555 owner=root group=bin path=4 facet.locale.fr_CA=True facet.locale.nl_ZA=True
+        add file tmp/facets_5 mode=0555 owner=root group=bin path=5 facet.locale.nl=True
+        add file tmp/facets_6 mode=0555 owner=root group=bin path=6 facet.locale.nl_NA=True
+        add file tmp/facets_7 mode=0555 owner=root group=bin path=7 facet.locale.nl_ZA=True
         close"""
 
-        misc_files = [p for p in pkg_A.split() if p.startswith("/")]
+        misc_files = ["tmp/facets_0", "tmp/facets_1", "tmp/facets_2",
+                      "tmp/facets_3", "tmp/facets_4", "tmp/facets_5",
+                      "tmp/facets_6", "tmp/facets_7"]
 
         def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self)
-
-
-                for p in self.misc_files:
-                        path = os.path.dirname(p)
-                        if not os.path.exists(path):
-                                os.makedirs(path)
-                        f = open(p, "w")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(p)
-                        f.close()
-                        self.debug("wrote %s" % p)
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
 
                 depot = self.dc.get_depot_url()
                 self.pkgsend_bulk(depot, self.pkg_A)
 
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-                for p in self.misc_files:
-                        os.remove(p)
-
         def assert_file_is_there(self, path, negate=False):
                 """Verify that the specified path exists. If negate is true, 
                 then make sure the path doesn't exist"""
@@ -153,3 +140,5 @@
                         self.assert_file_is_there("%d" % i, negate=(i != 0))
 
  
+if __name__ == "__main__":
+        unittest.main()
--- a/src/tests/cli/t_change_variant.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_change_variant.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,12 +20,13 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import re
@@ -39,17 +40,17 @@
 # needed to get variant settings
 import pkg.client.imageconfig as imageconfig
 
-class TestPkgChangeVariant(testutils.SingleDepotTestCase):
+class TestPkgChangeVariant(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         pkg_i386 = """
         open [email protected],5.11-0
         add set name=variant.arch value=i386
         add dir mode=0755 owner=root group=bin path=/shared
         add dir mode=0755 owner=root group=bin path=/unique
-        add file /tmp/pkg_i386/shared/pkg_i386_shared mode=0555 owner=root group=bin path=shared/pkg_arch_shared variant.arch=i386
-        add file /tmp/pkg_i386/unique/pkg_i386 mode=0555 owner=root group=bin path=unique/pkg_i386 variant.arch=i386
+        add file tmp/pkg_i386/shared/pkg_i386_shared mode=0555 owner=root group=bin path=shared/pkg_arch_shared variant.arch=i386
+        add file tmp/pkg_i386/unique/pkg_i386 mode=0555 owner=root group=bin path=unique/pkg_i386 variant.arch=i386
         close"""
 
         pkg_sparc = """
@@ -57,8 +58,8 @@
         add set name=variant.arch value=sparc
         add dir mode=0755 owner=root group=bin path=/shared
         add dir mode=0755 owner=root group=bin path=/unique
-        add file /tmp/pkg_sparc/shared/pkg_sparc_shared mode=0555 owner=root group=bin path=shared/pkg_arch_shared variant.arch=sparc
-        add file /tmp/pkg_sparc/unique/pkg_sparc mode=0555 owner=root group=bin path=unique/pkg_sparc variant.arch=sparc
+        add file tmp/pkg_sparc/shared/pkg_sparc_shared mode=0555 owner=root group=bin path=shared/pkg_arch_shared variant.arch=sparc
+        add file tmp/pkg_sparc/unique/pkg_sparc mode=0555 owner=root group=bin path=unique/pkg_sparc variant.arch=sparc
         close"""
 
         pkg_shared = """
@@ -66,13 +67,13 @@
         add set name=variant.arch value=sparc value=i386 value=zos
         add dir mode=0755 owner=root group=bin path=/shared
         add dir mode=0755 owner=root group=bin path=/unique
-        add file /tmp/pkg_shared/shared/common mode=0555 owner=root group=bin path=shared/common
-        add file /tmp/pkg_shared/shared/pkg_shared_i386 mode=0555 owner=root group=bin path=shared/pkg_shared variant.arch=i386
-        add file /tmp/pkg_shared/shared/pkg_shared_sparc mode=0555 owner=root group=bin path=shared/pkg_shared variant.arch=sparc
-        add file /tmp/pkg_shared/shared/global_motd mode=0555 owner=root group=bin path=shared/zone_motd variant.opensolaris.zone=global
-        add file /tmp/pkg_shared/shared/nonglobal_motd mode=0555 owner=root group=bin path=shared/zone_motd variant.opensolaris.zone=nonglobal
-        add file /tmp/pkg_shared/unique/global mode=0555 owner=root group=bin path=unique/global variant.opensolaris.zone=global
-        add file /tmp/pkg_shared/unique/nonglobal mode=0555 owner=root group=bin path=unique/nonglobal variant.opensolaris.zone=nonglobal
+        add file tmp/pkg_shared/shared/common mode=0555 owner=root group=bin path=shared/common
+        add file tmp/pkg_shared/shared/pkg_shared_i386 mode=0555 owner=root group=bin path=shared/pkg_shared variant.arch=i386
+        add file tmp/pkg_shared/shared/pkg_shared_sparc mode=0555 owner=root group=bin path=shared/pkg_shared variant.arch=sparc
+        add file tmp/pkg_shared/shared/global_motd mode=0555 owner=root group=bin path=shared/zone_motd variant.opensolaris.zone=global
+        add file tmp/pkg_shared/shared/nonglobal_motd mode=0555 owner=root group=bin path=shared/zone_motd variant.opensolaris.zone=nonglobal
+        add file tmp/pkg_shared/unique/global mode=0555 owner=root group=bin path=unique/global variant.opensolaris.zone=global
+        add file tmp/pkg_shared/unique/nonglobal mode=0555 owner=root group=bin path=unique/nonglobal variant.opensolaris.zone=nonglobal
 
         close"""
 
@@ -101,36 +102,25 @@
         ])
 
         misc_files = [
-                "/tmp/pkg_i386/shared/pkg_i386_shared",
-                "/tmp/pkg_i386/unique/pkg_i386",
+                "tmp/pkg_i386/shared/pkg_i386_shared",
+                "tmp/pkg_i386/unique/pkg_i386",
 
-                "/tmp/pkg_sparc/shared/pkg_sparc_shared",
-                "/tmp/pkg_sparc/unique/pkg_sparc",
+                "tmp/pkg_sparc/shared/pkg_sparc_shared",
+                "tmp/pkg_sparc/unique/pkg_sparc",
 
-                "/tmp/pkg_shared/shared/common",
-                "/tmp/pkg_shared/shared/pkg_shared_i386",
-                "/tmp/pkg_shared/shared/pkg_shared_sparc",
-                "/tmp/pkg_shared/shared/global_motd",
-                "/tmp/pkg_shared/shared/nonglobal_motd",
-                "/tmp/pkg_shared/unique/global",
-                "/tmp/pkg_shared/unique/nonglobal"
+                "tmp/pkg_shared/shared/common",
+                "tmp/pkg_shared/shared/pkg_shared_i386",
+                "tmp/pkg_shared/shared/pkg_shared_sparc",
+                "tmp/pkg_shared/shared/global_motd",
+                "tmp/pkg_shared/shared/nonglobal_motd",
+                "tmp/pkg_shared/unique/global",
+                "tmp/pkg_shared/unique/nonglobal"
         ]
 
         def setUp(self):
-                print "setUP"
-
-                testutils.SingleDepotTestCase.setUp(self)
+                pkg5unittest.SingleDepotTestCase.setUp(self)
 
-                for p in self.misc_files:
-                        path = os.path.dirname(p)
-                        if not os.path.exists(path):
-                                os.makedirs(path)
-                        f = open(p, "w")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(p)
-                        f.close()
-                        self.debug("wrote %s" % p)
+                self.make_misc_files(self.misc_files)
 
                 depot = self.dc.get_depot_url()
                 self.pkgsend_bulk(depot, self.pkg_i386)
@@ -145,12 +135,6 @@
                 # verify installed images before we changing variants
                 self.verify_install = False
 
-
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-                for p in self.misc_files:
-                        os.remove(p)
-
         def f_verify(self, path, token=None, negate=False):
                 """Verify that the specified path exists and contains
                 the specified token.  If negate is true, then make sure
--- a/src/tests/cli/t_colliding_links.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_colliding_links.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,12 +20,13 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import re
@@ -36,15 +37,15 @@
 import sys
 from stat import *
 
-class TestPkgCollidingLinks(testutils.SingleDepotTestCase):
+class TestPkgCollidingLinks(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         pkg_A = """
         open [email protected],5.11-0
-        add file /tmp/link_target_0 mode=0555 owner=root group=bin path=link_target_0
-        add file /tmp/link_target_1 mode=0555 owner=root group=bin path=link_target_1
-        add file /tmp/link_target_2 mode=0555 owner=root group=bin path=link_target_2
+        add file tmp/link_target_0 mode=0555 owner=root group=bin path=link_target_0
+        add file tmp/link_target_1 mode=0555 owner=root group=bin path=link_target_1
+        add file tmp/link_target_2 mode=0555 owner=root group=bin path=link_target_2
         close"""
 
         pkg_B = """
@@ -62,34 +63,18 @@
         close"""
 
 
-        misc_files = [p for p in pkg_A.split() if p.startswith("/")]
+        misc_files = [p for p in pkg_A.split() if "tmp/link_target" in p]
 
 
         def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self)
-
-                for p in self.misc_files:
-                        path = os.path.dirname(p)
-                        if not os.path.exists(path):
-                                os.makedirs(path)
-                        f = open(p, "w")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(p)
-                        f.close()
-                        self.debug("wrote %s" % p)
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
 
                 depot = self.dc.get_depot_url()
                 self.pkgsend_bulk(depot, self.pkg_A)
                 self.pkgsend_bulk(depot, self.pkg_B)
                 self.pkgsend_bulk(depot, self.pkg_C)
 
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-                for p in self.misc_files:
-                        os.remove(p)
-
-
         def test_1(self):
                 """Verify symlinks are correctly reference counted
                 during installation & removal of packages"""
@@ -115,3 +100,6 @@
 
                 self.pkg("uninstall pkg_B pkg_C")
                 self.pkg("verify")
+
+if __name__ == "__main__":
+        unittest.main()
--- a/src/tests/cli/t_fix.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_fix.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,67 +20,54 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import shutil
 import time
 import unittest
 
-class TestFix(testutils.SingleDepotTestCase):
+class TestFix(pkg5unittest.SingleDepotTestCase):
 
         # Don't need to restart depot for every test.
-        persistent_depot = True
+        persistent_setup = True
 
         amber10 = """
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/etc
-            add file $test_prefix/amber1 mode=0644 owner=root group=bin path=/etc/amber1
-            add file $test_prefix/amber2 mode=0644 owner=root group=bin path=/etc/amber2
+            add file amber1 mode=0644 owner=root group=bin path=/etc/amber1
+            add file amber2 mode=0644 owner=root group=bin path=/etc/amber2
             add hardlink path=/etc/amber.hardlink target=/etc/amber1
             close """
 
         licensed13 = """
             open [email protected],5.11-0
-            add file $test_prefix/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
-            add license $test_prefix/copyright.licensed license=copyright.licensed must-display=True
-            add license $test_prefix/license.licensed license=license.licensed must-accept=True
+            add file libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
+            add license copyright.licensed license=copyright.licensed must-display=True
+            add license license.licensed license=license.licensed must-accept=True
             close """
 
-        misc_files = ["copyright.licensed", "libc.so.1", "license.licensed",
-            "license.licensed.addendum", "amber1", "amber2"]
+        misc_files = [ "copyright.licensed", "license.licensed", "libc.so.1",
+            "license.licensed", "license.licensed.addendum", "amber1", "amber2"]
 
         def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self)
-
-                for p in ("amber10", "licensed13"):
-                        val = getattr(self, p).replace("$test_prefix",
-                            self.get_test_prefix())
-                        setattr(self, p, val)
-
-                for p in self.misc_files:
-                        fpath = os.path.join(self.get_test_prefix(), p)
-                        f = open(fpath, "wb")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(fpath)
-                        f.close()
-                        self.debug("wrote %s" % fpath)
-
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
                 durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.amber10 + self.licensed13)
+                self.pkgsend_bulk(durl, self.amber10)
+                self.pkgsend_bulk(durl, self.licensed13)
 
         def test_fix1(self):
                 """Basic fix test: install the amber package, modify one of the
                 files, and make sure it gets fixed.  """
 
                 durl = self.dc.get_depot_url()
-                shutil.rmtree(self.img_path, True)
                 self.image_create(durl)
                 self.pkg("install [email protected]")
 
@@ -116,7 +103,6 @@
                 hardlinks that point to it updated"""
 
                 durl = self.dc.get_depot_url()
-                shutil.rmtree(self.img_path, True)
                 self.image_create(durl)
                 self.pkg("install [email protected]")
 
@@ -139,7 +125,6 @@
                 and/or display."""
 
                 durl = self.dc.get_depot_url()
-                shutil.rmtree(self.img_path, True)
                 self.image_create(durl)
                 self.pkg("install --accept [email protected]")
 
@@ -161,12 +146,12 @@
 
                 # Verify that when the fix failed, it displayed the license
                 # that required display.
-                self.pkg("fix licensed | grep '/copyright.licensed'")
-                self.pkg("fix licensed | grep -v '/license.licensed'")
+                self.pkg("fix licensed | grep 'copyright.licensed'")
+                self.pkg("fix licensed | grep -v 'license.licensed'")
 
                 # Verify that fix will display all licenses when it fails,
                 # if provided the --licenses option.
-                self.pkg("fix --licenses licensed | grep '/license.licensed'")
+                self.pkg("fix --licenses licensed | grep 'license.licensed'")
 
                 # Finally, verify that fix will succeed when a package requires
                 # license acceptance if provided the --accept option.
--- a/src/tests/cli/t_lock.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_lock.py	Sat Jan 30 01:07:14 2010 -0800
@@ -28,6 +28,7 @@
 import testutils
 if __name__ == "__main__":
 	testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import cStringIO
 import os
@@ -44,7 +45,7 @@
 API_VERSION = 31
 PKG_CLIENT_NAME = "pkg"
 
-class TestPkgApi(testutils.SingleDepotTestCase):
+class TestPkgApi(pkg5unittest.SingleDepotTestCase):
         # restart the depot for every test
         persistent_depot = False
 
@@ -57,7 +58,7 @@
             close """
 
         def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self)
+                pkg5unittest.SingleDepotTestCase.setUp(self)
                 durl = self.dc.get_depot_url()
                 self.pkgsend_bulk(durl, self.foo10 + self.foo11)
                 self.image_create(durl)
--- a/src/tests/cli/t_pkg_R_option.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_R_option.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,18 +20,19 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import testutils
 if __name__ == "__main__":
 	testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import unittest
 
-class TestROption(testutils.SingleDepotTestCase):
+class TestROption(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         foo10 = """
             open [email protected],5.11-0
--- a/src/tests/cli/t_pkg_api_install.py	Fri Jan 29 13:24:14 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,583 +0,0 @@
-#!/usr/bin/python
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-#
-# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-#
-
-import testutils
-if __name__ == "__main__":
-	testutils.setup_environment("../../../proto")
-
-import os
-import time
-import sys
-import unittest
-from stat import *
-import pkg.client.api as api
-import pkg.client.api_errors as api_errors
-import pkg.client.progress as progress
-
-API_VERSION = 31
-PKG_CLIENT_NAME = "pkg"
-
-class TestPkgApiInstall(testutils.SingleDepotTestCase):
-        # Only start/stop the depot once (instead of for every test)
-        persistent_depot = False
-
-        foo10 = """
-            open [email protected],5.11-0
-            close """
-
-        foo11 = """
-            open [email protected],5.11-0
-            add dir mode=0755 owner=root group=bin path=/lib
-            add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1 timestamp="20080731T024051Z"
-            close """
-        foo11_timestamp = 1217472051
-
-        foo12 = """
-            open [email protected],5.11-0
-            add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
-            close """
-
-        bar10 = """
-            open [email protected],5.11-0
-            add depend type=require fmri=pkg:/[email protected]
-            add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
-            close """
-
-        bar11 = """
-            open [email protected],5.11-0
-            add depend type=require fmri=pkg:/[email protected]
-            add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
-            close """
-
-        xfoo10 = """
-            open [email protected],5.11-0
-            close """
-
-        xbar10 = """
-            open [email protected],5.11-0
-            add depend type=require fmri=pkg:/[email protected]
-            add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
-            close """
-
-        xbar11 = """
-            open [email protected],5.11-0
-            add depend type=require fmri=pkg:/[email protected]
-            add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
-            close """
-
-
-        bar12 = """
-            open [email protected],5.11-0
-            add depend type=require fmri=pkg:/[email protected]
-            add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat 
-            close """
-
-        baz10 = """
-            open [email protected],5.11-0
-            add depend type=require fmri=pkg:/[email protected]
-            add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/baz mode=0555 owner=root group=bin path=/bin/baz
-            close """
-
-        deep10 = """
-            open [email protected],5.11-0
-            add depend type=require fmri=pkg:/[email protected]
-            add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
-            close """
-        
-        xdeep10 = """
-            open [email protected],5.11-0
-            add depend type=require fmri=pkg:/[email protected]
-            add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
-            close """
-
-        ydeep10 = """
-            open [email protected],5.11-0
-            add depend type=require fmri=pkg:/[email protected]
-            add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
-            close """
-
-        misc_files = [ "/tmp/libc.so.1", "/tmp/cat", "/tmp/baz" ]
-
-        def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self)
-                for p in self.misc_files:
-                        f = open(p, "w")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(p)
-                        f.close
-                        self.debug("wrote %s" % p)
-
-        def tearDown(self):
-                self.debug("In teardown")
-                testutils.SingleDepotTestCase.tearDown(self)
-                for p in self.misc_files:
-                        os.remove(p)
-
-        @staticmethod
-        def __do_install(api_obj, fmris):
-                api_obj.reset()
-                api_obj.plan_install(fmris)
-                api_obj.prepare()
-                api_obj.execute_plan()
-
-        @staticmethod
-        def __do_uninstall(api_obj, fmris, recursive_removal=False):
-                api_obj.reset()
-                api_obj.plan_uninstall(fmris, recursive_removal)
-                api_obj.prepare()
-                api_obj.execute_plan()
-
-        def test_basics_1(self):
-                """ Send empty package [email protected], install and uninstall """
-
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.foo10)
-                self.image_create(durl)
-
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-                
-                self.pkg("list -a")
-                self.pkg("list", exit=1)
-
-                self.__do_install(api_obj, ["foo"])
-
-                self.pkg("list")
-                self.pkg("verify")
-
-                api_obj.reset()
-                self.__do_uninstall(api_obj, ["foo"])
-                self.pkg("verify")
-
-        def test_basics_2(self):
-                """ Send package [email protected], containing a directory and a file,
-                    install, search, and uninstall. """
-
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.foo10)
-                self.pkgsend_bulk(durl, self.foo11)
-                self.image_create(durl)
-
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                self.pkg("list -a")
-                self.__do_install(api_obj, ["foo"])
-
-                self.pkg("verify")
-                self.pkg("list")
-
-                self.pkg("search -l /lib/libc.so.1")
-                self.pkg("search -r /lib/libc.so.1")
-                self.pkg("search -l blah", exit = 1)
-                self.pkg("search -r blah", exit = 1)
-
-                # check to make sure timestamp was set to correct value
-
-                libc_path = os.path.join(self.get_img_path(), "lib/libc.so.1")
-                stat = os.stat(libc_path)
-
-                self.assert_(stat[ST_MTIME] == self.foo11_timestamp)
-
-                # check that verify finds changes
-                now = time.time()
-                os.utime(libc_path, (now, now))
-                self.pkg("verify", exit=1)
-
-                api_obj.reset()
-                self.__do_uninstall(api_obj, ["foo"])
-
-                self.pkg("verify")
-                self.pkg("list -a")
-                self.pkg("verify")
-
-        def test_basics_3(self):
-                """ Install [email protected], upgrade to [email protected], uninstall. """
-
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.foo10)
-                self.pkgsend_bulk(durl, self.foo11)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                self.__do_install(api_obj, ["[email protected]"])
-
-                self.pkg("list [email protected]")
-                self.pkg("list [email protected]", exit = 1)
-
-                api_obj.reset()
-                self.__do_install(api_obj, ["[email protected]"])
-                self.pkg("list [email protected]")
-                self.pkg("list [email protected]", exit = 1)
-                self.pkg("list foo@1")
-                self.pkg("verify")
-
-                api_obj.reset()
-                self.__do_uninstall(api_obj, ["foo"])
-                self.pkg("list -a")
-                self.pkg("verify")
-
-        def test_basics_4(self):
-                """ Add [email protected], dependent on [email protected], install, uninstall. """
-
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.foo10)
-                self.pkgsend_bulk(durl, self.foo11)
-                self.pkgsend_bulk(durl, self.bar10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                self.pkg("list -a")
-                api_obj.reset()
-                self.__do_install(api_obj, ["[email protected]"])
-
-                self.pkg("list")
-                self.pkg("verify")
-                api_obj.reset()
-                self.__do_uninstall(api_obj, ["bar", "foo"])
-
-                # foo and bar should not be installed at this point
-                self.pkg("list bar", exit = 1)
-                self.pkg("list foo", exit = 1)
-                self.pkg("verify")
-
-        def test_image_upgrade(self):
-                """ Send package [email protected], dependent on [email protected].  Install [email protected].
-                    List all packages.  Upgrade image. """
-
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.foo10)
-                self.pkgsend_bulk(durl, self.foo11)
-                self.pkgsend_bulk(durl, self.bar10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                self.__do_install(api_obj, ["[email protected]"])
-
-                self.pkgsend_bulk(durl, self.foo12)
-                self.pkgsend_bulk(durl, self.bar11)
-
-                self.pkg("contents -H")
-                self.pkg("list")
-                api_obj.refresh(immediate=True)
-
-                self.pkg("list")
-                self.pkg("verify")
-                api_obj.reset()
-                api_obj.plan_update_all(sys.argv[0])
-                api_obj.prepare()
-                api_obj.execute_plan()
-                self.pkg("verify")
-
-                self.pkg("list [email protected]")
-                self.pkg("list [email protected]")
-
-                api_obj.reset()
-                self.__do_uninstall(api_obj, ["bar", "foo"])
-                self.pkg("verify")
-
-
-        def test_recursive_uninstall(self):
-                """Install [email protected], dependent on [email protected], uninstall foo recursively."""
-
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.foo10)
-                self.pkgsend_bulk(durl, self.foo11)
-                self.pkgsend_bulk(durl, self.bar10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                self.__do_install(api_obj, ["[email protected]"])
-
-                # Here's the real part of the regression test;
-                # at this point foo and bar are installed, and
-                # bar depends on foo.  foo and bar should both
-                # be removed by this action.
-                self.__do_uninstall(api_obj, ["foo"], True)
-                                       
-                self.pkg("list bar", exit = 1)
-                self.pkg("list foo", exit = 1)
-
-        def test_nonrecursive_dependent_uninstall(self):
-                """Trying to remove a package that's a dependency of another
-                package should fail if the uninstall isn't recursive."""
-
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.foo10)
-                self.pkgsend_bulk(durl, self.bar10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                self.__do_install(api_obj, ["[email protected]"])
-
-                api_obj.reset()
-                self.assertRaises(api_errors.NonLeafPackageException,
-                    self.__do_uninstall, api_obj, ["foo"])
-                self.pkg("list bar")
-                self.pkg("list foo")
-
-        def test_basics_5(self):
-                """ Add [email protected], install [email protected]. """
-
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.xbar11)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                self.assertRaises(api_errors.PlanCreationException,
-                    self.__do_install, api_obj, ["[email protected]"])
-
-        def test_bug_1338(self):
-                """ Add [email protected], dependent on [email protected], install [email protected]. """
-                
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.bar11)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                self.pkg("list -a")
-
-                self.assertRaises(api_errors.PlanCreationException,
-                    self.__do_install, api_obj, ["[email protected]"])
-
-        def test_bug_1338_2(self):
-                """ Add [email protected], dependent on [email protected], and [email protected], dependent
-                    on [email protected], install [email protected] and [email protected]. """
-                
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.bar11)
-                self.pkgsend_bulk(durl, self.baz10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                self.assertRaises(api_errors.PlanCreationException,
-                    self.__do_install, api_obj, ["[email protected]", "[email protected]"])
-
-        def test_bug_1338_3(self):
-                """ Add [email protected], [email protected]. [email protected] depends on [email protected] which
-                    depends on [email protected], install [email protected]. """
-                
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.xbar10)
-                self.pkgsend_bulk(durl, self.xdeep10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                self.assertRaises(api_errors.PlanCreationException,
-                    self.__do_install, api_obj, ["[email protected]"])
-
-        def test_bug_1338_4(self):
-                """ Add [email protected]. [email protected] depends on [email protected] which depends
-                on [email protected], install [email protected]. """
-                
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.ydeep10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                self.assertRaises(api_errors.PlanCreationException,
-                    self.__do_install, api_obj, ["[email protected]"])
-
-        def test_bug_2795(self):
-                """ Try to install two versions of the same package """
-
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.foo11)
-                self.pkgsend_bulk(durl, self.foo12)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                self.assertRaises(api_errors.PlanCreationException,
-                    self.__do_install, api_obj, ["[email protected]", "[email protected]"])
-
-                self.pkg("list foo", exit = 1)
-
-                self.assertRaises(api_errors.PlanCreationException,
-                    self.__do_install, api_obj, ["[email protected]", "[email protected]"])
-
-
-                self.pkg("list foo", exit = 1)
-
-        def test_install_matching(self):
-                """ Try to [un]install packages matching a pattern """
-
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.foo10)
-                self.pkgsend_bulk(durl, self.bar10)
-                self.pkgsend_bulk(durl, self.baz10)
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-                self.__do_install(api_obj, ['ba*'])
-                self.pkg("list [email protected]", exit=0)
-                self.pkg("list [email protected]", exit=0)
-                self.pkg("list [email protected]", exit=0)
-
-                self.__do_uninstall(api_obj, ['ba*'])
-                self.pkg("list [email protected]", exit=0)
-                self.pkg("list [email protected]", exit=1)
-                self.pkg("list [email protected]", exit=1)
-
-        def test_bad_fmris(self):
-                """ Test passing problematic fmris into the api """
-
-                durl = self.dc.get_depot_url()
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                def check_unfound(e):
-                        return e.unmatched_fmris
-
-                def check_illegal(e):
-                        return e.illegal
-
-                def check_missing(e):
-                        return e.missing_matches
-
-
-                testutils.eval_assert_raises(api_errors.PlanCreationException,
-                    check_unfound, api_obj.plan_install, ["foo"])
-
-                api_obj.reset()
-                testutils.eval_assert_raises(api_errors.PlanCreationException,
-                    check_missing, api_obj.plan_uninstall, ["foo"], False)
-
-                api_obj.reset()
-                testutils.eval_assert_raises(api_errors.PlanCreationException,
-                    check_illegal, api_obj.plan_install, ["@/foo"])
-                
-                api_obj.reset()
-                testutils.eval_assert_raises(api_errors.PlanCreationException,
-                    check_illegal, api_obj.plan_uninstall, ["/foo"], False)
-
-                self.pkgsend_bulk(durl, self.foo10)
-
-                api_obj.refresh(False)
-                testutils.eval_assert_raises(api_errors.PlanCreationException,
-                    check_missing, api_obj.plan_uninstall, ["foo"], False)
-
-                api_obj.reset()
-                testutils.eval_assert_raises(api_errors.PlanCreationException,
-                    check_illegal, api_obj.plan_uninstall, ["/foo"], False)
-
-                api_obj.reset()
-                api_obj.refresh(True)
-                self.__do_install(api_obj, ["foo"])
-                self.__do_uninstall(api_obj, ["foo"])
-
-                api_obj.reset()                
-                testutils.eval_assert_raises(api_errors.PlanCreationException,
-                    check_missing, api_obj.plan_uninstall, ["foo"], False)
-
-        def test_bug_4109(self):
-                durl = self.dc.get_depot_url()
-                self.image_create(durl)
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: True, PKG_CLIENT_NAME)
-
-                def check_illegal(e):
-                        return e.illegal
-
-                api_obj.reset()
-                testutils.eval_assert_raises(api_errors.PlanCreationException,
-                    check_illegal, api_obj.plan_install, ["/foo"])
-
-        def test_catalog_v0(self):
-                """Test install from a publisher's repository that only supports
-                catalog v0, and then the transition from v0 to v1."""
-
-                self.dc.stop()
-                self.dc.set_disable_ops(["catalog/1"])
-                self.dc.start()
-
-                durl = self.dc.get_depot_url()
-                self.pkgsend_bulk(durl, self.foo10)
-                self.image_create(durl)
-
-                progresstracker = progress.NullProgressTracker()
-                api_obj = api.ImageInterface(self.get_img_path(), API_VERSION,
-                    progresstracker, lambda x: False, PKG_CLIENT_NAME)
-                self.__do_install(api_obj, ["foo"])
-
-                api_obj.reset()
-                self.__do_uninstall(api_obj, ["foo"])
- 
-                api_obj.reset()
-                self.__do_install(api_obj, ["pkg://test/foo"])
-
-                self.pkgsend_bulk(durl, self.bar10)
-                self.dc.stop()
-                self.dc.unset_disable_ops()
-                self.dc.start()
-
-                api_obj.reset()
-                api_obj.refresh(immediate=True)
-
-                api_obj.reset()
-                self.__do_install(api_obj, ["pkg://test/[email protected]"])
-
-
-if __name__ == "__main__":
-        unittest.main()
--- a/src/tests/cli/t_pkg_contents.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_contents.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,12 +20,13 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import testutils
 if __name__ == "__main__":
 	testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import unittest
 import os
@@ -33,44 +34,40 @@
 import shutil
 import difflib
 
-class TestPkgContentsBasics(testutils.SingleDepotTestCase):
+class TestPkgContentsBasics(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         bronze10 = """
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/usr
             add dir mode=0755 owner=root group=bin path=/usr/bin
-            add file /tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
+            add file tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
             add link path=/usr/bin/jsh target=./sh
-            add file /tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
-            add file /tmp/bronze2 mode=0444 owner=root group=bin path=/etc/bronze2
-            add file /tmp/bronzeA1 mode=0444 owner=root group=bin path=/A/B/C/D/E/F/bronzeA1
-            add license /tmp/copyright1 license=copyright
+            add file tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
+            add file tmp/bronze2 mode=0444 owner=root group=bin path=/etc/bronze2
+            add file tmp/bronzeA1 mode=0444 owner=root group=bin path=/A/B/C/D/E/F/bronzeA1
+            add license tmp/copyright1 license=copyright
             close
         """
 
-        misc_files = [ "/tmp/bronzeA1",  "/tmp/bronzeA2",
-                    "/tmp/bronze1", "/tmp/bronze2",
-                    "/tmp/copyright1", "/tmp/sh"]
+        # wire file contents to well known values so we're sure we
+        # know their hashes.
+        misc_files = {
+                "tmp/bronzeA1": "magic1",
+                "tmp/bronzeA2": "magic2",
+                "tmp/bronze1": "magic3",
+                "tmp/bronze2": "magic4",
+                "tmp/copyright1": "magic5",
+                "tmp/sh": "magic6",
+        }
 
         def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self)
-                for p in self.misc_files:
-                        f = open(p, "w")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(p)
-                        f.close()
-                        self.debug("wrote %s" % p)
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
 
                 self.pkgsend_bulk(self.dc.get_depot_url(), self.bronze10)
 
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-                for p in self.misc_files:
-                        os.remove(p)
-
         def assertEqualDiff(self, expected, actual):
                 self.assertEqual(expected, actual,
                     "Actual output differed from expected output.\n" +
@@ -143,20 +140,20 @@
                 # Basic -a
                 self.pkg("contents -H -o action.hash -a path=usr/bin/sh")
                 self.assert_(self.output.rstrip() ==
-                    "f2b5bfd72a6b759e4e47599f828a174a0668b243")
+                    "422bdb3eb2d613367933194e3f11220aebe56226")
 
                 # -a with a pattern
                 self.pkg("contents -H -o action.hash -a path=etc/bronze*")
                 self.assert_(self.output.splitlines() == [
-                    "28f75bcd652b188fbe0a7938265aa5d9196cb7e8",
-                    "3bb4541b7c38be84b76994cce8bc8233d5bc9720"])
+                    "02cdf31d12ccfb6d35e4b8eeff10535e22da3f7e",
+                    "b14e4cdfee720f1eab645bcbfb76eca153301715"])
 
                 # Multiple -a
                 self.pkg("contents -H -o action.hash -a path=etc/bronze1 "
                     "-a mode=0555")
                 self.assert_(self.output.splitlines() == [
-                    "28f75bcd652b188fbe0a7938265aa5d9196cb7e8",
-                    "f2b5bfd72a6b759e4e47599f828a174a0668b243"])
+                    "02cdf31d12ccfb6d35e4b8eeff10535e22da3f7e",
+                    "422bdb3eb2d613367933194e3f11220aebe56226"])
 
                 # Non-matching pattern should exit 1
                 self.pkg("contents -a path=usr/bin/notthere", 1)
--- a/src/tests/cli/t_pkg_depotd.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_depotd.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,12 +20,13 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import httplib
 import os
@@ -43,9 +44,9 @@
 import pkg.p5i as p5i
 import pkg.server.repositoryconfig as rcfg
 
-class TestPkgDepot(testutils.SingleDepotTestCase):
+class TestPkgDepot(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         foo10 = """
             open [email protected],5.11-0
@@ -60,8 +61,8 @@
         quux10 = """
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
-            add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            add file tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
             close """
 
         info10 = """
@@ -83,22 +84,11 @@
             add depend type=require fmri=pkg:/SUNWcsl
             close """
 
-        misc_files = [ "/tmp/libc.so.1", "/tmp/cat" ]
+        misc_files = [ "tmp/libc.so.1", "tmp/cat" ]
 
         def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self)
-                for p in self.misc_files:
-                        f = open(p, "w")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(p)
-                        f.close()
-                        self.debug("wrote %s" % p)
-
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-                for p in self.misc_files:
-                        os.remove(p)
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
 
         def test_depot_ping(self):
                 """ Ping the depot several times """
@@ -270,7 +260,7 @@
                 mode works and then a readonly depot again after that works.
                 """
 
-                dpath = os.path.join(self.get_test_prefix(), "repo_create")
+                dpath = os.path.join(self.test_root, "repo_create")
 
                 opath = self.dc.get_repodir()
                 self.dc.set_repodir(dpath)
@@ -331,21 +321,21 @@
                 self.dc.set_repodir(opath)
 
 
-class TestDepotController(testutils.CliTestCase):
+class TestDepotController(pkg5unittest.CliTestCase):
 
         def setUp(self):
-                testutils.CliTestCase.setUp(self)
+                pkg5unittest.CliTestCase.setUp(self)
 
                 self.__dc = dc.DepotController()
                 self.__pid = os.getpid()
                 self.__dc.set_property("publisher", "prefix", "test")
-                self.__dc.set_depotd_path(testutils.g_proto_area + \
+                self.__dc.set_depotd_path(pkg5unittest.g_proto_area + \
                     "/usr/lib/pkg.depotd")
-                self.__dc.set_depotd_content_root(testutils.g_proto_area + \
+                self.__dc.set_depotd_content_root(pkg5unittest.g_proto_area + \
                     "/usr/share/lib/pkg")
 
-                depotpath = os.path.join(self.get_test_prefix(), "depot")
-                logpath = os.path.join(self.get_test_prefix(), self.id())
+                depotpath = os.path.join(self.test_root, "depot")
+                logpath = os.path.join(self.test_root, self.id())
 
                 try:
                         os.makedirs(depotpath, misc.PKG_DIR_MODE)
@@ -356,11 +346,8 @@
                 self.__dc.set_logpath(logpath)
 
         def tearDown(self):
-                testutils.CliTestCase.tearDown(self)
-
+                pkg5unittest.CliTestCase.tearDown(self)
                 self.__dc.kill()
-                shutil.rmtree(self.__dc.get_repodir())
-                os.remove(self.__dc.get_logpath())
 
         def testStartStop(self):
                 self.__dc.set_port(12000)
@@ -371,7 +358,7 @@
                         self.assert_(not self.__dc.is_alive())
 
         def test_cfg_file(self):
-                cfg_file = os.path.join(self.get_test_prefix(), "cfg2")
+                cfg_file = os.path.join(self.test_root, "cfg2")
                 fh = open(cfg_file, "w")
                 fh.close()
                 self.__dc.set_port(12000)
@@ -381,19 +368,13 @@
         def test_writable_root(self):
                 """Tests whether the index and feed cache file are written to
                 the writable root parameter."""
-                for p in TestPkgDepot.misc_files:
-                        f = open(p, "w")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(p)
-                        f.close()
-                        self.debug("wrote %s" % p)
+                self.make_misc_files(TestPkgDepot.misc_files)
 
-                writable_root = os.path.join(self.get_test_prefix(),
+                writable_root = os.path.join(self.test_root,
                     "writ_root")
                 index_dir = os.path.join(writable_root, "index")
                 feed = os.path.join(writable_root, "feed.xml")
-                base_dir = os.path.join(self.get_test_prefix(), "depot")
+                base_dir = os.path.join(self.test_root, "depot")
                 o_index_dir = os.path.join(base_dir, "index")
                 o_feed = os.path.join(base_dir, "feed.xml")
 
@@ -457,8 +438,6 @@
                 get_feed(durl)
                 check_state(True)
                 self.pkg("search -r cat")
-                for p in TestPkgDepot.misc_files:
-                        os.remove(p)
 
         def testBadArgs(self):
                 self.__dc.set_port(12000)
@@ -543,10 +522,10 @@
                 self.assertFalse(self.__dc.is_alive())
 
 
-class TestDepotOutput(testutils.SingleDepotTestCase):
+class TestDepotOutput(pkg5unittest.SingleDepotTestCase):
         # Since these tests are output sensitive, the depots should be purged
         # after each one is run.
-        persistent_depot = False
+        persistent_setup = False
 
         quux10 = """
             open [email protected],5.11-0
@@ -600,7 +579,7 @@
         }
 
         def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self)
+                pkg5unittest.SingleDepotTestCase.setUp(self)
 
                 # All of the tests will start depot if needed.
                 self.dc.stop()
@@ -609,11 +588,8 @@
                 # tests will set as needed.
                 self.dc.clear_property("publisher", "prefix")
 
-                self.tpath = tempfile.mkdtemp()
-
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-                shutil.rmtree(self.tpath)
+                self.tpath = tempfile.mkdtemp(prefix="tpath",
+                    dir=self.test_root)
 
         def test_0_depot_bui_output(self):
                 """Verify that a non-error response and valid HTML is returned
--- a/src/tests/cli/t_pkg_help.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_help.py	Sat Jan 30 01:07:14 2010 -0800
@@ -21,27 +21,28 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import unittest
 
-class TestPkgHelp(testutils.CliTestCase):
+class TestPkgHelp(pkg5unittest.CliTestCase):
 
         def test_help(self):
                 """Verify that usage message works regardless of how it is
                 triggered."""
 
-                self.pkg("-?")
+                self.pkg("-\?")
                 self.pkg("--help")
                 self.pkg("help")
 
-                self.pkg("-? bobcat")
+                self.pkg("-\? bobcat")
                 self.pkg("--help bobcat")
                 self.pkg("help bobcat")
 
--- a/src/tests/cli/t_pkg_history.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_history.py	Sat Jan 30 01:07:14 2010 -0800
@@ -21,13 +21,14 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import re
@@ -35,9 +36,9 @@
 import time
 import unittest
 
-class TestPkgHistory(testutils.ManyDepotTestCase):
+class TestPkgHistory(pkg5unittest.ManyDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         foo1 = """
             open foo@1,5.11-0
@@ -53,7 +54,7 @@
             close """
 
         def setUp(self):
-                testutils.ManyDepotTestCase.setUp(self, ["test1", "test2"])
+                pkg5unittest.ManyDepotTestCase.setUp(self, ["test1", "test2"])
 
                 durl1 = self.dcs[1].get_depot_url()
                 self.pkgsend_bulk(durl1, self.foo1)
@@ -70,9 +71,6 @@
 
                 self.image_create(durl1, prefix="test1")
 
-        def tearDown(self):
-                testutils.ManyDepotTestCase.tearDown(self)
-
         def test_1_history_options(self):
                 """Verify all history options are accepted or rejected as
                 expected.
--- a/src/tests/cli/t_pkg_image_create.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_image_create.py	Sat Jan 30 01:07:14 2010 -0800
@@ -28,6 +28,7 @@
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import pkg.portable
@@ -36,15 +37,15 @@
 import unittest
 
 
-class TestPkgImageCreateBasics(testutils.ManyDepotTestCase):
+class TestPkgImageCreateBasics(pkg5unittest.ManyDepotTestCase):
         # Only start/stop the depots once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         def setUp(self):
                 # Extra instances of test1 are created so that a valid
                 # repository that is different than the actual test1
                 # repository can be used.
-                testutils.ManyDepotTestCase.setUp(self, ["test1", "test2",
+                pkg5unittest.ManyDepotTestCase.setUp(self, ["test1", "test2",
                     "test1", "test1"])
 
                 self.durl1 = self.dcs[1].get_depot_url()
@@ -110,7 +111,7 @@
                 """
                 self.pkgsend_bulk(self.durl1, pkgsend_data)
 
-                self.assertRaises(testutils.UnexpectedExitCodeException,
+                self.assertRaises(pkg5unittest.UnexpectedExitCodeException,
                     self.image_create, self.durl1, prefix="")
 
         def test_3588(self):
@@ -146,7 +147,7 @@
                 """Verify that all of the options for specifying publisher
                 information work as expected for image-create."""
 
-                img_path = os.path.join(self.get_test_prefix(), "test_4_img")
+                img_path = os.path.join(self.test_root, "test_4_img")
                 for opt in ("-a", "-p", "--publisher"):
                         self.pkg("image-create %s test1=%s %s" % (opt,
                             self.durl1, img_path))
@@ -188,12 +189,12 @@
 
                 pwd = os.getcwd()
                 img_path = "test_6_image"
-                abs_img_path = os.path.join(self.get_test_prefix(), img_path)
+                abs_img_path = os.path.join(self.test_root, img_path)
 
                 # Now verify that the image root isn't duplicated within the
                 # specified image root if the specified root doesn't already
                 # exist.
-                os.chdir(self.get_test_prefix())
+                os.chdir(self.test_root)
                 self.pkg("image-create -p test1=%s %s" % (self.durl1,
                     img_path))
                 os.chdir(pwd)
@@ -203,7 +204,7 @@
 
                 # Now verify that the image root isn't duplicated within the
                 # specified image root if the specified root already exists.
-                os.chdir(self.get_test_prefix())
+                os.chdir(self.test_root)
                 os.mkdir(img_path)
                 self.pkg("image-create -p test1=%s %s" % (self.durl1,
                     img_path))
@@ -315,7 +316,7 @@
                 for pl in sorted(os.listdir(inst_state_dir)):
                         # If there any other files but catalog files here, then
                         # the old state information didn't get properly removed.
-                        assert pl.startswith("catalog.")
+                        self.assert_(pl.startswith("catalog."))
 
         def test_9_bad_image_state(self):
                 """Verify that the pkg(1) command handles invalid image state
@@ -369,15 +370,15 @@
                 """Verify that pkg correctly handles permission errors during
                 image-create."""
 
-                p = os.path.join(self.get_test_prefix(), "unpriv_test_10")
+                p = os.path.join(self.test_root, "unpriv_test_10")
                 os.mkdir(p)
 
                 self.pkg("image-create -p test1=%s %s/image" % (
                     self.durl1, p), su_wrap=True, exit=1)
 
 
-class TestImageCreateNoDepot(testutils.CliTestCase):
-        persistent_depot = True
+class TestImageCreateNoDepot(pkg5unittest.CliTestCase):
+        persistent_setup = True
         def test_bad_image_create(self):
                 """ Create image from non-existent server """
 
@@ -388,44 +389,44 @@
                 # it will be universally able to be looked up.
                 #
                 durl = "http://localhost:4"
-                self.assertRaises(testutils.UnexpectedExitCodeException, \
+                self.assertRaises(pkg5unittest.UnexpectedExitCodeException, \
                     self.image_create, durl)
 
         def test_765(self):
                 """Bug 765: malformed publisher URL."""
 
                 durl = "bar=baz"
-                self.assertRaises(testutils.UnexpectedExitCodeException, \
+                self.assertRaises(pkg5unittest.UnexpectedExitCodeException, \
                     self.image_create, durl)
 
         def test_763a(self):
                 """Bug 763, traceback 1: no -p option given to image-create."""
 
-                self.assertRaises(testutils.UnexpectedExitCodeException, \
+                self.assertRaises(pkg5unittest.UnexpectedExitCodeException, \
                     self.pkg, "image-create foo")
 
         def test_763c(self):
                 """Bug 763, traceback 3: -p given to image-create, but no
                 publisher specified."""
 
-                self.assertRaises(testutils.UnexpectedExitCodeException, \
+                self.assertRaises(pkg5unittest.UnexpectedExitCodeException, \
                     self.pkg, "image-create -p foo")
 
         def test_bad_publisher_options(self):
                 """More tests that abuse the publisher prefix and URL."""
 
-                self.assertRaises(testutils.UnexpectedExitCodeException, \
+                self.assertRaises(pkg5unittest.UnexpectedExitCodeException, \
                     self.pkg, "image-create -p $%^8" + ("=http://%s1" %
                     self.bogus_url))
 
-                self.assertRaises(testutils.UnexpectedExitCodeException, \
+                self.assertRaises(pkg5unittest.UnexpectedExitCodeException, \
                     self.pkg, "image-create -p test1=http://$%^8")
 
-                self.assertRaises(testutils.UnexpectedExitCodeException, \
+                self.assertRaises(pkg5unittest.UnexpectedExitCodeException, \
                     self.pkg, "image-create -p test1=http://%s1:abcde" %
                     self.bogus_url)
 
-                self.assertRaises(testutils.UnexpectedExitCodeException, \
+                self.assertRaises(pkg5unittest.UnexpectedExitCodeException, \
                     self.pkg, "image-create -p test1=ftp://%s1" %
                     self.bogus_url)
 
--- a/src/tests/cli/t_pkg_image_update.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_image_update.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,19 +20,20 @@
 # CDDL HEADER END
 #
 
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import unittest
 import os
 
-class TestImageUpdate(testutils.ManyDepotTestCase):
+class TestImageUpdate(pkg5unittest.ManyDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         foo10 = """
             open [email protected],5.11-0
@@ -99,7 +100,7 @@
             close """
 
         def setUp(self):
-                testutils.ManyDepotTestCase.setUp(self, ["test1", "test2",
+                pkg5unittest.ManyDepotTestCase.setUp(self, ["test1", "test2",
                     "test3", "test4", "test5"])
                 durl1 = self.dcs[1].get_depot_url()
                 durl2 = self.dcs[2].get_depot_url()
--- a/src/tests/cli/t_pkg_info.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_info.py	Sat Jan 30 01:07:14 2010 -0800
@@ -26,6 +26,7 @@
 import testutils
 if __name__ == "__main__":
 	testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import difflib
 import os
@@ -33,44 +34,33 @@
 import shutil
 import unittest
 
-class TestPkgInfoBasics(testutils.SingleDepotTestCase):
+class TestPkgInfoBasics(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         bronze10 = """
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/usr
             add dir mode=0755 owner=root group=bin path=/usr/bin
-            add file /tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
+            add file tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
             add link path=/usr/bin/jsh target=./sh
-            add file /tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
-            add file /tmp/bronze2 mode=0444 owner=root group=bin path=/etc/bronze2
-            add file /tmp/bronzeA1 mode=0444 owner=root group=bin path=/A/B/C/D/E/F/bronzeA1
-            add license /tmp/copyright1 license=copyright
+            add file tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
+            add file tmp/bronze2 mode=0444 owner=root group=bin path=/etc/bronze2
+            add file tmp/bronzeA1 mode=0444 owner=root group=bin path=/A/B/C/D/E/F/bronzeA1
+            add license tmp/copyright1 license=copyright
             close
         """
 
-        misc_files = [ "/tmp/bronzeA1",  "/tmp/bronzeA2",
-                    "/tmp/bronze1", "/tmp/bronze2",
-                    "/tmp/copyright1", "/tmp/sh"]
+        misc_files = [ "tmp/bronzeA1",  "tmp/bronzeA2",
+                    "tmp/bronze1", "tmp/bronze2",
+                    "tmp/copyright1", "tmp/sh"]
 
         def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self)
-                for p in self.misc_files:
-                        f = open(p, "w")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(p)
-                        f.close()
-                        self.debug("wrote %s" % p)
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
 
                 self.pkgsend_bulk(self.dc.get_depot_url(), self.bronze10)
 
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-                for p in self.misc_files:
-                        os.remove(p)
-
         def assertEqualDiff(self, expected, actual):
                 self.assertEqual(expected, actual,
                     "Actual output differed from expected output.\n" +
--- a/src/tests/cli/t_pkg_install.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_install.py	Sat Jan 30 01:07:14 2010 -0800
@@ -28,6 +28,7 @@
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import pkg.catalog as catalog
@@ -40,9 +41,9 @@
 import urllib
 from stat import *
 
-class TestPkgInstallBasics(testutils.SingleDepotTestCase):
+class TestPkgInstallBasics(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         foo10 = """
             open [email protected],5.11-0
@@ -51,14 +52,14 @@
         foo11 = """
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/lib
-            add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1 timestamp="20080731T024051Z"
+            add file tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1 timestamp="20080731T024051Z"
             add signature pkg.sig_bit1=sig_bit_val1 pkg.sig_bit2=sig_bit_val2
             close """
         foo11_timestamp = 1217472051
 
         foo12 = """
             open [email protected],5.11-0
-            add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
+            add file tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
             close """
 
         afoo10 = """
@@ -77,14 +78,14 @@
             open [email protected],5.11-0
             add depend type=require fmri=pkg:/[email protected]
             add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
             close """
 
         bar11 = """
             open [email protected],5.11-0
             add depend type=require fmri=pkg:/[email protected]
             add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
             close """
 
         xfoo10 = """
@@ -95,14 +96,14 @@
             open [email protected],5.11-0
             add depend type=require fmri=pkg:/[email protected]
             add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
             close """
 
         xbar11 = """
             open [email protected],5.11-0
             add depend type=require fmri=pkg:/[email protected]
             add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
             close """
 
 
@@ -110,35 +111,35 @@
             open [email protected],5.11-0
             add depend type=require fmri=pkg:/[email protected]
             add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
             close """
 
         baz10 = """
             open [email protected],5.11-0
             add depend type=require fmri=pkg:/[email protected]
             add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/baz mode=0555 owner=root group=bin path=/bin/baz
+            add file tmp/baz mode=0555 owner=root group=bin path=/bin/baz
             close """
 
         deep10 = """
             open [email protected],5.11-0
             add depend type=require fmri=pkg:/[email protected]
             add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
             close """
 
         xdeep10 = """
             open [email protected],5.11-0
             add depend type=require fmri=pkg:/[email protected]
             add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
             close """
 
         ydeep10 = """
             open [email protected],5.11-0
             add depend type=require fmri=pkg:/[email protected]
             add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
             close """
 
         a6018_1 = """
@@ -152,22 +153,11 @@
             add depend type=optional fmri=a6018@1
             close """
 
-        misc_files = [ "/tmp/libc.so.1", "/tmp/cat", "/tmp/baz" ]
+        misc_files = [ "tmp/libc.so.1", "tmp/cat", "tmp/baz" ]
 
         def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self)
-                for p in self.misc_files:
-                        f = open(p, "w")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(p)
-                        f.close
-                        self.debug("wrote %s" % p)
-
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-                for p in self.misc_files:
-                        os.remove(p)
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
 
         def test_cli(self):
                 """Test bad cli options"""
@@ -508,7 +498,7 @@
                 self.pkg("install --no-refresh foo")
                 self.dc.start()
 
-class TestPkgInstallAmbiguousPatterns(testutils.SingleDepotTestCase):
+class TestPkgInstallAmbiguousPatterns(pkg5unittest.SingleDepotTestCase):
 
         # An "ambiguous" package name pattern is one which, because of the
         # pattern matching rules, might refer to more than one package.  This
@@ -630,9 +620,9 @@
                 # This is now ambiguous, should fail
                 self.pkg("install foo", exit=1)
 
-class TestPkgInstallCircularDependencies(testutils.SingleDepotTestCase):
+class TestPkgInstallCircularDependencies(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         pkg10 = """
             open [email protected],5.11-0
@@ -704,9 +694,9 @@
                 self.pkg("verify -v")
 
 
-class TestPkgInstallUpgrade(testutils.SingleDepotTestCase):
+class TestPkgInstallUpgrade(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         incorp10 = """
             open [email protected],5.11-0
@@ -751,12 +741,12 @@
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/lib
             add dir mode=0755 owner=root group=bin path=/etc
-            add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
+            add file tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
             add link path=/lib/libc.symlink target=/lib/libc.so.1
             add hardlink path=/lib/libc.hardlink target=/lib/libc.so.1
-            add file /tmp/amber1 mode=0444 owner=root group=bin path=/etc/amber1
-            add file /tmp/amber2 mode=0444 owner=root group=bin path=/etc/amber2
-            add license /tmp/copyright1 license=copyright
+            add file tmp/amber1 mode=0444 owner=root group=bin path=/etc/amber1
+            add file tmp/amber2 mode=0444 owner=root group=bin path=/etc/amber2
+            add license tmp/copyright1 license=copyright
             close
         """
 
@@ -770,14 +760,14 @@
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/usr
             add dir mode=0755 owner=root group=bin path=/usr/bin
-            add file /tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
+            add file tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
             add link path=/usr/bin/jsh target=./sh
             add hardlink path=/lib/libc.bronze target=/lib/libc.so.1
-            add file /tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
-            add file /tmp/bronze2 mode=0444 owner=root group=bin path=/etc/bronze2
-            add file /tmp/bronzeA1 mode=0444 owner=root group=bin path=/A/B/C/D/E/F/bronzeA1
+            add file tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
+            add file tmp/bronze2 mode=0444 owner=root group=bin path=/etc/bronze2
+            add file tmp/bronzeA1 mode=0444 owner=root group=bin path=/A/B/C/D/E/F/bronzeA1
             add depend fmri=pkg:/[email protected] type=require
-            add license /tmp/copyright2 license=copyright
+            add license tmp/copyright2 license=copyright
             close
         """
 
@@ -785,14 +775,14 @@
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/usr
             add dir mode=0755 owner=root group=bin path=/usr/bin
-            add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
+            add file tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
             add link path=/lib/libc.symlink target=/lib/libc.so.1
             add hardlink path=/lib/libc.amber target=/lib/libc.bronze
             add hardlink path=/lib/libc.hardlink target=/lib/libc.so.1
-            add file /tmp/amber1 mode=0444 owner=root group=bin path=/etc/amber1
-            add file /tmp/amber2 mode=0444 owner=root group=bin path=/etc/bronze2
+            add file tmp/amber1 mode=0444 owner=root group=bin path=/etc/amber1
+            add file tmp/amber2 mode=0444 owner=root group=bin path=/etc/bronze2
             add depend fmri=pkg:/[email protected] type=require
-            add license /tmp/copyright2 license=copyright
+            add license tmp/copyright2 license=copyright
             close
         """
 
@@ -800,14 +790,14 @@
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/etc
             add dir mode=0755 owner=root group=bin path=/lib
-            add file /tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
-            add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.bronze
+            add file tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
+            add file tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.bronze
             add link path=/usr/bin/jsh target=./sh
             add hardlink path=/lib/libc.bronze2.0.hardlink target=/lib/libc.so.1
-            add file /tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
-            add file /tmp/bronze2 mode=0444 owner=root group=bin path=/etc/amber2
-            add license /tmp/copyright3 license=copyright
-            add file /tmp/bronzeA2 mode=0444 owner=root group=bin path=/A1/B2/C3/D4/E5/F6/bronzeA2
+            add file tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
+            add file tmp/bronze2 mode=0444 owner=root group=bin path=/etc/amber2
+            add license tmp/copyright3 license=copyright
+            add file tmp/bronzeA2 mode=0444 owner=root group=bin path=/A1/B2/C3/D4/E5/F6/bronzeA2
             add depend fmri=pkg:/[email protected] type=require
             close
         """
@@ -816,14 +806,14 @@
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/etc
             add dir mode=0755 owner=root group=bin path=/lib
-            add file /tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
-            add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.bronze
+            add file tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
+            add file tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.bronze
             add link path=/usr/bin/jsh target=./sh
             add hardlink path=/lib/libc.bronze2.0.hardlink target=/lib/libc.so.1
-            add file /tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
-            add file /tmp/bronze2 mode=0444 owner=root group=bin path=/etc/amber2
-            add license /tmp/copyright3 license=copyright
-            add file /tmp/bronzeA2 mode=0444 owner=root group=bin path=/A1/B2/C3/D4/E5/F6/bronzeA2
+            add file tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
+            add file tmp/bronze2 mode=0444 owner=root group=bin path=/etc/amber2
+            add license tmp/copyright3 license=copyright
+            add file tmp/bronzeA2 mode=0444 owner=root group=bin path=/A1/B2/C3/D4/E5/F6/bronzeA2
             add depend fmri=pkg:/[email protected] type=require
             close
         """
@@ -831,18 +821,18 @@
 
         gold10 = """
             open [email protected],5.11-0
-            add file /tmp/gold-passwd1 mode=0644 owner=root group=bin path=etc/passwd preserve=true
-            add file /tmp/gold-group mode=0644 owner=root group=bin path=etc/group preserve=true
-            add file /tmp/gold-shadow mode=0600 owner=root group=bin path=etc/shadow preserve=true
-            add file /tmp/gold-ftpusers mode=0644 owner=root group=bin path=etc/ftpd/ftpusers preserve=true
-            add file /tmp/gold-silly mode=0644 owner=root group=bin path=etc/silly
-            add file /tmp/gold-silly mode=0644 owner=root group=bin path=etc/silly2
+            add file tmp/gold-passwd1 mode=0644 owner=root group=bin path=etc/passwd preserve=true
+            add file tmp/gold-group mode=0644 owner=root group=bin path=etc/group preserve=true
+            add file tmp/gold-shadow mode=0600 owner=root group=bin path=etc/shadow preserve=true
+            add file tmp/gold-ftpusers mode=0644 owner=root group=bin path=etc/ftpd/ftpusers preserve=true
+            add file tmp/gold-silly mode=0644 owner=root group=bin path=etc/silly
+            add file tmp/gold-silly mode=0644 owner=root group=bin path=etc/silly2
             close
         """
 
         gold20 = """
             open [email protected],5.11-0
-            add file /tmp/config2 mode=0644 owner=root group=bin path=etc/config2 original_name="gold:etc/passwd" preserve=true
+            add file tmp/config2 mode=0644 owner=root group=bin path=etc/config2 original_name="gold:etc/passwd" preserve=true
             close
         """
 
@@ -869,17 +859,17 @@
 
         silver20  = """
             open [email protected],5.11-0
-            add file /tmp/gold-passwd2 mode=0644 owner=root group=bin path=etc/passwd original_name="gold:etc/passwd" preserve=true
-            add file /tmp/gold-group mode=0644 owner=root group=bin path=etc/group original_name="gold:etc/group" preserve=true
-            add file /tmp/gold-shadow mode=0600 owner=root group=bin path=etc/shadow original_name="gold:etc/shadow" preserve=true
-            add file /tmp/gold-ftpusers mode=0644 owner=root group=bin path=etc/ftpd/ftpusers original_name="gold:etc/ftpd/ftpusers" preserve=true
-            add file /tmp/gold-silly mode=0644 owner=root group=bin path=etc/silly
-            add file /tmp/silver-silly mode=0644 owner=root group=bin path=etc/silly2
+            add file tmp/gold-passwd2 mode=0644 owner=root group=bin path=etc/passwd original_name="gold:etc/passwd" preserve=true
+            add file tmp/gold-group mode=0644 owner=root group=bin path=etc/group original_name="gold:etc/group" preserve=true
+            add file tmp/gold-shadow mode=0600 owner=root group=bin path=etc/shadow original_name="gold:etc/shadow" preserve=true
+            add file tmp/gold-ftpusers mode=0644 owner=root group=bin path=etc/ftpd/ftpusers original_name="gold:etc/ftpd/ftpusers" preserve=true
+            add file tmp/gold-silly mode=0644 owner=root group=bin path=etc/silly
+            add file tmp/silver-silly mode=0644 owner=root group=bin path=etc/silly2
             close
         """
         silver30  = """
             open [email protected],5.11-0
-            add file /tmp/config2 mode=0644 owner=root group=bin path=etc/config2 original_name="gold:etc/passwd" preserve=true
+            add file tmp/config2 mode=0644 owner=root group=bin path=etc/config2 original_name="gold:etc/passwd" preserve=true
             close
         """
 
@@ -893,14 +883,14 @@
         iron10 = """
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=etc
-            add file /tmp/config1 mode=0644 owner=root group=bin path=etc/foo
+            add file tmp/config1 mode=0644 owner=root group=bin path=etc/foo
             add hardlink path=etc/foo.link target=foo
             close
         """
         iron20 = """
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=etc
-            add file /tmp/config2 mode=0644 owner=root group=bin path=etc/foo
+            add file tmp/config2 mode=0644 owner=root group=bin path=etc/foo
             add hardlink path=etc/foo.link target=foo
             close
         """
@@ -916,8 +906,8 @@
             open dricon@1
             add dir path=/tmp mode=755 owner=root group=root
             add dir path=/etc mode=755 owner=root group=root
-            add file /tmp/dricon_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
-            add file /tmp/dricon_n2m path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
+            add file tmp/dricon_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
+            add file tmp/dricon_n2m path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
             close
         """
 
@@ -925,8 +915,8 @@
             open dricon@2
             add dir path=/tmp mode=755 owner=root group=root
             add dir path=/etc mode=755 owner=root group=root
-            add file /tmp/dricon2_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
-            add file /tmp/dricon_n2m path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
+            add file tmp/dricon2_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
+            add file tmp/dricon_n2m path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
             add driver name=zigit alias=pci8086,1234
             close
         """
@@ -935,8 +925,8 @@
             open dricon@3
             add dir path=/tmp mode=755 owner=root group=root
             add dir path=/etc mode=755 owner=root group=root
-            add file /tmp/dricon2_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
-            add file /tmp/dricon_n2m path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
+            add file tmp/dricon2_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
+            add file tmp/dricon_n2m path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
             add driver name=zigit alias=pci8086,1234
             add driver name=figit alias=pci8086,1234
             close
@@ -947,9 +937,9 @@
             add dir path=/tmp mode=755 owner=root group=root
             add dir path=/etc mode=755 owner=root group=root
             add dir path=/etc/security mode=755 owner=root group=root
-            add file /tmp/dricon2_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
-            add file /tmp/dricon_n2m path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
-            add file /tmp/dripol1_dp path=/etc/security/device_policy mode=644 owner=root group=sys preserve=true
+            add file tmp/dricon2_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
+            add file tmp/dricon_n2m path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
+            add file tmp/dripol1_dp path=/etc/security/device_policy mode=644 owner=root group=sys preserve=true
             add driver name=frigit policy="read_priv_set=net_rawaccess write_priv_set=net_rawaccess"
             close
         """
@@ -959,9 +949,9 @@
             add dir path=/tmp mode=755 owner=root group=root
             add dir path=/etc mode=755 owner=root group=root
             add dir path=/etc/security mode=755 owner=root group=root
-            add file /tmp/dricon2_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
-            add file /tmp/dricon_n2m path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
-            add file /tmp/dripol1_dp path=/etc/security/device_policy mode=644 owner=root group=sys preserve=true
+            add file tmp/dricon2_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
+            add file tmp/dricon_n2m path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
+            add file tmp/dripol1_dp path=/etc/security/device_policy mode=644 owner=root group=sys preserve=true
             add driver name=frigit
             close
         """
@@ -969,57 +959,57 @@
 	liveroot10 = """
             open [email protected]
             add dir path=/etc mode=755 owner=root group=root
-            add file /tmp/liveroot1 path=/etc/liveroot mode=644 owner=root group=sys reboot-needed=true
+            add file tmp/liveroot1 path=/etc/liveroot mode=644 owner=root group=sys reboot-needed=true
             close
         """
 	liveroot20 = """
             open [email protected]
             add dir path=/etc mode=755 owner=root group=root
-            add file /tmp/liveroot2 path=/etc/liveroot mode=644 owner=root group=sys reboot-needed=true
+            add file tmp/liveroot2 path=/etc/liveroot mode=644 owner=root group=sys reboot-needed=true
+            add file tmp/liveroot2 path=/etc/liveroot mode=644 owner=root group=sys reboot-needed=true
             close
         """
 
-        misc_files = [
-            "/tmp/amber1", "/tmp/amber2", "/tmp/bronzeA1",  "/tmp/bronzeA2",
-            "/tmp/bronze1", "/tmp/bronze2",
-            "/tmp/copyright1", "/tmp/copyright2",
-            "/tmp/copyright3", "/tmp/copyright4",
-            "/tmp/libc.so.1", "/tmp/sh", "/tmp/config1", "/tmp/config2",
-            "/tmp/gold-passwd1", "/tmp/gold-passwd2", "/tmp/gold-group",
-            "/tmp/gold-shadow", "/tmp/gold-ftpusers", "/tmp/gold-silly",
-            "/tmp/silver-silly",
-            "/tmp/dricon_da", "/tmp/dricon2_da", "/tmp/dricon_n2m",
-            "/tmp/dripol1_dp", "/tmp/liveroot1", "/tmp/liveroot2"
+        misc_files1 = [
+            "tmp/amber1", "tmp/amber2", "tmp/bronzeA1",  "tmp/bronzeA2",
+            "tmp/bronze1", "tmp/bronze2",
+            "tmp/copyright1", "tmp/copyright2",
+            "tmp/copyright3", "tmp/copyright4",
+            "tmp/libc.so.1", "tmp/sh", "tmp/config1", "tmp/config2",
+            "tmp/gold-passwd1", "tmp/gold-passwd2", "tmp/gold-group",
+            "tmp/gold-shadow", "tmp/gold-ftpusers", "tmp/gold-silly",
+            "tmp/silver-silly",
+            "tmp/liveroot1", "tmp/liveroot2"
         ]
 
-        misc_files_contents = {
-            "/tmp/dricon_da": """\
+        misc_files2 = {
+            "tmp/dricon_da": """\
 wigit "pci8086,1234"
 wigit "pci8086,4321"
 # someother "pci8086,1234"
 foobar "pci8086,9999"
 """,
-            "/tmp/dricon2_da": """\
+            "tmp/dricon2_da": """\
 zigit "pci8086,1234"
 wigit "pci8086,4321"
 # someother "pci8086,1234"
 foobar "pci8086,9999"
 """,
-            "/tmp/dricon_n2m": """\
+            "tmp/dricon_n2m": """\
 wigit 1
 foobar 2
 """,
-            "/tmp/dripol1_dp": """\
+            "tmp/dripol1_dp": """\
 *		read_priv_set=none		write_priv_set=none
 """,
-            "/tmp/gold-passwd1": """\
+            "tmp/gold-passwd1": """\
 root:x:0:0::/root:/usr/bin/bash
 daemon:x:1:1::/:
 bin:x:2:2::/usr/bin:
 sys:x:3:3::/:
 adm:x:4:4:Admin:/var/adm:
 """,
-            "/tmp/gold-passwd2": """\
+            "tmp/gold-passwd2": """\
 root:x:0:0::/root:/usr/bin/bash
 daemon:x:1:1::/:
 bin:x:2:2::/usr/bin:
@@ -1027,21 +1017,21 @@
 adm:x:4:4:Admin:/var/adm:
 bogus:x:10001:10001:Bogus User:/:
 """,
-            "/tmp/gold-group": """\
+            "tmp/gold-group": """\
 root::0:
 other::1:root
 bin::2:root,daemon
 sys::3:root,bin,adm
 adm::4:root,daemon
 """,
-            "/tmp/gold-shadow": """\
+            "tmp/gold-shadow": """\
 root:9EIfTNBp9elws:13817::::::
 daemon:NP:6445::::::
 bin:NP:6445::::::
 sys:NP:6445::::::
 adm:NP:6445::::::
 """,
-            "/tmp/gold-ftpusers": """\
+            "tmp/gold-ftpusers": """\
 root
 bin
 sys
@@ -1062,20 +1052,9 @@
 
 
         def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self)
-                for p in self.misc_files:
-                        f = open(p, "w")
-                        # If no contents are specified, write the name of the
-                        # file into the file, so that all files have differing
-                        # contents
-                        f.write(self.misc_files_contents.get(p, p))
-                        f.close()
-                        self.debug("wrote %s" % p)
-
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-                for p in self.misc_files:
-                        os.remove(p)
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                self.make_misc_files(self.misc_files1)
+                self.make_misc_files(self.misc_files2)
 
         def test_incorp_install(self):
                 """Make sure we don't round up packages we specify on
@@ -1420,11 +1399,12 @@
                         self.assert_(False, "File %s does not contain %s" % (path, string))
 
 
-class TestPkgInstallActions(testutils.SingleDepotTestCase):
+class TestPkgInstallActions(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
-
-        ftpusers_data = \
+        persistent_setup = True
+
+        misc_files = {
+                "ftpusers" :
 """# ident      "@(#)ftpusers   1.6     06/11/21 SMI"
 #
 # List of users denied access to the FTP server, see ftpusers(4).
@@ -1433,30 +1413,32 @@
 bin
 sys
 adm
-"""
-        group_data = \
+""",
+                "group" :
 """root::0:
 other::1:root
 bin::2:root,daemon
 sys::3:root,bin,adm
 adm::4:root,daemon
-"""
-        passwd_data = \
+""",
+                "passwd" :
 """root:x:0:0::/root:/usr/bin/bash
 daemon:x:1:1::/:
 bin:x:2:2::/usr/bin:
 sys:x:3:3::/:
 adm:x:4:4:Admin:/var/adm:
-"""
-        shadow_data = \
+""",
+                "shadow" :
 """root:9EIfTNBp9elws:13817::::::
 daemon:NP:6445::::::
 bin:NP:6445::::::
 sys:NP:6445::::::
 adm:NP:6445::::::
-"""
-
-        cat_data = " "
+""",
+                "cat" : " ",
+                "empty" : ""
+        }
+
 
         foo10 = """
             open [email protected],5.11-0
@@ -1517,45 +1499,37 @@
             add dir mode=0755 owner=Kermit group=adm path=/export/home/Kermit
             close """
 
-        empty_data = ""
-
-        misc_files = [ "empty", "ftpusers", "group", "passwd", "shadow", "cat" ]
-
-        testdata_dir = None
-
+        # some of these are subsets-- "always" and "at-end"-- for performance;
+        # we assume that e.g. if a and z work, that bcdef, etc. will too.
         pkg_name_valid_chars = {
             "never": " `~!@#$%^&*()=[{]}\\|;:\",<>?",
-            "always": "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ",
+            "always": "09azAZ",
             "after-first": "_/-.+",
-            "at-end": "0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-.+",
+            "at-end": "09azAZ_-.+",
         }
 
         def setUp(self):
 
-                testutils.SingleDepotTestCase.setUp(self)
-                tp = self.get_test_prefix()
-                self.testdata_dir = os.path.join(tp, "testdata")
-                os.mkdir(self.testdata_dir)
-
+                pkg5unittest.SingleDepotTestCase.setUp(self)
 
                 self.only_file10 = """
                     open [email protected],5.11-0
-                    add file """ + self.testdata_dir + """/cat mode=0555 owner=root group=bin path=/cat
+                    add file cat mode=0555 owner=root group=bin path=/cat
                     close """
 
                 self.only_license10 = """
                     open [email protected],5.11-0
-                    add license """ + self.testdata_dir + """/cat license=copyright
+                    add license cat license=copyright
                     close """
 
                 self.basics0 = """
                     open [email protected],5.11-0
-                    add file """ + self.testdata_dir + """/passwd mode=0644 owner=root group=sys path=etc/passwd preserve=true
-                    add file """ + self.testdata_dir + """/shadow mode=0400 owner=root group=sys path=etc/shadow preserve=true
-                    add file """ + self.testdata_dir + """/group mode=0644 owner=root group=sys path=etc/group preserve=true
-                    add file """ + self.testdata_dir + """/ftpusers mode=0644 owner=root group=sys path=etc/ftpd/ftpusers preserve=true
-                    add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=sys path=etc/name_to_major preserve=true
-                    add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=sys path=etc/driver_aliases preserve=true
+                    add file passwd mode=0644 owner=root group=sys path=etc/passwd preserve=true
+                    add file shadow mode=0400 owner=root group=sys path=etc/shadow preserve=true
+                    add file group mode=0644 owner=root group=sys path=etc/group preserve=true
+                    add file ftpusers mode=0644 owner=root group=sys path=etc/ftpd/ftpusers preserve=true
+                    add file empty mode=0644 owner=root group=sys path=etc/name_to_major preserve=true
+                    add file empty mode=0644 owner=root group=sys path=etc/driver_aliases preserve=true
                     add dir mode=0755 owner=root group=sys path=etc
                     add dir mode=0755 owner=root group=sys path=etc/ftpd
                     close """
@@ -1573,7 +1547,7 @@
                 self.grouptest = """
                     open [email protected],5.11-0
                     add dir mode=0755 owner=root group=Kermit path=/usr/Kermit
-                    add file """ + self.testdata_dir + """/empty mode=0755 owner=root group=Kermit path=/usr/local/bin/do_group_nothing
+                    add file empty mode=0755 owner=root group=Kermit path=/usr/local/bin/do_group_nothing
                     add group groupname=lp gid=8
                     add group groupname=staff gid=10
                     add group groupname=Kermit
@@ -1583,7 +1557,7 @@
                 self.usertest10 = """
                     open [email protected],5.11-0
                     add dir mode=0755 owner=Kermit group=Kermit path=/export/home/Kermit
-                    add file """ + self.testdata_dir + """/empty mode=0755 owner=Kermit group=Kermit path=/usr/local/bin/do_user_nothing
+                    add file empty mode=0755 owner=Kermit group=Kermit path=/usr/local/bin/do_user_nothing
                     add depend fmri=pkg:/[email protected] type=require
                     add user username=Kermit group=Kermit home-dir=/export/home/Kermit group-list=lp group-list=staff
                     add depend fmri=pkg:/[email protected] type=require
@@ -1593,7 +1567,7 @@
                 self.usertest11 = """
                     open [email protected],5.11-0
                     add dir mode=0755 owner=Kermit group=Kermit path=/export/home/Kermit
-                    add file """ + self.testdata_dir + """/empty mode=0755 owner=Kermit group=Kermit path=/usr/local/bin/do_user_nothing
+                    add file empty mode=0755 owner=Kermit group=Kermit path=/usr/local/bin/do_user_nothing
                     add depend fmri=pkg:/[email protected] type=require
                     add user username=Kermit group=Kermit home-dir=/export/home/Kermit2 group-list=lp group-list=staff group-list=root ftpuser=false
                     add depend fmri=pkg:/[email protected] type=require
@@ -1608,13 +1582,13 @@
 
                 self.silver10 = """
                     open [email protected],5.11-0
-                    add file """ + self.testdata_dir + """/empty mode=0755 owner=root group=root path=/usr/local/bin/silver
+                    add file empty mode=0755 owner=root group=root path=/usr/local/bin/silver
                     add depend fmri=pkg:/[email protected] type=require
                     add depend fmri=pkg:/[email protected] type=require
                     close """
                 self.silver20 = """
                     open [email protected],5.11-0
-                    add file """ + self.testdata_dir + """/empty mode=0755 owner=Kermit group=Kermit path=/usr/local/bin/silver
+                    add file empty mode=0755 owner=Kermit group=Kermit path=/usr/local/bin/silver
                     add user username=Kermit group=Kermit home-dir=/export/home/Kermit group-list=lp group-list=staff
                     add depend fmri=pkg:/[email protected] type=require
                     add depend fmri=pkg:/[email protected] type=require
@@ -1626,13 +1600,13 @@
                     add dir mode=0755 owner=root group=root path=/tmp
                     add dir mode=0755 owner=root group=root path=/etc
                     add dir mode=0755 owner=root group=root path=/etc/security
-                    add file """ + self.testdata_dir + """/empty mode=0600 owner=root group=root path=/etc/devlink.tab preserve=true
-                    add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=sys path=/etc/name_to_major preserve=true
-                    add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=sys path=/etc/driver_aliases preserve=true
-                    add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=sys path=/etc/driver_classes preserve=true
-                    add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=sys path=/etc/minor_perm preserve=true
-                    add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=root path=/etc/security/device_policy preserve=true
-                    add file """ + self.testdata_dir + """/empty mode=0644 owner=root group=sys path=/etc/security/extra_privs preserve=true
+                    add file empty mode=0600 owner=root group=root path=/etc/devlink.tab preserve=true
+                    add file empty mode=0644 owner=root group=sys path=/etc/name_to_major preserve=true
+                    add file empty mode=0644 owner=root group=sys path=/etc/driver_aliases preserve=true
+                    add file empty mode=0644 owner=root group=sys path=/etc/driver_classes preserve=true
+                    add file empty mode=0644 owner=root group=sys path=/etc/minor_perm preserve=true
+                    add file empty mode=0644 owner=root group=root path=/etc/security/device_policy preserve=true
+                    add file empty mode=0644 owner=root group=sys path=/etc/security/extra_privs preserve=true
                     close
                 """
 
@@ -1660,7 +1634,7 @@
 
                 self.badhardlink2 = """
                     open [email protected],5.11-0
-                    add file """ + self.testdata_dir + """/cat mode=0555 owner=root group=bin path=/etc/motd
+                    add file cat mode=0555 owner=root group=bin path=/etc/motd
                     add hardlink path=foo target=/etc/motd
                     close
                 """
@@ -1672,18 +1646,7 @@
                     close
                 """
 
-                for f in self.misc_files:
-                        filename = os.path.join(self.testdata_dir, f)
-                        file_handle = open(filename, 'wb')
-                        try:
-                                file_handle.write(eval("self.%s_data" % f))
-                        finally:
-                                file_handle.close()
-
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-                if self.testdata_dir:
-                        shutil.rmtree(self.testdata_dir)
+                self.make_misc_files(self.misc_files)
 
         def test_basics_0(self):
                 """Send basic infrastructure, install and uninstall."""
@@ -1933,30 +1896,22 @@
                 unused."""
 
                 durl = self.dc.get_depot_url()
+                self.pkgsend_bulk(durl, self.basics0)
                 self.pkgsend_bulk(durl, self.ugidtest)
                 self.image_create(durl)
 
-                os.mkdir(os.path.join(self.get_img_path(), "etc"))
-                os.mkdir(os.path.join(self.get_img_path(), "etc/ftpd"))
-                for f in self.misc_files:
-                        dir = "etc"
-                        if f == "ftpusers":
-                                dir = "etc/ftpd"
-                        filename = os.path.join(self.get_img_path(), dir, f)
-                        file_handle = open(filename, 'wb')
-                        exec("%s_path = \"%s\"" % (f, filename))
-                        try:
-                                file_handle.write(eval("self.%s_data" % f))
-                        finally:
-                                file_handle.close()
+                # This will lay down the sample passwd file, group file, etc.
+                self.pkg("install basics")
 
                 self.pkg("install ugidtest")
-                passwd_file = file(passwd_path)
+                passwd_file = file(os.path.join(self.get_img_path(),
+                    "/etc/passwd"))
                 for line in passwd_file:
                         if line.startswith("dummy"):
                                 self.assert_(line.startswith("dummy:x:5:"))
                 passwd_file.close()
-                group_file = file(group_path)
+                group_file = file(os.path.join(self.get_img_path(),
+                    "/etc/group"))
                 for line in group_file:
                         if line.startswith("dummy"):
                                 self.assert_(line.startswith("dummy::5:"))
@@ -1982,7 +1937,7 @@
                 self.pkg("verify -v")
 
         def test_invalid_open(self):
-                """Send a invalid package definition (invalid fmri); expect
+                """Send invalid package definitions (invalid fmris); expect
                 failure."""
 
                 durl = self.dc.get_depot_url()
@@ -2004,8 +1959,7 @@
                         self.pkgsend(durl, cmd, exit=1)
 
         def test_valid_open(self):
-                """Send a invalid package definition (valid fmri); expect
-                success."""
+                """Send a series of valid packages; expect success."""
 
                 durl = self.dc.get_depot_url()
                 for char in self.pkg_name_valid_chars["always"]:
@@ -2291,9 +2245,9 @@
 
                 self.pkg("install dirshouldbelink", exit=1)
 
-class TestDependencies(testutils.SingleDepotTestCase):
+class TestDependencies(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         pkg10 = """
             open [email protected],5.11-0
@@ -2445,7 +2399,7 @@
 
 
         def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self)
+                pkg5unittest.SingleDepotTestCase.setUp(self)
                 durl = self.dc.get_depot_url()
                 self.pkgsend_bulk(durl, self.pkg10)
                 self.pkgsend_bulk(durl, self.pkg20)
@@ -2567,9 +2521,9 @@
                 self.pkg("install bug_7394_incorp")
                 self.pkg("install pkg1", exit=1)
 
-class TestMultipleDepots(testutils.ManyDepotTestCase):
+class TestMultipleDepots(pkg5unittest.ManyDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         foo10 = """
             open [email protected],5.11-0
@@ -2647,7 +2601,7 @@
                     depot4 is not mapped during setUp"""
 
                 # Two depots are intentionally started for test2.
-                testutils.ManyDepotTestCase.setUp(self, ["test1", "test2",
+                pkg5unittest.ManyDepotTestCase.setUp(self, ["test1", "test2",
                     "test3", "test2", "test4"])
 
                 durl1 = self.dcs[1].get_depot_url()
@@ -2673,9 +2627,6 @@
                 # Create second publisher using depot #2
                 self.pkg("set-publisher -O " + durl2 + " test2")
 
-        def tearDown(self):
-                testutils.ManyDepotTestCase.tearDown(self)
-
         def test_01_basics(self):
                 self.pkg("list -a")
 
@@ -3061,14 +3012,14 @@
                 self.pkg("publisher")
                 self.pkg("install [email protected]", exit=1)
        
-class TestImageCreateCorruptImage(testutils.SingleDepotTestCaseCorruptImage):
+class TestImageCreateCorruptImage(pkg5unittest.SingleDepotTestCaseCorruptImage):
         """
         If a new essential directory is added to the format of an image it will
         be necessary to update this test suite. To update this test suite,
         decide in what ways it is necessary to corrupt the image (removing the
         new directory or file, or removing the some or all of contents of the
         new directory for example). Make the necessary changes in
-        testutils.SingleDepotTestCaseCorruptImage to allow the needed
+        pkg5unittest.SingleDepotTestCaseCorruptImage to allow the needed
         corruptions, then add new tests to the suite below. Be sure to add
         tests for both Full and User images, and perhaps Partial images if
         situations are found where these behave differently than Full or User
@@ -3076,35 +3027,24 @@
         """
 
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         foo11 = """
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/lib
-            add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
+            add file tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
             close """
 
-        misc_files = [ "/tmp/libc.so.1" ]
+        misc_files = [ "tmp/libc.so.1" ]
 
         PREFIX = "unset PKG_IMAGE; cd %s"
 
         def setUp(self):
-                testutils.SingleDepotTestCaseCorruptImage.setUp(self)
-                for p in self.misc_files:
-                        f = open(p, "w")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(p)
-                        f.close()
-                        self.debug("wrote %s" % p)
-
-        def tearDown(self):
-                testutils.SingleDepotTestCaseCorruptImage.tearDown(self)
-                for p in self.misc_files:
-                        os.remove(p)
+                pkg5unittest.SingleDepotTestCaseCorruptImage.setUp(self)
+                self.make_misc_files(self.misc_files)
 
         def pkg(self, command, exit=0, comment=""):
-                testutils.SingleDepotTestCaseCorruptImage.pkg(self, command,
+                pkg5unittest.SingleDepotTestCaseCorruptImage.pkg(self, command,
                     exit=exit, comment=comment, prefix=self.PREFIX % self.dir)
 
         # For each test:
@@ -3427,11 +3367,10 @@
                 self.pkg("install [email protected]")
 
 
-class TestPkgInstallObsolete(testutils.SingleDepotTestCase):
+class TestPkgInstallObsolete(pkg5unittest.SingleDepotTestCase):
         """Test cases for obsolete packages."""
 
-        persistent_depot = True
-
+        persistent_setup = True
         def test_basic(self):
                 foo1 = """
                     open foo@1
@@ -4187,7 +4126,7 @@
                 self.pkg("list inc2p2", exit=1)
 
 
-class TestPkgInstallMultiObsolete(testutils.ManyDepotTestCase):
+class TestPkgInstallMultiObsolete(pkg5unittest.ManyDepotTestCase):
         """Tests involving obsolete packages and multiple publishers."""
 
         obs = """
@@ -4201,10 +4140,10 @@
             close
         """
 
-        persistent_depot = True
+        persistent_setup = True
 
         def setUp(self):
-                testutils.ManyDepotTestCase.setUp(self, ["test1", "test2"])
+                pkg5unittest.ManyDepotTestCase.setUp(self, ["test1", "test2"])
 
         def test_01(self):
                 """If an obsolete package is found in a preferred publisher and
@@ -4252,7 +4191,7 @@
                 self.pkg("install stem", exit=1)
 
 
-class TestPkgInstallLicense(testutils.SingleDepotTestCase):
+class TestPkgInstallLicense(pkg5unittest.SingleDepotTestCase):
         """Tests involving one or more packages that require license acceptance
         or display."""
 
@@ -4260,14 +4199,14 @@
 
         baz10 = """
             open [email protected],5.11-0
-            add license $test_prefix/copyright.baz license=copyright.baz
+            add license copyright.baz license=copyright.baz
             close """
 
         # First iteration has just a copyright.
         licensed10 = """
             open [email protected],5.11-0
             add depend type=require [email protected]
-            add license $test_prefix/copyright.licensed license=copyright.licensed
+            add license copyright.licensed license=copyright.licensed
             close """
 
         # Second iteration has copyright that must-display and a new license
@@ -4275,39 +4214,26 @@
         licensed12 = """
             open [email protected],5.11-0
             add depend type=require [email protected]
-            add file $test_prefix/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
-            add license $test_prefix/copyright.licensed license=copyright.licensed must-display=True
-            add license $test_prefix/license.licensed license=license.licensed
+            add file libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
+            add license copyright.licensed license=copyright.licensed must-display=True
+            add license license.licensed license=license.licensed
             close """
 
         # Third iteration now requires acceptance of license.
         licensed13 = """
             open [email protected],5.11-0
             add depend type=require [email protected]
-            add file $test_prefix/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
-            add license $test_prefix/copyright.licensed license=copyright.licensed must-display=True
-            add license $test_prefix/license.licensed license=license.licensed must-accept=True
+            add file libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
+            add license copyright.licensed license=copyright.licensed must-display=True
+            add license license.licensed license=license.licensed must-accept=True
             close """
 
         misc_files = ["copyright.baz", "copyright.licensed", "libc.so.1",
             "license.licensed", "license.licensed.addendum"]
 
         def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self, publisher="bobcat")
-
-                for p in ("baz10", "licensed10", "licensed12", "licensed13"):
-                        val = getattr(self, p).replace("$test_prefix",
-                            self.get_test_prefix())
-                        setattr(self, p, val)
-
-                for p in self.misc_files:
-                        fpath = os.path.join(self.get_test_prefix(), p)
-                        f = open(fpath, "wb")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(fpath)
-                        f.close()
-                        self.debug("wrote %s" % fpath)
+                pkg5unittest.SingleDepotTestCase.setUp(self, publisher="bobcat")
+                self.make_misc_files(self.misc_files)
 
                 durl = self.dc.get_depot_url()
                 plist = self.pkgsend_bulk(durl, self.licensed10 + \
@@ -4328,16 +4254,16 @@
 
                 # Verify that --licenses include the license in output.
                 self.pkg("install -n --licenses [email protected] | "
-                    "grep '/license.licensed'")
+                    "grep 'license.licensed'")
 
                 # Verify that licenses are not included in -n output if
                 # --licenses is not provided.
-                self.pkg("install -n [email protected] | grep '/copyright.licensed'",
+                self.pkg("install -n [email protected] | grep 'copyright.licensed'",
                     exit=1)
 
                 # Next, check that an upgrade succeeds when a license requires
                 # display and that the license will be displayed.
-                self.pkg("install [email protected] | grep '/copyright.licensed'")
+                self.pkg("install [email protected] | grep 'copyright.licensed'")
 
                 # Next, check that an image-update fails if the user has not
                 # specified --accept and a license requires acceptance.
@@ -4345,11 +4271,11 @@
 
                 # Verify that licenses are not included in -n output if
                 # --licenses is not provided.
-                self.pkg("image-update -n | grep '/copyright.licensed", exit=1)
+                self.pkg("image-update -n | grep 'copyright.licensed", exit=1)
 
                 # Verify that --licenses include the license in output.
                 self.pkg("image-update -n --licenses | "
-                    "grep '/license.licensed'")
+                    "grep 'license.licensed'")
 
                 # Next, check that an image-update succeeds if the user has
                 # specified --accept and a license requires acceptance.
--- a/src/tests/cli/t_pkg_intent.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_intent.py	Sat Jan 30 01:07:14 2010 -0800
@@ -28,6 +28,7 @@
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import time
@@ -42,7 +43,7 @@
 API_VERSION = 31
 PKG_CLIENT_NAME = "pkg"
 
-class TestPkgIntent(testutils.SingleDepotTestCase):
+class TestPkgIntent(pkg5unittest.SingleDepotTestCase):
 
         foo10 = """
             open [email protected],5.11-0
@@ -51,60 +52,49 @@
         foo11 = """
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/lib
-            add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1 timestamp="20080731T024051Z"
+            add file tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1 timestamp="20080731T024051Z"
             close """
         foo11_timestamp = 1217472051
 
         foo12 = """
             open [email protected],5.11-0
-            add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
+            add file tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.so.1
             close """
 
         bar10 = """
             open [email protected],5.11-0
             add depend type=require fmri=pkg:/[email protected]
             add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
             close """
 
         bar11 = """
             open [email protected],5.11-0
             add depend type=require fmri=pkg:/[email protected]
             add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat
             close """
 
         bar12 = """
             open [email protected],5.11-0
             add depend type=require fmri=pkg:/[email protected]
             add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/cat mode=0555 owner=root group=bin path=/bin/cat 
+            add file tmp/cat mode=0555 owner=root group=bin path=/bin/cat 
             close """
 
         baz10 = """
             open [email protected],5.11-0
             add depend type=require fmri=pkg:/[email protected]
             add dir mode=0755 owner=root group=bin path=/bin
-            add file /tmp/baz mode=0555 owner=root group=bin path=/bin/baz
+            add file tmp/baz mode=0555 owner=root group=bin path=/bin/baz
             close """
 
-        misc_files = [ "/tmp/libc.so.1", "/tmp/cat", "/tmp/baz" ]
+        misc_files = [ "tmp/libc.so.1", "tmp/cat", "tmp/baz" ]
 
         def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self,
+                pkg5unittest.SingleDepotTestCase.setUp(self,
                     debug_features=["headers"])
-                for p in self.misc_files:
-                        f = open(p, "w")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(p)
-                        f.close
-                        self.debug("wrote %s" % p)
-
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-                for p in self.misc_files:
-                        os.remove(p)
+                self.make_misc_files(self.misc_files)
 
         def get_intent_entries(self):
                 """Scan logpath looking for request header log entries for
--- a/src/tests/cli/t_pkg_list.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_list.py	Sat Jan 30 01:07:14 2010 -0800
@@ -28,6 +28,7 @@
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import calendar
 import difflib
@@ -37,9 +38,9 @@
 import simplejson as json
 import unittest
 
-class TestPkgList(testutils.ManyDepotTestCase):
+class TestPkgList(pkg5unittest.ManyDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         foo1 = """
             open foo@1,5.11-0
@@ -70,7 +71,7 @@
             close """
 
         def setUp(self):
-                testutils.ManyDepotTestCase.setUp(self, ["test1", "test2",
+                pkg5unittest.ManyDepotTestCase.setUp(self, ["test1", "test2",
                     "test3"])
 
                 durl1 = self.dcs[1].get_depot_url()
@@ -112,9 +113,6 @@
                         expected.splitlines(), actual.splitlines(),
                         "Expected output", "Actual output", lineterm="")))
 
-        def tearDown(self):
-                testutils.ManyDepotTestCase.tearDown(self)
-
         def test_pkg_list_cli_opts(self):
 
                 self.pkg("list -@", exit=2)
--- a/src/tests/cli/t_pkg_property.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_property.py	Sat Jan 30 01:07:14 2010 -0800
@@ -21,13 +21,14 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
 import testutils
 if __name__ == "__main__":
 	testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import unittest
 import os
@@ -35,9 +36,9 @@
 import shutil
 import difflib
 
-class TestPkgInfoBasics(testutils.SingleDepotTestCase):
+class TestPkgInfoBasics(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         def test_pkg_properties(self):
                 """pkg: set, unset, and display properties"""
--- a/src/tests/cli/t_pkg_publisher.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_publisher.py	Sat Jan 30 01:07:14 2010 -0800
@@ -21,21 +21,22 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import unittest
 import os
 import tempfile
 
-class TestPkgPublisherBasics(testutils.SingleDepotTestCase):
+class TestPkgPublisherBasics(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         def test_pkg_publisher_bogus_opts(self):
                 """ pkg bogus option checks """
@@ -217,9 +218,8 @@
 
                 # Now change the first publisher to a https URL so that
                 # certificate failure cases can be tested.
-                key_fh, key_path = tempfile.mkstemp(dir=self.get_test_prefix())
-                cert_fh, cert_path = tempfile.mkstemp(
-                    dir=self.get_test_prefix())
+                key_fh, key_path = tempfile.mkstemp(dir=self.test_root)
+                cert_fh, cert_path = tempfile.mkstemp(dir=self.test_root)
 
                 self.pkg("set-publisher --no-refresh -O https://%s1 test1" %
                     self.bogus_url)
@@ -239,9 +239,9 @@
                 self.pkg("publisher test1", su_wrap=True, exit=3)
 
 
-class TestPkgPublisherMany(testutils.ManyDepotTestCase):
+class TestPkgPublisherMany(pkg5unittest.ManyDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         foo1 = """
             open foo@1,5.11-0
@@ -256,7 +256,7 @@
             close """
 
         def setUp(self):
-                testutils.ManyDepotTestCase.setUp(self, ["test1", "test2", "test3", 
+                pkg5unittest.ManyDepotTestCase.setUp(self, ["test1", "test2", "test3", 
                     "test1", "test1"])
 
                 durl1 = self.dcs[1].get_depot_url()
@@ -272,9 +272,6 @@
                 self.pkg("set-publisher -O " + durl2 + " test2")
                 self.pkg("set-publisher -O " + durl3 + " test3")
 
-        def tearDown(self):
-                testutils.ManyDepotTestCase.tearDown(self)
-
         def __test_mirror_origin(self, etype, add_opt, remove_opt):
                 durl1 = self.dcs[1].get_depot_url()
                 durl3 = self.dcs[3].get_depot_url()
--- a/src/tests/cli/t_pkg_rebuild_index.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_rebuild_index.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,19 +20,20 @@
 # CDDL HEADER END
 #
 
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import unittest
 import os
 
-class TestPkgRebuildIndex(testutils.SingleDepotTestCase):
+class TestPkgRebuildIndex(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         def test_rebuild_index_bad_opts(self):
                 """Test pkg with bad options."""
--- a/src/tests/cli/t_pkg_refresh.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_refresh.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,12 +20,13 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import testutils
 if __name__ == "__main__":
 	testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import difflib
 import os
@@ -37,7 +38,7 @@
 
 import pkg.catalog as catalog
 
-class TestPkgRefreshMulti(testutils.ManyDepotTestCase):
+class TestPkgRefreshMulti(pkg5unittest.ManyDepotTestCase):
 
         foo1 = """
             open foo@1,5.11-0
@@ -64,7 +65,7 @@
             close """
 
         def setUp(self):
-                testutils.ManyDepotTestCase.setUp(self, ["test1", "test2",
+                pkg5unittest.ManyDepotTestCase.setUp(self, ["test1", "test2",
                     "test1"])
 
                 self.durl1 = self.dcs[1].get_depot_url()
@@ -317,8 +318,8 @@
 
                 self.image_create(self.durl1, prefix="test1")
 
-                key_fh, key_path = tempfile.mkstemp(dir=self.get_test_prefix())
-                cert_fh, cert_path = tempfile.mkstemp(dir=self.get_test_prefix())
+                key_fh, key_path = tempfile.mkstemp(dir=self.test_root)
+                cert_fh, cert_path = tempfile.mkstemp(dir=self.test_root)
 
                 self.pkg("set-publisher --no-refresh -O https://%s1 test1" %
                     self.bogus_url)
@@ -436,7 +437,7 @@
                 # will induce a full refresh.
 
                 # Preserve a copy of the existing repository.
-                tdir = tempfile.mkdtemp(dir=self.get_test_prefix())
+                tdir = tempfile.mkdtemp(dir=self.test_root)
                 trpath = os.path.join(tdir, os.path.basename(dc.get_repodir()))
                 shutil.copytree(dc.get_repodir(), trpath)
 
--- a/src/tests/cli/t_pkg_search.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_search.py	Sat Jan 30 01:07:14 2010 -0800
@@ -21,13 +21,14 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import unittest
@@ -45,14 +46,14 @@
 import pkg.portable as portable
 import pkg.search_storage as ss
 
-class TestPkgSearchBasics(testutils.SingleDepotTestCase):
+class TestPkgSearchBasics(pkg5unittest.SingleDepotTestCase):
 
         example_pkg10 = """
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/bin
             add dir mode=0755 owner=root group=bin path=/bin/example_dir
             add dir mode=0755 owner=root group=bin path=/usr/lib/python2.6/vendor-packages/OpenSSL
-            add file /tmp/example_file mode=0555 owner=root group=bin path=/bin/example_path
+            add file tmp/example_file mode=0555 owner=root group=bin path=/bin/example_path
             add set name=com.sun.service.incorporated_changes value="6556919 6627937"
             add set name=com.sun.service.random_test value=42 value=79
             add set name=com.sun.service.bug_ids value="4641790 4725245 4817791 4851433 4897491 4913776 6178339 6556919 6627937"
@@ -202,7 +203,7 @@
             'com.sun.service.incorporated_changes set       6556919 6627937                   pkg:/[email protected]\n'
         ])
 
-        misc_files = ['/tmp/example_file']
+        misc_files = { "tmp/example_file": "magic" }
 
         res_local_pkg_ret_pkg = set([
             pkg_headers,
@@ -216,7 +217,7 @@
 
         res_remote_file = set([
             'path       file      bin/example_path          pkg:/[email protected]\n',
-            '820157a2043e3135f342b238129b556aade20347 file      bin/example_path          pkg:/[email protected]\n'
+            'b40981aab75932c5b2f555f50769d878e44913d7 file      bin/example_path          pkg:/[email protected]\n'
         ]) | res_remote_path
 
 
@@ -229,7 +230,7 @@
              headers,
              'path       file      bin/example_path          pkg:/[email protected]\n',
              'basename   file      bin/example_path          pkg:/[email protected]\n',
-             '820157a2043e3135f342b238129b556aade20347 file      bin/example_path          pkg:/[email protected]\n'
+             'b40981aab75932c5b2f555f50769d878e44913d7 file      bin/example_path          pkg:/[email protected]\n'
         ])
 
         o_headers = \
@@ -242,7 +243,7 @@
             "file bin/example_path example_pkg " \
             "pkg:/[email protected] bin/example_path " \
             "basename 0555 root bin " \
-            "file 820157a2043e3135f342b238129b556aade20347 chash=bfa46fc98d1ca97f1260090797d35a35e76096a3 group=bin mode=0555 owner=root path=bin/example_path pkg.csize=38 pkg.size=18\n"
+            "file b40981aab75932c5b2f555f50769d878e44913d7 chash=6a4299897fca0c4d0d18870da29a0dc7ae23b79c group=bin mode=0555 owner=root path=bin/example_path pkg.csize=25 pkg.size=5\n"
 
         o_results = o_results_no_pub.rstrip() + " test\n"
 
@@ -258,24 +259,10 @@
         res_pkg_options_local = set([pkg_headers, pkg_results_no_pub])
 
         def setUp(self):
-                for p in self.misc_files:
-                        f = open(p, "w")
-                        # Write the name of the file into the file, so that
-                        # all files have differing contents.
-                        f.write(p + "\n")
-                        f.close()
-                testutils.SingleDepotTestCase.setUp(self)
-                tp = self.get_test_prefix()
-                self.testdata_dir = os.path.join(tp, "search_results")
-                os.mkdir(self.testdata_dir)
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
                 self.init_mem_setting = None
 
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-                for p in self.misc_files:
-                        os.remove(p)
-                shutil.rmtree(self.testdata_dir)
-
         def _check(self, proposed_answer, correct_answer):
                 if correct_answer == proposed_answer:
                         return True
@@ -295,7 +282,7 @@
 
         def _search_op(self, remote, token, test_value, case_sensitive=False,
             return_actions=True, exit=0, su_wrap=False):
-                outfile = os.path.join(self.testdata_dir, "res")
+                outfile = os.path.join(self.test_root, "res")
                 if remote:
                         token = "-r " + token
                 else:
@@ -388,7 +375,7 @@
                 self.pkg("search -a -r 'e* OR <e*>'", exit=1)
 
         def _run_local_tests(self):
-                outfile = os.path.join(self.testdata_dir, "res")
+                outfile = os.path.join(self.test_root, "res")
 
                 # This finds something because the client side
                 # manifest has had the name of the package inserted
@@ -639,10 +626,10 @@
                 urllib2.urlopen("%s/en/search.shtml?token=Intel(R)&"
                     "action=Search" % durl)
 
-                testutils.eval_assert_raises(urllib2.HTTPError,
+                pkg5unittest.eval_assert_raises(urllib2.HTTPError,
                     lambda x: x.code == 400, urllib2.urlopen,
                     "%s/search/1/False_2_None_None_Intel%%28R%%29" % durl)
-                testutils.eval_assert_raises(urllib2.HTTPError,
+                pkg5unittest.eval_assert_raises(urllib2.HTTPError,
                     lambda x: x.code == 400, urllib2.urlopen,
                     "%s/search/1/False_2_None_None_foo%%20%%3Cbar%%3E" % durl)
 
--- a/src/tests/cli/t_pkg_uninstall.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_uninstall.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,19 +20,20 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import unittest
 
-class TestCommandLine(testutils.SingleDepotTestCase):
+class TestCommandLine(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         def test_pkg_bogus_opts(self):
                 """ pkg bogus option checks """
--- a/src/tests/cli/t_pkg_verify.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_verify.py	Sat Jan 30 01:07:14 2010 -0800
@@ -26,14 +26,13 @@
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import pkg.portable as portable
 import unittest
 
-class TestPkgVerify(testutils.SingleDepotTestCase):
-        # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+class TestPkgVerify(pkg5unittest.SingleDepotTestCase):
 
         foo10 = """
             open [email protected],5.11-0
@@ -41,46 +40,30 @@
             add dir mode=0755 owner=root group=sys path=/etc/security
             add dir mode=0755 owner=root group=sys path=/usr
             add dir mode=0755 owner=root group=bin path=/usr/bin
-            add file $test_prefix/bobcat mode=0644 owner=root group=bin path=/usr/bin/bobcat
-            add file $test_prefix/dricon_maj path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
-            add file $test_prefix/dricon_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
-            add file $test_prefix/dricon_cls path=/etc/driver_classes mode=644 owner=root group=sys preserve=true
-            add file $test_prefix/dricon_mp path=/etc/minor_perm mode=644 owner=root group=sys preserve=true
-            add file $test_prefix/dricon_dp path=/etc/security/device_policy mode=644 owner=root group=sys preserve=true
-            add file $test_prefix/dricon_ep path=/etc/security/extra_privs mode=644 owner=root group=sys preserve=true
+            add file bobcat mode=0644 owner=root group=bin path=/usr/bin/bobcat
+            add file dricon_maj path=/etc/name_to_major mode=644 owner=root group=sys preserve=true
+            add file dricon_da path=/etc/driver_aliases mode=644 owner=root group=sys preserve=true
+            add file dricon_cls path=/etc/driver_classes mode=644 owner=root group=sys preserve=true
+            add file dricon_mp path=/etc/minor_perm mode=644 owner=root group=sys preserve=true
+            add file dricon_dp path=/etc/security/device_policy mode=644 owner=root group=sys preserve=true
+            add file dricon_ep path=/etc/security/extra_privs mode=644 owner=root group=sys preserve=true
             add driver name=zigit alias=pci8086,1234
             close
             """
 
-        misc_files = [
-            ("bobcat", None),
-            ("dricon_da", """zigit "pci8086,1234"\n"""),
-            ("dricon_maj", """zigit 103\n"""),
-            ("dricon_cls", """\n"""),
-            ("dricon_mp", """\n"""),
-            ("dricon_dp", """\n"""),
-            ("dricon_ep", """\n""")
-        ]
+        misc_files = {
+           "bobcat": "",
+           "dricon_da": """zigit "pci8086,1234"\n""",
+           "dricon_maj": """zigit 103\n""",
+           "dricon_cls": """\n""",
+           "dricon_mp": """\n""",
+           "dricon_dp": """\n""",
+           "dricon_ep": """\n"""
+        }
 
         def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self)
-
-                for p in ("foo10",):
-                        val = getattr(self, p).replace("$test_prefix",
-                            self.get_test_prefix())
-                        setattr(self, p, val)
-
-                for p, v in self.misc_files:
-                        fpath = os.path.join(self.get_test_prefix(), p)
-                        f = open(fpath, "wb")
-
-                        if not v:
-                                # write the name of the file into the file, so that
-                                # all files have differing contents
-                                v = fpath
-                        f.write(v)
-                        f.close()
-                        self.debug("wrote %s" % fpath)
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
 
                 durl = self.dc.get_depot_url()
                 self.pkgsend_bulk(durl, self.foo10)
--- a/src/tests/cli/t_pkg_version.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkg_version.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,19 +20,18 @@
 # CDDL HEADER END
 #
 
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import unittest
 import os
 
-class TestPkgVersion(testutils.SingleDepotTestCase):
-        # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+class TestPkgVersion(pkg5unittest.SingleDepotTestCase):
 
         def test_pkg_version_bad_opts(self):
                 """ test pkg version with bad options """
--- a/src/tests/cli/t_pkgdep.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkgdep.py	Sat Jan 30 01:07:14 2010 -0800
@@ -26,6 +26,7 @@
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import shutil
@@ -38,8 +39,7 @@
 import pkg.flavor.depthlimitedmf as mf
 import pkg.portable as portable
 
-class TestPkgdepBasics(testutils.SingleDepotTestCase):
-        persistent_depot = True
+class TestPkgdepBasics(pkg5unittest.SingleDepotTestCase):
 
         test_manf_1 = """\
 hardlink path=baz target=var/log/authlog
@@ -50,17 +50,17 @@
 SH group=bin mode=0755 owner=root path=u\
 sr/xpg4/lib/libcurses.so.1
 """
-        test_manf_2 = """
+        test_manf_2 = """\
 file NOHASH group=bin mode=0755 owner=root path=usr/xpg4/lib/libcurses.so.1 variant.arch=foo
 file NOHASH group=bin mode=0755 owner=root path=etc/pam.conf
 """
 
-        int_hardlink_manf = """ \
+        int_hardlink_manf = """\
 hardlink path=usr/foo target=../var/log/syslog
 file NOHASH group=sys mode=0644 owner=root path=var/log/syslog
 """
 
-        resolve_dep_manf = """
+        resolve_dep_manf = """\
 file NOHASH group=sys mode=0600 owner=root path=var/log/authlog preserve=true
 """
 
@@ -102,11 +102,11 @@
                         # Remove any paths that start with the defined python
                         # paths.
                         res.extend(
-                            sorted([
+                            sorted(set([
                             fp for fp in sys.path
                             if not mf.DepthLimitedModuleFinder.startswith_path(
                                 fp, self.py_path)
-                            ]))
+                            ])))
                         return res
                         
                 sp = subprocess.Popen(
@@ -120,14 +120,17 @@
                 # by running python via the -c option. When running an
                 # executable python script, the first item is the directory
                 # containing the script.
-                return sorted([
+                return sorted(set([
                     fp for fp in eval(out)[1:]
                     if not mf.DepthLimitedModuleFinder.startswith_path(fp,
                         self.py_path)
-                ])
+                ]))
 
         @staticmethod
         def __make_paths(added, paths):
+                """ Append a dependency path for "added" to each of
+                the paths in the list "paths" """
+
                 return " ".join([
                     ("%(pfx)s.path=%(p)s/%(added)s" % {
                         "pfx":
@@ -261,6 +264,13 @@
     "replaced_path":"%(replaced_path)s"
 }
 
+        #
+        # You may wonder why libc.so.1 is here as a dependency-- it's an
+        # artifact of the way we compile our dummy module, and serves as
+        # a "something to depend on".  In this way, the sample elf file
+        # depends on libc.so.1 in the same way that a kernel module might
+        # depend on another kernel module.
+        #
         kernel_manf_stdout = """\
 depend fmri=%(dummy_fmri)s %(pfx)s.file=libc.so.1 %(pfx)s.path=kernel %(pfx)s.path=usr/kernel %(pfx)s.reason=kernel/foobar %(pfx)s.type=elf type=require\
 """ % {
@@ -287,8 +297,8 @@
 """
 
         double_plat_error = """\
-%(image_dir)s/proto/elf_test (which will be installed at bar/foo) had this token, $PLATFORM, in its run path: /platform/$PLATFORM/foo.  It is not currently possible to automatically expand this token. Please specify its value on the command line.
-%(image_dir)s/proto/elf_test (which will be installed at bar/foo) had this token, $PLATFORM, in its run path: /isadir/$PLATFORM/baz.  It is not currently possible to automatically expand this token. Please specify its value on the command line."""
+%(proto_dir)s/elf_test (which will be installed at bar/foo) had this token, $PLATFORM, in its run path: /platform/$PLATFORM/foo.  It is not currently possible to automatically expand this token. Please specify its value on the command line.
+%(proto_dir)s/elf_test (which will be installed at bar/foo) had this token, $PLATFORM, in its run path: /isadir/$PLATFORM/baz.  It is not currently possible to automatically expand this token. Please specify its value on the command line."""
 
         double_plat_stdout = """\
 depend fmri=%(dummy_fmri)s %(pfx)s.file=libc.so.1 %(pfx)s.path=lib %(pfx)s.path=usr/lib %(pfx)s.reason=bar/foo %(pfx)s.type=elf type=require\
@@ -298,7 +308,7 @@
 }
 
         double_plat_isa_error = """\
-%(image_dir)s/proto/elf_test (which will be installed at bar/foo) had this token, $ISALIST, in its run path: /$ISALIST/$PLATFORM/baz.  It is not currently possible to automatically expand this token. Please specify its value on the command line.\
+%(proto_dir)s/elf_test (which will be installed at bar/foo) had this token, $ISALIST, in its run path: /$ISALIST/$PLATFORM/baz.  It is not currently possible to automatically expand this token. Please specify its value on the command line.\
 """
 
         double_plat_isa_stdout = """\
@@ -414,6 +424,7 @@
                 discovered.
                 """
                 vp = self.get_ver_paths(ver, proto_area)
+                self.debug("ver_paths is %s" % vp)
                 pkg_path = self.__make_paths("pkg", vp)
                 return ("depend fmri=%(dummy_fmri)s "
                     "%(pfx)s.file=indexer.py "
@@ -508,19 +519,15 @@
 """
 
         def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self)
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                #
+                # To test pkgdepend resolve properly, we need an image.
+                # Side by side with the image, we create a testing proto area.
+                #
                 self.image_create(self.dc.get_depot_url())
-                self.manf_dirs = os.path.join(self.img_path, "manfs")
-                os.makedirs(self.manf_dirs)
-                self.proto_dir = os.path.join(self.img_path, "proto")
-                os.makedirs(self.proto_dir)
-        
-        def make_manifest(self, str):
-                t_fd, t_path = tempfile.mkstemp(dir=self.manf_dirs)
-                t_fh = os.fdopen(t_fd, "w")
-                t_fh.write(str)
-                t_fh.close()
-                return t_path
+
+                self.test_proto_dir = os.path.join(self.test_root, "proto")
+                os.makedirs(self.test_proto_dir)
 
         @staticmethod
         def __compare_res(b1, b2):
@@ -546,39 +553,23 @@
                 fh.close()
                 return lines
 
-        def make_elf(self, run_paths, o_path="elf_test"):
-                t_fd, t_path = tempfile.mkstemp(suffix=".c", dir=self.proto_dir)
-                t_fh = os.fdopen(t_fd, "w")
-                t_fh.write("int main(){}\n")
-                t_fh.close()
-                out_file = os.path.join(self.proto_dir, o_path)
-                out_dir = os.path.dirname(out_file)
-                if not os.path.exists(out_dir):
-                        os.makedirs(out_dir)
-                cmd = ["/usr/bin/cc", "-o", out_file]
-                for rp in run_paths:
-                        cmd.append("-R")
-                        cmd.append(rp)
-                cmd.append(t_path)
-                s = subprocess.Popen(cmd, stderr=subprocess.PIPE)
-                out, err = s.communicate()
-                rc = s.returncode
-                if rc != 0:
-                        raise RuntimeError("Compile of %s failed. Runpaths "
-                            "were %s\nCommand was:\n%s\nError was:\n%s" %
-                            (t_path, " ".join(run_paths), " ".join(cmd), err))
-                return out_file[len(self.img_path)+1:]
+        def make_proto_text_file(self, path, contents=""):
+                #
+                # We add a newline if it is missing because file(1) is sensitive
+                # to files which lack them.
+                #
+                contents = contents + "\n"
+                self.make_misc_files({ path: contents }, prefix="proto")
 
-        def make_text_file(self, o_path, o_text=""):
-                f_path = os.path.join(self.proto_dir, o_path)
-                f_dir = os.path.dirname(f_path)
-                if not os.path.exists(f_dir):
-                        os.makedirs(f_dir)
+        def make_elf(self, run_paths=[], output_path="elf_test"):
+                out_file = os.path.join(self.test_proto_dir, output_path)
 
-                fh = open(f_path, "w")
-                fh.write(o_text)
-                fh.close()
-                return f_path
+                # Make sure to quote the runpaths, as they may contain tokens
+                # like $PLATFORM which we do not want the shell to evaluate.
+                self.c_compile("int main(){}\n",
+                    ["-R'%s'" % rp for rp in run_paths], out_file)
+
+                return out_file[len(self.test_proto_dir)+1:]
 
         def check_res(self, expected, seen):
                 seen = seen.strip()
@@ -590,16 +581,18 @@
                 seen_but_not_expected = self.__compare_res(seen, expected)
                 expected_but_not_seen = self.__compare_res(expected, seen)
                 self.assertEqual(seen_but_not_expected, expected_but_not_seen)
-        
+
         def test_opts(self):
                 """Ensure that incorrect arguments don't cause a traceback."""
 
-                self.pkgdepend("generate", exit=2)
-                self.pkgdepend("generate foo", proto="", exit=2)
-                self.pkgdepend("generate -z foo bar", exit=2)
-                self.pkgdepend("generate no_such_file_should_exist", exit=2)
-                self.pkgdepend("generate -?")
-                self.pkgdepend("generate --help")
+                proto = pkg5unittest.g_proto_area
+                self.pkgdepend_generate("", proto=proto, exit=2)
+                self.pkgdepend_generate("foo", proto="", exit=2)
+                self.pkgdepend_generate("-z foo bar", proto=proto, exit=2)
+                self.pkgdepend_generate("no_such_file_should_exist",
+                    proto=proto, exit=2)
+                self.pkgdepend_generate("-\?", proto="")
+                self.pkgdepend_generate("--help", proto="")
                 
         def test_output(self):
                 """Check that the output is in the format expected."""
@@ -607,42 +600,43 @@
                 tp = self.make_manifest(self.test_manf_1)
                 fp = "usr/lib/python2.6/vendor-packages/pkg/client/indexer.py" 
                 
-                self.pkgdepend("generate %s" % tp, exit=1)
+                self.pkgdepend_generate("%s" % tp,
+                    proto=pkg5unittest.g_proto_area, exit=1)
                 self.check_res(self.make_res_manf_1(
-                        testutils.g_proto_area) % {"reason": fp},
+                        pkg5unittest.g_proto_area) % {"reason": fp},
                     self.output)
-                self.check_res(self.err_manf_1 % testutils.g_proto_area,
+                self.check_res(self.err_manf_1 % pkg5unittest.g_proto_area,
                     self.errout)
 
-                self.pkgdepend("generate -m %s" % tp, exit=1)
+                self.pkgdepend_generate("-m %s" % tp,
+                    proto=pkg5unittest.g_proto_area, exit=1)
                 self.check_res(
                     self.make_full_res_manf_1(
-                        testutils.g_proto_area) % {"reason": fp},
+                        pkg5unittest.g_proto_area) % {"reason": fp},
                     self.output)
-                self.check_res(self.err_manf_1 % testutils.g_proto_area,
+                self.check_res(self.err_manf_1 % pkg5unittest.g_proto_area,
                     self.errout)
 
-                self.make_text_file(fp, self.python_text)
+                self.make_proto_text_file(fp, self.python_text)
                 self.make_elf([], "usr/xpg4/lib/libcurses.so.1")
                 
-                self.pkgdepend("generate -m %s" % tp, proto=self.proto_dir)
+                self.pkgdepend_generate("-m %s" % tp, proto=self.test_proto_dir)
                 self.check_res(
                     self.make_full_res_manf_1_mod_proto(
-                        testutils.g_proto_area)  % {"reason": fp},
+                        pkg5unittest.g_proto_area)  % {"reason": fp},
                     self.output)
                 self.check_res("", self.errout)
 
                 tp = self.make_manifest(self.test_manf_2)
-                self.make_text_file("etc/pam.conf", "text")
+                self.make_proto_text_file("etc/pam.conf", "text")
                 
-                self.pkgdepend("generate %s" % tp, proto=self.proto_dir)
+                self.pkgdepend_generate("%s" % tp, proto=self.test_proto_dir)
                 self.check_res(self.res_manf_2, self.output)
                 self.check_res("", self.errout)
 
                 res_path = self.make_manifest(self.output)
 
-                self.pkgdepend("resolve -o %s" %
-                    res_path, use_proto=False, exit=1)
+                self.pkgdepend_resolve("-o %s" % res_path, exit=1)
                 self.check_res("%s" % res_path, self.output)
                 self.check_res(self.resolve_error % {
                         "manf_path": res_path,
@@ -651,7 +645,7 @@
                         "dummy_fmri":base.Dependency.DUMMY_FMRI
                     }, self.errout)
                 
-                self.pkgdepend("generate -M %s" % tp, proto=self.proto_dir)
+                self.pkgdepend_generate("-M %s" % tp, proto=self.test_proto_dir)
                 self.check_res(self.res_manf_2, self.output)
                 self.check_res(self.res_manf_2_missing, self.errout)
 
@@ -660,13 +654,13 @@
 
                 tp = self.make_manifest(self.int_hardlink_manf)
 
-                self.make_text_file("var/log/syslog", "text")
+                self.make_proto_text_file("var/log/syslog", "text")
                 
-                self.pkgdepend("generate %s" % tp, proto=self.proto_dir)
+                self.pkgdepend_generate("%s" % tp, proto=self.test_proto_dir)
                 self.check_res("", self.output)
                 self.check_res("", self.errout)
 
-                self.pkgdepend("generate -I %s" % tp, proto=self.proto_dir)
+                self.pkgdepend_generate("-I %s" % tp, proto=self.test_proto_dir)
                 self.check_res(self.res_int_manf, self.output)
                 self.check_res("", self.errout)
 
@@ -708,23 +702,24 @@
                 tp = self.make_manifest(self.pyver_test_manf_1 %
                     {"py_ver":"2.4"})
                 fp = "usr/lib/python2.4/vendor-packages/pkg/client/indexer.py"
-                self.make_text_file(fp, self.pyver_python_text % "2.6")
-                self.pkgdepend("generate %s" % tp, proto=self.proto_dir, exit=1)
+                self.make_proto_text_file(fp, self.pyver_python_text % "2.6")
+                self.pkgdepend_generate("%s" % tp, proto=self.test_proto_dir,
+                     exit=1)
                 self.check_res(self.pyver_mismatch_results +
-                    self.make_pyver_python_res("2.4", self.proto_dir) %
+                    self.make_pyver_python_res("2.4", self.test_proto_dir) %
                         {"reason": fp, "bin_ver": "2.6"},
                     self.output)
-                self.check_res(self.pyver_mismatch_errs % self.proto_dir,
+                self.check_res(self.pyver_mismatch_errs % self.test_proto_dir,
                     self.errout)
 
                 # Test line 2 (X D !F)
                 tp = self.make_manifest(self.pyver_test_manf_1 %
                     {"py_ver":"2.4"})
                 fp = "usr/lib/python2.4/vendor-packages/pkg/client/indexer.py"
-                self.make_text_file(fp, self.pyver_python_text % "")
-                self.pkgdepend("generate -m %s" % tp, proto=self.proto_dir)
+                self.make_proto_text_file(fp, self.pyver_python_text % "")
+                self.pkgdepend_generate("-m %s" % tp, proto=self.test_proto_dir)
                 self.check_res(
-                    self.pyver_res_full_manf_1("2.4", self.proto_dir) %
+                    self.pyver_res_full_manf_1("2.4", self.test_proto_dir) %
                         {"reason": fp, "bin_ver": ""},
                     self.output)
                 self.check_res("", self.errout)
@@ -732,10 +727,10 @@
                 # Test line 3 (X !D F)
                 tp = self.make_manifest(self.py_in_usr_bin_manf)
                 fp = "usr/bin/pkg"
-                self.make_text_file(fp, self.pyver_python_text % "2.4")
-                self.pkgdepend("generate -m %s" % tp, proto=self.proto_dir)
+                self.make_proto_text_file(fp, self.pyver_python_text % "2.4")
+                self.pkgdepend_generate("-m %s" % tp, proto=self.test_proto_dir)
                 self.check_res(
-                    self.pyver_res_full_manf_1("2.4", self.proto_dir) %
+                    self.pyver_res_full_manf_1("2.4", self.test_proto_dir) %
                         {"reason": fp, "bin_ver": "2.4"},
                     self.output)
                 self.check_res("", self.errout)
@@ -743,24 +738,24 @@
                 # Test line 4 (X !D !F)
                 tp = self.make_manifest(self.py_in_usr_bin_manf)
                 fp = "usr/bin/pkg"
-                self.make_text_file(fp, self.pyver_python_text % "")
-                self.pkgdepend("generate -m %s" % tp, proto=self.proto_dir,
+                self.make_proto_text_file(fp, self.pyver_python_text % "")
+                self.pkgdepend_generate("-m %s" % tp, proto=self.test_proto_dir,
                     exit=1)
                 self.check_res(
                     self.pyver_24_script_full_manf_1 %
                         {"reason": fp, "bin_ver": ""},
                     self.output)
-                self.check_res(self.pyver_unspecified_ver_err % self.proto_dir,
+                self.check_res(self.pyver_unspecified_ver_err % self.test_proto_dir,
                     self.errout)
 
                 # Test line 5 (!X D F)
                 tp = self.make_manifest(self.pyver_test_manf_1_non_ex %
                     {"py_ver":"2.4"})
                 fp = "usr/lib/python2.4/vendor-packages/pkg/client/indexer.py"
-                self.make_text_file(fp, self.pyver_python_text % "2.6")
-                self.pkgdepend("generate %s" % tp, proto=self.proto_dir)
+                self.make_proto_text_file(fp, self.pyver_python_text % "2.6")
+                self.pkgdepend_generate("%s" % tp, proto=self.test_proto_dir)
                 self.check_res(
-                    self.make_pyver_python_res("2.4", self.proto_dir) %
+                    self.make_pyver_python_res("2.4", self.test_proto_dir) %
                         {"reason": fp},
                     self.output)
                 self.check_res("", self.errout)
@@ -769,10 +764,10 @@
                 tp = self.make_manifest(self.pyver_test_manf_1_non_ex %
                     {"py_ver":"2.4"})
                 fp = "usr/lib/python2.4/vendor-packages/pkg/client/indexer.py"
-                self.make_text_file(fp, self.pyver_python_text % "")
-                self.pkgdepend("generate %s" % tp, proto=self.proto_dir)
+                self.make_proto_text_file(fp, self.pyver_python_text % "")
+                self.pkgdepend_generate("%s" % tp, proto=self.test_proto_dir)
                 self.check_res(
-                    self.make_pyver_python_res("2.4", self.proto_dir) %
+                    self.make_pyver_python_res("2.4", self.test_proto_dir) %
                         {"reason": fp},
                     self.output)
                 self.check_res("", self.errout)
@@ -780,16 +775,16 @@
                 # Test line 7 (!X !D F)
                 tp = self.make_manifest(self.py_in_usr_bin_manf_non_ex)
                 fp = "usr/bin/pkg"
-                self.make_text_file(fp, self.pyver_python_text % "2.4")
-                self.pkgdepend("generate %s" % tp, proto=self.proto_dir)
+                self.make_proto_text_file(fp, self.pyver_python_text % "2.4")
+                self.pkgdepend_generate("%s" % tp, proto=self.test_proto_dir)
                 self.check_res("", self.output)
                 self.check_res("", self.errout)
 
                 # Test line 8 (!X !D !F)
                 tp = self.make_manifest(self.py_in_usr_bin_manf_non_ex)
                 fp = "usr/bin/pkg"
-                self.make_text_file(fp, self.pyver_python_text % "")
-                self.pkgdepend("generate %s" % tp, proto=self.proto_dir)
+                self.make_proto_text_file(fp, self.pyver_python_text % "")
+                self.pkgdepend_generate("%s" % tp, proto=self.test_proto_dir)
                 self.check_res("", self.output)
                 self.check_res("", self.errout)
 
@@ -804,13 +799,13 @@
                             self.pyver_test_manf_1 % {"py_ver":py_ver})
                         fp = "usr/lib/python%s/vendor-packages/pkg/" \
                             "client/indexer.py" % py_ver 
-                        self.make_text_file(fp, self.python_text)
+                        self.make_proto_text_file(fp, self.python_text)
 
                         # Run generate and check the output.
-                        self.pkgdepend("generate -m %s" % tp,
-                            proto=self.proto_dir)
+                        self.pkgdepend_generate("-m %s" % tp,
+                            proto=self.test_proto_dir)
                         self.check_res(
-                            self.pyver_res_full_manf_1(py_ver, self.proto_dir) %
+                            self.pyver_res_full_manf_1(py_ver, self.test_proto_dir) %
                                 {"bin_ver": "", "reason":fp},
                             self.output)
                         self.check_res("", self.errout)
@@ -822,9 +817,8 @@
                             self.pyver_resolve_dep_manf % {"py_ver":py_ver})
 
                         # Run resolver and check the output.
-                        self.pkgdepend(
-                            "resolve %s %s" % (dependency_mp, provider_mp),
-                            use_proto=False)
+                        self.pkgdepend_resolve(
+                            "%s %s" % (dependency_mp, provider_mp))
                         self.check_res("", self.output)
                         self.check_res("", self.errout)
                         dependency_res_p = dependency_mp + ".res"
@@ -855,9 +849,8 @@
                 p2_name = "s-v-bar"
                 p3_name = "s-v-baz-one"
                 p4_name = "s-v-baz-two"
-                self.pkgdepend("resolve -o %s" %
-                    " ".join([m1_path, m2_path, m3_path, m4_path]),
-                    use_proto=False, exit=1)
+                self.pkgdepend_resolve("-o %s" %
+                    " ".join([m1_path, m2_path, m3_path, m4_path]), exit=1)
 
                 self.check_res(self.two_v_deps_output % {
                         "m1_path": m1_path,
@@ -873,29 +866,31 @@
                     }, self.errout)
 
         def test_bug_10518(self):
-
+                """ pkgdepend should exit 2 on input args of the wrong type """
                 m_path = self.make_manifest(self.test_manf_1)
 
-                self.pkgdepend("generate / %s " % m_path,
-                    use_proto=False, exit=2)
+                # Try feeding a directory where a manifest should be--
+                # a typical scenario we play out here is a user
+                # inverting the first and second args.
+                self.pkgdepend_generate("/", proto=m_path, exit=2)
                 self.check_res(
                     "pkgdepend: The manifest file / could not be found.\n" +
                     self.usage_msg, self.errout)
 
-                self.pkgdepend("resolve -o / ", use_proto=False, exit=2)
+                self.pkgdepend_resolve("-o /", exit=2)
                 self.check_res(
                     "pkgdepend: The manifest file / could not be found.\n" +
                     self.usage_msg, self.errout)
 
         def test_bug_11517(self):
+                """ Test the pkgdepend handles bad global options """
 
                 m_path = None
                 ill_usage = 'pkgdepend: illegal global option -- M\n'
                 try:
                         m_path = self.make_manifest(self.test_manf_1)
 
-                        self.pkgdepend("resolve -M -o %s " % m_path,
-                            use_proto=False, exit=2)
+                        self.pkgdepend_resolve("-M -o %s " % m_path, exit=2)
                         self.check_res(ill_usage + self.usage_msg,
                             self.errout)
                 finally:
@@ -909,45 +904,42 @@
                 dependencies analyzed correctly and that the correct path is
                 used for internal dependency resolution."""
 
+                proto = pkg5unittest.g_proto_area
                 tp = self.make_manifest(self.payload_manf)
-                self.pkgdepend("generate %s" % tp)
-                self.check_res(self.make_res_payload_1(testutils.g_proto_area) %\
+                self.pkgdepend_generate("%s" % tp, proto=proto)
+                self.check_res(self.make_res_payload_1(proto) %\
                         {"reason": "usr/lib/python2.6/foo/bar.py"},
                     self.output)
                 self.check_res("", self.errout)
 
         def test_bug_11829(self):
+                """ pkgdep should gracefully deal with a non-manifest """
 
                 m_path = None
                 nonsense = "This is a nonsense manifest"
-                try:
-                        m_path = self.make_manifest(nonsense)
-                        
-                        self.pkgdepend("generate %s /" % m_path,
-                            use_proto=False, exit=1)
-                        self.check_res('pkgdepend: Could not parse manifest ' + 
-                            '%s because of the following line:\n' % m_path +
-                            nonsense, self.errout)
+                m_path = self.make_manifest(nonsense)
+                
+                self.pkgdepend_generate("%s" % m_path,
+                    proto=self.test_proto_dir, exit=1)
+                self.check_res('pkgdepend: Could not parse manifest ' + 
+                    '%s because of the following line:\n' % m_path +
+                    nonsense, self.errout)
 
-                        self.pkgdepend("resolve -o %s " % m_path, 
-                            use_proto=False, exit=1)
-                        self.check_res("pkgdepend: Could not parse one or "
-                            "more manifests because of the following line:\n" +
-                            nonsense, self.errout)
-                finally:
-                        if m_path:
-                                portable.remove(m_path)
+                self.pkgdepend_resolve("-o %s " % m_path, exit=1)
+                self.check_res("pkgdepend: Could not parse one or "
+                    "more manifests because of the following line:\n" +
+                    nonsense, self.errout)
 
         def __run_dyn_tok_test(self, run_paths, replaced_path, dep_args):
                 """Using the provided run paths, produces a elf binary with
                 those paths set and checks to make sure that pkgdep run with
                 the provided arguments performs the substitution correctly."""
-
+                
                 elf_path = self.make_elf(run_paths)
                 m_path = self.make_manifest(self.elf_sub_manf %
                     {"file_loc": elf_path})
-                self.pkgdepend("generate %s %s %s" %
-                    (dep_args, m_path, self.img_path), use_proto=False)
+                self.pkgdepend_generate("%s %s" % (dep_args, m_path),
+                    proto=self.test_proto_dir)
                 self.check_res(self.payload_elf_sub_stdout %
                     {"replaced_path": \
                         (" %s.path=%s" %
@@ -965,33 +957,35 @@
                 elf_path = self.make_elf([])
                 m_path = self.make_manifest(self.kernel_manf %
                     {"file_loc":elf_path})
-                self.pkgdepend("generate %s %s" % (m_path, self.img_path),
-                    use_proto=False)
+                self.pkgdepend_generate("%s" % m_path,
+                    proto=self.test_proto_dir)
                 self.check_res("", self.errout)
                 self.check_res(self.kernel_manf_stdout, self.output)
 
-                self.pkgdepend("generate -k baz -k foo/bar %s %s" %
-                    (m_path, self.img_path), use_proto=False)
+                self.pkgdepend_generate("-k baz -k foo/bar %s" % m_path,
+                    proto=self.test_proto_dir)
                 self.check_res("", self.errout)
                 self.check_res(self.kernel_manf_stdout2, self.output)
 
-                # Test for platform substitution in kernel module paths. Bug
-                # 13057
-                self.pkgdepend("generate -D PLATFORM=baz -D PLATFORM=tp %s %s" %
-                    (m_path, self.img_path), use_proto=False)
+                self.debug("Test for platform substitution in kernel " \
+                    "module paths. Bug 13057")
+
+                self.pkgdepend_generate("-D PLATFORM=baz -D PLATFORM=tp %s" %
+                    m_path, proto=self.test_proto_dir)
                 self.check_res("", self.errout)
                 self.check_res(self.kernel_manf_stdout_platform, self.output)
                 
-                # Test unexpanded token 
+                self.debug("Test unexpanded token")
+
                 rp = ["/platform/$PLATFORM/foo"]
                 elf_path = self.make_elf(rp)
                 m_path = self.make_manifest(self.elf_sub_manf %
                     {"file_loc": elf_path})
-                self.pkgdepend("generate %s %s" % (m_path, self.img_path),
-                    use_proto=False, exit=1)
+                self.pkgdepend_generate("%s" % m_path, proto=self.test_proto_dir,
+                    exit=1)
                 self.check_res((self.payload_elf_sub_error %
                     {
-                        "payload_path": os.path.join(self.img_path, elf_path),
+                        "payload_path": os.path.join(self.test_proto_dir, elf_path),
                         "installed_path": "bar/foo",
                         "tok": "$PLATFORM",
                         "rp": rp[0]
@@ -1003,40 +997,44 @@
                     {"replaced_path": ""}, self.output)
 
                 # Test token expansion
+                self.debug("test token expansion: $PLATFORM")
                 self.__run_dyn_tok_test(["/platform/$PLATFORM/foo"],
                     "platform/pfoo/foo", "-D PLATFORM=pfoo")
 
+                self.debug("test token expansion: $ISALIST")
                 self.__run_dyn_tok_test(["/foo/bar/$ISALIST/baz"],
                     "foo/bar/SUBL/baz", "-D '$ISALIST=SUBL'")
 
+                self.debug("test token expansion: $PLATFORM and $ISALIST")
                 self.__run_dyn_tok_test(["/foo/$PLATFORM/$ISALIST/baz"],
                     "foo/pfoo/bar/SUBL/baz",
                     "-D ISALIST=SUBL -D PLATFORM=pfoo/bar")
 
+                self.debug("test token expansion: multiple $PLATFORM")
                 self.__run_dyn_tok_test(
                     ["/$PLATFORM/$PLATFORM/$ISALIST/$PLATFORM"],
                     "bar/bar/SUBL/bar", "-D ISALIST=SUBL -D PLATFORM=bar")
 
-                # Test multiple run paths and multiple subs
+                self.debug("Test multiple run paths and multiple subs")
                 rp = ["/platform/$PLATFORM/foo", "/$ISALIST/$PLATFORM/baz"]
                 elf_path = self.make_elf(rp)
                 m_path = self.make_manifest(self.elf_sub_manf %
                     {"file_loc": elf_path})
-                self.pkgdepend("generate -D ISALIST=isadir %s %s" %
-                    (m_path, self.img_path), use_proto=False, exit=1)
+                self.pkgdepend_generate("-D ISALIST=isadir %s" % m_path,
+                    proto=self.test_proto_dir, exit=1)
                 self.check_res(self.double_plat_error %
-                    {"image_dir": self.img_path}, self.errout)
+                    {"proto_dir": self.test_proto_dir}, self.errout)
                 self.check_res(self.double_plat_stdout, self.output)
 
-                self.pkgdepend("generate -D PLATFORM=pfoo %s %s" %
-                    (m_path, self.img_path), use_proto=False, exit=1)
+                self.pkgdepend_generate("-D PLATFORM=pfoo %s" % m_path,
+                    proto=self.test_proto_dir, exit=1)
                 self.check_res(self.double_plat_isa_error %
-                    {"image_dir": self.img_path}, self.errout)
+                    {"proto_dir": self.test_proto_dir}, self.errout)
                 self.check_res(self.double_plat_isa_stdout, self.output)
 
-                self.pkgdepend("generate -D PLATFORM=pfoo -D PLATFORM=pfoo2 "
-                    "-D ISALIST=isadir -D ISALIST=isadir %s %s" %
-                    (m_path, self.img_path), use_proto=False)
+                self.pkgdepend_generate("-D PLATFORM=pfoo -D PLATFORM=pfoo2 "
+                    "-D ISALIST=isadir -D ISALIST=isadir %s" % m_path,
+                    proto=self.test_proto_dir)
                 self.check_res("", self.errout)
                 self.check_res(self.double_double_stdout, self.output)
                 
@@ -1045,10 +1043,10 @@
                 uses the right path."""
 
                 m_path = self.make_manifest(self.miss_payload_manf)
-                self.pkgdepend("generate %s %s" % (m_path, self.img_path),
-                    use_proto=False, exit=1)
+                self.pkgdepend_generate("%s" % m_path,
+                    proto=self.test_proto_dir, exit=1)
                 self.check_res(self.miss_payload_manf_error %
-                    {"path_pref":self.img_path}, self.errout)
+                    {"path_pref":self.test_proto_dir}, self.errout)
                 self.check_res("", self.output)
 
         def test_bug_12896(self):
@@ -1060,16 +1058,20 @@
                 bar2_path = self.make_manifest(self.sat_bar_libc2)
                 foo_path = self.make_manifest(self.sat_foo_libc)
 
-                self.pkgdepend("resolve -o %s %s %s" %
-                    (col_path, bar_path, foo_path), use_proto=False, exit=1)
+                self.pkgdepend_resolve("-o %s %s %s" %
+                    (col_path, bar_path, foo_path), exit=1)
                 self.check_res("\n\n".join([col_path, bar_path, foo_path]),
                     self.output)
                 self.check_res(self.run_path_errors %
                     {"unresolved_path": col_path}, self.errout)
 
-                self.pkgdepend("resolve -o %s %s %s" %
-                    (col_path, bar_path, bar2_path), use_proto=False, exit=1)
+                self.pkgdepend_resolve("-o %s %s %s" %
+                    (col_path, bar_path, bar2_path), exit=1)
                 self.check_res("\n\n".join([col_path, bar_path, bar2_path]),
                     self.output)
                 self.check_res(self.amb_path_errors %
                     {"unresolved_path": col_path}, self.errout)
+
+
+if __name__ == "__main__":
+        unittest.main()
--- a/src/tests/cli/t_pkgdep_resolve.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkgdep_resolve.py	Sat Jan 30 01:07:14 2010 -0800
@@ -26,12 +26,12 @@
 import testutils
 if __name__ == "__main__":
 	testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import shutil
 import sys
 import tempfile
-import testutils
 import unittest
 
 import pkg.client.api as api
@@ -43,9 +43,9 @@
 API_VERSION = 31
 PKG_CLIENT_NAME = "pkg"
 
-class TestApiDependencies(testutils.SingleDepotTestCase):
+class TestApiDependencies(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = False
+        persistent_setup = False
 
         depend_dp = base.Dependency.DEPEND_DEBUG_PREFIX
 
@@ -202,38 +202,24 @@
 file NOHASH group=bin mode=0755 owner=root path=usr/lib/python2.6/vendor-packages/pkg/search_storage.pyc
 """
         
-        misc_files = ["foo"]
+        inst_pkg = """\
+open [email protected],5.11-0
+add file tmp/foo mode=0555 owner=root group=bin path=/usr/bin/python2.6
+close"""
+
+        var_pkg = """\
+open [email protected],5.11-0
+add set name=variant.foo value=bar value=baz
+add file tmp/foo group=sys mode=0644 owner=root path=var/log/syslog
+close"""
+
+
+        misc_files = ["tmp/foo"]
         
         def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self)
-                tp = self.get_test_prefix()
-                self.testdata_dir = os.path.join(tp, "manifest_dir")
-                os.mkdir(self.testdata_dir)
-                for n in self.misc_files:
-                        f = open(os.path.join(self.testdata_dir, n), "w")
-                        # Write the name of the file into the file, so that
-                        # all files have differing contents.
-                        f.write(n + "\n")
-                        f.close()
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
 
-                self.inst_pkg = """\
-open [email protected],5.11-0
-add file %(foo)s mode=0555 owner=root group=bin path=/usr/bin/python2.6
-close""" % { "foo": os.path.join(self.testdata_dir, "foo") }
-
-                self.var_pkg = """\
-open [email protected],5.11-0
-add set name=variant.foo value=bar value=baz
-add file %(foo)s group=sys mode=0644 owner=root path=var/log/syslog
-close""" % { "foo": os.path.join(self.testdata_dir, "foo") }
-
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-                for n in self.misc_files:
-                        os.remove(os.path.join(self.testdata_dir, n))
-                shutil.rmtree(self.testdata_dir)
-
-        def make_image(self):
                 self.durl = self.dc.get_depot_url()
                 self.image_create(self.durl)
                 progresstracker = progress.NullProgressTracker()
@@ -262,18 +248,10 @@
                 api_obj.execute_plan()
                 api_obj.reset()
 
-        def make_manifest(self, str):
-                t_fd, t_path = tempfile.mkstemp(dir=self.testdata_dir)
-                t_fh = os.fdopen(t_fd, "w")
-                t_fh.write(str)
-                t_fh.close()
-                return t_path
-        
         def test_resolve_cross_package(self):
                 """test that cross dependencies between published packages
                 works."""
 
-                self.make_image()
                 m1_path = self.make_manifest(self.hardlink1_manf_deps)
                 m2_path = self.make_manifest(self.hardlink2_manf_deps)
                 p1_name = os.path.basename(m1_path)
@@ -297,7 +275,6 @@
                 resolver picks up the name of the package if it's defined in
                 the package."""
                 
-                self.make_image()
 
                 self.pkgsend_bulk(self.durl, self.inst_pkg)
                 self.api_obj.refresh(immediate=True)
@@ -332,7 +309,6 @@
                 """Test that variants declared on the actions work correctly
                 when resolving dependencies."""
 
-                self.make_image()
                 m1_path = self.make_manifest(self.simple_variant_deps)
                 m2_path = self.make_manifest(self.simple_v_deps_bar)
                 m3_path = self.make_manifest(self.simple_v_deps_baz)
@@ -365,7 +341,6 @@
                 """Test that variants declared on the packages work correctly
                 when resolving dependencies."""
 
-                self.make_image()
                 m1_path = self.make_manifest(self.simple_variant_deps)
                 m2_path = self.make_manifest(self.simple_v_deps_bar2)
                 m3_path = self.make_manifest(self.simple_v_deps_baz2)
@@ -396,7 +371,6 @@
                 """Test that variants declared on the packages work correctly
                 when resolving dependencies."""
 
-                self.make_image()
                 m1_path = self.make_manifest(self.two_variant_deps)
                 m2_path = self.make_manifest(self.two_v_deps_bar)
                 m3_path = self.make_manifest(self.two_v_deps_baz_one)
@@ -454,8 +428,6 @@
                         d = pkg_deps[one_dep][0]
                         self.assertEqual(d.attrs["fmri"], exp_pkg)
                 
-                self.make_image()
-
                 col_path = self.make_manifest(self.multi_file_dep_manf)
                 # This manifest provides two files that satisfy col_path's
                 # file dependencies.
@@ -530,7 +502,6 @@
                 """Test that resolving against an installed, cached, manifest
                 works with variants."""
 
-                self.make_image()
 
                 self.pkgsend_bulk(self.durl, self.var_pkg)
                 self.api_obj.refresh(immediate=True)
@@ -575,8 +546,6 @@
                         d = pkg_deps[one_dep][0]
                         self.assertEqual(d.attrs["fmri"], exp_pkg)
                 
-                self.make_image()
-
                 col_path = self.make_manifest(self.collision_manf)
                 col_path_num_var = self.make_manifest(
                     self.collision_manf_num_var)
@@ -759,3 +728,6 @@
                                     "no_such_named_file")
                         else:
                                 raise RuntimeError("Unexpected error:%s" % e)
+
+if __name__ == "__main__":
+        unittest.main()
--- a/src/tests/cli/t_pkgmogrify.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkgmogrify.py	Sat Jan 30 01:07:14 2010 -0800
@@ -26,8 +26,9 @@
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
+
 import errno
-
 import os
 import shutil
 import stat
@@ -35,7 +36,7 @@
 import tempfile
 import unittest
 
-class TestPkgMogrify(testutils.CliTestCase):
+class TestPkgMogrify(pkg5unittest.CliTestCase):
         pkgcontents = \
             """
 # directories
@@ -80,25 +81,14 @@
         transform_files = []
 
         def setUp(self):
-                self.pid = os.getpid()
-                self.pwd = os.getcwd()
-                self.persistent_depot = False
-
-                self.__test_dir = os.path.join(tempfile.gettempdir(),
-                    "ips.test.%d" % self.pid)
+                pkg5unittest.CliTestCase.setUp(self)
 
-                try:
-                        os.makedirs(self.__test_dir, 0755)
-                except OSError, e:
-                        if e.errno != errno.EEXIST:
-                                raise e
-
-                f = file(os.path.join(self.__test_dir, "source_file"), "wb")
+                f = file(os.path.join(self.test_root, "source_file"), "wb")
                 f.write(self.pkgcontents)
                 f.close()
 
                 for i, s in enumerate(self.transforms):
-                        fname = os.path.join(self.__test_dir,
+                        fname = os.path.join(self.test_root,
                                 "transform_%s" % i)
                         self.transform_files.append(fname)
                         f = file(fname, "wb")
@@ -106,17 +96,13 @@
                         f.close()
 
         def pkgmogrify(self, args, exit=0):
-                cmd="%s/usr/bin/pkgmogrify %s" % (testutils.g_proto_area, args)
+                cmd="%s/usr/bin/pkgmogrify %s" % (pkg5unittest.g_proto_area, args)
                 self.cmdline_run(cmd, exit=exit)
 
-        def tearDown(self):
-                #shutil.rmtree(self.__test_dir)
-                pass
-
         def test_1(self):
                 """demonstrate macros working"""
-                source_file = os.path.join(self.__test_dir, "source_file")
-                output_file = os.path.join(self.__test_dir, "output_file")
+                source_file = os.path.join(self.test_root, "source_file")
+                output_file = os.path.join(self.test_root, "output_file")
 
                 self.pkgmogrify("-Di386_ONLY='#' -DBUILDID=0.126 %s |" \
                         "egrep -v SUNWxorg-mesa" % source_file)
@@ -129,15 +115,15 @@
 
         def test_2(self):
                 """display output to files """
-                source_file = os.path.join(self.__test_dir, "source_file")
-                output_file = os.path.join(self.__test_dir, "output_file")
+                source_file = os.path.join(self.test_root, "source_file")
+                output_file = os.path.join(self.test_root, "output_file")
                 self.pkgmogrify("-Di386_ONLY=' ' -DBUILDID=0.126 -O %s %s ;" \
                         "egrep [email protected] %s" %
                         (output_file, source_file, output_file))
 
         def test_3(self):
-                source_file = os.path.join(self.__test_dir, "source_file")
-                output_file = os.path.join(self.__test_dir, "output_file")
+                source_file = os.path.join(self.test_root, "source_file")
+                output_file = os.path.join(self.test_root, "output_file")
                 self.pkgmogrify("-Di386_ONLY='#' -DBUILDID=0.126 %s %s |" \
                         "egrep -v X11" %
                         (self.transform_files[1], source_file))
@@ -151,15 +137,15 @@
                         (self.transform_files[4], source_file))
 
         def test_4(self):
-                source_file = os.path.join(self.__test_dir, "source_file")
-                output_file = os.path.join(self.__test_dir, "output_file")
+                source_file = os.path.join(self.test_root, "source_file")
+                output_file = os.path.join(self.test_root, "output_file")
                 self.pkgmogrify("-Di386_ONLY='#' -DBUILDID=0.126 %s %s |" \
                         "egrep -v xkbprint" %
                         (self.transform_files[2], source_file))
 
         def test_5(self):
-                source_file = os.path.join(self.__test_dir, "source_file")
-                output_file = os.path.join(self.__test_dir, "output_file")
+                source_file = os.path.join(self.test_root, "source_file")
+                output_file = os.path.join(self.test_root, "output_file")
 
                 self.pkgmogrify("-Di386_ONLY='#' -DBUILDID=0.126 %s %s |" \
                     "egrep 'file NOHASH group=bin mode=0555 owner=root " \
@@ -171,7 +157,7 @@
                     self.transform_files[3], source_file))
                 self.pkgmogrify("-Di386_ONLY='#' -DBUILDID=0.126 -I %s %s %s" \
                     " |egrep 'file NOHASH group=bin mode=0755 owner=root " \
-                    "path=usr\/Y11\/bin\/Xserver'" % (self.__test_dir,
+                    "path=usr\/Y11\/bin\/Xserver'" % (self.test_root,
                     self.transform_files[7], source_file))
                 # check multiple modes to the same attribute on same action
                 self.pkgmogrify("-Di386_ONLY='#' -DBUILDID=0.126 %s %s %s |" \
@@ -180,8 +166,8 @@
                     self.transform_files[1], source_file))
 
         def test_6(self):
-                source_file = os.path.join(self.__test_dir, "source_file")
-                output_file = os.path.join(self.__test_dir, "output_file")
+                source_file = os.path.join(self.test_root, "source_file")
+                output_file = os.path.join(self.test_root, "output_file")
                 # check omitted NOHASH
                 self.pkgmogrify("-Di386_ONLY='#' -DBUILDID=0.126 %s %s %s |" \
                     "egrep 'file NOHASH group=bin mode=0555 owner=root " \
@@ -189,8 +175,8 @@
                     self.transform_files[1], source_file))
 
         def test_7(self):
-                source_file = os.path.join(self.__test_dir, "source_file")
-                output_file = os.path.join(self.__test_dir, "output_file")
+                source_file = os.path.join(self.test_root, "source_file")
+                output_file = os.path.join(self.test_root, "output_file")
 
                 # check error handling
                 self.pkgmogrify("-Di386_ONLY='#' -DBUILDID=0.126 --froob",
@@ -200,7 +186,7 @@
                         self.transform_files[8], exit=1)
                 # nested tranform error
                 self.pkgmogrify("-Di386_ONLY='#' -DBUILDID=0.126 -I %s %s" %
-                        (self.__test_dir, self.transform_files[8]), exit=1)
+                        (self.test_root, self.transform_files[8]), exit=1)
                 # bad transform
                 self.pkgmogrify("-Di386_ONLY='#' -DBUILDID=0.126 %s %s" %
                         (self.transform_files[6], source_file), exit=1)
@@ -208,9 +194,9 @@
 
         def test_8(self):
                 """test for graceful exit with no output on abort"""
-                source_file = os.path.join(self.__test_dir, "source_file")
-                no_output = os.path.join(self.__test_dir, "no_output")
-                no_print = os.path.join(self.__test_dir, "no_print")
+                source_file = os.path.join(self.test_root, "source_file")
+                no_output = os.path.join(self.test_root, "no_output")
+                no_print = os.path.join(self.test_root, "no_print")
                 #
                 # add an abort transform that's expected to trigger
                 # this should cover the "exit gracefully" part of abort
@@ -225,9 +211,9 @@
 
         def test_9(self):
                 """test for print output to specified file"""
-                source_file = os.path.join(self.__test_dir, "source_file")
-                output_file = os.path.join(self.__test_dir, "output_file")
-                print_file = os.path.join(self.__test_dir, "print_file")
+                source_file = os.path.join(self.test_root, "source_file")
+                output_file = os.path.join(self.test_root, "output_file")
+                print_file = os.path.join(self.test_root, "print_file")
                 #
                 # generate output for each file action, and count resulting
                 # lines in print file to be sure it matches our expectations
@@ -237,3 +223,6 @@
                         "grep -w '3'" % (print_file, output_file,
                         self.transform_files[10], self.transform_files[11],
                         source_file, print_file))
+
+if __name__ == "__main__":
+        unittest.main()
--- a/src/tests/cli/t_pkgrecv.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkgrecv.py	Sat Jan 30 01:07:14 2010 -0800
@@ -21,13 +21,14 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import difflib
 import os
@@ -46,9 +47,9 @@
 import unittest
 import zlib
 
-class TestPkgrecvMulti(testutils.ManyDepotTestCase):
+class TestPkgrecvMulti(pkg5unittest.ManyDepotTestCase):
         # Cleanup after every test.
-        persistent_depot = False
+        persistent_setup = False
 
         scheme10 = """
             open pkg:/[email protected],5.11-0
@@ -76,14 +77,14 @@
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/usr
             add dir mode=0755 owner=root group=bin path=/usr/bin
-            add file /tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
+            add file tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
             add link path=/usr/bin/jsh target=./sh
             add hardlink path=/lib/libc.bronze target=/lib/libc.so.1
-            add file /tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
-            add file /tmp/bronze2 mode=0444 owner=root group=bin path=/etc/bronze2
-            add file /tmp/bronzeA1 mode=0444 owner=root group=bin path=/A/B/C/D/E/F/bronzeA1
+            add file tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
+            add file tmp/bronze2 mode=0444 owner=root group=bin path=/etc/bronze2
+            add file tmp/bronzeA1 mode=0444 owner=root group=bin path=/A/B/C/D/E/F/bronzeA1
             add depend fmri=pkg:/[email protected] type=require
-            add license /tmp/copyright2 license=copyright
+            add license tmp/copyright2 license=copyright
             close
         """
 
@@ -91,22 +92,22 @@
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/etc
             add dir mode=0755 owner=root group=bin path=/lib
-            add file /tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
-            add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.bronze
+            add file tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
+            add file tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.bronze
             add link path=/usr/bin/jsh target=./sh
             add hardlink path=/lib/libc.bronze2.0.hardlink target=/lib/libc.so.1
-            add file /tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
-            add file /tmp/bronze2 mode=0444 owner=root group=bin path=/etc/amber2
-            add license /tmp/copyright3 license=copyright
-            add file /tmp/bronzeA2 mode=0444 owner=root group=bin path=/A1/B2/C3/D4/E5/F6/bronzeA2
+            add file tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
+            add file tmp/bronze2 mode=0444 owner=root group=bin path=/etc/amber2
+            add license tmp/copyright3 license=copyright
+            add file tmp/bronzeA2 mode=0444 owner=root group=bin path=/A1/B2/C3/D4/E5/F6/bronzeA2
             add depend fmri=pkg:/[email protected] type=require
             close 
         """
 
-        misc_files = [ "/tmp/bronzeA1",  "/tmp/bronzeA2",
-                    "/tmp/bronze1", "/tmp/bronze2",
-                    "/tmp/copyright2", "/tmp/copyright3",
-                    "/tmp/libc.so.1", "/tmp/sh"]
+        misc_files = [ "tmp/bronzeA1",  "tmp/bronzeA2",
+                    "tmp/bronze1", "tmp/bronze2",
+                    "tmp/copyright2", "tmp/copyright3",
+                    "tmp/libc.so.1", "tmp/sh"]
 
         def setUp(self):
                 """ Start two depots.
@@ -114,15 +115,9 @@
                     depot1 is mapped to publisher test1 (preferred)
                     depot2 is mapped to publisher test2 """
 
-                testutils.ManyDepotTestCase.setUp(self, ["test1", "test2"])
+                pkg5unittest.ManyDepotTestCase.setUp(self, ["test1", "test2"])
 
-                for p in self.misc_files:
-                        f = open(p, "w")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(p)
-                        f.close()
-                        self.debug("wrote %s" % p)
+                self.make_misc_files(self.misc_files)
 
                 self.dpath1 = self.dcs[1].get_repodir()
                 self.durl1 = self.dcs[1].get_depot_url()
@@ -138,13 +133,7 @@
 
                 self.dpath2 = self.dcs[2].get_repodir()
                 self.durl2 = self.dcs[2].get_depot_url()
-                self.tempdir = tempfile.mkdtemp(dir=self.get_test_prefix())
-
-        def tearDown(self):
-                testutils.ManyDepotTestCase.tearDown(self)
-                for p in self.misc_files:
-                        os.remove(p)
-                shutil.rmtree(self.tempdir)
+                self.tempdir = tempfile.mkdtemp(dir=self.test_root)
 
         @staticmethod
         def get_repo(uri):
@@ -187,7 +176,7 @@
                 self.pkgrecv(command="-h", exit=0)
 
                 # Verify that a non-existent repository results in failure.
-                npath = os.path.join(self.get_test_prefix(), "nochance")
+                npath = os.path.join(self.test_root, "nochance")
                 self.pkgrecv(self.durl1, "-d file://%s foo" % npath,  exit=1)
 
                 # Test list newest.
@@ -280,7 +269,7 @@
                                     misc.get_data_digest(new))
 
                 # Second, pkgrecv to the pkg to a file repository.
-                npath = tempfile.mkdtemp(dir=self.get_test_prefix())
+                npath = tempfile.mkdtemp(dir=self.test_root)
                 self.pkgsend("file://%s" % npath,
                     "create-repository --set-property publisher.prefix=test1")
                 self.pkgrecv(self.durl1, "-d file://%s %s" % (npath, f))
@@ -352,7 +341,7 @@
                 # Fifth, pkgrecv the pkg to a file repository and compare the
                 # manifest of a package published with the scheme (pkg:/) given.
                 f = fmri.PkgFmri(self.published[6], None)
-                npath = tempfile.mkdtemp(dir=self.get_test_prefix())
+                npath = tempfile.mkdtemp(dir=self.test_root)
                 self.pkgsend("file://%s" % npath,
                     "create-repository --set-property publisher.prefix=test1")
                 self.pkgrecv(self.durl1, "-d file://%s %s" % (npath, f))
@@ -497,4 +486,3 @@
 
 if __name__ == "__main__":
         unittest.main()
-
--- a/src/tests/cli/t_pkgsend.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_pkgsend.py	Sat Jan 30 01:07:14 2010 -0800
@@ -26,6 +26,7 @@
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import shutil
@@ -35,8 +36,8 @@
 
 from pkg import misc
 
-class TestPkgsendBasics(testutils.SingleDepotTestCase):
-        persistent_depot = False
+class TestPkgsendBasics(pkg5unittest.SingleDepotTestCase):
+        persistent_setup = False
 
         def test_0_pkgsend_bad_opts(self):
                 """Verify that non-existent or invalid option combinations
@@ -89,7 +90,7 @@
                         self.pkgsend(scheme, "open [email protected]", exit=1)
 
                 # Create an empty directory to abuse as a repository.
-                junk_repo = os.path.join(self.get_test_prefix(), "junk-repo")
+                junk_repo = os.path.join(self.test_root, "junk-repo")
                 os.makedirs(junk_repo, misc.PKG_DIR_MODE)
 
                 # Point at a valid directory that does not contain a repository.
@@ -123,7 +124,7 @@
                 os.environ["PKG_TRANS_ID"] = "foobarbaz"
 
                 for url in (dfurl, dhurl):
-                        self.pkgsend(url, "add file /bin/ls path=/bin/ls",
+                        self.pkgsend(url, "add file bin/ls path=/bin/ls",
                             exit=1)
 
         def test_4_bad_actions(self):
@@ -135,8 +136,7 @@
 
                 dhurl = self.dc.get_depot_url()
                 dfurl = "file://%s" % self.dc.get_repodir()
-                test_dir = self.get_test_prefix()
-                imaginary_file = os.path.join(test_dir, "imaginary_file")
+                imaginary_file = os.path.join(self.test_root, "imaginary_file")
 
                 # Must open transaction using HTTP url first so that transaction
                 # will be seen by the depot server and when using file://.
@@ -153,11 +153,11 @@
 
                         # Should fail because path attribute is missing.
                         self.pkgsend(url,
-                            "add file /bin/ls", exit=1)
+                            "add file bin/ls", exit=1)
 
                         # Should fail because path attribute is missing a value.
                         self.pkgsend(url,
-                            "add file /bin/ls path=", exit=1)
+                            "add file bin/ls path=", exit=1)
 
                         # Should fail because the file does not exist.
                         self.pkgsend(url,
@@ -210,7 +210,7 @@
                 """Verify that create-repository works as expected."""
 
                 self.dc.stop()
-                rpath = os.path.join(self.get_test_prefix(), "example_repo")
+                rpath = os.path.join(self.test_root, "example_repo")
                 self.pkgsend("file://%s" % rpath,
                     "create-repository --set-property publisher.prefix=test")
 
@@ -233,13 +233,13 @@
                 file, that publishing will still work as expected."""
 
                 # First create our dummy data file.
-                fd, fpath = tempfile.mkstemp(dir=self.get_test_prefix())
+                fd, fpath = tempfile.mkstemp(dir=self.test_root)
                 fp = os.fdopen(fd, "wb")
                 fp.write("foo")
                 fp.close()
 
                 # Then, create a link to it.
-                lpath = os.path.join(self.get_test_prefix(), "test_8_foo")
+                lpath = os.path.join(self.test_root, "test_8_foo")
                 os.symlink(fpath, lpath)
 
                 # Next, publish it using both the real path and the linked path
@@ -249,7 +249,7 @@
                     """open [email protected]
                     add file %s mode=0755 owner=root group=bin path=/tmp/f.foo
                     add file %s mode=0755 owner=root group=bin path=/tmp/l.foo
-                    close""" % (fpath, lpath))
+                    close""" % (os.path.basename(fpath), os.path.basename(lpath)))
 
                 # Finally, verify that both files were published.
                 self.image_create(dhurl)
@@ -260,7 +260,7 @@
                 self.image_destroy()
 
         def test_9_multiple_dirs(self):
-                rootdir = self.get_test_prefix()
+                rootdir = self.test_root
                 dir_1 = os.path.join(rootdir, "dir_1")
                 dir_2 = os.path.join(rootdir, "dir_2")
                 os.mkdir(dir_1)
@@ -285,7 +285,7 @@
                 self.image_destroy()
 
         def test_10_bundle_dir(self):
-                rootdir = self.get_test_prefix()
+                rootdir = self.test_root
                 dir1 = os.path.join(rootdir, "foo")
                 os.mkdir(dir1)
                 file(os.path.join(dir1, "bar"), "wb").close()
@@ -299,7 +299,7 @@
                 self.image_destroy()
 
         def test_11_bundle_sysv_dir(self):
-                rootdir = self.get_test_prefix()
+                rootdir = self.test_root
                 dir1 = os.path.join(rootdir, "foobar")
                 os.mkdir(dir1)
                 file(os.path.join(dir1, "bar"), "wb").close()
@@ -337,7 +337,7 @@
 
 
         def test_12_bundle_sysv_datastream(self):
-                rootdir = self.get_test_prefix()
+                rootdir = self.test_root
                 dir1 = os.path.join(rootdir, "foobar")
                 os.mkdir(dir1)
                 file(os.path.join(dir1, "bar"), "wb").close()
@@ -383,7 +383,7 @@
                 dhurl = self.dc.get_depot_url()
                 dfurl = "file://%s" % urllib.pathname2url(self.dc.get_repodir())
 
-                fd, fpath = tempfile.mkstemp(dir=self.get_test_prefix())
+                fd, fpath = tempfile.mkstemp(dir=self.test_root)
 
                 self.image_create(dhurl)
 
@@ -484,7 +484,7 @@
                     (bob, -1)
                 ]
                 dhurl = self.dc.get_depot_url()
-                junk_repo = os.path.join(self.get_test_prefix(), "obs-junkrepo")
+                junk_repo = os.path.join(self.test_root, "obs-junkrepo")
                 dfurl = "file://" + junk_repo
                 self.pkgsend(dfurl,
                     "create-repository --set-property publisher.prefix=test")
@@ -525,7 +525,7 @@
 """
                 self.dc.stop()
                 rpath = self.dc.get_repodir()
-                fpath = os.path.join(self.get_test_prefix(), "manifest")
+                fpath = os.path.join(self.test_root, "manifest")
                 f = file(fpath, "w")
                 f.write(pkg_manifest)
                 f.close()
@@ -536,7 +536,8 @@
                 self.pkgsend("file://%s publish --fmri-in-manifest --no-catalog %s" % (
                                 rpath, fpath))
                 new_mtime = os.stat(cat_path).st_mtime
-                assert(mtime == new_mtime, "modified times not the same before and after publication")
+                # check that modified times are the same before and after publication
+                self.assertEqual(mtime, new_mtime)
                 self.dc.set_add_content()
                 
                 self.dc.start()
@@ -551,22 +552,17 @@
                 """Verify that when sending multiple manifests, the contents
                 of all manifests are published."""
 
-                test_files = []
-
                 # First create two dummy data files.
-                for i in range(2):
-                        fd, fpath = tempfile.mkstemp(dir=self.get_test_prefix())
-                        fp = os.fdopen(fd, "wb")
-                        test_files.append(fpath)
-                        fp.write("foo")
-                        fp.close()
+                test_files = ["dummy1", "dummy2"]
+                self.make_misc_files(test_files)
 
                 # create two manifests.
                 for path in test_files:
-                        mf = open(path + ".manifest", "w")
-                        mf.write("file %s mode=0644 owner=root path=/foo%s" %
-                            (path, path))
-                        mf.close()
+                        manfpath = path + ".manifest"
+                        self.make_misc_files({
+                            manfpath:
+                                "file %s mode=0644 owner=root path=/foo%s" % \
+                                (path, path)})
 
                 # publish
                 url = self.dc.get_depot_url()
--- a/src/tests/cli/t_publish_api.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_publish_api.py	Sat Jan 30 01:07:14 2010 -0800
@@ -21,13 +21,14 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
 import testutils
 if __name__ == "__main__":
 	testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import pkg.fmri as fmri
@@ -35,11 +36,11 @@
 import urlparse
 import urllib
 
-class TestPkgPublicationApi(testutils.SingleDepotTestCase):
+class TestPkgPublicationApi(pkg5unittest.SingleDepotTestCase):
         """Various publication tests."""
 
         # Restart the depot and recreate the repository every test.
-        persistent_depot = False
+        persistent_setup = False
 
         def test_stress_http_publish(self):
                 """Publish lots of packages rapidly ensuring that http
@@ -74,3 +75,6 @@
                         pkg_fmri, pkg_state = t.close(refresh_index=True)
                         self.debug("%s: %s" % (pkg_fmri, pkg_state))
 
+
+if __name__ == "__main__":
+        unittest.main()
--- a/src/tests/cli/t_setUp.py	Fri Jan 29 13:24:14 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,63 +0,0 @@
-#!/usr/bin/python
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-
-import testutils
-import pkg5unittest
-
-if __name__ == "__main__":
-	testutils.setup_environment("../../../proto")
-
-import unittest
-
-class TestSetUp(testutils.SingleDepotTestCase):
-        """Test whether an exception in setUp leaves a depot running.
-        If it does, the second test will fail with a DepotStateException.
-        If the baseline.SuccessfulException is raised, BaselineTestCase
-        will report the test a success.
-        """
-
-        def setUp(self):
-                testutils.SingleDepotTestCase.setUp(self)
-                raise pkg5unittest.EarlyTearDownException("Died in setup")
-
-        def test_first_depot_start(self):
-                """Attempt to start a depot, which dies because of an exception
-                raised during setUP.
-                """
-
-                durl = self.dc.get_depot_url()
-
-        def test_second_depot_start(self):
-                """Test whether the first depot was shut down.  If this test
-                raises a exception because a depot was already running on that
-                port, then the test has failed.  If it raises the
-                SuccessfulException, then it has passed because it was able to
-                successfully start a depot."""
-
-                durl = self.dc.get_depot_url()
-
-
-if __name__ == "__main__":
-        unittest.main()
--- a/src/tests/cli/t_solver.py	Fri Jan 29 13:24:14 2010 -0800
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,2214 +0,0 @@
-#!/usr/bin/python
-#
-# CDDL HEADER START
-#
-# The contents of this file are subject to the terms of the
-# Common Development and Distribution License (the "License").
-# You may not use this file except in compliance with the License.
-#
-# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
-# or http://www.opensolaris.org/os/licensing.
-# See the License for the specific language governing permissions
-# and limitations under the License.
-#
-# When distributing Covered Code, include this CDDL HEADER in each
-# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
-# If applicable, add the following below this CDDL HEADER, with the
-# fields enclosed by brackets "[]" replaced with your own identifying
-# information: Portions Copyright [yyyy] [name of copyright owner]
-#
-# CDDL HEADER END
-#
-
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
-# Use is subject to license terms.
-
-import unittest
-import pkg.solver as solver
-import os
-import sys
-
-# Set the path so that modules above can be found
-path_to_parent = os.path.join(os.path.dirname(__file__), "..")
-sys.path.insert(0, path_to_parent)
-import pkg5unittest
-
-class TestSolver(pkg5unittest.Pkg5TestCase):
-
-        def test_no_solution(self):
-                cnf_test(failing_test_case.splitlines())
-
-        def test_solution(self):
-                cnf_test(working_test_case.splitlines())
-
-def cnf_test(lines):
-        s = solver.msat_solver()
-        
-        for l in lines:
-                if l and l[0] in 'pc%0':
-                        pass # comment
-                else:
-                        # skip trailing 0
-                        cl = [int(i) for i in l.split()[0:-1]]
-                        if cl and not s.add_clause(cl):
-                                return False
-        # create new copy of solver instance to test copy code
-        n = solver.msat_solver(s)
-        del s # force gc of old solver instance
-        return n.solve([])
-
-
-failing_test_case = """
-c This Formular is generated by mcnf
-c
-c    horn? no
-c    forced? no
-c    mixed sat? no
-c    clause length = 3
-c
-p cnf 250  1065
- -128 -209 148 0
-2 196 -115 0
--66 -189 -241 0
--84 -132 -93 0
-214 179 66 0
-203 132 -237 0
-164 -13 -172 0
--157 198 160 0
--91 -164 235 0
--70 -116 54 0
--164 171 -189 0
-126 -184 211 0
--19 118 41 0
-32 105 -33 0
--141 -108 50 0
--1 156 -188 0
-138 -181 142 0
--191 -247 -220 0
--101 -207 -88 0
-68 114 -234 0
-134 -57 -131 0
--30 -133 116 0
--24 -173 92 0
-226 -4 -224 0
--190 204 61 0
-148 205 -174 0
-213 -56 53 0
-174 -250 206 0
-32 219 -112 0
-203 -222 202 0
-130 42 226 0
-222 33 58 0
-58 35 34 0
--121 80 245 0
--231 38 -248 0
--205 -179 184 0
--182 -204 -36 0
-23 35 -181 0
-82 -168 -59 0
-103 132 -182 0
--243 -18 -160 0
--180 130 95 0
-111 -140 -107 0
-19 28 -72 0
--222 207 -103 0
-134 -50 -184 0
-185 155 -11 0
--102 230 -18 0
--112 39 242 0
-154 -87 53 0
-173 -123 -159 0
--238 -101 -40 0
--126 -232 -139 0
-107 -51 197 0
--194 -138 -150 0
-106 -66 -11 0
--150 -159 -27 0
--98 -32 138 0
-144 -32 128 0
-153 74 -249 0
--190 -175 -208 0
--127 88 -38 0
--59 125 -225 0
--23 4 181 0
-12 247 -133 0
-151 -238 127 0
-237 -65 -154 0
--218 -26 -55 0
-91 -245 169 0
--81 -156 10 0
-166 -66 -45 0
-109 -162 47 0
--193 153 40 0
-162 -186 -7 0
-93 38 -58 0
--159 -167 -39 0
--187 68 124 0
-247 23 212 0
-49 182 -243 0
-206 -105 -237 0
-236 116 154 0
-236 -6 182 0
--168 236 35 0
--186 70 -236 0
-127 80 103 0
-100 79 -176 0
-117 -88 -1 0
-60 -115 -224 0
--148 181 -65 0
--132 235 19 0
--44 -197 190 0
--214 67 129 0
--203 175 -191 0
--172 166 -115 0
--176 -180 207 0
--56 -208 -1 0
--37 140 -19 0
--242 -55 58 0
--116 -153 241 0
--203 64 -219 0
--214 64 90 0
--166 96 155 0
-68 -2 63 0
--200 49 196 0
--230 -232 -148 0
--81 105 219 0
-187 -236 -123 0
--99 237 136 0
--205 61 -118 0
--235 -230 128 0
-38 -9 -124 0
--34 -116 179 0
--40 -55 -85 0
-244 170 6 0
--7 -54 -236 0
-153 -223 173 0
--219 -13 -217 0
-244 -210 -228 0
-23 -128 -113 0
-35 -245 -235 0
-184 31 143 0
--207 -24 135 0
-97 -165 -14 0
--17 15 26 0
-61 78 -8 0
-215 -30 -166 0
-229 93 -246 0
--167 -113 80 0
-78 205 -87 0
-117 -144 207 0
--10 153 -84 0
--147 238 61 0
--58 -17 -190 0
-209 -25 -81 0
--175 244 -57 0
-185 127 -147 0
-237 199 -144 0
-124 148 -10 0
-190 244 231 0
--185 214 -101 0
--237 31 -94 0
--39 36 -94 0
--175 206 81 0
-141 -209 -109 0
-228 -165 -112 0
--45 142 238 0
--34 -64 -71 0
--60 170 -109 0
-6 245 87 0
-12 -93 -231 0
-80 216 28 0
--103 137 116 0
--77 -73 -30 0
--63 219 -129 0
--215 -94 86 0
-81 46 221 0
-161 -215 -212 0
--137 -215 48 0
--50 211 229 0
-172 74 154 0
--14 -100 166 0
-59 -119 -243 0
-244 -31 -96 0
-51 -247 205 0
--90 97 -139 0
-113 118 -7 0
-57 -161 -84 0
-180 -174 -9 0
--19 16 -202 0
--39 -134 224 0
-84 240 195 0
--55 75 -207 0
-116 54 60 0
-80 98 40 0
--159 109 217 0
--210 -119 82 0
--201 -14 174 0
-43 -19 -100 0
--126 223 26 0
--249 163 -205 0
--58 -4 109 0
--239 109 -82 0
-210 -58 -2 0
-238 -36 117 0
-109 -199 32 0
--54 221 -80 0
-230 99 97 0
-45 221 169 0
-191 17 114 0
--177 -138 -12 0
-35 -5 145 0
--102 -147 103 0
--59 3 84 0
--56 240 -130 0
--233 -223 -47 0
-169 216 -3 0
--68 -182 67 0
-34 -189 27 0
-230 -222 66 0
-19 123 84 0
-64 35 231 0
-236 165 242 0
-77 -119 -61 0
--179 215 198 0
--105 -93 211 0
--204 221 -112 0
--244 23 -125 0
--107 152 78 0
-144 -183 28 0
--179 -32 194 0
-217 174 72 0
--38 101 -132 0
--122 193 108 0
-12 3 -44 0
-140 -23 -2 0
-185 -129 145 0
--116 -245 -102 0
-203 -29 -131 0
--172 239 243 0
--186 -167 109 0
-158 -184 149 0
--53 56 100 0
--92 5 35 0
--212 -236 250 0
--42 137 -193 0
-171 231 127 0
-176 -85 -122 0
-32 81 -178 0
-78 -14 -227 0
-104 -10 -65 0
-239 -81 -118 0
-182 76 -235 0
--226 -132 54 0
-145 25 120 0
-49 205 99 0
-250 240 -89 0
-17 37 -65 0
-226 -66 -47 0
-136 -112 19 0
--94 -32 74 0
-200 144 -65 0
-27 29 207 0
-6 112 53 0
--170 -192 -65 0
--18 206 8 0
--158 245 147 0
-222 34 24 0
-69 182 -121 0
--22 -202 -232 0
--213 -82 173 0
-78 -176 -151 0
-245 215 242 0
--126 -96 243 0
--164 -220 205 0
--60 128 162 0
--237 -126 -20 0
-105 -144 -165 0
--158 76 -38 0
-153 -236 206 0
-187 -191 247 0
--192 159 171 0
-162 -151 -213 0
-19 155 238 0
--43 207 -46 0
-117 250 118 0
-159 40 -199 0
-149 -163 -145 0
-23 7 46 0
-71 106 56 0
--43 220 -118 0
--200 242 6 0
-143 219 -168 0
--179 102 -163 0
--74 183 -82 0
-248 92 -154 0
-81 202 229 0
-92 243 19 0
-165 -210 199 0
--54 -8 244 0
--70 -135 -223 0
--80 -89 -189 0
--7 182 -16 0
-172 53 8 0
-114 -107 197 0
--135 -35 -239 0
--214 -10 137 0
-136 -131 151 0
-15 -37 -89 0
--234 -7 97 0
-118 191 101 0
-215 123 185 0
--230 202 -190 0
-211 -59 210 0
-200 -162 116 0
-158 12 212 0
--56 229 196 0
--50 -52 218 0
-164 -142 -71 0
-233 -140 159 0
-119 93 65 0
-155 -156 -57 0
-117 -197 180 0
--97 -100 -2 0
-165 206 83 0
--127 173 -110 0
-20 158 116 0
--205 -125 -209 0
--244 -57 -246 0
--139 -173 21 0
-89 -150 149 0
--51 60 -224 0
--81 -193 195 0
--208 -209 83 0
--141 70 -223 0
-200 -121 99 0
--207 201 -61 0
-167 157 -71 0
-200 78 182 0
-82 171 -183 0
-4 -33 -85 0
--103 87 186 0
-41 183 169 0
-84 244 -116 0
-128 -108 -67 0
-24 165 181 0
-94 118 -148 0
--41 -71 -98 0
-248 15 -135 0
-10 -157 -17 0
--225 241 93 0
-217 -192 227 0
-28 -11 78 0
--16 218 24 0
-59 -91 -210 0
-4 141 166 0
--204 12 -206 0
-187 153 -186 0
-23 -43 -124 0
-100 2 -46 0
--236 -80 -102 0
-165 129 159 0
--45 245 -187 0
-137 31 -7 0
-214 -178 200 0
-222 107 -74 0
--37 -161 -129 0
--202 -214 99 0
-69 3 78 0
--7 -217 51 0
-215 -99 96 0
-124 41 195 0
--233 -223 206 0
-233 197 87 0
--102 33 70 0
-175 241 162 0
-86 -202 83 0
-137 -214 64 0
--111 -204 197 0
--23 12 -121 0
-101 28 -95 0
--206 57 220 0
--122 -2 -125 0
-75 -241 86 0
--72 185 77 0
--125 210 -143 0
-106 36 54 0
-136 142 -93 0
--142 -180 214 0
-44 -22 -60 0
--235 88 -130 0
--124 -162 245 0
-19 -121 156 0
-84 -23 -191 0
--173 -43 -163 0
-151 148 213 0
--239 147 -180 0
--247 -92 -36 0
-163 37 -188 0
--245 -7 -231 0
--32 -139 41 0
--13 -157 211 0
--107 136 126 0
--58 201 -115 0
--184 -48 -205 0
-57 -237 -80 0
-160 -243 155 0
-154 -42 -179 0
--107 -242 -167 0
-169 170 -19 0
--65 -140 -209 0
-143 146 182 0
-90 -170 158 0
--235 54 83 0
--122 193 239 0
-112 130 -212 0
--9 -167 93 0
--57 54 -28 0
--55 -56 29 0
--206 -79 245 0
--16 -81 -190 0
-174 160 131 0
--125 156 -148 0
--128 174 -25 0
--209 -16 60 0
--13 -225 109 0
-167 -124 168 0
-142 -16 173 0
-8 -45 216 0
-13 160 -41 0
--101 125 -225 0
--218 244 -49 0
-153 -183 204 0
-117 230 167 0
--108 24 -27 0
-149 -198 13 0
-48 124 -84 0
--35 -162 58 0
-110 -103 9 0
--143 -43 169 0
--91 -87 -70 0
-11 -117 244 0
--141 37 -177 0
-238 126 -215 0
-157 103 -27 0
--133 134 -3 0
-112 -107 -113 0
--225 -104 26 0
-109 -220 -174 0
-58 -140 -86 0
-1 97 14 0
-249 161 -217 0
-99 -242 33 0
-172 2 -235 0
--79 -132 107 0
-43 -217 -169 0
--166 218 -128 0
-63 178 135 0
-110 224 30 0
--62 147 -237 0
--241 -103 -169 0
-125 -75 -106 0
-146 20 -112 0
-59 226 -136 0
--194 132 -101 0
-133 -41 -14 0
-190 74 -247 0
-230 221 224 0
--3 -61 -65 0
-93 15 194 0
--155 105 117 0
--146 -127 -35 0
-170 -173 213 0
--13 -234 -117 0
--244 -225 15 0
--41 151 -185 0
--196 -2 114 0
--220 111 -238 0
-234 134 146 0
-100 -29 -4 0
--195 -6 151 0
--116 109 -9 0
-45 -58 -61 0
-195 224 66 0
-119 174 129 0
-122 233 100 0
-30 -227 -120 0
-238 1 16 0
-231 229 -46 0
-188 226 23 0
--181 247 -216 0
-233 84 97 0
-8 41 71 0
-37 52 56 0
--227 58 84 0
-116 48 -95 0
--58 233 36 0
-210 11 -116 0
--107 -103 242 0
-21 -161 169 0
-202 25 82 0
-248 163 65 0
--108 26 -78 0
--162 163 -248 0
--14 -95 92 0
-218 -151 -26 0
--132 -195 44 0
-14 85 -136 0
--236 219 -105 0
-164 136 -25 0
-7 36 124 0
--163 -216 -15 0
--66 176 -76 0
--144 -3 -101 0
--178 -149 -108 0
-175 -161 210 0
--118 106 -11 0
--124 128 98 0
--81 -223 117 0
-154 149 -1 0
--186 26 66 0
--190 192 -114 0
--122 -197 -52 0
--84 -226 105 0
-52 61 225 0
-206 -7 -101 0
--29 93 -116 0
-67 -164 135 0
-1 -217 -5 0
--180 218 222 0
-230 -225 -50 0
-4 -25 45 0
--57 234 -1 0
--221 -103 100 0
-137 234 -109 0
-20 -227 -202 0
--103 -247 198 0
--29 -148 -35 0
--191 102 18 0
--52 -195 18 0
-61 5 -247 0
-165 -207 -217 0
--147 -207 27 0
-100 117 -129 0
--152 -83 132 0
--190 53 -121 0
-156 230 181 0
-2 -239 -65 0
--55 -20 -107 0
--119 -39 -221 0
--116 147 16 0
--211 238 -60 0
-249 -111 141 0
--54 -193 -81 0
-49 -245 -5 0
--233 110 -109 0
--79 -56 180 0
--41 196 150 0
-242 -63 231 0
-39 22 100 0
-5 23 204 0
--55 -100 105 0
--22 -28 247 0
--209 200 67 0
--46 59 62 0
--239 -107 -125 0
-242 25 -246 0
--148 -30 -11 0
--148 160 -169 0
-5 145 249 0
-168 -28 -207 0
--188 212 -201 0
--166 205 -239 0
-145 -246 -100 0
-3 215 -93 0
-101 -198 -160 0
--233 178 -90 0
--143 -26 -102 0
--72 -97 -195 0
--119 -163 -120 0
-93 13 98 0
--131 -53 15 0
--118 129 151 0
-168 81 199 0
--17 121 -21 0
--36 -175 196 0
--221 57 68 0
-111 145 -183 0
-114 -31 24 0
--170 159 -146 0
-123 -80 152 0
--84 -184 -134 0
--206 30 -55 0
-81 -154 198 0
-129 135 248 0
--2 198 122 0
-230 101 -18 0
-25 208 216 0
--247 176 160 0
-34 -159 9 0
--74 184 31 0
-29 -66 -148 0
--233 204 -107 0
-204 -30 -127 0
--237 8 -65 0
-79 112 181 0
-157 -85 83 0
-204 113 -216 0
--11 -15 27 0
-44 114 8 0
-105 188 -158 0
--51 204 -48 0
-145 211 40 0
--107 -31 -114 0
--134 212 -105 0
-188 -174 -151 0
-58 -9 -151 0
-33 -37 -119 0
-172 -3 169 0
--26 -21 48 0
--94 -99 -41 0
-192 1 -7 0
-250 -138 185 0
--6 -131 -83 0
-11 191 -240 0
--175 -163 -249 0
--214 -98 193 0
-120 190 -185 0
--135 -64 -24 0
--187 249 -129 0
-76 -232 112 0
--17 -161 117 0
--6 250 246 0
-85 -188 117 0
--47 91 -103 0
--123 -92 142 0
-3 -183 -249 0
--175 148 -129 0
-223 172 119 0
-194 76 -114 0
-206 123 -222 0
--186 -110 -71 0
--63 152 -110 0
--122 -44 -119 0
--14 76 -224 0
--8 -77 -97 0
--116 110 63 0
-148 106 192 0
-204 -168 -56 0
--221 173 -13 0
-168 57 -211 0
-218 151 245 0
-70 -234 -143 0
-24 194 106 0
-16 -236 -187 0
-162 97 43 0
-8 79 228 0
--39 -179 48 0
--119 213 -231 0
--239 57 -232 0
--161 247 8 0
-30 -127 197 0
-72 168 -233 0
--157 -217 -135 0
-134 180 233 0
-27 -14 -64 0
-153 247 -60 0
--154 -76 -106 0
--59 -100 170 0
-120 -121 -41 0
--169 13 158 0
--166 199 120 0
-164 202 -199 0
--223 148 -242 0
-4 211 100 0
-188 -231 -98 0
-218 129 -93 0
--211 18 -93 0
-51 -10 -78 0
-22 -155 -130 0
-207 -135 -172 0
-199 197 14 0
-182 -245 -135 0
--204 181 -32 0
--18 -237 80 0
--96 69 193 0
--98 245 -91 0
-71 -24 93 0
-48 -131 194 0
-29 144 -12 0
-128 15 -71 0
-125 58 -238 0
--84 111 38 0
-224 168 246 0
--82 -188 -33 0
--67 98 242 0
-34 248 -112 0
-217 95 59 0
-56 245 13 0
-72 129 -245 0
-82 134 -61 0
--128 55 -183 0
--187 42 38 0
-90 -102 54 0
--159 224 229 0
--117 -158 -180 0
-113 108 5 0
-239 34 -122 0
--85 -118 -19 0
--240 129 -145 0
--15 149 129 0
--144 -189 217 0
-228 -223 97 0
-16 -84 -242 0
-206 -212 91 0
--71 -194 21 0
-59 -31 37 0
--89 156 -243 0
-60 21 75 0
-14 12 -8 0
--227 -183 131 0
--95 -190 -49 0
--151 -54 -133 0
--134 49 -157 0
-6 -114 224 0
-201 -195 -17 0
--99 -36 88 0
-123 -67 105 0
-142 -94 49 0
-58 106 234 0
-22 -18 -86 0
-201 -245 71 0
--220 -228 227 0
--117 31 -212 0
--177 -140 -59 0
-229 233 150 0
-47 -36 103 0
--239 102 -241 0
--35 194 208 0
-199 -37 -180 0
-140 -176 -123 0
-148 -36 243 0
-14 141 227 0
--182 -141 248 0
-178 85 144 0
-247 231 15 0
-77 -168 -40 0
--194 -181 -83 0
--225 116 -79 0
--80 182 -50 0
-63 -36 -122 0
-82 231 -59 0
--64 -244 157 0
--86 140 -207 0
--129 -192 -143 0
--69 227 216 0
--83 137 -101 0
-117 -71 145 0
-115 -53 199 0
--32 96 -1 0
-104 93 -142 0
-190 116 83 0
-191 -124 -161 0
-144 11 -181 0
--151 113 243 0
--66 -141 -108 0
--153 -149 7 0
--75 -129 137 0
-113 -107 43 0
--191 99 237 0
-199 67 163 0
--198 -177 -21 0
-217 -236 88 0
--136 -84 158 0
-52 68 -204 0
--61 200 21 0
-95 -204 -221 0
--75 -125 118 0
-213 113 173 0
--226 -92 118 0
--134 -189 67 0
--198 7 -26 0
--49 197 57 0
--5 -72 -146 0
-226 167 -27 0
-211 -229 94 0
--101 -80 -12 0
-58 -47 -80 0
-148 -217 -9 0
-229 -120 -117 0
-161 -174 191 0
-10 -51 -154 0
--155 235 -198 0
--171 247 127 0
--130 19 140 0
--209 -185 -25 0
--223 -199 -27 0
--28 124 187 0
-135 -28 31 0
--31 88 89 0
-22 -43 -47 0
-21 165 -184 0
--250 69 -27 0
-221 -177 162 0
--72 -218 207 0
-23 -159 83 0
--54 225 -190 0
--140 -21 49 0
--50 -177 -18 0
-80 -250 172 0
--77 183 -218 0
-184 55 -146 0
--104 181 -188 0
-243 146 -70 0
--215 -187 -247 0
--196 -50 90 0
--84 143 -146 0
-147 119 -118 0
-227 14 -110 0
-44 238 -153 0
-197 -69 -176 0
-127 65 27 0
-208 190 -162 0
--39 250 -196 0
-114 -89 206 0
-142 75 -148 0
--202 237 -194 0
--21 216 -177 0
-114 -80 -200 0
--27 91 -84 0
--63 249 -36 0
-89 -18 -133 0
--19 -17 -107 0
-145 62 -227 0
--89 -148 -44 0
--133 -192 -149 0
--65 240 -233 0
--88 -40 -245 0
-92 -129 4 0
-22 -62 -21 0
-216 116 -93 0
-79 100 234 0
-39 134 44 0
--226 -170 -157 0
-104 9 -191 0
-26 -39 40 0
-113 232 -174 0
--101 81 -104 0
-173 90 101 0
--208 173 -97 0
--72 209 -111 0
--51 -93 108 0
--248 216 181 0
--65 -170 212 0
--102 -161 146 0
--72 -28 -25 0
--117 -18 229 0
--52 163 -79 0
-94 120 79 0
-105 116 -227 0
-67 186 -211 0
--226 -235 196 0
--67 -11 23 0
--55 -85 -197 0
--200 -245 -76 0
-109 -61 -127 0
--248 127 -229 0
-53 148 -197 0
-151 -98 -24 0
--58 180 -158 0
-74 214 -200 0
--31 241 172 0
-26 219 -56 0
-1 110 -18 0
-156 19 -89 0
-112 87 204 0
--5 151 -59 0
-34 -149 100 0
-83 248 220 0
-31 2 -78 0
-110 -152 -37 0
--132 -217 -57 0
--71 176 79 0
-31 -98 -75 0
--60 229 -171 0
-87 207 112 0
-30 151 -41 0
-17 162 109 0
--172 111 -221 0
-166 170 -147 0
--48 143 -201 0
-233 -46 -122 0
-207 -149 -124 0
--188 -166 -65 0
--76 -77 -96 0
--216 211 45 0
-137 -103 -106 0
-220 -82 -136 0
-47 -84 -44 0
--37 67 -32 0
-33 -5 156 0
--137 58 127 0
-229 -36 -84 0
-243 175 63 0
-242 -73 -121 0
-219 237 164 0
-149 -201 -142 0
-27 172 243 0
--90 29 45 0
-206 57 153 0
--235 -49 -94 0
-233 71 108 0
-82 -122 223 0
--195 -71 37 0
--70 179 -159 0
--79 -240 -38 0
--79 -121 30 0
--238 -78 -246 0
-218 96 48 0
-107 -154 -199 0
-4 -205 194 0
-1 -205 -203 0
--155 129 -26 0
--128 57 22 0
--195 -168 -10 0
-97 -186 -90 0
-122 227 171 0
-22 163 191 0
--223 191 -85 0
-100 -59 -63 0
-245 49 -181 0
--51 210 -135 0
--34 55 54 0
-2 74 -57 0
-233 168 -230 0
--40 22 230 0
-128 -157 27 0
--154 -161 -114 0
--74 -136 38 0
-51 -205 23 0
--212 40 -71 0
-9 -138 -83 0
--95 54 121 0
--174 -85 140 0
-66 16 67 0
--137 -8 105 0
--133 -206 -3 0
-175 86 -206 0
--50 -217 51 0
-51 244 31 0
-184 -218 84 0
--153 58 -237 0
-56 -198 63 0
-228 -42 74 0
-43 -32 245 0
--150 82 -44 0
--14 -22 25 0
-228 -232 -245 0
--147 -221 29 0
--222 41 -40 0
-42 -13 -20 0
-53 9 161 0
-125 236 69 0
--105 -172 32 0
--142 114 -71 0
--120 -122 -197 0
--29 9 -200 0
-26 210 -193 0
--155 183 140 0
-216 -208 -146 0
--220 -8 98 0
-109 175 -63 0
--16 -139 -108 0
-176 137 -119 0
--97 39 142 0
-218 -44 -37 0
--119 -69 -107 0
--79 142 109 0
--123 25 227 0
-177 -187 -89 0
--99 -147 -207 0
--68 81 236 0
-145 90 3 0
-93 -149 -127 0
--120 -67 154 0
-121 234 -229 0
--245 186 21 0
-92 5 -121 0
-197 -100 -46 0
--40 -39 -3 0
-25 -117 -121 0
--194 -189 175 0
-246 10 40 0
-13 50 147 0
--243 163 105 0
-132 -131 -218 0
--241 78 101 0
--200 -38 -29 0
--36 -166 183 0
-248 -216 218 0
--203 92 204 0
--83 -84 -165 0
--202 -197 -244 0
-112 -221 63 0
-100 151 -1 0
-141 -206 -52 0
-181 -208 -229 0
-53 93 173 0
-193 -184 -79 0
-41 -78 -133 0
-1 -35 -90 0
--198 -60 174 0
-152 207 -157 0
-183 -196 -163 0
--244 242 218 0
-11 32 146 0
--66 -32 -84 0
--54 -109 -195 0
-190 -116 144 0
--242 -122 86 0
--71 7 -150 0
-241 -173 -15 0
-62 -217 81 0
-205 -116 130 0
-193 -209 128 0
-146 -240 -132 0
-29 197 161 0
-15 83 -39 0
--109 -44 81 0
-244 85 -7 0
--246 9 165 0
-115 -83 67 0
--98 -141 170 0
--102 94 -52 0
--231 -74 -28 0
-162 191 -149 0
-197 -183 -35 0
-102 -56 50 0
-30 -45 -129 0
-25 -207 -33 0
-192 -106 -169 0
-43 -129 -169 0
-237 244 182 0
--72 -44 -168 0
--158 -150 102 0
-168 -143 151 0
--72 26 212 0
-116 -89 98 0
-171 -197 156 0
-233 -54 -181 0
-129 -161 25 0
-113 69 -33 0
-179 -175 224 0
-138 -143 -46 0
-75 213 -246 0
--137 -175 -150 0
--169 -67 215 0
-86 69 -199 0
--159 233 63 0
--145 101 6 0
-129 -243 -227 0
--175 72 -247 0
-163 -109 207 0
-31 77 33 0
--136 175 160 0
--192 -193 -7 0
-99 145 232 0
--233 198 114 0
-240 -89 -108 0
--81 -67 -63 0
-5 149 69 0
--172 166 -184 0
-158 -244 -166 0
--53 -172 -62 0
-49 25 61 0
-237 19 -166 0
-94 202 -148 0
--246 13 152 0
--135 -86 -5 0
--190 -44 -223 0
--17 -141 6 0
-165 39 237 0
-221 -62 -104 0
--206 107 -223 0
--159 -243 -13 0
-118 -9 57 0
-%
-0
-"""
-working_test_case = """
-c This Formular is generated by mcnf
-c
-c    horn? no
-c    forced? no
-c    mixed sat? no
-c    clause length = 3
-c
-p cnf 250  1065
- -108 246 59 0
--161 -43 234 0
-7 41 -88 0
-26 178 -41 0
--7 -145 -33 0
-206 18 -136 0
--15 173 -213 0
-31 -91 215 0
-3 216 196 0
-234 -85 179 0
-155 -195 106 0
--211 -223 -41 0
-97 2 -217 0
--81 -122 27 0
--149 34 239 0
-69 -216 183 0
--69 148 -92 0
--89 -120 184 0
-231 110 -213 0
-67 173 -195 0
-132 155 183 0
--115 83 4 0
-173 163 -242 0
--198 43 90 0
-71 -116 37 0
--232 52 28 0
-21 -230 -124 0
--146 -108 -110 0
--116 163 214 0
-69 -143 128 0
-228 141 -99 0
--47 75 -193 0
--118 -244 -235 0
-148 -246 -112 0
-124 19 -76 0
--49 102 -125 0
-110 155 3 0
--180 -192 -94 0
--114 -67 -219 0
--159 53 187 0
-219 -102 162 0
-21 -109 -173 0
--124 90 189 0
--191 117 175 0
-77 -250 -155 0
--74 203 60 0
--4 65 166 0
-174 -212 -165 0
--220 119 -35 0
--247 105 126 0
--110 -192 63 0
--227 181 172 0
--219 -31 -221 0
-51 113 19 0
-212 -4 151 0
-197 -14 -211 0
-117 159 -69 0
-48 -19 207 0
--168 203 -212 0
--232 250 -222 0
-151 34 139 0
-249 -159 229 0
--243 244 -48 0
-48 180 -153 0
--227 -98 190 0
--73 -130 60 0
-33 239 -11 0
-41 -48 -201 0
--39 43 143 0
-131 -28 106 0
--97 49 -215 0
-7 42 -194 0
--224 -94 46 0
-137 -220 -84 0
--38 41 -163 0
--229 208 -187 0
-149 -120 238 0
--90 111 135 0
-176 -171 -36 0
-144 -238 237 0
--194 111 -55 0
-76 203 -38 0
--105 134 34 0
-55 -194 -239 0
-37 -95 177 0
--121 -94 -169 0
--93 49 -175 0
-54 -217 102 0
--155 11 63 0
-83 -138 109 0
--68 -30 103 0
--208 -48 -125 0
--100 230 -204 0
--70 222 171 0
-146 -198 158 0
-13 24 98 0
-191 217 100 0
-52 -198 5 0
-166 219 -43 0
-107 -247 105 0
--83 -13 86 0
-232 -68 -61 0
--107 185 -112 0
--106 225 -226 0
-48 71 238 0
-144 -83 -135 0
--56 -27 -39 0
-243 94 55 0
-38 139 35 0
--146 -127 180 0
-182 -83 84 0
-45 211 -70 0
-31 -91 72 0
--146 -232 244 0
--39 140 -200 0
-219 205 -220 0
--94 -65 -87 0
--143 180 -24 0
-70 161 -201 0
-136 128 85 0
--223 64 62 0
--69 209 147 0
-88 -15 -225 0
-80 48 -149 0
-224 246 -117 0
--166 -53 -26 0
--59 -63 -100 0
--1 -55 -237 0
-214 246 13 0
--101 249 -118 0
--180 -222 -250 0
--97 -7 58 0
--169 -213 -80 0
--120 152 242 0
-5 115 15 0
-70 -12 -43 0
-65 63 -248 0
--148 177 173 0
--224 201 12 0
--231 -88 -141 0
-66 29 -233 0
-99 163 12 0
--56 -183 197 0
-89 133 229 0
-126 79 149 0
--238 -139 -137 0
--170 -95 -148 0
--202 -246 115 0
--176 -63 158 0
-216 38 -83 0
-221 41 44 0
--91 181 135 0
-171 -63 71 0
--60 136 107 0
-222 5 57 0
-210 -89 -151 0
--44 36 -91 0
-3 -194 -15 0
--117 38 -110 0
-242 226 155 0
-158 -240 110 0
-218 -37 90 0
-11 217 57 0
-250 -157 73 0
--9 -122 53 0
-185 -76 73 0
--99 -101 102 0
-52 -171 33 0
--143 195 228 0
-42 -63 -229 0
--178 -160 224 0
--65 -54 208 0
-232 -43 -38 0
-85 43 -178 0
--171 -50 45 0
-47 71 -180 0
-127 135 -187 0
--201 33 222 0
--221 -131 -165 0
--131 114 221 0
-195 60 185 0
--8 206 -140 0
-124 -240 223 0
--217 198 149 0
-52 -227 -206 0
-136 -96 29 0
--76 -228 64 0
--157 -47 93 0
-148 -108 17 0
-139 40 -89 0
-63 198 86 0
-199 94 -33 0
--116 216 -2 0
-27 242 -1 0
--156 177 28 0
-234 -83 37 0
--124 -123 -149 0
-112 -1 173 0
-7 235 10 0
-245 -184 -224 0
--112 -161 77 0
-203 104 124 0
--59 -123 -10 0
-250 -242 -203 0
-56 243 164 0
-24 126 -2 0
--101 227 86 0
--233 138 -218 0
--211 -119 -196 0
-143 -183 -186 0
--148 236 76 0
--131 -187 -77 0
-62 -144 -43 0
--232 96 -30 0
-121 -152 89 0
-7 105 37 0
-182 135 -58 0
--164 -162 -112 0
--118 173 93 0
--54 220 -2 0
--193 32 65 0
--101 46 203 0
--127 -219 -215 0
-235 -42 -77 0
--179 -242 -145 0
--140 77 203 0
--23 157 -112 0
--28 -193 134 0
--147 -166 100 0
-148 171 -31 0
--214 241 -166 0
--217 204 93 0
--219 -211 -142 0
-107 57 50 0
-227 220 119 0
--234 62 24 0
--131 -223 24 0
-232 133 -4 0
-74 200 -201 0
-211 6 220 0
--113 -9 102 0
--207 39 -80 0
-24 244 -125 0
-171 190 -167 0
-122 24 -201 0
--132 216 -235 0
--90 58 -181 0
-161 62 185 0
--3 -9 242 0
-115 2 -78 0
-42 -225 -145 0
-168 -46 55 0
--40 -126 -154 0
-26 164 -1 0
--71 199 -133 0
--78 55 -201 0
-219 249 -203 0
-116 137 -43 0
-11 -137 -118 0
-143 224 -150 0
--2 -199 218 0
-108 -140 -47 0
-228 28 -30 0
-224 58 -27 0
--42 -211 153 0
-104 -238 -222 0
--120 47 -33 0
-61 85 223 0
-230 -78 -77 0
-185 -210 106 0
-111 4 80 0
-226 195 -66 0
--204 172 8 0
-195 -241 191 0
-166 182 -69 0
--114 -130 223 0
-213 -189 243 0
--201 151 26 0
-70 21 28 0
--119 -208 -207 0
--156 94 106 0
--177 250 -6 0
-24 -227 -103 0
-87 4 -200 0
-139 133 -200 0
--71 226 23 0
--244 -32 60 0
-202 225 -63 0
--233 -111 1 0
-175 -114 -147 0
-54 -30 193 0
--137 -199 78 0
-31 -149 3 0
-90 186 138 0
-105 -43 -227 0
--218 220 -216 0
-206 -182 119 0
-62 158 -215 0
--92 -91 -103 0
-92 35 -13 0
--4 -148 -219 0
--119 125 8 0
-214 -160 -39 0
-120 -1 59 0
-190 216 -43 0
--11 -5 119 0
--118 -36 -187 0
--200 -152 98 0
-194 -50 -8 0
-32 88 -154 0
--45 106 159 0
--226 202 112 0
--101 28 -201 0
--206 -209 180 0
-152 244 165 0
-210 112 -115 0
-195 -1 -151 0
-104 -14 5 0
-185 -167 -229 0
-192 31 184 0
--116 -46 -113 0
-178 -108 140 0
-56 17 67 0
-80 6 195 0
--250 -61 -106 0
-184 31 -236 0
-185 188 -7 0
--127 -72 187 0
--221 212 -13 0
-240 -19 192 0
-36 -135 -139 0
--170 -116 87 0
-96 66 173 0
-40 -229 16 0
-184 -134 55 0
-233 13 141 0
-19 -204 -188 0
--208 226 -192 0
--185 48 178 0
-236 -34 -204 0
--46 141 -194 0
--8 -30 181 0
-72 -92 37 0
--212 157 -92 0
--210 -92 -225 0
-95 176 23 0
--16 120 -63 0
-7 -136 40 0
--88 -110 168 0
-121 208 -115 0
-228 215 171 0
-35 -19 -151 0
-45 222 -101 0
-95 103 108 0
--35 -152 -64 0
-144 -226 -149 0
--95 11 -170 0
-211 -152 106 0
--59 80 223 0
-22 126 -156 0
--19 -167 128 0
--68 76 -114 0
--121 32 122 0
-96 152 187 0
--72 -90 -152 0
-129 193 93 0
--109 -177 -149 0
-193 35 2 0
-172 -106 246 0
-134 -245 152 0
-212 100 -19 0
-127 -214 -56 0
--245 -128 3 0
-89 -114 119 0
-147 -105 37 0
--125 -102 -108 0
-22 33 177 0
-46 52 -240 0
--62 -136 45 0
-222 -117 120 0
-16 -40 111 0
-86 206 49 0
-123 -78 -158 0
-44 188 90 0
--103 89 176 0
-232 -112 130 0
--109 70 19 0
--15 204 128 0
--127 -110 192 0
--26 52 -147 0
--41 5 105 0
-234 206 -160 0
--52 128 195 0
--184 -176 121 0
-184 167 -120 0
--74 158 -148 0
--18 62 200 0
-169 115 -190 0
--124 229 164 0
--63 37 221 0
--76 190 245 0
--217 136 -134 0
--228 231 62 0
-156 -218 -85 0
-124 -25 225 0
--182 32 -31 0
--250 -221 35 0
--80 114 -78 0
-248 186 139 0
--19 -128 125 0
-85 154 113 0
-14 -80 -88 0
--145 -43 88 0
-145 181 55 0
-134 31 -187 0
--89 -109 -62 0
--68 237 -222 0
--130 -180 -227 0
--86 48 90 0
--199 -215 -132 0
-44 60 -14 0
--248 -79 224 0
--154 114 189 0
--39 167 -139 0
-230 -5 -184 0
-17 184 -215 0
--17 37 54 0
--249 159 -151 0
--29 -78 -148 0
-136 186 209 0
--224 64 33 0
--163 111 108 0
--4 99 23 0
-137 -64 138 0
--237 -116 29 0
-44 158 -139 0
-147 -8 -92 0
--118 -228 42 0
-201 19 141 0
--182 -39 -238 0
--36 27 -79 0
--157 249 -181 0
--191 121 132 0
--59 212 32 0
-72 -233 122 0
-230 -229 -132 0
--231 60 -233 0
--66 -249 106 0
--210 -40 -79 0
--75 61 111 0
--51 -98 -32 0
--166 137 245 0
--134 113 52 0
--107 19 72 0
--64 85 -121 0
-227 82 -87 0
--194 180 -128 0
-241 -211 38 0
--74 -56 115 0
-206 -54 -210 0
--66 -204 72 0
-144 156 16 0
--197 84 54 0
--80 199 59 0
-69 49 103 0
-19 190 -34 0
--176 235 -151 0
-33 -202 -78 0
--90 -15 -151 0
-198 28 -43 0
--131 -74 -108 0
-159 89 -184 0
--54 -62 141 0
--83 -238 91 0
-227 -84 -76 0
-187 -15 205 0
--243 -87 -207 0
-115 200 -48 0
--82 -163 184 0
-221 -122 153 0
--178 77 -52 0
--250 113 -65 0
--192 -153 -161 0
-185 -240 153 0
-187 -133 171 0
--127 -108 139 0
--158 -240 -121 0
-183 -137 -62 0
--84 -60 210 0
--35 -115 -5 0
--16 81 41 0
-163 -167 -20 0
-192 -71 -102 0
--223 -248 -37 0
-54 -18 79 0
-242 -238 114 0
-64 55 -39 0
--48 30 -248 0
--126 -6 -159 0
--127 242 -160 0
-238 42 120 0
-224 -138 -66 0
--189 -18 -183 0
-99 -43 -220 0
-149 -82 -59 0
--25 239 60 0
-99 -201 137 0
--50 188 -223 0
-84 147 157 0
-240 -183 -212 0
-239 243 -149 0
-119 217 162 0
-46 126 21 0
-204 196 21 0
--174 26 53 0
--45 63 -15 0
-155 -229 -99 0
--149 29 -51 0
-43 250 -107 0
--183 -34 -169 0
-7 -214 -55 0
-154 -61 -143 0
--176 -25 -155 0
--138 235 201 0
-137 -231 95 0
-48 -223 -227 0
--16 -147 193 0
--34 75 94 0
-140 -189 21 0
--152 70 49 0
--9 173 -238 0
-118 -39 129 0
--129 -230 -101 0
-7 -58 89 0
--96 50 -92 0
--158 54 -139 0
-126 -156 -201 0
--31 94 127 0
-32 72 103 0
--142 195 51 0
-200 -246 -150 0
--1 17 94 0
--98 -52 -152 0
-20 213 -38 0
--123 -225 -81 0
--19 -158 165 0
--107 -246 73 0
--9 45 145 0
--127 39 164 0
--34 95 130 0
--226 -210 213 0
--250 -201 -91 0
-209 -191 -78 0
--245 -248 192 0
-208 -191 -157 0
-136 123 169 0
--117 -17 -74 0
--140 174 162 0
-121 -37 119 0
-124 -152 217 0
--240 -125 237 0
-33 90 -20 0
--77 -187 -160 0
--109 24 -239 0
--3 -209 85 0
-84 -229 -199 0
-74 170 12 0
--79 102 -245 0
--191 -197 172 0
--111 -176 -216 0
--19 229 184 0
--139 -123 240 0
--208 45 -116 0
-100 -224 151 0
--28 -13 -249 0
--198 -226 -122 0
--201 -81 43 0
-205 -189 53 0
--23 240 -60 0
--246 38 -224 0
-138 229 156 0
--179 -60 -221 0
-204 -98 32 0
--46 -228 -178 0
--215 25 112 0
-96 -34 198 0
-32 -203 -225 0
-231 -156 -232 0
-130 -224 -197 0
-196 156 209 0
-99 210 -49 0
-91 95 143 0
--199 79 -250 0
-150 221 152 0
--31 223 249 0
-4 -127 -73 0
--244 13 231 0
--231 -27 -156 0
-159 -107 -217 0
--153 -234 -216 0
-15 227 122 0
--223 -23 -56 0
--31 139 160 0
--183 28 -223 0
-142 -241 -159 0
--102 -157 -109 0
-17 -216 160 0
-206 -200 207 0
--232 -70 -104 0
-131 -110 182 0
-171 70 -230 0
-167 -58 189 0
-145 -86 -57 0
-177 -183 -13 0
--221 18 90 0
--225 228 -127 0
-177 -174 226 0
-222 -144 -191 0
--222 -171 -74 0
-214 172 229 0
--111 49 12 0
--155 179 -192 0
--236 14 86 0
--68 -13 -1 0
-103 210 -123 0
--116 124 -244 0
-145 -14 -174 0
-28 129 230 0
--192 123 35 0
-143 -118 241 0
--211 -64 -128 0
-201 -85 -1 0
-91 198 24 0
--92 -2 -201 0
--158 87 83 0
-152 63 94 0
-17 218 119 0
--162 183 237 0
--13 -95 -49 0
-179 129 -79 0
--42 -178 242 0
-169 -224 227 0
-76 152 1 0
--109 98 99 0
--150 240 -198 0
--158 -43 152 0
--159 -97 82 0
--203 210 223 0
-208 132 -157 0
-127 -189 -208 0
--48 -74 -1 0
--57 132 -26 0
--210 -220 -120 0
--241 -131 23 0
-115 -64 -250 0
-31 -185 -239 0
--210 190 94 0
-144 -38 80 0
--155 211 134 0
--238 222 134 0
--153 74 205 0
--103 64 28 0
--57 -193 143 0
-139 110 -73 0
--93 25 -153 0
--247 164 20 0
-40 157 -189 0
-172 160 -180 0
--177 -185 245 0
-180 49 56 0
-28 -22 232 0
-172 13 193 0
-97 1 206 0
--161 -242 -185 0
--186 170 -190 0
-59 28 -236 0
-76 246 222 0
-64 -202 51 0
--20 138 107 0
-96 -228 16 0
--249 28 44 0
--193 -143 -113 0
-215 -224 -170 0
--131 -12 35 0
-84 61 54 0
--116 94 50 0
--26 -21 -9 0
-107 -150 -143 0
--174 45 147 0
-34 -116 174 0
--109 -80 -113 0
-25 -14 -212 0
-203 9 -46 0
--231 -209 4 0
--239 200 151 0
-181 146 -195 0
--234 79 195 0
--91 -65 -105 0
-96 141 98 0
-135 -6 215 0
-150 -98 -147 0
--26 124 -30 0
--66 160 206 0
--60 -142 6 0
--173 -126 -28 0
-138 -60 -43 0
-235 -179 57 0
-156 -215 34 0
--227 195 -221 0
-6 -25 -87 0
-228 49 -57 0
-203 68 139 0
--133 237 -1 0
--247 74 -80 0
-179 62 206 0
-12 73 -165 0
--28 45 -65 0
--203 186 -132 0
--88 99 53 0
-99 246 171 0
-172 23 -88 0
--84 119 224 0
--44 -237 211 0
--155 -28 -163 0
--67 44 -224 0
-3 19 7 0
--19 189 -216 0
--18 130 -237 0
--42 -210 -204 0
--183 -233 192 0
--141 222 -59 0
--244 80 -102 0
--210 90 68 0
-123 110 -82 0
--226 -246 -231 0
-206 -43 -172 0
-178 -184 -63 0
-217 103 224 0
--157 -172 -152 0
--236 -223 211 0
-166 96 155 0
--70 38 -28 0
--18 34 23 0
--33 -224 -242 0
-149 -197 213 0
--222 -79 198 0
--220 235 -95 0
--167 -135 194 0
-10 159 -235 0
--241 242 143 0
-55 -72 133 0
--59 -168 -33 0
-64 81 -35 0
-18 30 -70 0
-198 -22 153 0
-146 29 75 0
-76 -89 189 0
-10 55 -184 0
-205 79 233 0
-186 29 35 0
--91 14 37 0
-187 -118 -155 0
--228 236 201 0
-115 235 -90 0
--111 193 199 0
--153 122 80 0
--6 223 -239 0
-57 -76 -200 0
-18 -101 -214 0
--28 -59 -165 0
-42 107 67 0
--243 -52 -77 0
--196 20 -249 0
-125 -45 87 0
--60 -179 93 0
--169 196 -154 0
--89 60 -1 0
-88 -237 233 0
--73 7 -53 0
-193 -154 133 0
--82 46 232 0
--184 119 -109 0
--148 -121 136 0
--138 -30 24 0
-145 -130 -23 0
-63 -247 -195 0
--94 166 93 0
--103 -247 -246 0
-6 -14 -232 0
--148 98 -50 0
-69 -187 -212 0
-237 76 -108 0
--205 130 204 0
--152 -124 93 0
-54 -51 143 0
-68 39 -204 0
-222 39 11 0
--37 72 169 0
--69 173 160 0
-206 -110 112 0
-116 30 -121 0
-4 29 210 0
--53 -144 -149 0
--7 202 -93 0
-228 -69 -9 0
-171 32 1 0
--212 104 -87 0
--249 -170 -89 0
--68 146 175 0
-59 -39 105 0
-39 48 -53 0
--98 -50 7 0
--129 221 -44 0
-190 186 -79 0
-151 -155 179 0
-27 11 -104 0
--233 147 -242 0
--113 -210 183 0
--89 -118 237 0
--58 -132 -236 0
--42 -163 218 0
-87 -225 -164 0
--40 -76 -204 0
-24 -71 -249 0
-91 46 -111 0
--33 -73 -161 0
--17 -54 127 0
--174 -172 -167 0
-9 -168 -219 0
-237 19 1 0
-95 -128 105 0
-157 144 127 0
-124 247 180 0
--188 -134 -241 0
-112 -127 187 0
--145 68 158 0
--73 228 179 0
--207 -135 249 0
--210 113 -6 0
-119 -130 -23 0
--87 -138 -63 0
--30 -210 112 0
--210 116 -7 0
-81 -211 43 0
-233 30 -191 0
-250 -171 -71 0
-196 -194 168 0
--179 111 -191 0
--116 -150 153 0
--220 -219 -93 0
--94 224 99 0
-122 232 207 0
-115 -218 219 0
--247 -19 -187 0
-214 147 143 0
-234 150 -90 0
-95 -185 -107 0
--160 -88 113 0
-167 140 -33 0
--27 2 -106 0
-35 42 61 0
-249 219 59 0
-2 180 120 0
--129 225 -151 0
--121 104 -192 0
--138 -57 -41 0
--73 179 -133 0
-164 -36 -83 0
--45 -28 -116 0
-135 60 47 0
-76 173 125 0
--31 194 233 0
--67 239 -53 0
--40 67 -231 0
--98 -148 229 0
-213 -50 187 0
-141 197 2 0
--140 177 66 0
-145 115 -155 0
-44 117 65 0
--36 223 88 0
-30 200 31 0
--212 237 174 0
--49 -177 167 0
--218 63 -148 0
--25 46 23 0
-25 -54 226 0
-163 -88 21 0
-98 -41 -9 0
--98 -181 18 0
--182 -194 -137 0
--230 214 -46 0
-240 182 9 0
-93 -116 41 0
-57 -228 186 0
-165 154 -49 0
-42 88 -202 0
-8 33 -152 0
-17 -136 -35 0
--62 45 141 0
--102 33 -18 0
-138 -126 214 0
--59 -221 39 0
--130 4 -218 0
--78 123 250 0
-83 221 -151 0
--225 8 110 0
--194 156 43 0
-65 -245 34 0
--238 -237 217 0
-106 -37 -56 0
-240 111 184 0
--172 -243 185 0
-245 40 -45 0
-122 60 -189 0
--174 -152 181 0
-155 -147 -178 0
-117 -168 -219 0
--102 -127 234 0
-99 26 -114 0
-181 36 -62 0
-178 169 116 0
-81 -123 -30 0
--243 -26 -38 0
--31 20 217 0
-55 239 -116 0
--85 -27 49 0
-62 212 177 0
-3 -4 127 0
--233 -9 68 0
--28 208 -114 0
-23 159 240 0
-125 171 83 0
-152 16 97 0
--77 -39 -84 0
--19 -15 195 0
-95 -180 177 0
-204 -125 -207 0
--130 78 235 0
--51 182 79 0
-122 -95 -80 0
-85 -72 -167 0
-48 -109 -41 0
--223 -25 -44 0
-248 -51 -81 0
--141 57 -2 0
-208 -207 -50 0
-41 15 -63 0
-48 -242 -232 0
-240 196 -32 0
--227 -163 -23 0
-207 -90 102 0
-210 5 84 0
--230 -134 95 0
--193 214 239 0
--192 -11 173 0
--109 -196 145 0
-30 -161 -113 0
-216 164 83 0
-103 67 21 0
-102 -233 66 0
--79 56 -250 0
--82 -45 112 0
--144 -124 208 0
-33 -37 -149 0
--109 230 173 0
--229 82 -174 0
-179 137 -235 0
-84 -225 -16 0
-123 233 235 0
--211 144 92 0
--2 46 -177 0
-115 -202 -119 0
-241 75 174 0
--205 238 -105 0
--53 219 34 0
--239 103 -148 0
-147 -143 123 0
--214 -232 188 0
-10 -193 41 0
-6 185 18 0
-141 -68 -222 0
-209 -129 -143 0
--194 -108 116 0
--184 5 -46 0
-23 -125 -113 0
--159 54 -8 0
-130 -50 119 0
-156 -74 120 0
--124 139 -119 0
--97 -134 112 0
--150 -82 -79 0
-148 91 219 0
--30 19 -172 0
--13 164 -15 0
--119 -179 -11 0
-5 -38 -15 0
--4 94 -66 0
--71 140 -198 0
--119 -51 -151 0
-9 50 162 0
--203 35 88 0
-192 122 -127 0
--187 -164 -126 0
-121 -25 -215 0
--5 -167 -196 0
-216 138 -11 0
--86 46 250 0
-199 239 -8 0
--238 244 188 0
-98 -19 -11 0
-19 -151 -83 0
--158 40 232 0
-1 200 -23 0
-171 -11 -139 0
--203 60 173 0
--160 -122 -8 0
--179 -58 1 0
--194 -216 -202 0
--111 144 -237 0
-153 -206 9 0
--182 79 -233 0
--150 -249 -191 0
-153 102 121 0
-79 -178 -239 0
-14 -79 196 0
-133 84 193 0
--248 173 -13 0
--93 225 22 0
-58 -158 -16 0
--36 236 -20 0
-96 140 7 0
-53 -2 202 0
-235 -32 249 0
-94 53 -234 0
-50 134 -191 0
--243 -211 88 0
--28 52 94 0
-3 101 65 0
-78 200 -112 0
--16 -108 -93 0
--154 -169 242 0
--196 220 -177 0
--177 187 24 0
-5 242 -195 0
-81 157 -247 0
--191 -3 123 0
--16 115 10 0
--152 -217 33 0
--7 -149 67 0
-105 45 23 0
--55 -23 109 0
--217 -220 -144 0
-73 -63 149 0
--180 -245 -191 0
--113 -50 199 0
-242 -205 52 0
-129 98 -226 0
-205 146 -200 0
-145 -180 -182 0
--240 -39 176 0
-217 166 -31 0
--24 -144 9 0
-137 -120 -228 0
--24 -117 158 0
-%
-0
-"""
--- a/src/tests/cli/t_util_merge.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_util_merge.py	Sat Jan 30 01:07:14 2010 -0800
@@ -21,13 +21,14 @@
 #
 
 #
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import difflib
 import os
@@ -49,9 +50,9 @@
 
 path_to_pub_util = "../util/publish"
 
-class TestUtilMerge(testutils.ManyDepotTestCase):
+class TestUtilMerge(pkg5unittest.ManyDepotTestCase):
         # Cleanup after every test.
-        persistent_depot = False
+        persistent_setup = False
 
         scheme10 = """
             open pkg:/[email protected],5.11-0
@@ -79,14 +80,14 @@
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/usr
             add dir mode=0755 owner=root group=bin path=/usr/bin
-            add file /tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
+            add file tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
             add link path=/usr/bin/jsh target=./sh
             add hardlink path=/lib/libc.bronze target=/lib/libc.so.1
-            add file /tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
-            add file /tmp/bronze2 mode=0444 owner=root group=bin path=/etc/bronze2
-            add file /tmp/bronzeA1 mode=0444 owner=root group=bin path=/A/B/C/D/E/F/bronzeA1
+            add file tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
+            add file tmp/bronze2 mode=0444 owner=root group=bin path=/etc/bronze2
+            add file tmp/bronzeA1 mode=0444 owner=root group=bin path=/A/B/C/D/E/F/bronzeA1
             add depend fmri=pkg:/[email protected] type=require
-            add license /tmp/copyright2 license=copyright
+            add license tmp/copyright2 license=copyright
             close
         """
 
@@ -94,22 +95,22 @@
             open [email protected],5.11-0
             add dir mode=0755 owner=root group=bin path=/etc
             add dir mode=0755 owner=root group=bin path=/lib
-            add file /tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
-            add file /tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.bronze
+            add file tmp/sh mode=0555 owner=root group=bin path=/usr/bin/sh
+            add file tmp/libc.so.1 mode=0555 owner=root group=bin path=/lib/libc.bronze
             add link path=/usr/bin/jsh target=./sh
             add hardlink path=/lib/libc.bronze2.0.hardlink target=/lib/libc.so.1
-            add file /tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
-            add file /tmp/bronze2 mode=0444 owner=root group=bin path=/etc/amber2
-            add license /tmp/copyright3 license=copyright
-            add file /tmp/bronzeA2 mode=0444 owner=root group=bin path=/A1/B2/C3/D4/E5/F6/bronzeA2
+            add file tmp/bronze1 mode=0444 owner=root group=bin path=/etc/bronze1
+            add file tmp/bronze2 mode=0444 owner=root group=bin path=/etc/amber2
+            add license tmp/copyright3 license=copyright
+            add file tmp/bronzeA2 mode=0444 owner=root group=bin path=/A1/B2/C3/D4/E5/F6/bronzeA2
             add depend fmri=pkg:/[email protected] type=require
             close 
         """
 
-        misc_files = [ "/tmp/bronzeA1",  "/tmp/bronzeA2",
-                    "/tmp/bronze1", "/tmp/bronze2",
-                    "/tmp/copyright2", "/tmp/copyright3",
-                    "/tmp/libc.so.1", "/tmp/sh"]
+        misc_files = [ "tmp/bronzeA1",  "tmp/bronzeA2",
+                    "tmp/bronze1", "tmp/bronze2",
+                    "tmp/copyright2", "tmp/copyright3",
+                    "tmp/libc.so.1", "tmp/sh"]
 
         def setUp(self):
                 """ Start two depots.
@@ -117,14 +118,8 @@
                     depot1 is mapped to publisher test1 (preferred)
                     depot2 is mapped to publisher test2 """
 
-                testutils.ManyDepotTestCase.setUp(self, ["os.org", "os.org"])
-                for p in self.misc_files:
-                        f = open(p, "w")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(p)
-                        f.close()
-                        self.debug("wrote %s" % p)
+                pkg5unittest.ManyDepotTestCase.setUp(self, ["os.org", "os.org"])
+                self.make_misc_files(self.misc_files)
 
                 # Publish a set of packages to one repository.
                 self.dpath1 = self.dcs[1].get_repodir()
@@ -144,12 +139,7 @@
                 self.published += self.pkgsend_bulk(self.durl2, self.amber10 + \
                     self.amber20 + self.bronze10 + self.bronze20)
 
-                self.merge_dir = tempfile.mkdtemp(dir=self.get_test_prefix())
-
-        def tearDown(self):
-                testutils.ManyDepotTestCase.tearDown(self)
-                for p in self.misc_files:
-                        os.remove(p)
+                self.merge_dir = tempfile.mkdtemp(dir=self.test_root)
 
         def assertEqualDiff(self, expected, actual):
                 self.assertEqual(expected, actual,
@@ -252,4 +242,3 @@
 
 if __name__ == "__main__":
         unittest.main()
-
--- a/src/tests/cli/t_util_update_file_layout.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_util_update_file_layout.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,12 +20,13 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import errno
 import os
@@ -39,33 +40,17 @@
 
 path_to_pub_util = "../util/publish"
 
-class TestFileManager(testutils.CliTestCase):
+class TestFileManager(pkg5unittest.CliTestCase):
 
         def setUp(self):
-                self.pid = os.getpid()
-                self.pwd = os.getcwd()
-
-                self.__base_test_dir = os.path.join(tempfile.gettempdir(),
-                    "ips.test.%d" % self.pid)
-
-                self.__test_dir = os.path.join(self.__base_test_dir,
-                    "migrate_test")
-
-                try:
-                        os.makedirs(self.__test_dir, 0755)
-                except OSError, e:
-                        if e.errno != errno.EEXIST:
-                                raise e
-
-        def tearDown(self):
-                shutil.rmtree(self.__base_test_dir)
+                pkg5unittest.CliTestCase.setUp(self)
 
         @staticmethod
         def old_hash(s):
                 return os.path.join(s[0:2], s[2:8], s)
 
         def touch_old_file(self, s):
-                p = os.path.join(self.__test_dir, self.old_hash(s))
+                p = os.path.join(self.test_root, self.old_hash(s))
                 if not os.path.exists(os.path.dirname(p)):
                         os.makedirs(os.path.dirname(p))
                 fh = open(p, "wb")
@@ -92,7 +77,7 @@
 
                 old_paths = [self.touch_old_file(h) for h in hashes]
 
-                self.update_file_layout(self.__test_dir)
+                self.update_file_layout(self.test_root)
                 for p in old_paths:
                         if os.path.exists(p):
                                 raise RuntimeError("%s should not exist" % p)
@@ -101,13 +86,13 @@
                                     "exist")
                 l = layout.get_preferred_layout()
                 for h in hashes:
-                        if not os.path.exists(os.path.join(self.__test_dir,
+                        if not os.path.exists(os.path.join(self.test_root,
                             l.lookup(h))):
                                 raise RuntimeError("file for %s is missing" % h)
 
-                self.update_file_layout(self.__test_dir)
+                self.update_file_layout(self.test_root)
                 for h in hashes:
-                        if not os.path.exists(os.path.join(self.__test_dir,
+                        if not os.path.exists(os.path.join(self.test_root,
                             l.lookup(h))):
                                 raise RuntimeError("file for %s is missing" % h)
 
@@ -117,8 +102,11 @@
 
                 self.update_file_layout("", exit=2)
                 self.update_file_layout("%s %s" %
-                    (self.__test_dir, self.__test_dir), exit=2)
+                    (self.test_root, self.test_root), exit=2)
                 self.update_file_layout("/foo/doesntexist/", exit=2)
 
-                empty_dir = tempfile.mkdtemp(dir=self.__test_dir)
+                empty_dir = tempfile.mkdtemp(dir=self.test_root)
                 self.update_file_layout(empty_dir)
+                 
+if __name__ == "__main__":
+        unittest.main()
--- a/src/tests/cli/t_variants.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/t_variants.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,12 +20,13 @@
 # CDDL HEADER END
 #
 
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
 
 import os
 import re
@@ -34,70 +35,56 @@
 import shutil
 from stat import *
 
-class TestPkgVariants(testutils.SingleDepotTestCase):
+class TestPkgVariants(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         bronze10 = """
         open [email protected],5.11-0
         add set name=variant.arch value=sparc value=i386 value=zos
         add dir mode=0755 owner=root group=bin path=/etc
-        add file /tmp/bronze_sparc/etc/motd mode=0555 owner=root group=bin path=etc/motd variant.arch=sparc
-        add file /tmp/bronze_i386/etc/motd mode=0555 owner=root group=bin path=etc/motd variant.arch=i386
-        add file /tmp/bronze_zos/etc/motd mode=0555 owner=root group=bin path=etc/motd variant.arch=zos
-        add file /tmp/bronze_zone/etc/nonglobal_motd mode=0555 owner=root group=bin path=etc/zone_motd variant.opensolaris.zone=nonglobal
-        add file /tmp/bronze_zone/etc/global_motd mode=0555 owner=root group=bin path=etc/zone_motd variant.opensolaris.zone=global
-        add file /tmp/bronze_zone/etc/sparc_nonglobal mode=0555 owner=root group=bin path=etc/zone_arch variant.arch=sparc variant.opensolaris.zone=nonglobal
-        add file /tmp/bronze_zone/etc/i386_nonglobal mode=0555 owner=root group=bin path=etc/zone_arch variant.arch=i386 variant.opensolaris.zone=nonglobal
-        add file /tmp/bronze_zone/etc/zos_nonglobal mode=0555 owner=root group=bin path=etc/zone_arch variant.arch=zos variant.opensolaris.zone=nonglobal
-        add file /tmp/bronze_zone/etc/sparc_global mode=0555 owner=root group=bin path=etc/zone_arch variant.arch=sparc variant.opensolaris.zone=global
-        add file /tmp/bronze_zone/etc/i386_global mode=0555 owner=root group=bin path=etc/zone_arch variant.arch=i386 variant.opensolaris.zone=global
-        add file /tmp/bronze_zone/etc/zos_global mode=0555 owner=root group=bin path=etc/zone_arch variant.arch=zos variant.opensolaris.zone=global
-        add file /tmp/bronze_zone/false mode=0555 owner=root group=bin path=etc/isdebug variant.debug.kernel=false 
-        add file /tmp/bronze_zone/true mode=0555 owner=root group=bin path=etc/isdebug variant.debug.kernel=true
+        add file tmp/bronze_sparc/etc/motd mode=0555 owner=root group=bin path=etc/motd variant.arch=sparc
+        add file tmp/bronze_i386/etc/motd mode=0555 owner=root group=bin path=etc/motd variant.arch=i386
+        add file tmp/bronze_zos/etc/motd mode=0555 owner=root group=bin path=etc/motd variant.arch=zos
+        add file tmp/bronze_zone/etc/nonglobal_motd mode=0555 owner=root group=bin path=etc/zone_motd variant.opensolaris.zone=nonglobal
+        add file tmp/bronze_zone/etc/global_motd mode=0555 owner=root group=bin path=etc/zone_motd variant.opensolaris.zone=global
+        add file tmp/bronze_zone/etc/sparc_nonglobal mode=0555 owner=root group=bin path=etc/zone_arch variant.arch=sparc variant.opensolaris.zone=nonglobal
+        add file tmp/bronze_zone/etc/i386_nonglobal mode=0555 owner=root group=bin path=etc/zone_arch variant.arch=i386 variant.opensolaris.zone=nonglobal
+        add file tmp/bronze_zone/etc/zos_nonglobal mode=0555 owner=root group=bin path=etc/zone_arch variant.arch=zos variant.opensolaris.zone=nonglobal
+        add file tmp/bronze_zone/etc/sparc_global mode=0555 owner=root group=bin path=etc/zone_arch variant.arch=sparc variant.opensolaris.zone=global
+        add file tmp/bronze_zone/etc/i386_global mode=0555 owner=root group=bin path=etc/zone_arch variant.arch=i386 variant.opensolaris.zone=global
+        add file tmp/bronze_zone/etc/zos_global mode=0555 owner=root group=bin path=etc/zone_arch variant.arch=zos variant.opensolaris.zone=global
+        add file tmp/bronze_zone/false mode=0555 owner=root group=bin path=etc/isdebug variant.debug.kernel=false 
+        add file tmp/bronze_zone/true mode=0555 owner=root group=bin path=etc/isdebug variant.debug.kernel=true
         close"""
 
         silver10 = """
         open [email protected],5.11-0
         add set name=variant.arch value=i386
         add dir mode=0755 owner=root group=bin path=/etc
-        add file /tmp/bronze_i386/etc/motd mode=0555 owner=root group=bin path=etc/motd variant.arch=i386
+        add file tmp/bronze_i386/etc/motd mode=0555 owner=root group=bin path=etc/motd variant.arch=i386
         close"""
 
         misc_files = [ 
-                "/tmp/bronze_sparc/etc/motd",
-                "/tmp/bronze_i386/etc/motd",
-                "/tmp/bronze_zos/etc/motd",
-                "/tmp/bronze_zone/etc/nonglobal_motd",
-                "/tmp/bronze_zone/etc/global_motd",
-                "/tmp/bronze_zone/etc/i386_nonglobal",
-                "/tmp/bronze_zone/etc/sparc_nonglobal",
-                "/tmp/bronze_zone/etc/zos_nonglobal",
-                "/tmp/bronze_zone/etc/i386_global",
-                "/tmp/bronze_zone/etc/sparc_global",
-                "/tmp/bronze_zone/etc/zos_global",
-                "/tmp/bronze_zone/false",
-                "/tmp/bronze_zone/true",
+                "tmp/bronze_sparc/etc/motd",
+                "tmp/bronze_i386/etc/motd",
+                "tmp/bronze_zos/etc/motd",
+                "tmp/bronze_zone/etc/nonglobal_motd",
+                "tmp/bronze_zone/etc/global_motd",
+                "tmp/bronze_zone/etc/i386_nonglobal",
+                "tmp/bronze_zone/etc/sparc_nonglobal",
+                "tmp/bronze_zone/etc/zos_nonglobal",
+                "tmp/bronze_zone/etc/i386_global",
+                "tmp/bronze_zone/etc/sparc_global",
+                "tmp/bronze_zone/etc/zos_global",
+                "tmp/bronze_zone/false",
+                "tmp/bronze_zone/true",
                 ]
 
         def setUp(self):
-                print "setUP"
-                testutils.SingleDepotTestCase.setUp(self)
-                for p in self.misc_files:
-                        path = os.path.dirname(p)
-                        if not os.path.exists(path):
-                                os.makedirs(path)
-                        f = open(p, "w")
-                        # write the name of the file into the file, so that
-                        # all files have differing contents
-                        f.write(p)
-                        f.close()
-                        self.debug("wrote %s" % p)
-                
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-                for p in self.misc_files:
-                        os.remove(p)
+                self.debug("setUp")
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
 
         def test_variant_1(self):
                 self.__test_common("no-change", "no-change")
--- a/src/tests/cli/testutils.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/cli/testutils.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,923 +20,17 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
-import unittest
 import os
 import sys
-import subprocess
-import shutil
-import errno
-import platform
-import tempfile
-import time
-try:
-        import pwd
-except ImportError:
-        pass
 
-# Set the path so that modules above can be found
+# Set the path so that modules can be found
 path_to_parent = os.path.join(os.path.dirname(__file__), "..")
 sys.path.insert(0, path_to_parent)
 
-import pkg5unittest
-from pkg.misc import EmptyI
-
-g_proto_area=""
-
-def setup_environment(path_to_proto):
-        """ Set up environment for doing testing.
-
-            We set PYTHONPATH and PATH so that they reference the proto
-            area, and clear packaging related environment variables
-            (every variable prefixed with PKG_).
-
-            path_to_proto should be a relative path indicating a path
-            to proto area of the workspace.  So, if your test case is
-            three levels deep: ex. src/tests/cli/foo.py, this should be
-            "../../../proto"
-
-            This function looks at argv[0] to compute the ultimate
-            path to the proto area; this is nice because you can then
-            invoke test cases like normal commands; i.e.:
-            "python cli/t_my_test_case.py" will just work.
-
-        """
-
-        global g_proto_area
-
-        osname = platform.uname()[0].lower()
-        proc = 'unknown'
-        if osname == 'sunos':
-                proc = platform.processor()
-        elif osname == 'linux':
-                proc = "linux_" + platform.machine()
-        elif osname == 'windows':
-                proc = osname
-        elif osname == 'darwin':
-                proc = osname
-        elif osname == 'aix':
-                proc = osname
-        else:
-                print "Unable to determine appropriate proto area location."
-                print "This is a porting problem."
-                sys.exit(1)
-
-        # Figure out from where we're invoking the command
-        cmddir, cmdname = os.path.split(sys.argv[0])
-        cmddir = os.path.realpath(cmddir)
-
-        if "ROOT" in os.environ:
-                g_proto_area = os.environ["ROOT"]
-        else:
-                g_proto_area = "%s/%s/root_%s" % (cmddir, path_to_proto, proc)
-
-        # Clean up relative ../../, etc. out of path to proto
-        g_proto_area = os.path.realpath(g_proto_area)
-
-        pkgs = "%s/usr/lib/python2.6/vendor-packages" % g_proto_area
-        bins = "%s/usr/bin" % g_proto_area
-
-        sys.path.insert(1, pkgs)
-
-        #
-        # Because subprocesses must also source from the proto area,
-        # we need to set PYTHONPATH in the environment as well as
-        # in sys.path.
-        #
-        if "PYTHONPATH" in os.environ:
-                pypath = os.pathsep + os.environ["PYTHONPATH"]
-        else:
-                pypath = ""
-        os.environ["PYTHONPATH"] = "." + os.pathsep + pkgs + pypath
-
-        os.environ["PATH"] = bins + os.pathsep + os.environ["PATH"]
-
-        # Use "keys"; otherwise we'll change dictionary size during iteration.
-        for k in os.environ.keys():
-                if k.startswith("PKG_"):
-                        del os.environ[k]
-
-        from pkg.client import global_settings
-        global_settings.client_name = "pkg"
-
-
-topdivider = \
-",---------------------------------------------------------------------\n"
-botdivider = \
-"`---------------------------------------------------------------------\n"
-
-def format_comment(comment):
-        if comment is not None:
-                comment = comment.expandtabs()
-                comm = ""
-                for line in comment.splitlines():
-                        line = line.strip()
-                        if line == "":
-                                continue
-                        comm += "  " + line + "\n"
-                return comm + "\n"
-        else:
-                return "<no comment>\n\n"
-
-def format_output(command, output):
-        str = "  Output Follows:\n"
-        str += topdivider
-        if command is not None:
-                str += "| $ " + command + "\n"
-
-        if output is None or output == "":
-                str += "| <no output>\n"
-        else:
-                for line in output.split("\n"):
-                        str += "| " + line.rstrip() + "\n"
-        str += botdivider
-        return str
-
-def format_debug(output):
-        str = "  Debug Buffer Follows:\n"
-        str += topdivider
-
-        if output is None or output == "":
-                str += "| <no debug buffer>\n"
-        else:
-                for line in output.split("\n"):
-                        str += "| " + line.rstrip() + "\n"
-        str += botdivider
-        return str
-
-def get_su_wrap_user():
-        for u in ["noaccess", "nobody"]:
-                try:
-                        pwd.getpwnam(u)
-                        return u
-                except (KeyError, NameError):
-                        pass
-        raise RuntimeError("Unable to determine user for su.")
-
-class DepotTracebackException(pkg5unittest.Pkg5TestCase.failureException):
-        def __init__(self, logfile, output):
-                Exception.__init__(self)
-                self.__logfile = logfile
-                self.__output = output
-
-        def __str__(self):
-                str = "During this test, a depot Traceback was detected.\n"
-                str += "Log file: %s.\n" % self.__logfile
-                str += "Log file output is:\n"
-                str += format_output(None, self.__output)
-                return str
-
-class TracebackException(pkg5unittest.Pkg5TestCase.failureException):
-        def __init__(self, command, output = None, comment = None,
-            debug = None):
-                Exception.__init__(self)
-                self.__command = command
-                self.__output = output
-                self.__comment = comment
-                self.__debug = debug
-
-        def __str__(self):
-                if self.__comment is None and self.__output is None:
-                        return (Exception.__str__(self))
-
-                str = ""
-                str += format_comment(self.__comment)
-                str += format_output(self.__command, self.__output)
-                if self.__debug is not None and self.__debug != "":
-                        str += format_debug(self.__debug)
-                return str
-
-
-class AssFailException(pkg5unittest.Pkg5TestCase.failureException):
-        def __init__(self, comment = None, debug=None):
-                Exception.__init__(self)
-                self.__comment = comment
-                self.__debug = debug
-
-        def __str__(self):
-
-                str = ""
-                if self.__comment is None:
-                        str += Exception.__str__(self)
-                else:
-                        str += format_comment(self.__comment)
-                if self.__debug is not None and self.__debug != "":
-                        str += format_debug(self.__debug)
-                return str
-
-
-class UnexpectedExitCodeException(pkg5unittest.Pkg5TestCase.failureException):
-        def __init__(self, command, expected, got, output=None, comment=None,
-            debug=None):
-                Exception.__init__(self)
-                self.__command = command
-                self.__output = output
-                self.__expected = expected
-                self.__got = got
-                self.__comment = comment
-                self.__debug = debug
-
-        def __str__(self):
-                if self.__comment is None and self.__output is None:
-                        return (Exception.__str__(self))
-
-                str = ""
-                str += format_comment(self.__comment)
-                
-                str += "  Expected exit status: %s.  Got: %d." % \
-                    (self.__expected, self.__got)
-
-                str += format_output(self.__command, self.__output)
-                if self.__debug is not None and self.__debug != "":
-                        str += format_debug(self.__debug)
-                return str
-
-        @property
-        def exitcode(self):
-                return self.__got
-
-
-class PkgSendOpenException(pkg5unittest.Pkg5TestCase.failureException):
-        def __init__(self, com = ""):
-                Exception.__init__(self, com)
-
-class CliTestCase(pkg5unittest.Pkg5TestCase):
-        __debug = False
-        __debug_buf = ""
-
-        def in_debug_mode(self):
-                return self.__debug
-
-        def setUp(self):
-                self.image_dir = None
-                self.pid = os.getpid()
-                self.pwd = os.getcwd()
-
-                self.__test_prefix = os.path.join(tempfile.gettempdir(),
-                    "ips.test.%d" % self.pid)
-                self.img_path = os.path.join(self.__test_prefix, "image")
-                os.environ["PKG_IMAGE"] = self.img_path
-
-                if "TEST_DEBUG" in os.environ:
-                        self.__debug = True
-
-                try:
-                        os.makedirs(self.__test_prefix, 0755)
-                except OSError, e:
-                        if e.errno != errno.EEXIST:
-                                raise e
-
-        def tearDown(self):
-                self.image_destroy()
-
-        # In the case of an assertion (not a pkg() failure)
-        # raise an assertion so we can get the debug logs displayed
-        def assert_(self, expr, msg=None):
-                if not expr:
-                        raise AssFailException(comment=msg,
-                            debug=self.get_debugbuf())
- 
-
-        def get_img_path(self):
-                return self.img_path
-
-        def get_test_prefix(self):
-                return self.__test_prefix
-
-        def debug(self, s):
-                s = str(s)
-                if self.__debug:
-                        print >> sys.stderr, s
-                self.__debug_buf += s
-                if not s.endswith("\n"):
-                        self.__debug_buf += "\n"
-
-        def debugcmd(self, cmdline):
-                self.debug("$ %s" % cmdline)
-
-        def debugresult(self, retcode, output):
-                if output.strip() != "":
-                        self.debug(output.strip())
-                if retcode != 0:
-                        self.debug("[returned %d]" % retcode)
-
-        def get_debugbuf(self):
-                return self.__debug_buf
-
-        def image_create(self, repourl, prefix="test", additional_args=""):
-                assert self.img_path
-                assert self.img_path != "/"
-
-                self.image_destroy()
-                os.mkdir(self.img_path)
-                cmdline = "pkg image-create -F -p %s=%s %s %s" % \
-                    (prefix, repourl, additional_args, self.img_path)
-                self.debugcmd(cmdline)
-
-                p = subprocess.Popen(cmdline, shell = True,
-                    stdout = subprocess.PIPE,
-                    stderr = subprocess.STDOUT)
-                retcode = p.wait()
-                output = p.stdout.read()
-                self.debugresult(retcode, output)
-
-                if retcode == 99:
-                        raise TracebackException(cmdline, output,
-                            debug=self.get_debugbuf())
-                if retcode != 0:
-                        raise UnexpectedExitCodeException(cmdline, 0,
-                            retcode, output, debug=self.get_debugbuf())
-
-                return retcode
-
-        def image_set(self, imgdir):
-                self.debug("image_set: %s" % imgdir)
-                self.img_path = imgdir
-                os.environ["PKG_IMAGE"] = self.img_path
-
-        def image_destroy(self):
-                self.debug("image_destroy")
-                os.chdir(self.pwd)
-
-                
-                if not self.in_debug_mode() and os.path.exists(self.img_path):
-                        shutil.rmtree(self.img_path)
-
-        def get_su_wrapper(self, su_wrap=None):
-                if su_wrap:
-                        if su_wrap == True:
-                                su_wrap = get_su_wrap_user()
-                        cov_env = " ".join(
-                            ("%s=%s" % e for e in self.coverage_env.items()))
-                        su_wrap = "su %s -c 'LD_LIBRARY_PATH=%s %s " % \
-                            (su_wrap, os.getenv("LD_LIBRARY_PATH", ""), cov_env)
-                        su_end = "'"
-                else:
-                        su_wrap = ""
-                        su_end = ""
-                return su_wrap, su_end
-
-        def pkg(self, command, exit=0, comment="", prefix="", su_wrap=None):
-                wrapper = self.coverage_cmd
-
-                su_wrap, su_end = self.get_su_wrapper(su_wrap=su_wrap)
-                if prefix:
-                        cmdline = "%s;%s%s %s/usr/bin/pkg %s%s" % (prefix,
-                            su_wrap, wrapper, g_proto_area, command, su_end)
-                else:
-                        cmdline = "%s%s %s/usr/bin/pkg %s%s" % (su_wrap, wrapper,
-                            g_proto_area, command, su_end)
-                self.debugcmd(cmdline)
-
-                newenv = os.environ.copy()
-                newenv.update(self.coverage_env)
-                p = subprocess.Popen(cmdline, shell=True, env=newenv,
-                    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-
-                self.output = p.stdout.read()
-                retcode = p.wait()
-                self.debugresult(retcode, self.output)
-
-                if retcode == 99:
-                        raise TracebackException(cmdline, self.output, comment,
-                            debug=self.get_debugbuf())
-
-                if not isinstance(exit, list):
-                        exit = [exit]
-
-                if retcode not in exit:
-                        raise UnexpectedExitCodeException(cmdline,
-                            exit, retcode, self.output, comment,
-                            debug=self.get_debugbuf())
-
-                return retcode
-
-        def pkgdepend(self, command, proto=None, use_proto=True, exit=0,
-            comment=""):
-                wrapper = self.coverage_cmd
-
-                if proto is None:
-                        proto = g_proto_area
-
-                if not use_proto:
-                        proto = ""
-                        
-                cmdline = "%s %s/usr/bin/pkgdepend %s %s" % (wrapper, g_proto_area,
-                    command, proto)
-                self.debugcmd(cmdline)
-
-                newenv = os.environ.copy()
-                newenv.update(self.coverage_env)
-                p = subprocess.Popen(cmdline, shell=True, env=newenv,
-                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
-
-                self.output, self.errout = p.communicate()
-                retcode = p.wait()
-                self.debugresult(retcode, self.output)
-
-                if retcode == 99:
-                        raise TracebackException(cmdline, self.output, comment,
-                            debug=self.errout)
-                elif retcode != exit:
-                        raise UnexpectedExitCodeException(cmdline,
-                            exit, retcode, self.output, comment,
-                            debug=self.errout)
-
-                return retcode
-
-        def pkgrecv(self, server_url=None, command=None, exit=0, out=False,
-            comment=""):
-                wrapper = self.coverage_cmd
-
-                args = []
-                if server_url:
-                        args.append("-s %s" % server_url)
-
-                if command:
-                        args.append(command)
-
-                cmdline = "%s %s/usr/bin/pkgrecv %s" % (wrapper,
-                    g_proto_area, " ".join(args))
-                self.debugcmd(cmdline)
-
-                newenv = os.environ.copy()
-                newenv.update(self.coverage_env)
-                p = subprocess.Popen(cmdline, shell=True, env=newenv,
-                    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-
-                self.output = p.stdout.read()
-                retcode = p.wait()
-                self.debugresult(retcode, self.output)
-
-                if retcode == 99:
-                        raise TracebackException(cmdline, self.output, comment,
-			    debug = self.get_debugbuf())
-                elif retcode != exit:
-                        raise UnexpectedExitCodeException(cmdline,
-                            exit, retcode, self.output, comment,
-			    debug = self.get_debugbuf())
-
-                if out:
-                        return retcode, self.output
-
-                return retcode
-
-        def pkgsend(self, depot_url="", command="", exit=0, comment="", retry400=True):
-                wrapper = self.coverage_cmd
-
-                args = []
-                if depot_url:
-                        args.append("-s " + depot_url)
+import pkg5testenv
 
-                if command:
-                        args.append(command)
-
-                cmdline = "%s %s/usr/bin/pkgsend %s" % (wrapper, g_proto_area,
-                    " ".join(args))
-                self.debugcmd(cmdline)
-
-                # XXX may need to be smarter.
-                output = ""
-                published = None
-                newenv = os.environ.copy()
-                newenv.update(self.coverage_env)
-                if command.startswith("open "):
-                        p = subprocess.Popen(cmdline, shell=True, env=newenv,
-                            stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-
-                        out, err = p.communicate()
-                        retcode = p.wait()
-                        self.debugresult(retcode, out)
-                        if retcode == 0:
-                                out = out.rstrip()
-                                assert out.startswith("export PKG_TRANS_ID=")
-                                arr = out.split("=")
-                                assert arr
-                                out = arr[1]
-                                os.environ["PKG_TRANS_ID"] = out
-
-                        # retcode != 0 will be handled below
-
-                else:
-                        p = subprocess.Popen(cmdline, shell=True, env=newenv,
-                            stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-
-                        output = p.stdout.read()
-                        retcode = p.wait()
-                        self.debugresult(retcode, output)
-                        
-                        if retcode != 0:
-                                if retry400 and (command.startswith("publish") or \
-                                    command.startswith("open")) and \
-                                    "status '400'" in output:    
-                                    # this may be error 400 - too quick to republish
-                                    # try once more after sleeping
-                                         time.sleep(1)
-                                         return self.pkgsend(depot_url, command, 
-                                             exit, comment, retry400=False)
-
-                        elif command.startswith("close") or \
-                            command.startswith("publish"):
-                                os.environ["PKG_TRANS_ID"] = ""
-                                for l in output.splitlines():
-                                        if l.startswith("pkg:/"):
-                                                published = l
-                                                break                                        
-
-                if retcode == 99:
-                        raise TracebackException(cmdline, output, comment,
-                            debug=self.get_debugbuf())
-
-                if retcode != exit:
-                        raise UnexpectedExitCodeException(cmdline, exit,
-                            retcode, output, comment, debug=self.get_debugbuf())
-
-                return retcode, published
-
-        def pkgsend_bulk(self, depot_url, commands, exit=0, comment=""):
-                """ Send a series of packaging commands; useful for quickly
-                    doing a bulk-load of stuff into the repo.  All commands are
-                    expected to work; if not, the transaction is abandoned.  If
-                    'exit' is set, then if none of the actions triggers that
-                    exit code, an UnexpectedExitCodeException is raised.
-
-                    A list containing the fmris of any packages that were
-                    published as a result of the commands executed will be
-                    returned; it will be empty if none were. """
-
-                plist = []
-                retcode = None
-                try:
-                        accumulate = []
-                        current_fmri = None
-
-                        for line in commands.split("\n"):
-                                line = line.strip()
-                                if line == "":
-                                        continue
-                                if line.startswith("add"):
-                                        accumulate.append(line[4:])
-                                else:
-                                        if current_fmri: # send any content seen so far (can be 0)
-                                                self.assert_(current_fmri != None, 
-                                                    "Missing open in pkgsend string")
-                                                f = tempfile.NamedTemporaryFile(dir="/tmp")
-                                                for l in accumulate:
-                                                        f.write("%s\n" % l)
-                                                f.flush()
-                                                cmd = "publish -d / %s %s" % (current_fmri, f.name)
-                                                current_fmri = None
-                                                accumulate = []
-                                                retcode, published = self.pkgsend(depot_url, cmd)
-                                                if retcode == 0 and published:
-                                                        plist.append(published)
-                                                f.close()
-                                        if line.startswith("open"):
-                                                current_fmri = line[5:].strip()
-                                        
-                except UnexpectedExitCodeException, e:
-                        if e.exitcode != exit:
-                                raise
-                        retcode = e.exitcode
-
-                if retcode != exit:
-                        raise UnexpectedExitCodeException(line, exit, retcode,
-                            debug=self.get_debugbuf())
-
-                return plist
-                                                
-
-        def cmdline_run(self, cmdline, exit=0):
-                p = subprocess.Popen(cmdline,
-                    shell=True,
-                    stdout=subprocess.PIPE,
-                    stderr=subprocess.STDOUT)
-
-                output = p.stdout.read()
-                retcode = p.wait()
-                self.debugresult(retcode, output)
-                if retcode != exit:
-                        raise UnexpectedExitCodeException(cmdline, exit,
-                            retcode, output, debug=self.get_debugbuf())
-
-        def copy_repository(self, src, src_pub, dest, dest_pub):
-                """Copies the packages from the src repository to a new
-                destination repository that will be created at dest.  In
-                addition, any packages from the src_pub will be assigned
-                to the dest_pub during the copy.  The new repository will
-                not have a catalog or search indices, so a depot server
-                pointed at the new repository must be started with the
-                --rebuild option."""
-
-                shutil.rmtree(dest, True)
-                os.makedirs(dest, mode=0755)
-
-                for entry in os.listdir(src):
-                        spath = os.path.join(src, entry)
-
-                        # Skip the catalog, index, and pkg directories
-                        # as they will be copied manually.  Also skip
-                        # any unknown files in the repository directory.
-                        if entry in ("catalog", "index", "pkg") or \
-                            not os.path.isdir(spath):
-                                continue
-                        shutil.copytree(spath, os.path.join(dest, entry))
-
-                # Now copy each manifest and replace any references to the old
-                # publisher with that of the new publisher as they are copied.
-                pkg_root = os.path.join(src, "pkg")
-                for stem in os.listdir(pkg_root):
-                        pkg_path = os.path.join(pkg_root, stem)
-                        for mname in os.listdir(pkg_path):
-                                # Ensure destination manifest directory exists.
-                                dmdpath = os.path.join(dest, "pkg", stem)
-                                if not os.path.isdir(dmdpath):
-                                        os.makedirs(dmdpath, mode=0755)
-
-                                msrc = open(os.path.join(pkg_path, mname), "rb")
-                                mdest = open(os.path.join(dmdpath, mname), "wb")
-                                for l in msrc:
-                                        if l.find("pkg://") > -1:
-                                                mdest.write(l.replace(src_pub,
-                                                    dest_pub))
-                                        else:
-                                                mdest.write(l)
-                                msrc.close()
-                                mdest.close()
-
-        def validate_html_file(self, fname, exit=0, comment="",
-            options="-quiet -utf8"):
-                cmdline = "tidy %s %s" % (options, fname)
-                self.debugcmd(cmdline)
-
-                output = ""
-                p = subprocess.Popen(cmdline, shell=True,
-                    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
-
-                output = p.stdout.read()
-                retcode = p.wait()
-                self.debugresult(retcode, output)
-
-                if retcode == 99:
-                        raise TracebackException(cmdline, output, comment,
-                            debug=self.get_debugbuf())
-
-                if retcode != exit:
-                        raise UnexpectedExitCodeException(cmdline, exit,
-                            retcode, output, comment, debug=self.get_debugbuf())
-
-                return retcode
-
-        def start_depot(self, port, depotdir, logpath, refresh_index=False,
-            debug_features=EmptyI, properties=EmptyI):
-                """ Convenience routine to help subclasses start
-                    depots.  Returns a depotcontroller. """
-
-                # Note that this must be deferred until after PYTHONPATH
-                # is set up.
-                import pkg.depotcontroller as depotcontroller
-
-                self.debug("start_depot: depot listening on port %d" % port)
-                self.debug("start_depot: depot data in %s" % depotdir)
-                self.debug("start_depot: depot logging to %s" % logpath)
-
-                dc = depotcontroller.DepotController(
-                    wrapper_start=self.coverage_cmd.split(),
-                    env=self.coverage_env)
-                dc.set_depotd_path(g_proto_area + "/usr/lib/pkg.depotd")
-                dc.set_depotd_content_root(g_proto_area + "/usr/share/lib/pkg")
-                for f in debug_features:
-                        dc.set_debug_feature(f)
-                dc.set_repodir(depotdir)
-                dc.set_logpath(logpath)
-                dc.set_port(port)
-                for section in properties:
-                        for prop, val in properties[section].iteritems():
-                                dc.set_property(section, prop, val)
-                if refresh_index:
-                        dc.set_refresh_index()
-                dc.start()
-                return dc
-
-
-class ManyDepotTestCase(CliTestCase):
-
-        def setUp(self, publishers, debug_features=EmptyI):
-                CliTestCase.setUp(self)
-
-                self.debug("setup: %s" % self.id())
-                self.debug("starting %d depot(s)" % len(publishers))
-                self.debug("publishers: %s" % publishers)
-                self.debug("debug_features: %s" % list(debug_features))
-                self.dcs = {}
-
-                for n, pub in enumerate(publishers):
-                        i = n + 1
-                        testdir = os.path.join(self.get_test_prefix(),
-                            self.id())
-
-                        depotdir = os.path.join(testdir,
-                            "depot_contents%d" % i)
-
-                        for dir in (testdir, depotdir):
-                                try:
-                                        os.makedirs(dir, 0755)
-                                except OSError, e:
-                                        if e.errno != errno.EEXIST:
-                                                raise e
-
-                        # We pick an arbitrary base port.  This could be more
-                        # automated in the future.
-                        depot_logfile = os.path.join(testdir,
-                            "depot_logfile%d" % i)
-
-                        props = { "publisher": { "prefix": pub } }
-                        self.dcs[i] = self.start_depot(12000 + i,
-                            depotdir, depot_logfile,
-                            debug_features=debug_features,
-                            properties=props)
-
-        def check_traceback(self, logpath):
-                """ Scan logpath looking for tracebacks.
-                    Raise a DepotTracebackException if one is seen.
-                """
-                self.debug("check for depot tracebacks in %s" % logpath)
-                logfile = open(logpath, "r")
-                output = logfile.read()
-                for line in output.splitlines():
-                        if line.find("Traceback") > -1:
-                                raise DepotTracebackException(logpath, output)
-
-        def restart_depots(self):
-                self.debug("restarting %d depot(s)" % len(self.dcs))
-                for i in sorted(self.dcs.keys()):
-                        dc = self.dcs[i]
-                        self.debug("stopping depot at url: %s" % dc.get_depot_url())
-                        dc.stop()
-                        self.debug("starting depot at url: %s" % dc.get_depot_url())
-                        dc.start()
-
-        def tearDown(self):
-                self.debug("teardown: %s" % self.id())
-
-                for i in sorted(self.dcs.keys()):
-                        dc = self.dcs[i]
-                        dir = dc.get_repodir()
-                        try:
-                                self.check_traceback(dc.get_logpath())
-                        finally:
-                                status = dc.kill()
-                                if status:
-                                        self.debug("depot: %s" % status)
-                                shutil.rmtree(dir)
-
-                self.dcs = None
-                CliTestCase.tearDown(self)
-
-        def run(self, result=None):
-                if result is None:
-                        result = self.defaultTestResult()
-                CliTestCase.run(self, result)
-
-
-class SingleDepotTestCase(ManyDepotTestCase):
-
-        def setUp(self, debug_features=EmptyI, publisher="test"):
-                ManyDepotTestCase.setUp(self, [publisher],
-                    debug_features=debug_features)
-                self.dc = self.dcs[1]
-
-        def tearDown(self):
-                ManyDepotTestCase.tearDown(self)
-                self.dc = None
-
-
-class SingleDepotTestCaseCorruptImage(SingleDepotTestCase):
-        """ A class which allows manipulation of the image directory that
-        SingleDepotTestCase creates. Specifically, it supports removing one
-        or more of the files or subdirectories inside an image (publisher,
-        cfg_cache, etc...) in a controlled way.
-
-        To add a new directory or file to be corrupted, it will be necessary
-        to update corrupt_image_create to recognize a new option in config
-        and perform the appropriate action (removing the directory or file
-        for example).
-        """
-
-        def setUp(self, debug_features=EmptyI, publisher="test"):
-                self.backup_img_path = None
-                SingleDepotTestCase.setUp(self, debug_features=debug_features,
-                    publisher=publisher)
-
-        def tearDown(self):
-                self.__uncorrupt_img_path()
-                SingleDepotTestCase.tearDown(self)
-
-        def __uncorrupt_img_path(self):
-                """ Function which restores the img_path back to the original
-                level. """
-                if self.backup_img_path:
-                        self.img_path = self.backup_img_path
-
-        def corrupt_image_create(self, repourl, config, subdirs, prefix = "test",
-            destroy = True):
-                """ Creates two levels of directories under the original image
-                directory. In the first level (called bad), it builds a "corrupt
-                image" which means it builds subdirectories the subdirectories
-                speicified by subdirs (essentially determining whether a user
-                image or a full image will be built). It populates these
-                subdirectories with a partial image directory stucture as
-                speicified by config. As another subdirectory of bad, it
-                creates a subdirectory called final which represents the
-                directory the command was actually run from (which is why
-                img_path is set to that location). Exisintg image destruction
-                was made optional to allow testing of two images installed next
-                to each other (a user and full image created in the same
-                directory for example). """
-                if not self.backup_img_path:
-                        self.backup_img_path = self.img_path
-                self.img_path = os.path.join(self.img_path, "bad")
-                assert self.img_path
-                assert self.img_path and self.img_path != "/"
-
-                if destroy:
-                        self.image_destroy()
-
-                for s in subdirs:
-                        if s == "var/pkg":
-                                cmdline = "pkg image-create -F -p %s=%s %s" % \
-                                    (prefix, repourl, self.img_path)
-                        elif s == ".org.opensolaris,pkg":
-                                cmdline = "pkg image-create -U -p %s=%s %s" % \
-                                    (prefix, repourl, self.img_path)
-                        else:
-                                raise RuntimeError("Got unknown subdir option:"
-                                    "%s\n" % s)
-
-                        self.debugcmd(cmdline)
-
-                        # Run the command to actually create a good image
-                        p = subprocess.Popen(cmdline, shell = True,
-                                             stdout = subprocess.PIPE,
-                                             stderr = subprocess.STDOUT)
-                        retcode = p.wait()
-                        output = p.stdout.read()
-                        self.debugresult(retcode, output)
-
-                        if retcode == 99:
-                                raise TracebackException(cmdline, output,
-                                    debug=self.get_debugbuf())
-                        if retcode != 0:
-                                raise UnexpectedExitCodeException(cmdline, 0,
-                                    retcode, output, debug=self.get_debugbuf())
-
-                        tmpDir = os.path.join(self.img_path, s)
-
-                        # This is where the actual corruption of the
-                        # image takes place. A normal image was created
-                        # above and this goes in and removes critical
-                        # directories and files.
-                        if "publisher_absent" in config or \
-                           "publisher_empty" in config:
-                                shutil.rmtree(os.path.join(tmpDir, "publisher"))
-                        if "known_absent" in config or \
-                           "known_empty" in config:
-                                shutil.rmtree(os.path.join(tmpDir, "state",
-                                    "known"))
-                        if "known_empty" in config:
-                                os.mkdir(os.path.join(tmpDir, "state", "known"))
-                        if "publisher_empty" in config:
-                                os.mkdir(os.path.join(tmpDir, "publisher"))
-                        if "cfg_cache_absent" in config:
-                                os.remove(os.path.join(tmpDir, "cfg_cache"))
-                        if "file_absent" in config:
-                                shutil.rmtree(os.path.join(tmpDir, "file"))
-                        if "pkg_absent" in config:
-                                shutil.rmtree(os.path.join(tmpDir, "pkg"))
-                        if "index_absent" in config:
-                                shutil.rmtree(os.path.join(tmpDir, "index"))
-
-                # Make find root start at final. (See the doc string for
-                # more explanation.)
-                cmd_path = os.path.join(self.img_path, "final")
-
-                os.mkdir(cmd_path)
-                return cmd_path
-
-def eval_assert_raises(ex_type, eval_ex_func, func, *args):
-        try:
-                func(*args)
-        except ex_type, e:
-                print str(e)
-                if not eval_ex_func(e):
-                        raise
-        else:
-                raise RuntimeError("Function did not raise exception.")
-
-
-if __name__ == "__main__":
-        unittest.main()
-
+def setup_environment(proto):
+        pkg5testenv.setup_environment(proto)
--- a/src/tests/gui/t_pm_addrepo.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/gui/t_pm_addrepo.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,53 +20,49 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
-from cli import testutils
-
+import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
+import unittest
 
 try:
         import ldtp
 except ImportError:
         raise ImportError, "SUNWldtp package not installed."
 
-class TestPkgGuiAddRepoBasics(testutils.SingleDepotTestCase):
-
-        persistent_depot = False
+class TestPkgGuiAddRepoBasics(pkg5unittest.SingleDepotTestCase):
 
         foo10 = """
             open [email protected],5.11-0
             add set name="description" value="Some package1 description"
-            close """        
-
-        def setUp(self, debug_features=None):
-                testutils.SingleDepotTestCase.setUp(self)
-
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
+            close """
 
         def testAddRepository(self):
                 repo_name = 'testadd'
                 repo_url = self.dc.get_depot_url()
                 self.pkgsend_bulk(repo_url, self.foo10)
                 self.image_create(repo_url)
-        
-                ldtp.launchapp("%s/usr/bin/packagemanager" % testutils.g_proto_area)
-                                
+
+                ldtp.launchapp("%s/usr/bin/packagemanager" % pkg5unittest.g_proto_area)
+
                 ldtp.selectmenuitem('frmPackageManager', 'mnuManageRepositories')
-                
+
                 ldtp.waittillguiexist('dlgManageRepositories')
 
-                ldtp.settextvalue("dlgManageRepositories", "txtName", repo_name)        
+                ldtp.settextvalue("dlgManageRepositories", "txtName", repo_name)
                 ldtp.settextvalue("dlgManageRepositories", "txtURL", repo_url)
                 ldtp.click('dlgManageRepositories', 'btnAdd')
-        
+
                 ldtp.click('dlgManageRepositories', 'btnClose')
-        
+
                 # Verify result
-                self.pkg('publisher | grep %s' % repo_name)        
+                self.pkg('publisher | grep %s' % repo_name)
                 # Quit Package Manager
                 ldtp.selectmenuitem('frmPackageManager', 'mnuQuit')
+
+if __name__ == "__main__":
+	unittest.main()
--- a/src/tests/gui/t_pm_helpabout.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/gui/t_pm_helpabout.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,22 +20,23 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
-from cli import testutils
-
+import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
+import unittest
 
 try:
         import ldtp
 except ImportError:
         raise ImportError, "SUNWldtp package not installed."
 
-class TestPkgGuiHelp(testutils.SingleDepotTestCase):
+class TestPkgGuiHelp(pkg5unittest.SingleDepotTestCase):
         # Only start/stop the depot once (instead of for every test)
-        persistent_depot = True
+        persistent_setup = True
 
         foo10 = """
             open [email protected],5.11-0
@@ -43,41 +44,41 @@
             close """
 
         def setUp(self, debug_features=None):
-                testutils.SingleDepotTestCase.setUp(self)
-
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-
-        def testPmHelp(self):
+                pkg5unittest.SingleDepotTestCase.setUp(self)
                 repo_url = self.dc.get_depot_url()
                 self.pkgsend_bulk(repo_url, self.foo10)
                 self.image_create(repo_url)
 
-                ldtp.launchapp("%s/usr/bin/packagemanager" % testutils.g_proto_area)
+        def tearDown(self):
+                pkg5unittest.SingleDepotTestCase.tearDown(self)
+
+        def testPmHelp(self):
+                ldtp.launchapp("%s/usr/bin/packagemanager" % pkg5unittest.g_proto_area)
 
                 ldtp.click('frmPackageManager', 'mnuContents')
 
                 # Verify result
                 ldtp.waittillguiexist('*Online Help')
                 self.assertEqual(ldtp.guiexist('*Online Help'), 1)
-                        
+
                 ldtp.selectmenuitem('*Online Help', 'mnuCloseWindow')
 
-                
                 # Quit UpdateManager
                 ldtp.click('frmPackageManager', 'mnuQuit')
 
         def testPmAbout(self):
-
-                ldtp.launchapp("%s/usr/bin/packagemanager" % testutils.g_proto_area)
+                ldtp.launchapp("%s/usr/bin/packagemanager" % pkg5unittest.g_proto_area)
 
                 ldtp.selectmenuitem('frmPackageManager', 'mnuAbout')
 
                 # Verify result
                 self.assertEqual(ldtp.guiexist('About Package Manager'), 1)
-                                
+
                 ldtp.waittillguiexist('dlgAboutPackageManager')
                 ldtp.click('dlgAboutPackageManager', 'btnClose')
-                
+
                 # Quit Package Manager
                 ldtp.selectmenuitem('frmPackageManager', 'mnuQuit')
+
+if __name__ == "__main__":
+	unittest.main()
--- a/src/tests/gui/t_pm_rmrepo.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/gui/t_pm_rmrepo.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,22 +20,21 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
-from cli import testutils
-
+import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
+import unittest
 
 try:
         import ldtp
 except ImportError:
         raise ImportError, "SUNWldtp package not installed."
 
-class TestPkgGuiRmRepoBasics(testutils.ManyDepotTestCase):
-
-        persistent_depot = False
+class TestPkgGuiRmRepoBasics(pkg5unittest.ManyDepotTestCase):
 
         foo1 = """
             open foo@1,5.11-0
@@ -46,7 +45,7 @@
             close """
 
         def setUp(self):
-                testutils.ManyDepotTestCase.setUp(self, ["test1", "test2"])
+                pkg5unittest.ManyDepotTestCase.setUp(self, ["test1", "test2"])
 
                 durl1 = self.dcs[1].get_depot_url()
                 self.pkgsend_bulk(durl1, self.foo1)
@@ -57,13 +56,10 @@
                 self.image_create(durl1, prefix="test1")
                 self.pkg("set-publisher -O " + durl2 + " test2")
 
-        def tearDown(self):
-                testutils.ManyDepotTestCase.tearDown(self)
-        
         def testRmRepository(self):
                 repo_name = "test2"
 
-                ldtp.launchapp("%s/usr/bin/packagemanager" % testutils.g_proto_area)
+                ldtp.launchapp("%s/usr/bin/packagemanager" % pkg5unittest.g_proto_area)
 
                 ldtp.selectmenuitem('frmPackageManager', 'mnuManageRepositories')
                 
@@ -82,3 +78,6 @@
 
                 # Quit Package Manager
                 ldtp.selectmenuitem('frmPackageManager', 'mnuQuit')
+
+if __name__ == "__main__":
+	unittest.main()
--- a/src/tests/gui/t_pm_start.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/gui/t_pm_start.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,34 +20,27 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
-from cli import testutils
-
+import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
+import unittest
 
 try:
         import ldtp
 except ImportError:
         raise ImportError, "SUNWldtp package not installed."
 
-class TestPkgGuiStartBasics(testutils.SingleDepotTestCase):
-
-        persistent_depot = False
+class TestPkgGuiStartBasics(pkg5unittest.SingleDepotTestCase):
 
         foo10 = """
             open [email protected],5.11-0
             add set name="description" value="Some package description"
             close """
 
-        def setUp(self, debug_features=None):
-                testutils.SingleDepotTestCase.setUp(self)
-
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-
         def testStartPackagemanager(self):
                 durl = self.dc.get_depot_url()
                 self.pkgsend_bulk(durl, self.foo10)
@@ -56,5 +49,8 @@
                 # so it's not needed to call self.image_destroy()
                 self.image_create(durl)
 
-                ldtp.launchapp("%s/usr/bin/packagemanager" % testutils.g_proto_area)
+                ldtp.launchapp("%s/usr/bin/packagemanager" % pkg5unittest.g_proto_area)
                 ldtp.click('frmPackageManager', 'mnuQuit')
+
+if __name__ == "__main__":
+	unittest.main()
--- a/src/tests/gui/t_pm_uninstall.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/gui/t_pm_uninstall.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,34 +20,27 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
-from cli import testutils
-
+import testutils
 if __name__ == "__main__":
         testutils.setup_environment("../../../proto")
+import pkg5unittest
+import unittest
 
 try:
         import ldtp
 except ImportError:
         raise ImportError, "SUNWldtp package not installed."
 
-class TestPkgGuiUninstallBasics(testutils.SingleDepotTestCase):
-
-        persistent_depot = False
+class TestPkgGuiUninstallBasics(pkg5unittest.SingleDepotTestCase):
 
         foo10 = """
             open [email protected],5.11-0
             add set name="description" value="Some package1 description"
             close """
 
-        def setUp(self, debug_features=None):
-                testutils.SingleDepotTestCase.setUp(self)
-
-        def tearDown(self):
-                testutils.SingleDepotTestCase.tearDown(self)
-
         def testUninstallSimplePackage(self):
                 pkgname = 'package1'
                 repo_url = self.dc.get_depot_url()
@@ -55,7 +48,7 @@
                 self.image_create(repo_url)
                 self.pkg("install %s" % pkgname)
 
-                ldtp.launchapp("%s/usr/bin/packagemanager" % testutils.g_proto_area)
+                ldtp.launchapp("%s/usr/bin/packagemanager" % pkg5unittest.g_proto_area)
 
                 ldtp.activatetext('frmPackageManager', 'txtSearch')
                 ldtp.enterstring('frmPackageManager', 'txtSearch', pkgname)
@@ -82,3 +75,6 @@
                 self.pkg('verify')
 
                 ldtp.click('frmPackageManager', 'mnuQuit')
+
+if __name__ == "__main__":
+	unittest.main()
--- a/src/tests/gui/testutils.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/gui/testutils.py	Sat Jan 30 01:07:14 2010 -0800
@@ -20,13 +20,26 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
+import os
+import sys
+
+# Set the path so that modules can be found
+path_to_parent = os.path.join(os.path.dirname(__file__), "..")
+sys.path.insert(0, path_to_parent)
+
+import pkg5testenv
+
+def setup_environment(proto):
+        pkg5testenv.setup_environment(proto)
+
 try:
-        import pygtk
-        pygtk.require('2.0')
-        import gtk
+        if "DISPLAY" in os.environ:
+                import pygtk
+                pygtk.require('2.0')
+                import gtk
 except ImportError:
         pass
 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/pkg5testenv.py	Sat Jan 30 01:07:14 2010 -0800
@@ -0,0 +1,115 @@
+#!/usr/bin/python
+
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+
+import os
+import sys
+import platform
+import tempfile
+
+def setup_environment(path_to_proto, debug=False):
+        """ Set up environment for doing testing.
+
+            We set PYTHONPATH and PATH so that they reference the proto
+            area, and clear packaging related environment variables
+            (every variable prefixed with PKG_).
+
+            path_to_proto should be a relative path indicating a path
+            to proto area of the workspace.  So, if your test case is
+            three levels deep: ex. src/tests/cli/foo.py, this should be
+            "../../../proto"
+
+            This function looks at argv[0] to compute the ultimate
+            path to the proto area; this is nice because you can then
+            invoke test cases like normal commands; i.e.:
+            "python cli/t_my_test_case.py" will just work.
+
+        """
+
+        osname = platform.uname()[0].lower()
+        proc = 'unknown'
+        if osname == 'sunos':
+                proc = platform.processor()
+        elif osname == 'linux':
+                proc = "linux_" + platform.machine()
+        elif osname == 'windows':
+                proc = osname
+        elif osname == 'darwin':
+                proc = osname
+        elif osname == 'aix':
+                proc = osname
+        else:
+                print "Unable to determine appropriate proto area location."
+                print "This is a porting problem."
+                sys.exit(1)
+
+        # Figure out from where we're invoking the command
+        cmddir, cmdname = os.path.split(sys.argv[0])
+        cmddir = os.path.realpath(cmddir)
+
+        if "ROOT" in os.environ:
+                proto_area = os.environ["ROOT"]
+        else:
+                proto_area = "%s/%s/root_%s" % (cmddir, path_to_proto, proc)
+
+        # Clean up relative ../../, etc. out of path to proto
+        proto_area = os.path.realpath(proto_area)
+
+        pkgs = "%s/usr/lib/python2.6/vendor-packages" % proto_area
+        bins = "%s/usr/bin" % proto_area
+
+        sys.path.insert(1, pkgs)
+
+        #
+        # Because subprocesses must also source from the proto area,
+        # we need to set PYTHONPATH in the environment as well as
+        # in sys.path.
+        #
+        if "PYTHONPATH" in os.environ:
+                pypath = os.pathsep + os.environ["PYTHONPATH"]
+        else:
+                pypath = ""
+        os.environ["PYTHONPATH"] = "." + os.pathsep + pkgs + pypath
+
+        os.environ["PATH"] = bins + os.pathsep + os.environ["PATH"]
+
+        # Use "keys"; otherwise we'll change dictionary size during iteration.
+        for k in os.environ.keys():
+                if k.startswith("PKG_"):
+                        del os.environ[k]
+
+        #
+        # Tell package manager where its application data files live.
+        #
+        os.environ["PACKAGE_MANAGER_ROOT"] = proto_area
+
+        from pkg.client import global_settings
+        global_settings.client_name = "pkg"
+
+        import pkg5unittest
+        pkg5unittest.g_proto_area = proto_area
+
+        # Save off the value for tempdir when we were invoked, since the
+        # suite will subsequently modify tempdir to sandbox test cases.
+        pkg5unittest.g_tempdir = tempfile.gettempdir()
--- a/src/tests/pkg5unittest.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/pkg5unittest.py	Sat Jan 30 01:07:14 2010 -0800
@@ -1,5 +1,5 @@
 #!/usr/bin/python
-#
+
 # CDDL HEADER START
 #
 # The contents of this file are subject to the terms of the
@@ -20,173 +20,803 @@
 # CDDL HEADER END
 #
 
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import baseline
 import copy
+import errno
+import gettext
+import os
+import shutil
+import signal
 import string
+import subprocess
 import sys
+import tempfile
 import time
 import unittest
-import gettext
-import os
+import platform
+import pwd
+import textwrap
+
+EmptyI = tuple()
 
+#
+# These are initialized by pkg5testenv.setup_environment.
+#
+g_proto_area = "TOXIC"
+# User's value for TEMPDIR
+g_tempdir = "/tmp"
+
+g_debug_output = False
+if "DEBUG" in os.environ:
+        g_debug_output = True
+
+#
+# XXX?
+#
 gettext.install("pkg", "/usr/lib/locale")
 
 OUTPUT_DOTS=0           # Dots ...
 OUTPUT_VERBOSE=1        # Verbose
 OUTPUT_PARSEABLE=2      # Machine readable
 
-class EarlyTearDownException(Exception):
-        """An exception for inidicating early teardown of the testcase is
-        desired.  This exception is only useful for testing depot startup and
-        whatnot from the test case setUp() functions, and shouldn't be used or
-        inherited from for other purposes.  
-        """
+class TestStopException(Exception):
+        """An exception used to signal that all testing should cease.
+	This is a framework-internal exception that tests should not
+	raise"""
         pass
 
+class TestSkippedException(Exception):
+        """An exception used to signal that a test was skipped.
+        Should be initialized with a string giving a more detailed
+        reason.  Test cases can raise this to the framework
+	that some prerequisite of the test is unsatisfied.  A string
+	explaining the error should be passed at construction.  """
+	def __str__(self):
+		return "Test Skipped: " + " ".join(self.args)
+
+
+
+#
+# Errors for which the traceback is likely not useful.
+#
+import pkg.depotcontroller as depotcontroller
+ELIDABLE_ERRORS = [ TestSkippedException, depotcontroller.DepotStateException ]
+
+class Pkg5CommonException(AssertionError):
+        def __init__(self, com = ""):
+                Pkg5TestCase.failureException.__init__(self, com)
+
+        topdivider = \
+        ",---------------------------------------------------------------------\n"
+        botdivider = \
+        "`---------------------------------------------------------------------\n"
+        def format_comment(self, comment):
+                if comment is not None:
+                        comment = comment.expandtabs()
+                        comm = ""
+                        for line in comment.splitlines():
+                                line = line.strip()
+                                if line == "":
+                                        continue
+                                comm += "  " + line + "\n"
+                        return comm + "\n"
+                else:
+                        return "<no comment>\n\n"
+
+        def format_output(self, command, output):
+                str = "  Output Follows:\n"
+                str += self.topdivider
+                if command is not None:
+                        str += "| $ " + command + "\n"
+
+                if output is None or output == "":
+                        str += "| <no output>\n"
+                else:
+                        for line in output.split("\n"):
+                                str += "| " + line.rstrip() + "\n"
+                str += self.botdivider
+                return str
+
+        def format_debug(self, output):
+                str = "  Debug Buffer Follows:\n"
+                str += self.topdivider
+
+                if output is None or output == "":
+                        str += "| <no debug buffer>\n"
+                else:
+                        for line in output.split("\n"):
+                                str += "| " + line.rstrip() + "\n"
+                str += self.botdivider
+                return str
+
+
+class AssFailException(Pkg5CommonException):
+        def __init__(self, comment = None, debug=None):
+                Pkg5CommonException.__init__(self, comment)
+                self.__comment = comment
+                self.__debug = debug
+
+        def __str__(self):
+                str = ""
+                if self.__comment is None:
+                        str += Exception.__str__(self)
+                else:
+                        str += self.format_comment(self.__comment)
+                if self.__debug is not None and self.__debug != "":
+                        str += self.format_debug(self.__debug)
+                return str
+
+
 class Pkg5TestCase(unittest.TestCase):
 
         # Needed for compatability
         failureException = AssertionError
 
         bogus_url = "test.invalid"
+        __debug_buf = ""
 
         def __init__(self, methodName='runTest'):
                 super(Pkg5TestCase, self).__init__(methodName)
-                self.__testMethodName = methodName
+                self.__test_root = None
+                self.__pid = os.getpid()
+                self.__pwd = os.getcwd()
+                self.__didteardown = False
 
         def __str__(self):
                 return "%s.py %s.%s" % (self.__class__.__module__,
-                    self.__class__.__name__, self.__testMethodName)
+                    self.__class__.__name__, self._testMethodName)
+
+        #
+        # Uses property() to implements test_root as a read-only attribute.
+        #
+        test_root = property(fget=lambda self: self.__test_root)
+
+        def debug(self, s):
+                s = str(s)
+                for x in s.splitlines():
+                        if g_debug_output:
+                                print >> sys.stderr, "# %s" % x
+                        self.__debug_buf += x + "\n"
+
+        def debugcmd(self, cmdline):
+                wrapper = textwrap.TextWrapper(initial_indent="$ ",
+                    subsequent_indent="\t",
+                    break_long_words=False,
+                    break_on_hyphens=False)
+                res = wrapper.wrap(cmdline.strip())
+                self.debug(" \\\n".join(res))
+
+        def debugfilecreate(self, content, path):
+                lines = content.splitlines()
+                if lines == []:
+                        lines = [""]
+                if len(lines) > 1:
+                        ins = " [+%d lines...]" % (len(lines) - 1)
+                else:
+                        ins = ""
+                self.debugcmd(
+                    "echo '%s%s' > %s" % (lines[0], ins, path))
+
+        def debugresult(self, retcode, expected, output):
+                if output.strip() != "":
+                        self.debug(output.strip())
+                if isinstance(expected, list):
+                        if retcode != 0 or retcode not in expected:
+                                self.debug("[exited %d, expected %s]" %
+                                    (retcode, expected))
+                else:
+                        if retcode != 0 or retcode != expected:
+                                self.debug("[exited %d, expected %d]" %
+                                    (retcode, expected))
+
+        def get_debugbuf(self):
+                return self.__debug_buf
+
         def getTeardownFunc(self):
                 return (self, self.tearDown)
 
+        def getSetupFunc(self):
+                return (self, self.setUp)
+
+        def setUp(self):
+                self.__test_root = os.path.join(g_tempdir,
+                    "ips.test.%d" % self.__pid)
+                self.__didtearDown = False
+                try:
+                        os.makedirs(self.__test_root, 0755)
+                except OSError, e:
+                        if e.errno != errno.EEXIST:
+                                raise e
+                #
+                # TMPDIR affects the behavior of mkdtemp and mkstemp.
+                # Setting this here should ensure that tests will make temp
+                # files and dirs inside the test directory rather than
+                # polluting /tmp.
+                #
+                os.environ["TMPDIR"] = self.__test_root
+                tempfile.tempdir = self.__test_root
+
+        def impl_tearDown(self):
+                # impl_tearDown exists so that we can ensure that this class's
+                # teardown is actually called.  Sometimes, subclasses will
+                # implement teardown but forget to call the superclass teardown.
+                if self.__didteardown:
+                        return
+                self.__didteardown = True
+                try:
+                        os.chdir(self.__pwd)
+                except OSError:
+                        # working directory of last resort.
+                        os.chdir(g_tempdir)
+
+                #
+                # Kill depots before blowing away test dir-- otherwise
+                # the depot can race with the shutil.rmtree()
+                #
+                if hasattr(self, "killalldepots"):
+                        try:
+                                self.killalldepots()
+                        except Exception, e:
+                                print >> sys.stderr, str(e)
+
+                #
+                # We have some sloppy subclasses which don't call the superclass
+                # setUp-- in which case the dir might not exist.  Tolerate it.
+                #
+                if self.__test_root is not None and \
+                    os.path.exists(self.__test_root):
+                        shutil.rmtree(self.__test_root)
+
+        def tearDown(self):
+                # In reality this call does nothing.
+                unittest.TestCase.tearDown(self)
+
+                self.impl_tearDown()
+
         def run(self, result=None):
                 if result is None:
                         result = self.defaultTestResult()
+                pwd = os.getcwd()
                 result.startTest(self)
-                testMethod = getattr(self, self.__testMethodName)
-                if result.coverage:
+                testMethod = getattr(self, self._testMethodName)
+                if getattr(result, "coverage", None) is not None:
                         self.coverage_cmd, self.coverage_env = result.coverage
                 else:
                         self.coverage_cmd, self.coverage_env = "", {}
                 try:
+                        needtodie = False
                         try:
                                 self.setUp()
                         except KeyboardInterrupt:
-                                raise
-                        except EarlyTearDownException:
-                                self.tearDown()
-                                result.addSuccess(self)
-                                return
+                                # Try hard to make sure we've done a teardown.
+                                try:
+                                        self.tearDown()
+                                except:
+                                        pass
+                                self.impl_tearDown()
+                                raise TestStopException
                         except:
+                                # teardown could fail too, esp. if setup failed...
+                                try:
+                                        self.tearDown()
+                                except:
+                                        pass
+                                # Try hard to make sure we've done a teardown.
+                                self.impl_tearDown()
                                 result.addError(self, sys.exc_info())
                                 return
 
                         ok = False
+                        error_added = False
                         try:
                                 testMethod()
                                 ok = True
                         except self.failureException:
                                 result.addFailure(self, sys.exc_info())
                         except KeyboardInterrupt:
-                                raise
+                                # Try hard to make sure we've done a teardown.
+                                needtodie = True
                         except:
+                                error_added = True
                                 result.addError(self, sys.exc_info())
 
                         try:
                                 self.tearDown()
                         except KeyboardInterrupt:
-                                raise
+                                needtodie = True
                         except:
-                                result.addError(self, sys.exc_info())
+                                # Try hard to make sure we've done a teardown.
+                                self.impl_tearDown()
+                                # Make sure we don't mark this error'd twice.
+                                if not error_added:
+                                        result.addError(self, sys.exc_info())
                                 ok = False
 
+                        if needtodie:
+                                try:
+                                        self.impl_tearDown()
+                                except:
+                                        pass
+                                raise TestStopException
+
                         if ok:
                                 result.addSuccess(self)
                 finally:
                         result.stopTest(self)
+                        # make sure we restore our directory
+                        os.chdir(pwd)
+
+        #
+        # The following are utility functions for use by testcases.
+        #
+        def c_compile(self, prog_text, opts, outputfile):
+                """Given a C program (as a string), compile it into the
+                executable given by outputfile.  Outputfile should be
+                given as a relative path, and will be located below the
+                test prefix path.  Additional compiler options should be
+                passed in 'opts'.  Suitable for compiling small test
+                programs."""
+
+                #
+                # We use a series of likely compilers.  At present we support
+                # this testing with SunStudio.
+                #
+                if os.path.dirname(outputfile) != "":
+                        try:
+                                os.makedirs(os.path.dirname(outputfile))
+                        except OSError, e:
+                                if e.errno != errno.EEXIST:
+                                        raise
+                c_fd, c_path = tempfile.mkstemp(suffix=".c",
+                    dir=self.test_root)
+                c_fh = os.fdopen(c_fd, "w")
+                c_fh.write(prog_text)
+                c_fh.close()
+
+                found = False
+                outpath = os.path.join(self.test_root, outputfile)
+                compilers = ["/usr/bin/cc", "cc", "$CC"]
+                for compiler in compilers:
+                        cmd = [compiler, "-o", outpath]
+                        cmd.extend(opts)
+                        cmd.append(c_path)
+                        try:
+                                # Make sure to use shell=true so that env.
+                                # vars and $PATH are evaluated.
+                                self.debugcmd(" ".join(cmd))
+                                s = subprocess.Popen(" ".join(cmd),
+                                    shell=True,
+                                    stdout=subprocess.PIPE,
+                                    stderr=subprocess.STDOUT)
+                                sout, serr = s.communicate()
+                                rc = s.returncode
+                                if rc != 0 and rc != 127:
+                                        try: os.remove(outpath)
+                                        except OSError: pass
+                                        try: os.remove(c_path)
+                                        except OSError: pass
+                                        raise RuntimeError(
+                                            "Compile failed: %s --> %d\n%s" % \
+                                            (cmd, rc, sout))
+                                if rc == 127:
+                                        self.debug("[%s not found]" % compiler)
+                                        continue
+                                # so rc == 0
+                                found = True
+                                break
+                        except OSError:
+                                continue
+                try:
+                        os.remove(c_path)
+                except OSError:
+                        pass
+                if not found:
+                        raise TestSkippedException(
+                            "No suitable Sun Studio compiler found. "
+                            "Tried: %s.  Try setting $CC to a valid"
+                            "compiler." % compilers)
+
+
+        def make_misc_files(self, files, prefix=None, mode=0644):
+                """ Make miscellaneous text files.  Files can be a
+                single relative pathname, a list of relative pathnames,
+                or a hash mapping relative pathnames to specific contents.
+                If file contents are nto specified, the pathname of the
+                file is placed into the file as default content. """
+
+                outpaths = []
+                #
+                # If files is a string, make it a list.  Then, if it is
+                # a list, simply turn it into a dict where each file's
+                # contents is its own name, so that we get some uniqueness.
+                #
+                if isinstance(files, basestring):
+                        files = [files]
+
+                if isinstance(files, list):
+                        nfiles = {}
+                        for f in files:
+                                nfiles[f] = f
+                        files = nfiles
+
+                if prefix is None:
+                        prefix = self.test_root
+                else:
+                        assert(not prefix.startswith(os.pathsep))
+                        prefix = os.path.join(self.test_root, prefix)
+
+                for f, content in files.items():
+                        assert not f.startswith("/"), \
+                            ("%s: misc file paths must be relative!" % f)
+                        path = os.path.join(prefix, f)
+                        if not os.path.exists(os.path.dirname(path)):
+                                os.makedirs(os.path.dirname(path))
+                        self.debugfilecreate(content, path)
+                        file_handle = open(path, 'wb')
+                        file_handle.write(content)
+                        file_handle.close()
+                        os.chmod(path, mode)
+                        outpaths.append(path)
+                return outpaths
+
+        def make_manifest(self, content, manifest_dir="manifests"):
+                # Trim to ensure nice looking output.
+                content = content.strip()
+
+                # Place inside of test prefix.
+                manifest_dir = os.path.join(self.test_root,
+                    manifest_dir)
+
+                if not os.path.exists(manifest_dir):
+                        os.makedirs(manifest_dir)
+                t_fd, t_path = tempfile.mkstemp(prefix="mfst.", dir=manifest_dir)
+                t_fh = os.fdopen(t_fd, "w")
+                t_fh.write(content)
+                t_fh.close()
+                self.debugfilecreate(content, t_path)
+                return t_path
 
 class _Pkg5TestResult(unittest._TextTestResult):
         baseline = None
         machsep = "|"
-        def __init__(self, stream, output, baseline, bailonfail=False):
+
+        def __init__(self, stream, output, baseline, bailonfail=False,
+            show_on_expected_fail=False, archive_dir=None):
                 unittest.TestResult.__init__(self)
                 self.stream = stream
                 self.output = output
                 self.baseline = baseline
                 self.success = []
+                self.mismatches = []
                 self.bailonfail = bailonfail
+                self.show_on_expected_fail = show_on_expected_fail
+                self.archive_dir = archive_dir
+
+	def getDescription(self, test):
+		return str(test)
+
+        # Override the unittest version of this so that success is
+        # considered "matching the baseline"
+        def wasSuccessful(self):
+                return len(self.mismatches) == 0
+
+        def dobailout(self, test):
+                """ Pull the ejection lever.  Stop execution, doing as
+                much forcible cleanup as possible. """
+                inst, tdf = test.getTeardownFunc()
+                try:
+                        tdf()
+                except Exception, e:
+                        print >> sys.stderr, str(e)
+                        pass
+
+                if getattr(test, "persistent_setup", None):
+                        try:
+                                test.reallytearDown()
+                        except Exception, e:
+                                print >> sys.stderr, str(e)
+                                pass
+
+                if hasattr(inst, "killalldepots"):
+                        try:
+                                inst.killalldepots()
+                        except Exception, e:
+                                print >> sys.stderr, str(e)
+                                pass
+                raise TestStopException()
+
+        def fmt_parseable(self, match, actual, expected):
+                if match == baseline.BASELINE_MATCH:
+                        mstr = "MATCH"
+                else:
+                        mstr = "MISMATCH"
+                return "%s|%s|%s" % (mstr, actual, expected)
+
+
+        @staticmethod
+        def fmt_prefix_with(instr, prefix):
+                res = ""
+                for s in instr.splitlines():
+                        res += "%s%s\n" % (prefix, s)
+                return res
+
+        @staticmethod
+        def fmt_box(instr, title, prefix=""):
+                trailingdashes = (50 - len(title)) * "-"
+                res = "\n.---" + title + trailingdashes + "\n"
+                for s in instr.splitlines():
+                        if s.strip() == "":
+                                continue
+                        res += "| %s\n" % s
+                res += "`---" + len(title) * "-" + trailingdashes
+                return _Pkg5TestResult.fmt_prefix_with(res, prefix)
+
+        def do_archive(self, test, info):
+                assert self.archive_dir
+                if not os.path.exists(self.archive_dir):
+                        os.makedirs(self.archive_dir, mode=0755)
+
+                archive_path = os.path.join(self.archive_dir,
+                    "%d" % os.getpid())
+                if not os.path.exists(archive_path):
+                        os.makedirs(archive_path, mode=0755)
+                archive_path = os.path.join(archive_path, test.id())
+                if g_debug_output:
+                        self.stream.writeln("# Archiving to %s" % archive_path)
+
+                if os.path.exists(test.test_root):
+                        shutil.copytree(test.test_root, archive_path,
+                            symlinks=True)
+                else:
+                        # If the test has failed without creating its directory,
+                        # make it manually, so that we have a place to write out
+                        # ERROR_INFO.
+                        os.makedirs(archive_path, mode=0755)
+
+                f = open(os.path.join(archive_path, "ERROR_INFO"), "w")
+                f.write("------------------DEBUG LOG---------------\n")
+                f.write(test.get_debugbuf())
+                if info is not None:
+                        f.write("\n\n------------------EXCEPTION---------------\n")
+                        f.write(info)
+                f.close()
 
         def addSuccess(self, test):
                 unittest.TestResult.addSuccess(self, test)
+
+                # If we're debugging, we'll have had output since we
+                # announced the name of the test, so restate it.
+                if g_debug_output:
+                        self.statename(test)
+
+                errinfo = self.format_output_and_exc(test, None)
+
                 bresult = self.baseline.handleresult(str(test), "pass")
-                if self.output == OUTPUT_VERBOSE or \
-                    self.output == OUTPUT_PARSEABLE:
-                        res = ""
-                        if bresult == True:
-                                res = "pass"
+                expected = self.baseline.expectedresult(str(test))
+                if self.output == OUTPUT_PARSEABLE:
+                        res = self.fmt_parseable(bresult, "pass", expected)
+
+                elif self.output == OUTPUT_VERBOSE:
+                        if bresult == baseline.BASELINE_MATCH:
+                                res = "match pass"
                         else:
-                                res = "pass (FAIL)"
+                                res = "MISMATCH pass (expected: %s)" % \
+                                    expected
+                                res = self.fmt_box(errinfo,
+                                    "Successful Test", "# ")
+                else:
+                        assert self.output == OUTPUT_DOTS
+                        res = "."
+
+                if self.output != OUTPUT_DOTS:
                         self.stream.writeln(res)
-                elif self.output == OUTPUT_DOTS:
-                        self.stream.write('.')
+                else:
+                        self.stream.write(res)
                 self.success.append(test)
 
+                if bresult == baseline.BASELINE_MISMATCH:
+                        self.mismatches.append(test)
+
+                if bresult == baseline.BASELINE_MISMATCH and self.archive_dir:
+                        self.do_archive(test, None)
+
+                # Bail out completely if the 'bail on fail' flag is set
+                # but iff the result disagrees with the baseline.
+                if self.bailonfail and bresult == baseline.BASELINE_MISMATCH:
+                        self.dobailout(test)
+
+
         def addError(self, test, err):
-                unittest.TestResult.addError(self, test, err)
+                errtype, errval = err[:2]
+		# for a few special exceptions, we delete the traceback so
+		# as to elide it.  use only when the traceback itself
+		# is not likely to be useful.
+		if errtype in ELIDABLE_ERRORS:
+			unittest.TestResult.addError(self, test,
+			    (err[0], err[1], None))
+		else:
+			unittest.TestResult.addError(self, test, err)
+
+                # If we're debugging, we'll have had output since we
+                # announced the name of the test, so restate it.
+                if g_debug_output:
+                        self.statename(test)
+
+                errinfo = self.format_output_and_exc(test, err)
+
                 bresult = self.baseline.handleresult(str(test), "error")
-                if self.output == OUTPUT_VERBOSE or \
-                    self.output == OUTPUT_PARSEABLE:
-                        self.stream.writeln("ERROR")
-                        if self.output == OUTPUT_VERBOSE:
-                                self.stream.writeln("%s" % self.errors[-1][1])
+                expected = self.baseline.expectedresult(str(test))
+                if self.output == OUTPUT_PARSEABLE:
+                        if errtype in ELIDABLE_ERRORS:
+                                res = self.fmt_parseable(bresult, "ERROR", expected)
+                                res += "\n# %s\n" % str(errval).strip()
+                        else:
+                                res = self.fmt_parseable(bresult, "ERROR", expected)
+                                res += "\n"
+                                if bresult == baseline.BASELINE_MISMATCH \
+                                   or self.show_on_expected_fail:
+                                        res += self.fmt_prefix_with(errinfo, "# ")
+
+                elif self.output == OUTPUT_VERBOSE:
+                        if bresult == baseline.BASELINE_MATCH:
+                                b = "match"
+                        else:
+                                b = "MISMATCH"
+
+                        if errtype in ELIDABLE_ERRORS:
+                                res = "%s ERROR\n" % b
+                                res += "#\t%s" % str(errval)
+                        else:
+                                res = "%s ERROR\n" % b
+                                if bresult == baseline.BASELINE_MISMATCH \
+                                   or self.show_on_expected_fail:
+                                        res += self.fmt_box(errinfo,
+                                            "Error Information", "# ")
+
                 elif self.output == OUTPUT_DOTS:
-                        if bresult:
-                                self.stream.write('e')
+                        if bresult == baseline.BASELINE_MATCH:
+                                res = "e"
                         else:
-                                self.stream.write('E')
+                                res = "E"
+
+                if self.output == OUTPUT_DOTS:
+                        self.stream.write(res)
+                else:
+                        self.stream.writeln(res)
+
+                if bresult == baseline.BASELINE_MISMATCH:
+                        self.mismatches.append(test)
+
+                # Check to see if we should archive this baseline mismatch.
+                if bresult == baseline.BASELINE_MISMATCH and self.archive_dir:
+                        self.do_archive(test, self._exc_info_to_string(err, test))
+
+                # Bail out completely if the 'bail on fail' flag is set
+                # but iff the result disagrees with the baseline.
+                if self.bailonfail and bresult == baseline.BASELINE_MISMATCH:
+                        self.dobailout(test)
+
+        def format_output_and_exc(self, test, error):
+                res = ""
+                dbgbuf = test.get_debugbuf()
+                if dbgbuf != "":
+                        res += dbgbuf
+                if error is not None:
+                        res += self._exc_info_to_string(error, test)
+                return res
 
         def addFailure(self, test, err):
-                unittest.TestResult.addFailure(self, test, err)
+		unittest.TestResult.addFailure(self, test, err)
+
                 bresult = self.baseline.handleresult(str(test), "fail")
-                if self.output == OUTPUT_VERBOSE or \
-                    self.output == OUTPUT_PARSEABLE:
-                        res = ""
-                        if bresult == True:
-                                res = "FAIL (pass)"
+                expected = self.baseline.expectedresult(str(test))
+
+                # If we're debugging, we'll have had output since we
+                # announced the name of the test, so restate it.
+                if g_debug_output:
+                        self.statename(test)
+
+                errinfo = self.format_output_and_exc(test, err)
+
+                if self.output == OUTPUT_PARSEABLE:
+                        res = self.fmt_parseable(bresult, "FAIL", expected)
+                        res += "\n"
+                        if bresult == baseline.BASELINE_MISMATCH \
+                           or self.show_on_expected_fail:
+                                res += self.fmt_prefix_with(errinfo, "# ")
+                elif self.output == OUTPUT_VERBOSE:
+                        if bresult == baseline.BASELINE_MISMATCH:
+                                res = "MISMATCH FAIL (expected: %s)" % expected
                         else:
-                                res = "FAIL"
-                        self.stream.writeln(res)
-                        if self.output == OUTPUT_VERBOSE:
-                                self.stream.writeln("%s" % self.failures[-1][1])
+                                res = "match FAIL (expected: FAIL)"
+
+                        if bresult == baseline.BASELINE_MISMATCH \
+                           or self.show_on_expected_fail:
+                                res += self.fmt_box(errinfo,
+                                    "Failure Information", "# ")
+
                 elif self.output == OUTPUT_DOTS:
-                        if bresult:
-                                self.stream.write('f')
+                        if bresult == baseline.BASELINE_MATCH:
+                                res = "f"
                         else:
-                                self.stream.write('F')
-                if self.bailonfail and not bresult:
-                    tdf = test.getTeardownFunc()[1]
-                    tdf()
-                    if test.persistent_depot:
-                            test.reallytearDown()
-                    raise
+                                res = "F"
+
+                if self.output == OUTPUT_DOTS:
+                        self.stream.write(res)
+                else:
+                        self.stream.writeln(res)
+
+                if bresult == baseline.BASELINE_MISMATCH:
+                        self.mismatches.append(test)
+
+                # Check to see if we should archive this baseline mismatch.
+                if bresult == baseline.BASELINE_MISMATCH and self.archive_dir:
+                        self.do_archive(test, self._exc_info_to_string(err, test))
+
+                # Bail out completely if the 'bail on fail' flag is set
+                # but iff the result disagrees with the baseline.
+                if self.bailonfail and bresult == baseline.BASELINE_MISMATCH:
+                        self.dobailout(test)
+
+        def addPersistentSetupError(self, test, err):
+                errtype, errval = err[:2]
+
+                errinfo = self.format_output_and_exc(test, err)
+
+                res = "# ERROR during persistent setup for %s\n" % test.id()
+                res += "# As a result, all test cases in this class will " \
+                    "result in errors."
 
-        def getDescription(self, test):
-                return str(test)
+                if errtype in ELIDABLE_ERRORS:
+                        res += "#   " + str(errval)
+                else:
+                        res += self.fmt_box(errinfo, \
+                            "Persistent Setup Error Information", "# ")
+                self.stream.writeln(res)
+
+        def addPersistentTeardownError(self, test, err):
+                errtype, errval = err[:2]
+
+                errinfo = self.format_output_and_exc(test, err)
+
+                res = "# ERROR during persistent teardown for %s\n" % test.id()
+                if errtype in ELIDABLE_ERRORS:
+                        res += "#   " + str(errval)
+                else:
+                        res += self.fmt_box(errinfo, \
+                            "Persistent Teardown Error Information", "# ")
+                self.stream.writeln(res)
+
+        def statename(self, test, prefix=""):
+                name = self.getDescription(test)
+                if self.output == OUTPUT_VERBOSE:
+                        name = string.ljust(name, 65) + "  "
+                elif self.output == OUTPUT_PARSEABLE:
+                        name += "|"
+                elif self.output == OUTPUT_DOTS:
+                        return
+                self.stream.write(name)
 
         def startTest(self, test):
                 unittest.TestResult.startTest(self, test)
-                if not self.output == OUTPUT_DOTS:
-                        self.stream.write(
-                            string.ljust(self.getDescription(test), 60))
-                if self.output == OUTPUT_VERBOSE:
-                        self.stream.write("   ")
-                elif self.output == OUTPUT_PARSEABLE:
-                        self.stream.write(" | ")
-                self.stream.flush()
+                test.debug("_" * 75)
+                test.debug("Start:   %s" % \
+                    self.getDescription(test))
+                if test._testMethodDoc is not None:
+                        docs = ["  " + x.strip() \
+                            for x in test._testMethodDoc.splitlines()]
+                        while len(docs) > 0 and docs[-1] == "":
+                                del docs[-1]
+                        for x in docs:
+                                test.debug(x)
+                test.debug("_" * 75)
+                test.debug("")
+
+                if not g_debug_output:
+                        self.statename(test)
 
         def printErrors(self):
                 self.stream.writeln()
@@ -205,161 +835,976 @@
         """TestRunner for test suites that we want to be able to compare
         against a result baseline."""
         baseline = None
-        sep1 = '=' * 70
-        sep2 = '-' * 70
 
         def __init__(self, baseline, stream=sys.stderr, output=OUTPUT_DOTS,
-            timing_file=None, bailonfail=False, coverage=None):
-                """Set up the runner, creating a baseline object that has
-                a name of 'suite'_baseline.pkl, where suite is 'cli', 'api',
-                etc."""
-                # output is one of "dots", "verbose", "machine"
+            timing_file=None, bailonfail=False, coverage=None,
+            show_on_expected_fail=False, archive_dir=None):
+                """Set up the test runner"""
+                # output is one of OUTPUT_DOTS, OUTPUT_VERBOSE, OUTPUT_PARSEABLE
                 super(Pkg5TestRunner, self).__init__(stream)
                 self.baseline = baseline
                 self.output = output
                 self.timing_file = timing_file
                 self.bailonfail = bailonfail
                 self.coverage = coverage
+                self.show_on_expected_fail = show_on_expected_fail
+                self.archive_dir = archive_dir
 
         def _makeResult(self):
                 return _Pkg5TestResult(self.stream, self.output, self.baseline,
-                    bailonfail=self.bailonfail)
+                    bailonfail=self.bailonfail,
+                    show_on_expected_fail=self.show_on_expected_fail,
+                    archive_dir=self.archive_dir)
 
-        def run(self, test):
-                "Run the given test case or test suite."
-                result = self._makeResult()
-                startTime = time.time()
-                result.coverage = self.coverage
-                test.run(result)
-                stopTime = time.time()
-                timeTaken = stopTime - startTime
+        @staticmethod
+        def __write_timing_info(stream, suite_name, class_list, method_list):
+                if not class_list and not method_list:
+                        return
+                tot = 0
+                print >> stream, "Tests run for '%s' Suite, " \
+                    "broken down by class:\n" % suite_name
+                for secs, cname in class_list:
+                        print >> stream, "%6.2f %s.%s" % (secs, suite_name, cname)
+                        tot += secs
+                        for secs, mcname, mname in method_list:
+                                if mcname != cname:
+                                        continue
+                                print >> stream, \
+                                    "    %6.2f %s" % (secs, mname)
+                        print >> stream
+                print >> stream, "%6.2f Total time\n" % tot
+                print >> stream, "=" * 60
+                print >> stream, "\nTests run for '%s' Suite, " \
+                    "sorted by time taken:\n" % suite_name
+                for secs, cname, mname in method_list:
+                        print >> stream, "%6.2f %s %s" % (secs, cname, mname)
+                print >> stream, "%6.2f Total time\n" % tot
+                print >> stream, "=" * 60
+                print >> stream, ""
+
+        def _do_timings(self, test):
                 timing = {}
                 lst = []
+                suite_name = None
                 for t in test._tests:
-                        for (cname, mname), secs in t.timing.items():
+                        for (sname, cname, mname), secs in t.timing.items():
                                 lst.append((secs, cname, mname))
                                 if cname not in timing:
                                         timing[cname] = 0
                                 timing[cname] += secs
+                                suite_name = sname
                 lst.sort()
                 clst = sorted((secs, cname) for cname, secs in timing.items())
-                                        
-                if self.output != OUTPUT_VERBOSE:
-                        result.printErrors()
-                        self.stream.writeln(result.separator2)
-                run = result.testsRun
-                self.stream.writeln("Ran %d test%s in %.3fs" %
-                    (run, run != 1 and "s" or "", timeTaken))
-                self.stream.writeln()
-                if not result.wasSuccessful():
-                        self.stream.write("FAILED (")
-                        success, failed, errored, mismatches = map(len,
-                            (result.success, result.failures, result.errors,
-                                self.baseline.getfailures()))
-                        self.stream.write("successes=%d, " % success)
-                        self.stream.write("failures=%d, " % failed)
-                        self.stream.write("errors=%d, " % errored)
-                        self.stream.write("mismatches=%d" % mismatches)
-                        self.stream.writeln(")")
-                else:
-                        self.stream.writeln("OK")
 
                 if self.timing_file:
                         try:
                                 fh = open(self.timing_file, "ab+")
                                 opened = True
                         except KeyboardInterrupt:
-                                raise
+                                raise TestStopException()
                         except Exception:
                                 fh = sys.stderr
                                 opened = False
-                        self.__write_timing_info(fh, clst, lst)
+                        self.__write_timing_info(fh, suite_name, clst, lst)
                         if opened:
                                 fh.close()
 
+        def run(self, test):
+                "Run the given test case or test suite."
+                result = self._makeResult()
+
+                startTime = time.time()
+                result.coverage = self.coverage
+                try:
+                        test.run(result)
+                finally:
+                        stopTime = time.time()
+                        timeTaken = stopTime - startTime
+
+                        run = result.testsRun
+                        if run > 0:
+                                if self.output != OUTPUT_VERBOSE:
+                                        result.printErrors()
+                                        self.stream.writeln("# " + result.separator2)
+                                self.stream.writeln("\n# Ran %d test%s in %.3fs" %
+                                    (run, run != 1 and "s" or "", timeTaken))
+                                self.stream.writeln()
+                        if not result.wasSuccessful():
+                                self.stream.write("FAILED (")
+                                success, failed, errored, mismatches = map(len,
+                                    (result.success, result.failures, result.errors,
+                                        result.mismatches))
+                                self.stream.write("successes=%d, " % success)
+                                self.stream.write("failures=%d, " % failed)
+                                self.stream.write("errors=%d, " % errored)
+                                self.stream.write("mismatches=%d" % mismatches)
+                                self.stream.writeln(")")
+
+                        self._do_timings(test)
                 return result
 
-        @staticmethod
-        def __write_timing_info(stream, class_list, method_list):
-                if not class_list and not method_list:
-                        return
-                tot = 0
-                for secs, cname in class_list:
-                        print >> stream, "%6.2f %s" % (secs, cname)
-                        tot += secs
-                print >> stream, "%6.2f Total time" % tot
-                print >> stream, "=" * 60
-                for secs, cname, mname in method_list:
-                        print >> stream, "%6.2f %s %s" % (secs, cname, mname)
-                print >> stream, "=" * 60
-                print >> stream, "=" * 60 + "\n" * 4
 
 class Pkg5TestSuite(unittest.TestSuite):
-        """Test suite that handles persistent depot tests.  Persistent depot
-        tests are ones that are able to only call their setUp/tearDown
-        functions once per class, instead of before and after every test case.
-        Aside from actually running the test it defers the majority of its
-        work to unittest.TestSuite.
+        """Test suite that extends unittest.TestSuite to handle persistent
+        tests.  Persistent tests are ones that are able to only call their
+        setUp/tearDown functions once per class, instead of before and after
+        every test case.  Aside from actually running the test it defers the
+        majority of its work to unittest.TestSuite.
+
+        To make a test class into a persistent one, add this class
+        variable declaration:
+                persistent_setup = True
+        """
 
-        To make a test class into a persistent depot one, add this class
-        variable declaration:
-                persistent_depot = True
-        """
+        def __init__(self, tests=()):
+                unittest.TestSuite.__init__(self, tests)
+                self.timing = {}
+
+        def cleanup_and_die(self, inst, info):
+                print >> sys.stderr, \
+                    "\nCtrl-C: Attempting cleanup during %s" % info
+
+                if hasattr(inst, "killalldepots"):
+                        print >> sys.stderr, "Killing depots..."
+                        inst.killalldepots()
+                print >> sys.stderr, "Stopping tests..."
+                raise TestStopException()
 
         def run(self, result):
                 self.timing = {}
                 inst = None
                 tdf = None
                 try:
-                        persistent_depot = getattr(self._tests[0],
-                            "persistent_depot", False)
+                        persistent_setup = getattr(self._tests[0],
+                            "persistent_setup", False)
                 except IndexError:
                         # No tests, thats ok.
                         return
 
-                if persistent_depot:
+                def setUp_donothing():
+                        pass
+
+                def tearDown_donothing():
+                        pass
+
+                def setUp_dofail():
+                        raise TestSkippedException(
+                            "Persistent setUp Failed, skipping test.")
+
+                if persistent_setup:
+                        setUpFailed = False
+
+                        # Save a reference to the tearDown func and neuter
+                        # normal per-test-function teardown.
                         inst, tdf = self._tests[0].getTeardownFunc()
+                        inst.reallytearDown = tdf
+                        inst.tearDown = tearDown_donothing
+
                         if result.coverage:
                                 inst.coverage_cmd, inst.coverage_env = result.coverage
                         else:
                                 inst.coverage_cmd, inst.coverage_env = "", {}
+
                         try:
                                 inst.setUp()
                         except KeyboardInterrupt:
-                                raise
+                                self.cleanup_and_die(inst, "persistent setup")
                         except:
-                                result.addError(inst, sys.exc_info())
-                def donothing():
-                        pass
+                                result.addPersistentSetupError(inst, sys.exc_info())
+                                setUpFailed = True
+                                # XXX do cleanup?
+
+                        # If the setUp function didn't work, then cause
+                        # every test case to fail.
+                        if setUpFailed:
+                                inst.setUp = setUp_dofail
+                        else:
+                                inst.setUp = setUp_donothing
+
                 for test in self._tests:
                         if result.shouldStop:
                                 break
-                        real_test_name = test._Pkg5TestCase__testMethodName
+                        real_test_name = test._testMethodName
+                        suite_name = test._Pkg5TestCase__suite_name
                         cname = test.__class__.__name__
+
                         # Populate test with the data from the instance
                         # already constructed, but update the method name.
                         # We need to do this so that we have all the state
                         # that the object is populated with when setUp() is
                         # called (depot controller list, etc).
-                        if persistent_depot:
-                                name = test._Pkg5TestCase__testMethodName
+                        if persistent_setup:
+                                name = test._testMethodName
+                                doc = test._testMethodDoc
                                 test = copy.copy(inst)
-                                test._Pkg5TestCase__testMethodName = name
-                                # For test classes with persistent_depot set,
-                                # make their setup/teardown methods do nothing
-                                # since we are calling them here.
-                                test.reallytearDown = tdf
-                                test.setUp = donothing
-                                test.tearDown = donothing
+                                test._testMethodName = name
+                                test._testMethodDoc = doc
+
                         test_start = time.time()
                         test(result)
                         test_end = time.time()
-                        self.timing[cname, real_test_name] = \
+                        self.timing[suite_name, cname, real_test_name] = \
                             test_end - test_start
-                if persistent_depot:
+                if persistent_setup:
                         try:
-                                tdf()
+                                inst.reallytearDown()
                         except KeyboardInterrupt:
+                                self.cleanup_and_die(inst, "persistent teardown")
+                        except:
+                                result.addPersistentTeardownError(inst, sys.exc_info())
+
+                # Try to ensure that all depots have been nuked.
+                if hasattr(inst, "killalldepots"):
+                        inst.killalldepots()
+
+
+
+def get_su_wrap_user():
+        for u in ["noaccess", "nobody"]:
+                try:
+                        pwd.getpwnam(u)
+                        return u
+                except (KeyError, NameError):
+                        pass
+        raise RuntimeError("Unable to determine user for su.")
+
+class DepotTracebackException(Pkg5CommonException):
+        def __init__(self, logfile, output):
+                Pkg5CommonException.__init__(self)
+                self.__logfile = logfile
+                self.__output = output
+
+        def __str__(self):
+                str = "During this test, a depot Traceback was detected.\n"
+                str += "Log file: %s.\n" % self.__logfile
+                str += "Log file output is:\n"
+                str += self.format_output(None, self.__output)
+                return str
+
+class TracebackException(Pkg5CommonException):
+        def __init__(self, command, output=None, comment=None):
+                Pkg5CommonException.__init__(self)
+                self.__command = command
+                self.__output = output
+                self.__comment = comment
+                self.__debug = debug
+
+        def __str__(self):
+                if self.__comment is None and self.__output is None:
+                        return (Exception.__str__(self))
+
+                str = ""
+                str += self.format_comment(self.__comment)
+                str += self.format_output(self.__command, self.__output)
+                if self.__debug is not None and self.__debug != "":
+                        str += self.format_debug(self.__debug)
+                return str
+
+class UnexpectedExitCodeException(Pkg5CommonException):
+        def __init__(self, command, expected, got, output=None, comment=None):
+                Pkg5CommonException.__init__(self)
+                self.__command = command
+                self.__output = output
+                self.__expected = expected
+                self.__got = got
+                self.__comment = comment
+
+        def __str__(self):
+                if self.__comment is None and self.__output is None:
+                        return (Exception.__str__(self))
+
+                str = ""
+                str += self.format_comment(self.__comment)
+
+                str += "  Invoked: %s\n" % self.__command
+                str += "  Expected exit status: %s.  Got: %d." % \
+                    (self.__expected, self.__got)
+
+                str += self.format_output(self.__command, self.__output)
+                return str
+
+        @property
+        def exitcode(self):
+                return self.__got
+
+class PkgSendOpenException(Pkg5CommonException):
+        def __init__(self, com = ""):
+                Pkg5CommonException.__init__(self, com)
+
+class CliTestCase(Pkg5TestCase):
+        bail_on_fail = False
+
+        def setUp(self):
+                Pkg5TestCase.setUp(self)
+
+                self.image_dir = None
+                self.img_path = os.path.join(self.test_root, "image")
+                os.environ["PKG_IMAGE"] = self.img_path
+
+        def tearDown(self):
+                Pkg5TestCase.tearDown(self)
+
+        def get_img_path(self):
+                return self.img_path
+
+
+        def image_create(self, repourl, prefix="test", additional_args=""):
+                assert self.img_path
+                assert self.img_path != "/"
+
+                self.image_destroy()
+                os.mkdir(self.img_path)
+                cmdline = "pkg image-create -F -p %s=%s %s %s" % \
+                    (prefix, repourl, additional_args, self.img_path)
+                self.debugcmd(cmdline)
+
+                p = subprocess.Popen(cmdline, shell = True,
+                    stdout = subprocess.PIPE,
+                    stderr = subprocess.STDOUT)
+                output = p.stdout.read()
+                retcode = p.wait()
+                self.debugresult(retcode, 0, output)
+
+                if retcode == 99:
+                        raise TracebackException(cmdline, output)
+                if retcode != 0:
+                        raise UnexpectedExitCodeException(cmdline, 0,
+                            retcode, output)
+
+                return retcode
+
+        def image_set(self, imgdir):
+                self.debug("image_set: %s" % imgdir)
+                self.img_path = imgdir
+                os.environ["PKG_IMAGE"] = self.img_path
+
+        def image_destroy(self):
+                self.debug("image_destroy %s" % self.img_path)
+                # Make sure we're not in the image.
+                if os.path.exists(self.img_path):
+                        os.chdir(self.test_root)
+                        shutil.rmtree(self.img_path)
+
+
+        def get_su_wrapper(self, su_wrap=None):
+                if su_wrap:
+                        if su_wrap == True:
+                                su_wrap = get_su_wrap_user()
+                        cov_env = " ".join(
+                            ("%s=%s" % e for e in self.coverage_env.items()))
+                        su_wrap = "su %s -c 'LD_LIBRARY_PATH=%s %s " % \
+                            (su_wrap, os.getenv("LD_LIBRARY_PATH", ""), cov_env)
+                        su_end = "'"
+                else:
+                        su_wrap = ""
+                        su_end = ""
+                return su_wrap, su_end
+
+        def pkg(self, command, exit=0, comment="", prefix="", su_wrap=None):
+                wrapper = self.coverage_cmd
+
+                su_wrap, su_end = self.get_su_wrapper(su_wrap=su_wrap)
+
+                if prefix:
+                        cmdline = "%s;%s%s %s/usr/bin/pkg %s%s" % (prefix,
+                            su_wrap, wrapper, g_proto_area, command, su_end)
+                else:
+                        cmdline = "%s%s %s/usr/bin/pkg %s%s" % (su_wrap, wrapper,
+                            g_proto_area, command, su_end)
+                self.debugcmd(cmdline)
+
+                newenv = os.environ.copy()
+                newenv.update(self.coverage_env)
+                p = subprocess.Popen(cmdline, shell=True, env=newenv,
+                    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+
+                self.output = p.stdout.read()
+                retcode = p.wait()
+                self.debugresult(retcode, exit, self.output)
+
+                if retcode == 99:
+                        raise TracebackException(cmdline, self.output, comment)
+
+                if not isinstance(exit, list):
+                        exit = [exit]
+
+                if retcode not in exit:
+                        raise UnexpectedExitCodeException(cmdline,
+                            exit, retcode, self.output, comment)
+
+                return retcode
+
+        def pkgdepend_resolve(self, args, exit=0, comment=""):
+                wrapper = self.coverage_cmd
+
+                cmdline = "%s %s/usr/bin/pkgdepend resolve %s" % (wrapper,
+                    g_proto_area, args)
+                self.debugcmd(cmdline)
+
+                newenv = os.environ.copy()
+                newenv.update(self.coverage_env)
+                p = subprocess.Popen(cmdline, shell=True, env=newenv,
+                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+                self.output, self.errout = p.communicate()
+                retcode = p.returncode
+                self.debugresult(retcode, exit, self.output)
+                if self.errout != "":
+                        self.debug(self.errout)
+
+                if retcode == 99:
+                        raise TracebackException(cmdline, self.output, comment)
+                elif retcode != exit:
+                        raise UnexpectedExitCodeException(cmdline,
+                            exit, retcode, self.output, comment)
+                return retcode
+
+        def pkgdepend_generate(self, args, proto, exit=0, comment=""):
+                wrapper = self.coverage_cmd
+
+                cmdline = "%s %s/usr/bin/pkgdepend generate %s %s" % (wrapper,
+                    g_proto_area, args, proto)
+                self.debugcmd(cmdline)
+
+                newenv = os.environ.copy()
+                newenv.update(self.coverage_env)
+                p = subprocess.Popen(cmdline, shell=True, env=newenv,
+                    stdout=subprocess.PIPE, stderr=subprocess.PIPE)
+
+                self.output, self.errout = p.communicate()
+                retcode = p.returncode
+                self.debugresult(retcode, exit, self.output)
+                if self.errout != "":
+                        self.debug(self.errout)
+
+                if retcode == 99:
+                        raise TracebackException(cmdline, self.output, comment)
+                elif retcode != exit:
+                        raise UnexpectedExitCodeException(cmdline,
+                            exit, retcode, self.output, comment)
+                return retcode
+
+        def pkgrecv(self, server_url=None, command=None, exit=0, out=False,
+            comment=""):
+                wrapper = self.coverage_cmd
+
+                args = []
+                if server_url:
+                        args.append("-s %s" % server_url)
+
+                if command:
+                        args.append(command)
+
+                cmdline = "%s %s/usr/bin/pkgrecv %s" % (wrapper,
+                    g_proto_area, " ".join(args))
+                self.debugcmd(cmdline)
+
+                newenv = os.environ.copy()
+                newenv.update(self.coverage_env)
+                p = subprocess.Popen(cmdline, shell=True, env=newenv,
+                    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+
+                self.output = p.stdout.read()
+                retcode = p.wait()
+                self.debugresult(retcode, exit, self.output)
+
+                if retcode == 99:
+                        raise TracebackException(cmdline, self.output, comment)
+                elif retcode != exit:
+                        raise UnexpectedExitCodeException(cmdline,
+                            exit, retcode, self.output, comment)
+
+                if out:
+                        return retcode, self.output
+
+                return retcode
+
+        def pkgsend(self, depot_url="", command="", exit=0, comment="", retry400=True):
+                wrapper = self.coverage_cmd
+
+                args = []
+                if depot_url:
+                        args.append("-s " + depot_url)
+
+                if command:
+                        args.append(command)
+
+                cmdline = "cd %s; %s %s/usr/bin/pkgsend %s" % \
+                    (self.test_root, wrapper,
+                    g_proto_area, " ".join(args))
+                self.debugcmd(cmdline)
+
+                # XXX may need to be smarter.
+                published = None
+                newenv = os.environ.copy()
+                newenv.update(self.coverage_env)
+
+                p = subprocess.Popen(cmdline, shell=True, env=newenv,
+                    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+
+                out, err = p.communicate()
+                retcode = p.returncode
+                self.debugresult(retcode, exit, out)
+
+                cmdop = command.split(' ')[0]
+                if cmdop == "open" and retcode == 0:
+                        out = out.rstrip()
+                        assert out.startswith("export PKG_TRANS_ID=")
+                        arr = out.split("=")
+                        assert arr
+                        out = arr[1]
+                        os.environ["PKG_TRANS_ID"] = out
+                        self.debug("$ export PKG_TRANS_ID=%s" % out)
+                        # retcode != 0 will be handled below
+
+                if (cmdop == "close" and retcode == 0) or cmdop == "publish":
+                        os.environ["PKG_TRANS_ID"] = ""
+                        self.debug("$ export PKG_TRANS_ID=")
+                        for l in out.splitlines():
+                                if l.startswith("pkg:/"):
+                                        published = l
+                                        break
+
+                # This may be a failure due to us being too quick to republish,
+                # and getting the same timestamp twice.  Keep trying for a
+                # little more than 1 second.
+                #
+                # This is a nasty hack which is here as a placeholder until
+                # pkgsend can give us better error granularity.
+                #
+                if cmdop in ["publish", "open"] and "status '400'" in out and \
+                    "already exists" in out and retry400:
+                        time.sleep(1)
+                        return self.pkgsend(depot_url, command, exit,
+                            comment, retry400=False)
+
+                if retcode == 99:
+                        raise TracebackException(cmdline, out, comment)
+
+                if retcode != exit:
+                        raise UnexpectedExitCodeException(cmdline, exit,
+                            retcode, out, comment)
+
+                return retcode, published
+
+        def pkgsend_bulk(self, depot_url, commands, exit=0, comment=""):
+                """ Send a series of packaging commands; useful for quickly
+                    doing a bulk-load of stuff into the repo.  All commands are
+                    expected to work; if not, the transaction is abandoned.  If
+                    'exit' is set, then if none of the actions triggers that
+                    exit code, an UnexpectedExitCodeException is raised.
+
+                    A list containing the fmris of any packages that were
+                    published as a result of the commands executed will be
+                    returned; it will be empty if none were. """
+
+                plist = []
+                try:
+                        accumulate = []
+                        current_fmri = None
+
+                        for line in commands.split("\n"):
+                                line = line.strip()
+                                if line == "":
+                                        continue
+                                if line.startswith("add"):
+                                        self.assert_(current_fmri != None,
+                                            "Missing open in pkgsend string")
+                                        accumulate.append(line[4:])
+                                        continue
+
+                                if current_fmri: # send any content seen so far (can be 0)
+                                        fd, f_path = tempfile.mkstemp(dir=self.test_root)
+                                        for l in accumulate:
+                                                os.write(fd, "%s\n" % l)
+                                        os.close(fd)
+                                        try:
+                                                cmd = "publish -d %s %s %s" % \
+                                                    (self.test_root,
+                                                     current_fmri, f_path)
+                                                current_fmri = None
+                                                accumulate = []
+                                                retcode, published = self.pkgsend(depot_url, cmd)
+                                                if retcode == 0 and published:
+                                                        plist.append(published)
+                                        except:
+                                                os.remove(f_path)
+                                                raise
+                                        os.remove(f_path)
+                                if line.startswith("open"):
+                                        current_fmri = line[5:].strip()
+
+                except UnexpectedExitCodeException, e:
+                        if e.exitcode != exit:
                                 raise
-                        except:
-                                result.addError(inst, sys.exc_info())
+                        retcode = e.exitcode
+
+                if retcode != exit:
+                        raise UnexpectedExitCodeException(line, exit, retcode)
+
+                return plist
+
+
+        def cmdline_run(self, cmdline, exit=0):
+                p = subprocess.Popen(cmdline,
+                    shell=True,
+                    stdout=subprocess.PIPE,
+                    stderr=subprocess.STDOUT)
+
+                output = p.stdout.read()
+                retcode = p.wait()
+                self.debugresult(retcode, exit, output)
+                if retcode != exit:
+                        raise UnexpectedExitCodeException(cmdline, exit,
+                            retcode, output)
+
+
+        def copy_repository(self, src, src_pub, dest, dest_pub):
+                """Copies the packages from the src repository to a new
+                destination repository that will be created at dest.  In
+                addition, any packages from the src_pub will be assigned
+                to the dest_pub during the copy.  The new repository will
+                not have a catalog or search indices, so a depot server
+                pointed at the new repository must be started with the
+                --rebuild option."""
+
+                shutil.rmtree(dest, True)
+                os.makedirs(dest, mode=0755)
+
+                for entry in os.listdir(src):
+                        spath = os.path.join(src, entry)
+
+                        # Skip the catalog, index, and pkg directories
+                        # as they will be copied manually.  Also skip
+                        # any unknown files in the repository directory.
+                        if entry in ("catalog", "index", "pkg") or \
+                            not os.path.isdir(spath):
+                                continue
+                        shutil.copytree(spath, os.path.join(dest, entry))
+
+                # Now copy each manifest and replace any references to the old
+                # publisher with that of the new publisher as they are copied.
+                pkg_root = os.path.join(src, "pkg")
+                for stem in os.listdir(pkg_root):
+                        pkg_path = os.path.join(pkg_root, stem)
+                        for mname in os.listdir(pkg_path):
+                                # Ensure destination manifest directory exists.
+                                dmdpath = os.path.join(dest, "pkg", stem)
+                                if not os.path.isdir(dmdpath):
+                                        os.makedirs(dmdpath, mode=0755)
+
+                                msrc = open(os.path.join(pkg_path, mname), "rb")
+                                mdest = open(os.path.join(dmdpath, mname), "wb")
+                                for l in msrc:
+                                        if l.find("pkg://") > -1:
+                                                mdest.write(l.replace(src_pub,
+                                                    dest_pub))
+                                        else:
+                                                mdest.write(l)
+                                msrc.close()
+                                mdest.close()
+
+        def validate_html_file(self, fname, exit=0, comment="",
+            options="-quiet -utf8"):
+                cmdline = "tidy %s %s" % (options, fname)
+                self.debugcmd(cmdline)
+
+                output = ""
+                p = subprocess.Popen(cmdline, shell=True,
+                    stdout=subprocess.PIPE, stderr=subprocess.STDOUT)
+
+                output = p.stdout.read()
+                retcode = p.wait()
+                self.debugresult(retcode, exit, output)
+
+                if retcode == 99:
+                        raise TracebackException(cmdline, output, comment)
+
+                if retcode != exit:
+                        raise UnexpectedExitCodeException(cmdline, exit,
+                            retcode, output, comment)
+
+                return retcode
+
+        def start_depot(self, port, depotdir, logpath, refresh_index=False,
+            debug_features=EmptyI, properties=EmptyI):
+                """ Convenience routine to help subclasses start
+                    depots.  Returns a depotcontroller. """
+
+                # Note that this must be deferred until after PYTHONPATH
+                # is set up.
+                import pkg.depotcontroller as depotcontroller
+
+                self.debug("start_depot: depot listening on port %d" % port)
+                self.debug("start_depot: depot data in %s" % depotdir)
+                self.debug("start_depot: depot logging to %s" % logpath)
+
+                dc = depotcontroller.DepotController(
+                    wrapper_start=self.coverage_cmd.split(),
+                    env=self.coverage_env)
+                dc.set_depotd_path(g_proto_area + "/usr/lib/pkg.depotd")
+                dc.set_depotd_content_root(g_proto_area + "/usr/share/lib/pkg")
+                for f in debug_features:
+                        dc.set_debug_feature(f)
+                dc.set_repodir(depotdir)
+                dc.set_logpath(logpath)
+                dc.set_port(port)
+                for section in properties:
+                        for prop, val in properties[section].iteritems():
+                                dc.set_property(section, prop, val)
+                if refresh_index:
+                        dc.set_refresh_index()
+                dc.start()
+                self.debug("start_depot: started")
+                return dc
+
+class ManyDepotTestCase(CliTestCase):
+
+        def __init__(self, methodName='runTest'):
+                super(ManyDepotTestCase, self).__init__(methodName)
+                self.dcs = {}
+
+        def setUp(self, publishers, debug_features=EmptyI):
+                CliTestCase.setUp(self)
+
+                self.debug("setup: %s" % self.id())
+                self.debug("starting %d depot(s)" % len(publishers))
+                self.debug("publishers: %s" % publishers)
+                self.debug("debug_features: %s" % list(debug_features))
+                self.dcs = {}
+
+                for n, pub in enumerate(publishers):
+                        i = n + 1
+                        testdir = os.path.join(self.test_root)
+
+                        depotdir = os.path.join(testdir,
+                            "depot_contents%d" % i)
+
+                        for dir in (testdir, depotdir):
+                                try:
+                                        os.makedirs(dir, 0755)
+                                except OSError, e:
+                                        if e.errno != errno.EEXIST:
+                                                raise e
+
+                        # We pick an arbitrary base port.  This could be more
+                        # automated in the future.
+                        depot_logfile = os.path.join(testdir,
+                            "depot_logfile%d" % i)
+
+                        props = { "publisher": { "prefix": pub } }
+                        self.dcs[i] = self.start_depot(12000 + i,
+                            depotdir, depot_logfile,
+                            debug_features=debug_features,
+                            properties=props)
+
+        def check_traceback(self, logpath):
+                """ Scan logpath looking for tracebacks.
+                    Raise a DepotTracebackException if one is seen.
+                """
+                self.debug("check for depot tracebacks in %s" % logpath)
+                logfile = open(logpath, "r")
+                output = logfile.read()
+                for line in output.splitlines():
+                        if line.find("Traceback") > -1:
+                                raise DepotTracebackException(logpath, output)
+
+        def restart_depots(self):
+                self.debug("restarting %d depot(s)" % len(self.dcs))
+                for i in sorted(self.dcs.keys()):
+                        dc = self.dcs[i]
+                        self.debug("stopping depot at url: %s" % dc.get_depot_url())
+                        dc.stop()
+                        self.debug("starting depot at url: %s" % dc.get_depot_url())
+                        dc.start()
+
+        def killall_sighandler(self, signum, frame):
+                print >> sys.stderr, \
+                    "Ctrl-C: I'm killing depots, please wait.\n"
+                print self
+                self.signalled = True
+
+        def killalldepots(self):
+                self.signalled = False
+                self.debug("killalldepots: %s" % self.id())
+
+                oldhdlr = signal.signal(signal.SIGINT, self.killall_sighandler)
+
+                try:
+                        for i in sorted(self.dcs.keys()):
+                                dc = self.dcs[i]
+                                dir = dc.get_repodir()
+                                self.debug("stopping depot at url: %s, %s" % \
+                                    (dc.get_depot_url(), dir))
+
+                                status = 0
+                                try:
+                                        status = dc.kill()
+                                except Exception:
+                                        pass
+
+                                if status:
+                                        self.debug("depot: %s" % status)
+                                
+                        for i in sorted(self.dcs.keys()):
+                                dc = self.dcs[i]
+                                try:
+                                        self.check_traceback(dc.get_logpath())
+                                except Exception:
+                                        pass
+                finally:
+                        signal.signal(signal.SIGINT, oldhdlr)
+
+                self.dcs = {}
+                if self.signalled:
+                        raise KeyboardInterrupt("Ctrl-C while killing depots.")
+
+        def tearDown(self):
+                self.debug("ManyDepotTestCase.tearDown: %s" % self.id())
+
+                self.killalldepots()
+                CliTestCase.tearDown(self)
+
+        def run(self, result=None):
+                if result is None:
+                        result = self.defaultTestResult()
+                CliTestCase.run(self, result)
+
+
+class SingleDepotTestCase(ManyDepotTestCase):
+
+        def setUp(self, debug_features=EmptyI, publisher="test"):
+                ManyDepotTestCase.setUp(self, [publisher],
+                    debug_features=debug_features)
+
+        def __get_dc(self):
+                if self.dcs:
+                        return self.dcs[1]
+                else:
+                        return None
+
+        # dc is a readonly property which is an alias for self.dcs[1],
+        # for convenience of writing test cases.
+        dc = property(fget=__get_dc)
+
+
+class SingleDepotTestCaseCorruptImage(SingleDepotTestCase):
+        """ A class which allows manipulation of the image directory that
+        SingleDepotTestCase creates. Specifically, it supports removing one
+        or more of the files or subdirectories inside an image (publisher,
+        cfg_cache, etc...) in a controlled way.
+
+        To add a new directory or file to be corrupted, it will be necessary
+        to update corrupt_image_create to recognize a new option in config
+        and perform the appropriate action (removing the directory or file
+        for example).
+        """
+
+        def setUp(self, debug_features=EmptyI, publisher="test"):
+                self.backup_img_path = None
+                SingleDepotTestCase.setUp(self, debug_features=debug_features,
+                    publisher=publisher)
+
+        def tearDown(self):
+                self.__uncorrupt_img_path()
+                SingleDepotTestCase.tearDown(self)
+
+        def __uncorrupt_img_path(self):
+                """ Function which restores the img_path back to the original
+                level. """
+                if self.backup_img_path:
+                        self.img_path = self.backup_img_path
+
+        def corrupt_image_create(self, repourl, config, subdirs, prefix = "test",
+            destroy = True):
+                """ Creates two levels of directories under the original image
+                directory. In the first level (called bad), it builds a "corrupt
+                image" which means it builds subdirectories the subdirectories
+                speicified by subdirs (essentially determining whether a user
+                image or a full image will be built). It populates these
+                subdirectories with a partial image directory stucture as
+                speicified by config. As another subdirectory of bad, it
+                creates a subdirectory called final which represents the
+                directory the command was actually run from (which is why
+                img_path is set to that location). Exisintg image destruction
+                was made optional to allow testing of two images installed next
+                to each other (a user and full image created in the same
+                directory for example). """
+                if not self.backup_img_path:
+                        self.backup_img_path = self.img_path
+                self.img_path = os.path.join(self.img_path, "bad")
+                assert self.img_path
+                assert self.img_path and self.img_path != "/"
+
+                if destroy:
+                        self.image_destroy()
+
+                for s in subdirs:
+                        if s == "var/pkg":
+                                cmdline = "pkg image-create -F -p %s=%s %s" % \
+                                    (prefix, repourl, self.img_path)
+                        elif s == ".org.opensolaris,pkg":
+                                cmdline = "pkg image-create -U -p %s=%s %s" % \
+                                    (prefix, repourl, self.img_path)
+                        else:
+                                raise RuntimeError("Got unknown subdir option:"
+                                    "%s\n" % s)
+
+                        self.debugcmd(cmdline)
+
+                        # Run the command to actually create a good image
+                        p = subprocess.Popen(cmdline, shell = True,
+                                             stdout = subprocess.PIPE,
+                                             stderr = subprocess.STDOUT)
+                        output = p.stdout.read()
+                        retcode = p.wait()
+                        self.debugresult(retcode, 0, output)
+
+                        if retcode == 99:
+                                raise TracebackException(cmdline, output)
+                        if retcode != 0:
+                                raise UnexpectedExitCodeException(cmdline, 0,
+                                    retcode, output)
+
+                        tmpDir = os.path.join(self.img_path, s)
+
+                        # This is where the actual corruption of the
+                        # image takes place. A normal image was created
+                        # above and this goes in and removes critical
+                        # directories and files.
+                        if "publisher_absent" in config or \
+                           "publisher_empty" in config:
+                                shutil.rmtree(os.path.join(tmpDir, "publisher"))
+                        if "known_absent" in config or \
+                           "known_empty" in config:
+                                shutil.rmtree(os.path.join(tmpDir, "state",
+                                    "known"))
+                        if "known_empty" in config:
+                                os.mkdir(os.path.join(tmpDir, "state", "known"))
+                        if "publisher_empty" in config:
+                                os.mkdir(os.path.join(tmpDir, "publisher"))
+                        if "cfg_cache_absent" in config:
+                                os.remove(os.path.join(tmpDir, "cfg_cache"))
+                        if "file_absent" in config:
+                                shutil.rmtree(os.path.join(tmpDir, "file"))
+                        if "pkg_absent" in config:
+                                shutil.rmtree(os.path.join(tmpDir, "pkg"))
+                        if "index_absent" in config:
+                                shutil.rmtree(os.path.join(tmpDir, "index"))
+
+                # Make find root start at final. (See the doc string for
+                # more explanation.)
+                cmd_path = os.path.join(self.img_path, "final")
+
+                os.mkdir(cmd_path)
+                return cmd_path
+
+def eval_assert_raises(ex_type, eval_ex_func, func, *args):
+        try:
+                func(*args)
+        except ex_type, e:
+                print str(e)
+                if not eval_ex_func(e):
+                        raise
+        else:
+                raise RuntimeError("Function did not raise exception.")
--- a/src/tests/run.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/tests/run.py	Sat Jan 30 01:07:14 2010 -0800
@@ -1,4 +1,4 @@
-#!/usr/bin/python2.6
+#!/usr/bin/python2.6 -u
 #
 # CDDL HEADER START
 #
@@ -20,23 +20,37 @@
 # CDDL HEADER END
 #
 
-# Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 
 import os
 import sys
-# We need to execute this from the tests directory
-if os.path.basename(os.getcwd()) != "tests":
+
+# We need cwd to be the same dir as our program.
+if os.path.dirname(__file__) != "" and \
+    os.path.dirname(__file__) != ".":
         os.putenv('PYEXE', sys.executable)
-        os.chdir(os.path.join(os.getcwd(), "tests"))
+        os.chdir(os.path.dirname(__file__))
         import subprocess
         cmd = [sys.executable, "run.py"]
         cmd.extend(sys.argv[1:]) # Skip argv[0]
         sys.exit(subprocess.call(cmd))
 
+#
+# Some modules we use are located in our own proto area.  So before doing
+# any more imports, setup the environment we need.
+#
+
+# Make sure current directory is in the path
+sys.path.insert(0, ".")
+
+import pkg5testenv
+if __name__ == "__main__":
+        pkg5testenv.setup_environment("../../proto")
+
 import baseline
+import fcntl
 import getopt
-import pkg5unittest
 import platform
 import re
 import shutil
@@ -44,15 +58,11 @@
 import tempfile
 import types
 import unittest
-import coverage
-
-# Make sure current directory is in the path
-sys.path.insert(0, ".")
+import warnings
 
-import cli.testutils
-
-if __name__ == "__main__":
-        cli.testutils.setup_environment("../../proto")
+import pkg5unittest
+from pkg5unittest import OUTPUT_DOTS, OUTPUT_VERBOSE, OUTPUT_PARSEABLE
+import coverage
 
 osname = platform.uname()[0].lower()
 arch = 'unknown' 
@@ -71,7 +81,8 @@
 if ostype == '':
         ostype = 'unknown'
 
-def find_tests(testdir, testpats, startatpat=False):
+
+def find_tests(testdir, testpats, startatpat=False, output=OUTPUT_DOTS):
         # Test pattern to match against
         pats = [ re.compile("%s" % pat, re.IGNORECASE) for pat in testpats ]
         startatpat = re.compile("%s" % startattest, re.IGNORECASE)
@@ -88,25 +99,42 @@
                         return True
                 return False
 
+        def _vprint(*text):
+                if output == OUTPUT_VERBOSE or output == OUTPUT_PARSEABLE:
+                        print ' '.join([str(l) for l in text]),
+
         loader = unittest.TestLoader()
         suite = unittest.TestSuite()
         testclasses = []
         # "testdir" will be "api", "cli", etc., so find all the files in that 
         # directory that match the pattern "t_*.py".
-        for f in os.listdir(testdir):
+        _vprint("# Loading %s tests:\n" % testdir)
+        curlinepos = 0
+        for f in sorted(os.listdir(testdir)):
+                if curlinepos == 0:
+                        _vprint("#        ")
+                        curlinepos += 9
+
                 if not (f.startswith("t_") and f.endswith(".py")):
                         continue
                 name = os.path.join(testdir, f)
                 name = name.replace(".py", "")
                 name = '.'.join(name.split(os.path.sep))
+                # "api.t_filter" -> ["api", "t_filter"]
+                suitename, filename = name.split(".")
+
                 try:
                         obj = __import__(name)
                 except ImportError, e:
-                        print "Skipping %s: %s" % (name, e.__str__())
+                        print "Skipping %s: %s" % (name, str(e))
                         continue
-                print "Loading tests from: %s" % name
-                # "api.t_filter" -> ["api", "t_filter"]
-                suitename, filename = name.split(".")
+
+                if curlinepos != 0 and (curlinepos + len(filename) + 1) >= 78:
+                        _vprint("\n#        ")
+                        curlinepos = 9
+                _vprint("%s" % filename,)
+                curlinepos += len(filename) + 1
+
                 # file object (t_filter, etc)
                 fileobj = getattr(obj, filename)
                 # Get all the classes from the file
@@ -116,6 +144,10 @@
                         # Make sure it's a test case
                         if not _istest(classobj):
                                 continue
+
+                        # We tack this in for pretty-printing.
+                        classobj._Pkg5TestCase__suite_name = suitename
+
                         for attrname in dir(classobj):
                                 methobj = getattr(classobj, attrname)
                                 # Make sure its a test method
@@ -135,6 +167,7 @@
                                 if not found:
                                         delattr(classobj, attrname)
                         testclasses.append(classobj)
+        _vprint("\n#\n")
                         
         for cobj in testclasses:
                 suite.addTest(unittest.makeSuite(cobj, 'test',
@@ -147,22 +180,36 @@
                 % sys.argv[0]
         print >> sys.stderr, "       %s [-chptvx] [-b filename] [-s regexp] "\
                 "[-o regexp]" % sys.argv[0]
-        print >> sys.stderr, "   -c             Collect code coverage data"
-        print >> sys.stderr, "   -g             Generate result baseline"
-        print >> sys.stderr, "   -h             This help message"
-        print >> sys.stderr, "   -p             Parseable output format"
-        print >> sys.stderr, "   -t             Generate timing info file"
-        print >> sys.stderr, "   -v             Verbose output"
-        print >> sys.stderr, "   -x             Stop after the first failure"
-        print >> sys.stderr, "   -b <filename>  Baseline filename"
-        print >> sys.stderr, "   -o <regexp>    Run only tests that match regexp"
-        print >> sys.stderr, "   -s <regexp>    Run tests starting at regexp"
-        print >> sys.stderr, ""
-        sys.exit(1)
+        print >> sys.stderr, \
+"""   -a <dir>       Archive failed test cases to <dir>/$pid/$testcasename
+   -c             Collect code coverage data
+   -d             Show debug output, including commands run, and outputs
+   -f             Show fail/error information even when test is expected to fail
+   -g             Generate result baseline
+   -h             This help message
+   -p             Parseable output format
+   -t             Generate timing info file
+   -v             Verbose output
+   -x             Stop after the first baseline mismatch
+   -b <filename>  Baseline filename
+   -o <regexp>    Run only tests that match regexp
+   -s <regexp>    Run tests starting at regexp
+"""
+        sys.exit(2)
 
 if __name__ == "__main__":
+        # Make all warnings be errors.
+        warnings.simplefilter('error')
+
         try:
-                opts, pargs = getopt.getopt(sys.argv[1:], "cghptvxb:o:s:",
+
+                #
+                # !!! WARNING !!!
+                #
+                # If you add options here, you need to also update setup.py's
+                # test_func to include said options.
+                #
+                opts, pargs = getopt.getopt(sys.argv[1:], "a:cdfghptvxb:o:s:",
                     ["generate-baseline", "parseable", "timing", "verbose",
                     "baseline-file", "only"])
         except getopt.GetoptError, e:
@@ -172,18 +219,26 @@
         bfile = os.path.join(os.getcwd(), "baseline.txt")
         generate = False
         onlyval = []
-        output = pkg5unittest.OUTPUT_DOTS
+        output = OUTPUT_DOTS
         bailonfail = False
         startattest = ""
         timing_file = False
         do_coverage = False
+        debug_output = False
+        show_on_expected_fail = False
+        archive_dir = None
+
         for opt, arg in opts:
                 if opt == "-v":
-                        output = pkg5unittest.OUTPUT_VERBOSE
+                        output = OUTPUT_VERBOSE
                 if opt == "-p":
-                        output = pkg5unittest.OUTPUT_PARSEABLE
+                        output = OUTPUT_PARSEABLE
                 if opt == "-c":
                         do_coverage = True
+                if opt == "-d":
+                        pkg5unittest.g_debug_output = True
+                if opt == "-f":
+                        show_on_expected_fail = True
                 if opt == "-g":
                         generate = True
                 if opt == "-b":
@@ -196,6 +251,8 @@
                         timing_file = True
                 if opt == "-s":
                         startattest = arg
+                if opt == "-a":
+                        archive_dir = arg
                 if opt == "-h":
 			usage()
         if (bailonfail or startattest) and generate:
@@ -211,6 +268,12 @@
                 cov = coverage.coverage(data_file=cov_file, data_suffix=True)
                 cov.start()
 
+        # Allow relative archive dir, but first convert it to abs. paths.
+        if archive_dir is not None:
+                archive_dir = os.path.abspath(archive_dir)
+                if not os.path.exists(archive_dir):
+                        os.makedirs(archive_dir)
+
         import pkg.portable
 
         if not pkg.portable.is_admin():
@@ -226,8 +289,8 @@
                             ppriv, "-s", "A-sys_linkdir", str(os.getpid())
                         ])
 
-        api_suite = find_tests("api", onlyval, startattest)
-        cli_suite = find_tests("cli", onlyval, startattest)
+        api_suite = find_tests("api", onlyval, startattest, output)
+        cli_suite = find_tests("cli", onlyval, startattest, output)
 
         suites = []
         suites.append(api_suite)
@@ -235,13 +298,22 @@
                 suites.append(cli_suite)
                 import gui.testutils
                 if not gui.testutils.check_for_gtk():
-                        print "GTK not present, GUI tests disabled."
+                        print "# GTK not present or $DISPLAY not " \
+                            "set, GUI tests disabled."
                 elif not gui.testutils.check_if_a11y_enabled():
-                        print "Accessibility not enabled, GUI tests disabled."
+                        print "# Accessibility not enabled, GUI tests disabled."
                 else:
-                        gui_suite = find_tests("gui", onlyval, startattest)
+                        gui_suite = find_tests("gui", onlyval,
+                            startattest, output)
                         suites.append(gui_suite)
 
+        # This is primarily of interest to developers altering the test suite,
+        # so don't enable it for now.  The testsuite suite tends to emit a bunch
+        # of harmless but noisy errors to the screen due to the way it exercises
+        # various corner cases.
+        #testsuite_suite = find_tests("testsuite", onlyval, startattest, output)
+        #suites.append(testsuite_suite)
+
         # Initialize the baseline results and load them
         baseline = baseline.BaseLine(bfile, generate)
         baseline.load()
@@ -249,7 +321,7 @@
         # Make sure we capture stdout
         testlogfd, testlogpath = tempfile.mkstemp(suffix='.pkg-test.log')
         testlogfp = os.fdopen(testlogfd, "w")
-        print "logging to %s" % testlogpath
+        print "# logging to %s" % testlogpath
         sys.stdout = testlogfp
 
         if timing_file:
@@ -269,17 +341,25 @@
         
         # Run the python test suites
         runner = pkg5unittest.Pkg5TestRunner(baseline, output=output,
-            timing_file=timing_file, bailonfail=bailonfail,
-            coverage=(cov_cmd, cov_env))
+            timing_file=timing_file,
+            bailonfail=bailonfail,
+            coverage=(cov_cmd, cov_env),
+            show_on_expected_fail=show_on_expected_fail,
+            archive_dir=archive_dir)
         exitval = 0
         for x in suites:
                 try:
-                    res = runner.run(x)
+                        res = runner.run(x)
                 except pkg5unittest.Pkg5TestCase.failureException, e:
-                    exitval = 1
-                    print >> sys.stderr, e
-                    break
-                if res.failures:
+                        exitval = 1
+                        print >> sys.stderr
+                        print >> sys.stderr, e
+                        break
+                except pkg5unittest.TestStopException, e:
+                        exitval = 1
+                        print >> sys.stderr
+                        break
+                if res.mismatches:
                         exitval = 1
 
         testlogfp.close()
@@ -299,7 +379,7 @@
                 os.rename("%s/pkg5" % covdir, ".coverage")
                 shutil.rmtree(covdir)
                 print >> sys.stderr, "Generating html coverage report"
-                vp = cli.testutils.g_proto_area + "/usr/lib/python2.6/vendor-packages"
+                vp = pkg5unittest.g_proto_area + "/usr/lib/python2.6/vendor-packages"
                 omits = [
                     # External modules
                     "%s/cherrypy" % vp,
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/testsuite/__init__.py	Sat Jan 30 01:07:14 2010 -0800
@@ -0,0 +1,25 @@
+#!/usr/bin/python
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/testsuite/t_setup_teardown.py	Sat Jan 30 01:07:14 2010 -0800
@@ -0,0 +1,132 @@
+#!/usr/bin/python
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
+import os
+import unittest
+
+from pkg import misc
+
+class TestAllFine(pkg5unittest.SingleDepotTestCase):
+        
+        def setUp(self):
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+
+        def tearDown(self):
+                pkg5unittest.SingleDepotTestCase.tearDown(self)
+
+        def test_shouldpass1(self):
+                pass
+
+        def test_shouldpass2(self):
+                pass
+
+class TestSetupFailing(pkg5unittest.SingleDepotTestCase):
+        
+        def setUp(self):
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                raise RuntimeError("setup failing")
+
+        def test_shoulderror1(self):
+                pass
+
+        def test_shoulderror2(self):
+                pass
+
+class TestSetupFailingEarly(pkg5unittest.SingleDepotTestCase):
+        
+        def setUp(self):
+                raise RuntimeError("setup failing")
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+
+        def test_shoulderror1(self):
+                pass
+
+class TestSetupFailingP(pkg5unittest.SingleDepotTestCase):
+        persistent_setup = True
+        
+        def setUp(self):
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                raise RuntimeError("setup failing")
+
+        def test_shoulderror1(self):
+                pass
+
+        def test_shoulderror2(self):
+                pass
+
+class TestSetupFailingEarlyP(pkg5unittest.SingleDepotTestCase):
+        persistent_setup = True
+        
+        def setUp(self):
+                raise RuntimeError("setup failing")
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+
+        def test_shoulderror1(self):
+                pass
+
+class TestTeardownFailing(pkg5unittest.SingleDepotTestCase):
+        def setUp(self):
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+
+        def tearDown(self):
+                raise RuntimeError("tearDown failing")
+
+        def test_shoulderror1(self):
+                pass
+
+        def test_shoulderror2(self):
+                pass
+
+class TestTeardownFailingP(pkg5unittest.SingleDepotTestCase):
+        persistent_setup = True
+
+        def setUp(self):
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+
+        def tearDown(self):
+                raise RuntimeError("tearDown failing")
+
+        def test_shouldpass1(self):
+                pass
+
+        def test_shouldpass2(self):
+                pass
+
+class TestMisc(pkg5unittest.CliTestCase):
+        def doassign(self):
+                self.test_root = "foo"
+
+        def test_testroot_readonly(self):
+                """ Test that test_root is readable but not writable """
+                x = self.test_root
+                self.assertRaises(AttributeError, self.doassign)
+
+if __name__ == "__main__":
+        unittest.main()
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/testsuite/testutils.py	Sat Jan 30 01:07:14 2010 -0800
@@ -0,0 +1,36 @@
+#!/usr/bin/python
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at usr/src/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+
+import os
+import sys
+
+# Set the path so that modules can be found
+path_to_parent = os.path.join(os.path.dirname(__file__), "..")
+sys.path.insert(0, path_to_parent)
+
+import pkg5testenv
+
+def setup_environment(proto):
+        pkg5testenv.setup_environment(proto)
--- a/src/util/publish/merge.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/util/publish/merge.py	Sat Jan 30 01:07:14 2010 -0800
@@ -19,7 +19,7 @@
 #
 # CDDL HEADER END
 #
-# Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
+# Copyright 2010 Sun Microsystems, Inc.  All rights reserved.
 # Use is subject to license terms.
 #
 
@@ -31,6 +31,7 @@
 import tempfile
 import gettext
 import shutil
+import warnings
 
 import pkg.fmri
 import pkg.pkgtarfile as ptf
@@ -464,6 +465,10 @@
 
 
 if __name__ == "__main__":
+
+        # Make all warnings be errors.
+        warnings.simplefilter('error')
+
         try:
                 ret = main_func()
         except SystemExit, e:
--- a/src/util/publish/pkgmogrify.py	Fri Jan 29 13:24:14 2010 -0800
+++ b/src/util/publish/pkgmogrify.py	Sat Jan 30 01:07:14 2010 -0800
@@ -29,10 +29,11 @@
 import re
 import shlex
 import sys
+import warnings
+
 import pkg.actions
 from pkg.misc import PipeError
 
-
 macros  = {}
 includes = []
 appends  = []
@@ -465,6 +466,10 @@
         return 0
 
 if __name__ == "__main__":
+
+        # Make all warnings be errors.
+        warnings.simplefilter('error')
+
         try:
                 exit_code = main_func()        
         except (PipeError, KeyboardInterrupt):