Repository: fedora-infra/bodhi

Issue:
Bodhi sends e-mails when it cannot modify private bugs
Bodhi tries to close private bugs, which it does not have permission to do. It should probably not try to do this in the first place, but more importantly it should catch the Exception that arises when it tries. Bodhi often sends error e-mails like this one:

Message
-------
[2018-06-09 20:39:48][     bodhi   ERROR]
```python
Unable to close bug #1549665
```


Process Details
---------------
- host:     bodhi-backend01.phx2.fedoraproject.org
- PID:      98853
- name:     fedmsg-hub
- command:  /usr/bin/python2 /usr/bin/fedmsg-hub
- msg_id:   

Callstack that lead to the logging statement
--------------------------------------------
```python
  File "/usr/lib64/python2.7/threading.py", line 777 in __bootstrap
    self.__bootstrap_inner()
  File "/usr/lib64/python2.7/threading.py", line 804 in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/masher.py", line 337 in run
    self.work()
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/masher.py", line 416 in work
    self.modify_bugs()
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/masher.py", line 70 in wrapper
    retval = method(self, *args, **kwargs)
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/masher.py", line 717 in modify_bugs
    update.modify_bugs()
  File "/usr/lib/python2.7/site-packages/bodhi/server/models.py", line 2735 in modify_bugs
    bug.close_bug(self)
  File "/usr/lib/python2.7/site-packages/bodhi/server/models.py", line 4155 in close_bug
    bugs.bugtracker.close(self.bug_id, versions=versions, comment=self.default_message(update))
  File "/usr/lib/python2.7/site-packages/bodhi/server/bugs.py", line 222 in close
    log.exception("Unable to close bug #%d" % bug_id)
```
```
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/bodhi/server/bugs.py", line 199, in close
    bug = self.bz.getbug(bug_id)
  File "/usr/lib/python2.7/site-packages/bugzilla/base.py", line 1024, in getbug
    extra_fields=extra_fields)
  File "/usr/lib/python2.7/site-packages/bugzilla/base.py", line 1016, in _getbug
    return self._getbugs([objid], permissive=False, **kwargs)[0]
  File "/usr/lib/python2.7/site-packages/bugzilla/base.py", line 984, in _getbugs
    r = self._proxy.Bug.get(getbugdata)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 1243, in __call__
    return self.__send(self.__name, args)
  File "/usr/lib/python2.7/site-packages/bugzilla/transport.py", line 100, in _ServerProxy__request
    ret = ServerProxy._ServerProxy__request(self, methodname, params)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 1602, in __request
    verbose=self.__verbose
  File "/usr/lib/python2.7/site-packages/bugzilla/transport.py", line 195, in request
    return self._request_helper(url, request_body)
  File "/usr/lib/python2.7/site-packages/bugzilla/transport.py", line 181, in _request_helper
    raise sys.exc_info()[1]
Fault: <Fault 102: 'You are not authorized to access bug #1549665. Most likely the bug has been restricted for internal development processes and we cannot grant access. If you are a Red Hat customer with an active subscription, please visit the Red Hat Customer Portal for assistance with your issue If you are a Fedora Project user and require assistance, please consider using one of the mailing lists we host for the Fedora Project.'>
```
Bodhi sends e-mails when it cannot modify private bugs
Bodhi tries to close private bugs, which it does not have permission to do. It should probably not try to do this in the first place, but more importantly it should catch the Exception that arises when it tries. Bodhi often sends error e-mails like this one:

Message
-------
[2018-06-09 20:39:48][     bodhi   ERROR]
```python
Unable to close bug #1549665
```


Process Details
---------------
- host:     bodhi-backend01.phx2.fedoraproject.org
- PID:      98853
- name:     fedmsg-hub
- command:  /usr/bin/python2 /usr/bin/fedmsg-hub
- msg_id:   

