Repository: fedora-infra/bodhi

Issue:
Comment and close bugs in same operation
It looks like Bodhi 2.0 is performing two separate Bugzilla transactions when closing bugs: first it writes the "has been pushed to the Fedora 23 stable repository. If problems still persist, please make note of it in this bug report." message, then it sends another request to close the bug. This results in two Bugzilla mails to everyone subscribed to the bug. It'd be better if it used one transaction both to post the comment and close the bug (only in the case where 'close bugs when update pushed stable' is set, of course).



Discussion:
I'm going to work on this one as my first "real" Bodhi commit, because it sounds doable and it annoys me too ☺


Resolving patch:
diff --git a/bodhi/bugs.py b/bodhi/bugs.py
--- a/bodhi/bugs.py
+++ b/bodhi/bugs.py
@@ -102,8 +102,12 @@ def on_qa(self, bug_id, comment):
         except:
             log.exception("Unable to alter bug #%d" % bug_id)
 
-    def close(self, bug_id, versions):
-        args = {}
+    def close(self, bug_id, versions, comment):
+        """
+        Close the bug given by bug_id, mark it as fixed in the given versions,
+        and add a comment.
+        """
+        args = {'comment': comment}
         try:
             bug = self.bz.getbug(bug_id)
             # If this bug is for one of these builds...
diff --git a/bodhi/models/models.py b/bodhi/models/models.py
--- a/bodhi/models/models.py
+++ b/bodhi/models/models.py
@@ -1203,11 +1203,11 @@ def modify_bugs(self):
                 log.debug('Adding testing comment to bugs for %s', self.title)
                 bug.testing(self)
         elif self.status is UpdateStatus.stable:
-            for bug in self.bugs:
-                log.debug('Adding stable comment to bugs for %s', self.title)
-                bug.add_comment(self)
-
-            if self.close_bugs:
+            if not self.close_bugs:
+                for bug in self.bugs:
+                    log.debug('Adding stable comment to bugs for %s', self.title)
+                    bug.add_comment(self)
+            else:
                 if self.type is UpdateType.security:
                     # Only close the tracking bugs
                     # https://github.com/fedora-infra/bodhi/issues/368#issuecomment-135155215
@@ -2027,7 +2027,7 @@ def close_bug(self, update):
         versions = dict([
             (get_nvr(b.nvr)[0], b.nvr) for b in update.builds
         ])
-        bugtracker.close(self.bug_id, versions=versions)
+        bugtracker.close(self.bug_id, versions=versions, comment=self.default_message(update))
 
     def modified(self, update):
         """ Change the status of this bug to MODIFIED """


Test patch:
diff --git a/bodhi/tests/models/test_models.py b/bodhi/tests/models/test_models.py
--- a/bodhi/tests/models/test_models.py
+++ b/bodhi/tests/models/test_models.py
@@ -198,6 +198,7 @@ def do_get_dependencies(self):
             )
 
     def get_update(self, name=u'TurboGears-1.0.8-3.fc11'):
+        """Return an Update instance for testing."""
         attrs = self.attrs.copy()
         attrs['title'] = name
         pkg = self.db.query(model.Package) \
@@ -216,6 +217,55 @@ def test_builds(self):
         eq_(self.obj.builds[0].release.name, u'F11')
         eq_(self.obj.builds[0].package.name, u'TurboGears')
 
+    @mock.patch('bodhi.models.models.bugtracker.close')
+    @mock.patch('bodhi.models.models.bugtracker.comment')
+    def test_modify_bugs_stable_close(self, comment, close):
+        """Test the modify_bugs() method with a stable status and with close_bugs set to True."""
+        update = self.get_update()
+        bug_1 = model.Bug(bug_id=1)
+        bug_2 = model.Bug(bug_id=2)
+        update.bugs.append(bug_1)
+        update.bugs.append(bug_2)
+        update.close_bugs = True
+        update.status = UpdateStatus.stable
+
+        update.modify_bugs()
+
+        # The comment call shouldn't have been made, since the comment should be included with the
+        # call to close().
+        eq_(comment.call_count, 0)
+        # Make sure close() was called correctly.
+        eq_([c[1][0] for c in close.mock_calls], [1, 2])
+        eq_(all(
+            ['to the Fedora 11 stable repository' in c[2]['comment'] for c in close.mock_calls]),
+            True)
+        eq_(all(
+            [c[2]['versions']['TurboGears'] == 'TurboGears-1.0.8-3.fc11'
+                for c in close.mock_calls]),
+            True)
+
+    @mock.patch('bodhi.models.models.bugtracker.close')
+    @mock.patch('bodhi.models.models.bugtracker.comment')
+    def test_modify_bugs_stable_no_close(self, comment, close):
+        """Test the modify_bugs() method with a stable status and with close_bugs set to False."""
+        update = self.get_update()
+        bug_1 = model.Bug(bug_id=1)
+        bug_2 = model.Bug(bug_id=2)
+        update.bugs.append(bug_1)
+        update.bugs.append(bug_2)
+        update.close_bugs = False
+        update.status = UpdateStatus.stable
+
+        update.modify_bugs()
+
+        # Make sure bugs number 1 and 2 were commented on correctly.
+        eq_([c[1][0] for c in comment.mock_calls], [1, 2])
+        eq_(all(
+            ['pushed to the Fedora 11 stable repository' in c[1][1] for c in comment.mock_calls]),
+            True)
+        # No bugs should have been closed
+        eq_(close.call_count, 0)
+
     def test_unpush_build(self):
         eq_(len(self.obj.builds), 1)
         b = self.obj.builds[0]