18477216 ImagePlan.plan_desc doesn't include all package changes s12b45
authorShawn Walker <shawn.walker@oracle.com>
Thu, 27 Mar 2014 16:49:57 -0700
changeset 3050 d3355dde03cb
parent 3049 3c35034dac27
child 3052 443449993da1
18477216 ImagePlan.plan_desc doesn't include all package changes
src/modules/client/imageplan.py
src/tests/api/t_pkg_api_revert.py
src/tests/pkg5unittest.py
--- a/src/modules/client/imageplan.py	Thu Mar 27 14:47:40 2014 -0700
+++ b/src/modules/client/imageplan.py	Thu Mar 27 16:49:57 2014 -0700
@@ -3832,11 +3832,14 @@
                 self.pd.install_actions.sort(key=addsort)
 
                 # cleanup pkg_plan objects which don't actually contain any
-                # changes
+                # changes and add any new ones to list of changes
                 for p in list(self.pd.pkg_plans):
                         if p.origin_fmri != p.destination_fmri or \
                             p.actions.removed or p.actions.changed or \
                             p.actions.added:
+                                pair = (p.origin_fmri, p.destination_fmri)
+                                if pair not in self.pd._fmri_changes:
+                                        self.pd._fmri_changes.append(pair)
                                 continue
                         self.pd.pkg_plans.remove(p)
                         fmri = p.origin_fmri
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/src/tests/api/t_pkg_api_revert.py	Thu Mar 27 16:49:57 2014 -0700
@@ -0,0 +1,87 @@
+#!/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 (c) 2014 Oracle and/or its affiliates. All rights reserved.
+#
+
+import testutils
+if __name__ == "__main__":
+        testutils.setup_environment("../../../proto")
+import pkg5unittest
+
+
+class TestPkgApiRevert(pkg5unittest.SingleDepotTestCase):
+        # Only start/stop the depot once (instead of for every test)
+        persistent_setup = True
+
+        pkgs = """
+            open [email protected],5.11-0
+            add dir mode=0755 owner=root group=bin path=etc
+            add file etc/file1 mode=0555 owner=root group=bin path=etc/file1
+            add file etc/file2 mode=0555 owner=root group=bin path=etc/file2
+            close
+            open [email protected],5.11-0
+            add dir mode=0755 owner=root group=bin path=etc
+            add file etc/file3 mode=0555 owner=root group=bin path=etc/file3
+            close
+            """
+
+        misc_files = ["etc/file1", "etc/file2", "etc/file3"]
+
+        def setUp(self):
+                pkg5unittest.SingleDepotTestCase.setUp(self)
+                self.make_misc_files(self.misc_files)
+                self.plist = self.pkgsend_bulk(self.rurl, self.pkgs)
+
+        def test_changed_packages(self):
+                """Verify that pkg revert correctly marks changed packages."""
+
+                api_inst = self.image_create(self.rurl)
+
+                # try reverting non-editable files
+                self._api_install(api_inst, ["[email protected]", "[email protected]"])
+
+                # remove a files from pkg A only
+                self.file_remove("etc/file2")
+
+                # make sure we broke only pkg A
+                self.pkg("verify A", exit=1)
+                self.pkg("verify B")
+
+                # now see if revert when files in both packages are named only
+                # marks pkg A as changed
+                self._api_revert(api_inst, ["/etc/file2"], noexecute=True)
+                plan = api_inst.describe()
+                pfmri = self.plist[0]
+                self.assertEqualDiff([(pfmri, pfmri)], [
+                    (str(entry[0]), str(entry[1]))
+                    for entry in plan.plan_desc
+                ])
+
+                # actually execute it, then check verify passes
+                self._api_revert(api_inst, ["/etc/file2", "/etc/file3"])
+                self.pkg("verify")
+
+
+if __name__ == "__main__":
+        unittest.main()
--- a/src/tests/pkg5unittest.py	Thu Mar 27 14:47:40 2014 -0700
+++ b/src/tests/pkg5unittest.py	Thu Mar 27 16:49:57 2014 -0700
@@ -3220,6 +3220,15 @@
 
                 self._api_finish(api_obj, catch_wsie=catch_wsie)
 
+        def _api_revert(self, api_obj, args, catch_wsie=True, noexecute=False,
+            **kwargs):
+                self.debug("revert %s" % " ".join(args))
+                for pd in api_obj.gen_plan_revert(args, **kwargs):
+                        continue
+                if noexecute:
+                        return
+                self._api_finish(api_obj, catch_wsie=catch_wsie)
+
         def _api_uninstall(self, api_obj, pkg_list, catch_wsie=True, **kwargs):
                 self.debug("uninstall %s" % " ".join(pkg_list))
                 for pd in api_obj.gen_plan_uninstall(pkg_list, **kwargs):