Callstack that lead to the logging statement
--------------------------------------------
```python
  File "/usr/lib64/python2.7/threading.py", line 777 in __bootstrap
    self.__bootstrap_inner()
  File "/usr/lib64/python2.7/threading.py", line 804 in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/masher.py", line 337 in run
    self.work()
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/masher.py", line 416 in work
    self.modify_bugs()
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/masher.py", line 70 in wrapper
    retval = method(self, *args, **kwargs)
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/masher.py", line 717 in modify_bugs
    update.modify_bugs()
  File "/usr/lib/python2.7/site-packages/bodhi/server/models.py", line 2735 in modify_bugs
    bug.close_bug(self)
  File "/usr/lib/python2.7/site-packages/bodhi/server/models.py", line 4155 in close_bug
    bugs.bugtracker.close(self.bug_id, versions=versions, comment=self.default_message(update))
  File "/usr/lib/python2.7/site-packages/bodhi/server/bugs.py", line 222 in close
    log.exception("Unable to close bug #%d" % bug_id)
```
```
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/bodhi/server/bugs.py", line 199, in close
    bug = self.bz.getbug(bug_id)
  File "/usr/lib/python2.7/site-packages/bugzilla/base.py", line 1024, in getbug
    extra_fields=extra_fields)
  File "/usr/lib/python2.7/site-packages/bugzilla/base.py", line 1016, in _getbug
    return self._getbugs([objid], permissive=False, **kwargs)[0]
  File "/usr/lib/python2.7/site-packages/bugzilla/base.py", line 984, in _getbugs
    r = self._proxy.Bug.get(getbugdata)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 1243, in __call__
    return self.__send(self.__name, args)
  File "/usr/lib/python2.7/site-packages/bugzilla/transport.py", line 100, in _ServerProxy__request
    ret = ServerProxy._ServerProxy__request(self, methodname, params)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 1602, in __request
    verbose=self.__verbose
  File "/usr/lib/python2.7/site-packages/bugzilla/transport.py", line 195, in request
    return self._request_helper(url, request_body)
  File "/usr/lib/python2.7/site-packages/bugzilla/transport.py", line 181, in _request_helper
    raise sys.exc_info()[1]
Fault: <Fault 102: 'You are not authorized to access bug #1549665. Most likely the bug has been restricted for internal development processes and we cannot grant access. If you are a Red Hat customer with an active subscription, please visit the Red Hat Customer Portal for assistance with your issue If you are a Fedora Project user and require assistance, please consider using one of the mailing lists we host for the Fedora Project.'>
```


Discussion:
A fix for this issue is planned to be included in the upcoming 3.9.0 release: #2477.
The patch for this issue was deployed to Fedora's production Bodhi instance yesterday.
This still occurs in other methods in ```bugs.py```. This email came in today:

Message
-------
[2018-09-13 17:51:46][     bodhi   ERROR]
```python
Unable to alter bug #1627832
```


Process Details
---------------
- host:     bodhi-backend01.phx2.fedoraproject.org
- PID:      31707
- name:     fedmsg-hub
- command:  /usr/bin/python2 /usr/bin/fedmsg-hub
- msg_id:   

Callstack that lead to the logging statement
--------------------------------------------
```python
  File "/usr/lib64/python2.7/threading.py", line 777 in __bootstrap
    self.__bootstrap_inner()
  File "/usr/lib64/python2.7/threading.py", line 804 in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/masher.py", line 338 in run
    self.work()
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/masher.py", line 417 in work
    self.modify_bugs()
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/masher.py", line 71 in wrapper
    retval = method(self, *args, **kwargs)
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/masher.py", line 724 in modify_bugs
    update.modify_bugs()
  File "/usr/lib/python2.7/site-packages/bodhi/server/models.py", line 2742 in modify_bugs
    bug.testing(self)
  File "/usr/lib/python2.7/site-packages/bodhi/server/models.py", line 4168 in testing
    bugs.bugtracker.on_qa(self.bug_id, comment)
  File "/usr/lib/python2.7/site-packages/bodhi/server/bugs.py", line 191 in on_qa
    log.exception("Unable to alter bug #%d" % bug_id)
```
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/bodhi/server/bugs.py", line 181, in on_qa
    bug = self.bz.getbug(bug_id)
  File "/usr/lib/python2.7/site-packages/bugzilla/base.py", line 1024, in getbug
    extra_fields=extra_fields)
  File "/usr/lib/python2.7/site-packages/bugzilla/base.py", line 1016, in _getbug
    return self._getbugs([objid], permissive=False, **kwargs)[0]
  File "/usr/lib/python2.7/site-packages/bugzilla/base.py", line 984, in _getbugs
    r = self._proxy.Bug.get(getbugdata)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 1243, in __call__
    return self.__send(self.__name, args)
  File "/usr/lib/python2.7/site-packages/bugzilla/transport.py", line 100, in _ServerProxy__request
    ret = ServerProxy._ServerProxy__request(self, methodname, params)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 1602, in __request
    verbose=self.__verbose
  File "/usr/lib/python2.7/site-packages/bugzilla/transport.py", line 195, in request
    return self._request_helper(url, request_body)
  File "/usr/lib/python2.7/site-packages/bugzilla/transport.py", line 181, in _request_helper
    raise sys.exc_info()[1]
