Repository: fedora-infra/bodhi

Issue:
If wiki is down, bodhi loops on updating bugs
The wiki was down for a few hours today as we upgraded it. 

During that time, someone filed a new update. 
Bodhi then looped adding comments about the update... this seems to be due to it not being able to talk to the wiki. 

See: 
https://pagure.io/fedora-infrastructure/issue/7953
and
https://bugzilla.redhat.com/show_bug.cgi?id=1722190 (908 comments)



Discussion:

Resolving patch:
diff --git a/bodhi/server/consumers/updates.py b/bodhi/server/consumers/updates.py
--- a/bodhi/server/consumers/updates.py
+++ b/bodhi/server/consumers/updates.py
@@ -134,7 +134,10 @@ def fetch_test_cases(self, session, update):
                 cases for their associated Packages..
         """
         for build in update.builds:
-            build.package.fetch_test_cases(session)
+            try:
+                build.package.fetch_test_cases(session)
+            except BodhiException:
+                log.warning('Error occurred during fetching testcases', exc_info=True)
 
     def work_on_bugs(self, session, update, bugs):
         """
diff --git a/bodhi/server/models.py b/bodhi/server/models.py
--- a/bodhi/server/models.py
+++ b/bodhi/server/models.py
@@ -27,6 +27,7 @@
 import time
 import typing
 import uuid
+from urllib.error import URLError
 
 from simplemediawiki import MediaWiki
 from sqlalchemy import (and_, Boolean, Column, DateTime, event, ForeignKey,
@@ -1089,6 +1090,8 @@ def fetch_test_cases(self, db):
 
         Args:
             db (sqlalchemy.orm.session.Session): A database session.
+        Raises:
+            BodhiException: When retrieving testcases from Wiki failed.
         """
         if not config.get('query_wiki_test_cases'):
             return
@@ -1103,7 +1106,10 @@ def list_categorymembers(wiki, cat_page, limit=500):
             # Build query arguments and call wiki
             query = dict(action='query', list='categorymembers',
                          cmtitle=cat_page, cmlimit=limit)
-            response = wiki.call(query)
+            try:
+                response = wiki.call(query)
+            except URLError:
+                raise BodhiException('Failed retrieving testcases from Wiki')
             members = [entry['title'] for entry in
                        response.get('query', {}).get('categorymembers', {})
                        if 'title' in entry]


Test patch:
diff --git a/bodhi/tests/server/consumers/test_updates.py b/bodhi/tests/server/consumers/test_updates.py
--- a/bodhi/tests/server/consumers/test_updates.py
+++ b/bodhi/tests/server/consumers/test_updates.py
@@ -20,6 +20,7 @@
 from unittest import mock
 import copy
 import unittest
+from urllib.error import URLError
 
 from fedora_messaging.api import Message
 import sqlalchemy
@@ -381,3 +382,24 @@ def test_work_on_bugs_exception(self, warning):
             h.work_on_bugs(h.db_factory, update, bugs)
 
         warning.assert_called_once_with('Error occurred during updating single bug', exc_info=True)
+
+
+class TestUpdatesHandlerFetchTestCases(base.BaseTestCase):
+    """This test class contains tests for the UpdatesHandler.fetch_test_cases() method."""
+
+    @mock.patch.dict(config.config, {'query_wiki_test_cases': True})
+    @mock.patch('bodhi.server.models.MediaWiki')
+    @mock.patch('bodhi.server.consumers.updates.log.warning')
+    def test_fetch_test_cases_exception(self, warning, MediaWiki):
+        """
+        Assert that fetch_test_cases logs a warning when an exception is raised.
+        """
+        h = updates.UpdatesHandler()
+        h.db_factory = base.TransactionalSessionMaker(self.Session)
+        MediaWiki.return_value.call.side_effect = URLError("oh no!")
+
+        update = self.db.query(models.Update).filter(
+            models.Build.nvr == 'bodhi-2.0-1.fc17').one()
+        h.fetch_test_cases(h.db_factory, update)
+
+        warning.assert_called_once_with('Error occurred during fetching testcases', exc_info=True)
diff --git a/bodhi/tests/server/test_models.py b/bodhi/tests/server/test_models.py
--- a/bodhi/tests/server/test_models.py
+++ b/bodhi/tests/server/test_models.py
@@ -24,6 +24,7 @@
 import time
 import unittest
 import uuid
+from urllib.error import URLError
 
 from fedora_messaging.testing import mock_sends
 from pyramid.testing import DummyRequest
@@ -1230,6 +1231,18 @@ def test_wiki_test_cases_recursive(self, MediaWiki):
                          {'Does Bodhi eat +1s', 'Fake', 'Uploading cat pictures'})
         self.assertEqual({tc.package.name for tc in model.TestCase.query.all()}, {'gnome-shell'})
 
+    @mock.patch.dict(config, {'query_wiki_test_cases': True})
+    @mock.patch('bodhi.server.models.MediaWiki')
+    def test_wiki_test_cases_exception(self, MediaWiki):
+        """Test querying the wiki for test cases when connection to Wiki failed"""
+        MediaWiki.return_value.call.side_effect = URLError("oh no!")
+
+        with self.assertRaises(BodhiException) as exc_context:
+            pkg = model.RpmPackage(name='gnome-shell')
+            pkg.fetch_test_cases(self.db)
+        self.assertEqual(len(pkg.test_cases), 0)
+        self.assertEqual(str(exc_context.exception), 'Failed retrieving testcases from Wiki')
+
     def test_adding_modulebuild(self):
         """Assert that validation fails when adding a ModuleBuild."""
         build1 = model.RpmBuild(nvr='the-greatest-package-1.0.0-fc17.1')