Fault: <Fault 102: 'You are not authorized to access bug #1627832. Most likely the bug has been restricted for internal development processes and we cannot grant access. If you are a Red Hat customer with an active subscription, please visit the Red Hat Customer Portal for assistance with your issue If you are a Fedora Project user and require assistance, please consider using one of the mailing lists we host for the Fedora Project.'>
A fix for this issue is planned to be included in the upcoming 3.9.0 release: #2477.
The patch for this issue was deployed to Fedora's production Bodhi instance yesterday.
This still occurs in other methods in ```bugs.py```. This email came in today:

Message
-------
[2018-09-13 17:51:46][     bodhi   ERROR]
```python
Unable to alter bug #1627832
```


Process Details
---------------
- host:     bodhi-backend01.phx2.fedoraproject.org
- PID:      31707
- name:     fedmsg-hub
- command:  /usr/bin/python2 /usr/bin/fedmsg-hub
- msg_id:   

Callstack that lead to the logging statement
--------------------------------------------
```python
  File "/usr/lib64/python2.7/threading.py", line 777 in __bootstrap
    self.__bootstrap_inner()
  File "/usr/lib64/python2.7/threading.py", line 804 in __bootstrap_inner
    self.run()
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/masher.py", line 338 in run
    self.work()
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/masher.py", line 417 in work
    self.modify_bugs()
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/masher.py", line 71 in wrapper
    retval = method(self, *args, **kwargs)
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/masher.py", line 724 in modify_bugs
    update.modify_bugs()
  File "/usr/lib/python2.7/site-packages/bodhi/server/models.py", line 2742 in modify_bugs
    bug.testing(self)
  File "/usr/lib/python2.7/site-packages/bodhi/server/models.py", line 4168 in testing
    bugs.bugtracker.on_qa(self.bug_id, comment)
  File "/usr/lib/python2.7/site-packages/bodhi/server/bugs.py", line 191 in on_qa
    log.exception("Unable to alter bug #%d" % bug_id)
```
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/bodhi/server/bugs.py", line 181, in on_qa
    bug = self.bz.getbug(bug_id)
  File "/usr/lib/python2.7/site-packages/bugzilla/base.py", line 1024, in getbug
    extra_fields=extra_fields)
  File "/usr/lib/python2.7/site-packages/bugzilla/base.py", line 1016, in _getbug
    return self._getbugs([objid], permissive=False, **kwargs)[0]
  File "/usr/lib/python2.7/site-packages/bugzilla/base.py", line 984, in _getbugs
    r = self._proxy.Bug.get(getbugdata)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 1243, in __call__
    return self.__send(self.__name, args)
  File "/usr/lib/python2.7/site-packages/bugzilla/transport.py", line 100, in _ServerProxy__request
    ret = ServerProxy._ServerProxy__request(self, methodname, params)
  File "/usr/lib64/python2.7/xmlrpclib.py", line 1602, in __request
    verbose=self.__verbose
  File "/usr/lib/python2.7/site-packages/bugzilla/transport.py", line 195, in request
    return self._request_helper(url, request_body)
  File "/usr/lib/python2.7/site-packages/bugzilla/transport.py", line 181, in _request_helper
    raise sys.exc_info()[1]
Fault: <Fault 102: 'You are not authorized to access bug #1627832. Most likely the bug has been restricted for internal development processes and we cannot grant access. If you are a Red Hat customer with an active subscription, please visit the Red Hat Customer Portal for assistance with your issue If you are a Fedora Project user and require assistance, please consider using one of the mailing lists we host for the Fedora Project.'>

Resolving patch:
diff --git a/bodhi/server/bugs.py b/bodhi/server/bugs.py
--- a/bodhi/server/bugs.py
+++ b/bodhi/server/bugs.py
@@ -154,14 +154,14 @@ def comment(self, bug_id, comment):
                     break
                 except xmlrpc_client.Fault as e:
                     attempts += 1
-                    log.exception(
+                    log.info(
                         "\nA fault has occurred \nFault code: %d \nFault string: %s" %
                         (e.faultCode, e.faultString))
         except InvalidComment:
-            log.exception(
+            log.info(
                 "Comment too long for bug #%d:  %s" % (bug_id, comment))
         except Exception:
-            log.exception("Unable to add comment to bug #%d" % bug_id)
+            log.info("Unable to add comment to bug #%d" % bug_id)
 
     def on_qa(self, bug_id, comment):
         """
@@ -188,7 +188,7 @@ def on_qa(self, bug_id, comment):
             else:
                 bug.addcomment(comment)
         except Exception:
-            log.exception("Unable to alter bug #%d" % bug_id)
+            log.info("Unable to alter bug #%d" % bug_id)
 
     def close(self, bug_id, versions, comment):
         """
@@ -248,10 +248,10 @@ def update_details(self, bug, bug_entity):
                 bug = self.bz.getbug(bug_entity.bug_id)
             except xmlrpc_client.Fault:
                 bug_entity.title = 'Invalid bug number'
-                log.exception("Got fault from Bugzilla")
+                log.info("Got fault from Bugzilla")
                 return
             except Exception:
-                log.exception("Unknown exception from Bugzilla")
+                log.info("Unknown exception from Bugzilla")
                 return
         if bug.product == 'Security Response':
             bug_entity.parent = True
@@ -287,7 +287,7 @@ def modified(self, bug_id, comment):
             else:
                 bug.addcomment(comment)
         except Exception:
-            log.exception("Unable to alter bug #%d" % bug_id)
+            log.info("Unable to alter bug #%d" % bug_id)
 
 
 def set_bugtracker():


Test patch:
diff --git a/bodhi/tests/server/test_bugs.py b/bodhi/tests/server/test_bugs.py
--- a/bodhi/tests/server/test_bugs.py
+++ b/bodhi/tests/server/test_bugs.py
@@ -103,9 +103,9 @@ def test_close_fault(self, info):
 
         info.assert_called_once_with('Unable to close bug #12345')
 
-    @mock.patch('bodhi.server.bugs.log.exception')
+    @mock.patch('bodhi.server.bugs.log.info')
     @mock.patch.dict('bodhi.server.bugs.config', {'bz_products': 'aproduct'})
-    def test_close_successful(self, exception):
+    def test_close_successful(self, info):
         """Test the close() method with a success case."""
         bz = bugs.Bugzilla()
         bz._bz = mock.MagicMock()
@@ -120,11 +120,11 @@ def test_close_successful(self, exception):
             'ERRATA',
             comment='Fixed. Closing bug and adding version to fixed_in field.',
             fixedin='bodhi-3.1.0-1.fc27')
-        self.assertEqual(exception.call_count, 0)
+        self.assertEqual(info.call_count, 0)
 
-    @mock.patch('bodhi.server.bugs.log.exception')
+    @mock.patch('bodhi.server.bugs.log.info')
     @mock.patch.dict('bodhi.server.bugs.config', {'bz_products': 'aproduct'})
-    def test_close_fixedin_maxlength(self, exception):
+    def test_close_fixedin_maxlength(self, info):
         """Test the close() method when fixed_in field may go over 255 chars."""
         bz = bugs.Bugzilla()
         bz._bz = mock.MagicMock()
@@ -140,11 +140,11 @@ def test_close_fixedin_maxlength(self, exception):
         bz._bz.getbug.return_value.close.assert_called_once_with(
             'ERRATA',
             comment='Closing, but don\'t modify fixed_in field to not cross 255 chars limit.')
-        self.assertEqual(exception.call_count, 0)
+        self.assertEqual(info.call_count, 0)
 
-    @mock.patch('bodhi.server.bugs.log.exception')
+    @mock.patch('bodhi.server.bugs.log.info')
     @mock.patch.dict('bodhi.server.bugs.config', {'bz_products': 'aproduct'})
-    def test_close_pre_existing_fixedin(self, exception):
+    def test_close_pre_existing_fixedin(self, info):
         """Test the close() method at the edge of the allowed size of the fixedin field (254)."""
         bz = bugs.Bugzilla()
         bz._bz = mock.MagicMock()
@@ -163,7 +163,7 @@ def test_close_pre_existing_fixedin(self, exception):
             'ERRATA',
             comment='Fixed. Closing bug and adding version to fixed_in field.',
             fixedin=expected_fixedin)
-        self.assertEqual(exception.call_count, 0)
+        self.assertEqual(info.call_count, 0)
 
     @mock.patch('bodhi.server.bugs.log.info')
     def test_close_product_skipped(self, info):
@@ -179,8 +179,8 @@ def test_close_product_skipped(self, info):
         info.assert_called_once_with("Skipping set closed on 'not fedora!' bug #12345")
         self.assertEqual(bz._bz.getbug.return_value.setstatus.call_count, 0)
 
-    @mock.patch('bodhi.server.bugs.log.exception')
-    def test_comment_successful(self, exception):
+    @mock.patch('bodhi.server.bugs.log.info')
+    def test_comment_successful(self, info):
         """Test the comment() method with a success case."""
         bz = bugs.Bugzilla()
         bz._bz = mock.MagicMock()
@@ -190,10 +190,10 @@ def test_comment_successful(self, exception):
         bz._bz.getbug.assert_called_once_with(1411188)
         bz._bz.getbug.return_value.addcomment.assert_called_once_with('A nice message.')
         # No exceptions should have been logged
-        self.assertEqual(exception.call_count, 0)
+        self.assertEqual(info.call_count, 0)
 
-    @mock.patch('bodhi.server.bugs.log.exception')
-    def test_comment_too_long(self, exception):
+    @mock.patch('bodhi.server.bugs.log.info')
+    def test_comment_too_long(self, info):
         """Assert that the comment() method gets angry if the comment is too long."""
         bz = bugs.Bugzilla()
         bz._bz = mock.MagicMock()
@@ -204,11 +204,11 @@ def test_comment_too_long(self, exception):
 
         self.assertEqual(bz._bz.getbug.call_count, 0)
         # An exception should have been logged
-        exception.assert_called_once_with(
+        info.assert_called_once_with(
             u'Comment too long for bug #1411188:  {}'.format(long_comment))
 
-    @mock.patch('bodhi.server.bugs.log.exception')
-    def test_comment_too_many_attempts(self, exception):
+    @mock.patch('bodhi.server.bugs.log.info')
+    def test_comment_too_many_attempts(self, info):
         """Assert that only 5 attempts are made to comment before giving up."""
         bz = bugs.Bugzilla()
         bz._bz = mock.MagicMock()
@@ -225,12 +225,12 @@ def test_comment_too_many_attempts(self, exception):
                          [('A nice message.',) for i in range(5)])
         # Five exceptions should have been logged
         self.assertEqual(
-            [c[1] for c in exception.mock_calls],
+            [c[1] for c in info.mock_calls],
             [(('\nA fault has occurred \nFault code: 42 \nFault string: Someone turned the '
                'microwave on and now the WiFi is down.'),) for i in range(5)])
 
-    @mock.patch('bodhi.server.bugs.log.exception')
-    def test_comment_unexpected_exception(self, exception):
+    @mock.patch('bodhi.server.bugs.log.info')
+    def test_comment_unexpected_exception(self, info):
         """Test the comment() method with an unexpected Exception."""
         bz = bugs.Bugzilla()
         bz._bz = mock.MagicMock()
@@ -241,7 +241,7 @@ def test_comment_unexpected_exception(self, exception):
 
         bz._bz.getbug.assert_called_once_with(1411188)
         bz._bz.getbug.return_value.addcomment.assert_called_once_with('A nice message.')
-        exception.assert_called_once_with('Unable to add comment to bug #1411188')
+        info.assert_called_once_with('Unable to add comment to bug #1411188')
 
     def test_get_url(self):
         """
@@ -307,8 +307,8 @@ def test_modified_product_skipped(self, info):
         info.assert_called_once_with("Skipping set modified on 'not fedora!' bug #1411188")
         self.assertEqual(bz._bz.getbug.return_value.setstatus.call_count, 0)
 
-    @mock.patch('bodhi.server.bugs.log.exception')
-    def test_modified_exception(self, exception_log):
+    @mock.patch('bodhi.server.bugs.log.info')
+    def test_modified_exception(self, info_log):
         """Test the modified() method logs an exception if encountered"""
         bz = bugs.Bugzilla()
         bz._bz = mock.MagicMock()
@@ -317,11 +317,11 @@ def test_modified_exception(self, exception_log):
         bz.modified(1411188, 'A mean message.')
 
         bz._bz.getbug.assert_called_once_with(1411188)
-        exception_log.assert_called_once_with("Unable to alter bug #1411188")
+        info_log.assert_called_once_with("Unable to alter bug #1411188")
         self.assertEqual(bz._bz.getbug.return_value.setstatus.call_count, 0)
 
-    @mock.patch('bodhi.server.bugs.log.exception')
-    def test_update_details_exception(self, mock_exceptionlog):
+    @mock.patch('bodhi.server.bugs.log.info')
+    def test_update_details_exception(self, mock_infolog):
         """Test we log an exception if update_details raises one"""
         bz = bugs.Bugzilla()
         bz._bz = mock.MagicMock()
@@ -329,7 +329,7 @@ def test_update_details_exception(self, mock_exceptionlog):
 
         bz.update_details(0, 0)
 
-        mock_exceptionlog.assert_called_once_with('Unknown exception from Bugzilla')
+        mock_infolog.assert_called_once_with('Unknown exception from Bugzilla')
 
     def test_update_details_keywords_str(self):
         """Assert that we split the keywords into a list when they are a str."""
@@ -357,9 +357,9 @@ def test_update_details_parent_bug(self):
         self.assertIs(bug_entity.parent, True)
         self.assertEqual(bug_entity.title, 'Fedora gets you, good job guys!')
 
-    @mock.patch('bodhi.server.bugs.log.exception')
-    def test_update_details_xmlrpc_fault(self, exception):
-        """Test we log an exception if update_details raises one"""
+    @mock.patch('bodhi.server.bugs.log.info')
+    def test_update_details_xmlrpc_fault(self, info):
+        """Test we log an info if update_details raises one"""
         bz = bugs.Bugzilla()
         bz._bz = mock.MagicMock()
         bz._bz.getbug.side_effect = xmlrpc_client.Fault(42, 'You found the meaning.')
@@ -370,11 +370,11 @@ def test_update_details_xmlrpc_fault(self, exception):
 
         self.assertEqual(bug.title, 'Invalid bug number')
         bz._bz.getbug.assert_called_once_with(123)
-        exception.assert_called_once_with('Got fault from Bugzilla')
+        info.assert_called_once_with('Got fault from Bugzilla')
 
-    @mock.patch('bodhi.server.bugs.log.exception')
+    @mock.patch('bodhi.server.bugs.log.info')
     @mock.patch.dict('bodhi.server.bugs.config', {'bz_products': 'aproduct'})
-    def test_on_qa_failure(self, exception):
+    def test_on_qa_failure(self, info):
         """
         Test the on_qa() method with a failure case.
         """
@@ -389,11 +389,11 @@ def test_on_qa_failure(self, exception):
         bz._bz.getbug.assert_called_once_with(1411188)
         bz._bz.getbug.return_value.setstatus.assert_called_once_with('ON_QA',
                                                                      comment='A mean message.')
-        exception.assert_called_once_with('Unable to alter bug #1411188')
+        info.assert_called_once_with('Unable to alter bug #1411188')
 
-    @mock.patch('bodhi.server.bugs.log.exception')
+    @mock.patch('bodhi.server.bugs.log.info')
     @mock.patch.dict('bodhi.server.bugs.config', {'bz_products': 'aproduct'})
-    def test_on_qa_success(self, exception):
+    def test_on_qa_success(self, info):
         """
         Test the on_qa() method with a success case.
         """
@@ -405,11 +405,11 @@ def test_on_qa_success(self, exception):
 
         bz._bz.getbug.assert_called_once_with(1411188)
         bz._bz.getbug.return_value.setstatus.assert_called_once_with('ON_QA', comment='A message.')
-        self.assertEqual(exception.call_count, 0)
+        self.assertEqual(info.call_count, 0)
 
-    @mock.patch('bodhi.server.bugs.log.exception')
+    @mock.patch('bodhi.server.bugs.log.info')
     @mock.patch.dict('bodhi.server.bugs.config', {'bz_products': 'aproduct'})
-    def test_on_qa_skipped_because_closed(self, exception):
+    def test_on_qa_skipped_because_closed(self, info):
         """
         Test the on_qa() method when the bug is already CLOSED.
         It must not change bug state, only post the comment.
@@ -424,11 +424,11 @@ def test_on_qa_skipped_because_closed(self, exception):
         bz._bz.getbug.assert_called_once_with(1411188)
         bz._bz.getbug.return_value.addcomment.assert_called_once_with('A message.')
         bz._bz.getbug.return_value.setstatus.assert_not_called()
-        self.assertEqual(exception.call_count, 0)
+        self.assertEqual(info.call_count, 0)
 
-    @mock.patch('bodhi.server.bugs.log.exception')
+    @mock.patch('bodhi.server.bugs.log.info')
     @mock.patch.dict('bodhi.server.bugs.config', {'bz_products': 'aproduct'})
-    def test_on_qa_skipped_because_verified(self, exception):
+    def test_on_qa_skipped_because_verified(self, info):
         """
         Test the on_qa() method when the bug is already VERIFIED.
         It must not change bug state, only post the comment.
@@ -443,11 +443,11 @@ def test_on_qa_skipped_because_verified(self, exception):
         bz._bz.getbug.assert_called_once_with(1411188)
         bz._bz.getbug.return_value.addcomment.assert_called_once_with('A message.')
         bz._bz.getbug.return_value.setstatus.assert_not_called()
-        self.assertEqual(exception.call_count, 0)
+        self.assertEqual(info.call_count, 0)
 
-    @mock.patch('bodhi.server.bugs.log.exception')
+    @mock.patch('bodhi.server.bugs.log.info')
     @mock.patch.dict('bodhi.server.bugs.config', {'bz_products': 'aproduct'})
-    def test_on_qa_skipped_because_already_set(self, exception):
+    def test_on_qa_skipped_because_already_set(self, info):
         """
         Test the on_qa() method when the bug is already ON_QA.
         It must not be set again ON_QA, only post the comment.
@@ -462,7 +462,7 @@ def test_on_qa_skipped_because_already_set(self, exception):
         bz._bz.getbug.assert_called_once_with(1411188)
         bz._bz.getbug.return_value.addcomment.assert_called_once_with('A message.')
         bz._bz.getbug.return_value.setstatus.assert_not_called()
-        self.assertEqual(exception.call_count, 0)
+        self.assertEqual(info.call_count, 0)
 
     @mock.patch('bodhi.server.bugs.log.info')
     def test_on_qa_product_skipped(self, info):