Repository: fedora-infra/bodhi

Issue:
bodhi-backend02 is unable to lookup updates by alias
Message
-------
[2017-04-25 02:43:33][    fedmsg   ERROR]
```python
{'body': {u'username': u'bodhi', u'certificate': u'LS0tLS1CRUdJTiBDRVJUSUZJQ0FURS0tLS0tCk1JSUVUakNDQTdlZ0F3SUJBZ0lDQWdnd0RRWUpL\nb1pJaHZjTkFRRUZCUUF3Z2FBeEN6QUpCZ05WQkFZVEFsVlQKTVFzd0NRWURWUVFJRXdKT1F6RVFN\nQTRHQTFVRUJ4TUhVbUZzWldsbmFERVhNQlVHQTFVRUNoTU9SbVZrYjNKaApJRkJ5YjJwbFkzUXhE\nekFOQmdOVkJBc1RCbVpsWkcxelp6RVBNQTBHQTFVRUF4TUdabVZrYlhObk1ROHdEUVlEClZRUXBF\nd1ptWldSdGMyY3hKakFrQmdrcWhraUc5dzBCQ1FFV0YyRmtiV2x1UUdabFpHOXlZWEJ5YjJwbFkz\nUXUKYjNKbk1CNFhEVEUxTURjeU1URTVNVE15TTFvWERUSTFNRGN4T0RFNU1UTXlNMW93Z2R3eEN6\nQUpCZ05WQkFZVApBbFZUTVFzd0NRWURWUVFJRXdKT1F6RVFNQTRHQTFVRUJ4TUhVbUZzWldsbmFE\nRVhNQlVHQTFVRUNoTU9SbVZrCmIzSmhJRkJ5YjJwbFkzUXhEekFOQmdOVkJBc1RCbVpsWkcxelp6\nRXRNQ3NHQTFVRUF4TWtZbTlrYUdrdFltOWsKYUdrd015NXdhSGd5TG1abFpHOXlZWEJ5YjJwbFkz\nUXViM0puTVMwd0t3WURWUVFwRXlSaWIyUm9hUzFpYjJSbwphVEF6TG5Cb2VESXVabVZrYjNKaGNI\nSnZhbVZqZEM1dmNtY3hKakFrQmdrcWhraUc5dzBCQ1FFV0YyRmtiV2x1ClFHWmxaRzl5WVhCeWIy\ncGxZM1F1YjNKbk1JR2ZNQTBHQ1NxR1NJYjNEUUVCQVFVQUE0R05BRENCaVFLQmdRQ28KcjF1MmE3\nU20vcGhMMG5
 lZG9FZXNyUUZDRGZVYmMwdGt1bUowQlBiRHcxdzdtblp0MERVSjhrNkVXVFNwL25E\nNwpoK0NNMmRucG5lRm5XVllycDlXSGpSUVZEbzBCemE3MnJQRjEwcjhPb3phN3k3VTBFUlhmMkNy\nZnBxZTJzREpNCkFyWThZZnZVWnluemIwVUVzOFlmNkgrQ2h5S1JldGNXaWF1TTBZQU5zUUlEQVFB\nQm80SUJWekNDQVZNd0NRWUQKVlIwVEJBSXdBREF0QmdsZ2hrZ0JodmhDQVEwRUlCWWVSV0Z6ZVMx\nU1UwRWdSMlZ1WlhKaGRHVmtJRU5sY25ScApabWxqWVhSbE1CMEdBMVVkRGdRV0JCUmQyMWNBdnZJ\ncFlrQWlIR05nUmRpdHdMODZLVENCMVFZRFZSMGpCSUhOCk1JSEtnQlJyUUZyNUVnaUpXZWRaNVFY\nMUFoMEtUbjhVQUtHQnBxU0JvekNCb0RFTE1Ba0dBMVVFQmhNQ1ZWTXgKQ3pBSkJnTlZCQWdUQWs1\nRE1SQXdEZ1lEVlFRSEV3ZFNZV3hsYVdkb01SY3dGUVlEVlFRS0V3NUdaV1J2Y21FZwpVSEp2YW1W\namRERVBNQTBHQTFVRUN4TUdabVZrYlhObk1ROHdEUVlEVlFRREV3Wm1aV1J0YzJjeER6QU5CZ05W\nCkJDa1RCbVpsWkcxelp6RW1NQ1FHQ1NxR1NJYjNEUUVKQVJZWFlXUnRhVzVBWm1Wa2IzSmhjSEp2\nYW1WamRDNXYKY21lQ0NRRGpVQjVIVHhjZVJUQVRCZ05WSFNVRUREQUtCZ2dyQmdFRkJRY0RBakFM\nQmdOVkhROEVCQU1DQjRBdwpEUVlKS29aSWh2Y05BUUVGQlFBRGdZRUFieTE3QVExbGhzckxuamZk\nWEhaWG9Kd2pWcVdTNHRudWZvVzFLK3pLCnZiTkdMNlBmQVZHa3Q5RzlENENpQzV6amlPNzdi
 Y2lX\nTkYzeWdUUjZqcmdoUnJOZmZnQ1MzSWFpT3JNemVnaHYKeWRqcXJqdDBDY3VoRXM3WFRndVlHcWoz\ndThxS3J6ZGVtNGxETm9wNENoZ0ZtS1ZUdk1pc3R4UVdIMEhCdDZkcApZYXM9Ci0tLS0tRU5EIENF\nUlRJRklDQVRFLS0tLS0K\n', u'i': 2, u'timestamp': 1493088212, u'msg_id': u'2017-f9a6f510-50b5-4612-b5be-a96fa11c6135', u'crypto': u'x509', u'topic': u'org.fedoraproject.prod.bodhi.update.request.testing', u'signature': u'X9KIpc/uXZPiCH6HTcC+jk1FlN6iBVfhv7CS/PKxcBAQ4Kvrehjiqs0j5BHSfAiD2gfj0eLPeaoB\nKqvXJLWr3R87+xO/FHuJ+Sk7b4GeS9ANcRAY4yH6Gmc0c42Gti2U4FHwOS7JPQEoEZhmNB9kx6cE\nh4XAtTjlMAAEwq/T8a4=\n', u'msg': {u'update': {u'date_testing': None, u'old_updateid': None, u'pushed': False, u'require_testcases': True, u'date_stable': None, u'critpath': False, u'date_approved': None, u'stable_karma': 3, u'date_pushed': None, u'requirements': u'', u'severity': u'unspecified', u'autokarma': True, u'title': u'xrdp-0.9.2-10.fc25', u'suggest': u'unspecified', u'require_bugs': True, u'comments': [{u'bug_feedback': [], u'user_id': 91, u'times
 tamp': u'2017-04-25 02:43:31', u'text': u'This update has been submitted for testing by bojan. ', u'karma_critpath': 0, u'update_id': 86094, u'karma': 0, u'anonymous': False, u'testcase_feedback': [], u'id': 598316, u'user': {u'openid': None, u'name': u'bodhi', u'show_popups': True, u'email': None, u'avatar': None, u'groups': [], u'id': 91}}], u'updateid': u'FEDORA-2017-dfced1cc2a', u'test_cases': [], u'close_bugs': True, u'meets_testing_requirements': False, u'date_locked': None, u'date_submitted': u'2017-04-25 02:43:31', u'unstable_karma': -3, u'submitter': u'bojan', u'user': {u'openid': None, u'name': u'bojan', u'show_popups': True, u'email': u'bojan@rexursive.com', u'avatar': None, u'groups': [{u'name': u'packager'}], u'id': 198}, u'locked': False, u'builds': [{u'epoch': 0, u'nvr': u'xrdp-0.9.2-10.fc25', u'signed': False}], u'date_modified': None, u'url': u'https://bodhi.fedoraproject.org/updates/FEDORA-2017-dfced1cc2a', u'type': u'enhancement', u'notes': u'SELinux related impro
 vements:\n\n- move scripts to /usr/libexec/xrdp, so that they get labelled as bin_t\n- add SELinux policy sub-package', u'request': u'testing', u'bugs': [], u'alias': u'FEDORA-2017-dfced1cc2a', u'status': u'pending', u'karma': 0, u'release': {u'dist_tag': u'f25', u'name': u'F25', u'testing_tag': u'f25-updates-testing', u'pending_stable_tag': u'f25-updates-pending', u'pending_signing_tag': u'f25-signing-pending', u'long_name': u'Fedora 25', u'state': u'current', u'version': u'25', u'override_tag': u'f25-override', u'branch': u'f25', u'id_prefix': u'FEDORA', u'pending_testing_tag': u'f25-updates-testing-pending', u'stable_tag': u'f25-updates', u'candidate_tag': u'f25-updates-candidate'}}, u'agent': u'bojan'}}, 'topic': u'org.fedoraproject.prod.bodhi.update.request.testing'}
```


Process Details
---------------
- host:     bodhi-backend02.phx2.fedoraproject.org
- PID:      20075
- name:     fedmsg-hub
- command:  /usr/bin/python /usr/bin/fedmsg-hub
- msg_id:   

Callstack that lead to the logging statement
--------------------------------------------
```python
  File "/usr/lib64/python2.7/threading.py", line 784 in __bootstrap
    self.__bootstrap_inner()
  File "/usr/lib64/python2.7/threading.py", line 811 in __bootstrap_inner
    self.run()
  File "/usr/lib64/python2.7/threading.py", line 764 in run
    self.__target(*self.__args, **self.__kwargs)
  File "/usr/lib64/python2.7/site-packages/twisted/python/threadpool.py", line 167 in _worker
    result = context.call(ctx, function, *args, **kwargs)
  File "/usr/lib64/python2.7/site-packages/twisted/python/context.py", line 118 in callWithContext
    return self.currentContext().callWithContext(ctx, func, *args, **kw)
  File "/usr/lib64/python2.7/site-packages/twisted/python/context.py", line 81 in callWithContext
    return func(*args,**kw)
  File "/usr/lib/python2.7/site-packages/moksha/hub/api/consumer.py", line 193 in _work
    self.log.exception(message)
```

```
Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/moksha/hub/api/consumer.py", line 191, in _work
    self.consume(message)
  File "/usr/lib/python2.7/site-packages/bodhi/server/consumers/updates.py", line 96, in consume
    raise BodhiException("Couldn't find alias %r in DB" % alias)
BodhiException: Couldn't find alias u'FEDORA-2017-dfced1cc2a' in DB
```


Discussion:

Resolving patch:
diff --git a/bodhi/server/__init__.py b/bodhi/server/__init__.py
--- a/bodhi/server/__init__.py
+++ b/bodhi/server/__init__.py
@@ -188,13 +188,14 @@ def main(global_config, testing=None, session=None, **settings):
 
     # Initialize the database scoped session
     initialize_db(settings)
-    config.registry.sessionmaker = Session.session_factory
 
     # Lazy-loaded memoized request properties
     if session:
-        config.add_request_method(lambda _: session, 'db', reify=True)
+        config.registry.sessionmaker = lambda: session
     else:
-        config.add_request_method(get_db_session_for_request, 'db', reify=True)
+        config.registry.sessionmaker = Session
+
+    config.add_request_method(get_db_session_for_request, 'db', reify=True)
 
     config.add_request_method(get_user, 'user', reify=True)
     config.add_request_method(get_koji, 'koji', reify=True)


Test patch:
diff --git a/bodhi/tests/server/base.py b/bodhi/tests/server/base.py
--- a/bodhi/tests/server/base.py
+++ b/bodhi/tests/server/base.py
@@ -46,16 +46,20 @@
 
 
 class BaseTestCase(unittest.TestCase):
+    _populate_db = True
+
     def setUp(self):
         bugs.set_bugtracker()
         self.config = {'sqlalchemy.url': DB_PATH}
         self.engine = initialize_db(self.config)
+        Session.configure(bind=self.engine, expire_on_commit=False)
         self.Session = Session
         log.debug('Creating all models for %s' % self.engine)
         models.Base.metadata.bind = self.engine
         models.Base.metadata.create_all(self.engine)
         self.db = self.Session()
-        populate(self.db)
+        if self._populate_db:
+            populate(self.db)
 
         # Track sql statements in every test
         self.sql_statements = []
diff --git a/bodhi/tests/server/services/test_updates.py b/bodhi/tests/server/services/test_updates.py
--- a/bodhi/tests/server/services/test_updates.py
+++ b/bodhi/tests/server/services/test_updates.py
@@ -565,6 +565,9 @@ def test_provenpackager_request_privs(self, publish, *args):
                             status=200)
 
         eq_(res.json_body['update']['request'], None)
+        # We need to re-fetch the update from the database since the post calls committed the
+        # transaction.
+        update = self.db.query(Update).filter_by(title=nvr).one()
         eq_(update.request, None)
         eq_(update.status, UpdateStatus.obsolete)
 
@@ -1819,8 +1822,6 @@ def test_edit_locked_update(self, publish, *args):
         up.request = None
         up_id = up.id
 
-        build = self.db.query(RpmBuild).filter_by(nvr=nvr).one()
-
         # Changing the notes should work
         args['edited'] = args['builds']
         args['notes'] = 'Some new notes'
@@ -1838,6 +1839,7 @@ def test_edit_locked_update(self, publish, *args):
                       r['errors'])
         up = self.db.query(Update).get(up_id)
         self.assertEquals(up.notes, 'Some new notes')
+        build = self.db.query(RpmBuild).filter_by(nvr=nvr).one()
         self.assertEquals(up.builds, [build])
 
         # Changing the request should fail
@@ -1853,6 +1855,9 @@ def test_edit_locked_update(self, publish, *args):
             r['errors'])
         up = self.db.query(Update).get(up_id)
         self.assertEquals(up.notes, 'Some new notes')
+        # We need to re-retrieve the build since we started a new transaction in the call to
+        # /updates
+        build = self.db.query(RpmBuild).filter_by(nvr=nvr).one()
         self.assertEquals(up.builds, [build])
         self.assertEquals(up.request, None)
 
@@ -2237,21 +2242,21 @@ def test_request_to_stable_based_on_stable_karma(self, *args):
 
         # Checks failure for requesting to stable push before the update reaches stable karma
         up.comment(self.db, u'Not working', author=u'ralph', karma=0)
-        up = Update.get(nvr, self.db)
         self.app.post_json(
             '/updates/%s/request' % args['builds'],
             {'request': 'stable', 'csrf_token': self.get_csrf_token()},
             status=400)
+        up = Update.get(nvr, self.db)
         self.assertEquals(up.request, None)
         self.assertEquals(up.status, UpdateStatus.testing)
 
         # Checks Success for requesting to stable push after the update reaches stable karma
         up.comment(self.db, u'LGTM', author=u'ralph', karma=1)
-        up = Update.get(nvr, self.db)
         self.app.post_json(
             '/updates/%s/request' % args['builds'],
             {'request': 'stable', 'csrf_token': self.get_csrf_token()},
             status=200)
+        up = Update.get(nvr, self.db)
         self.assertEquals(up.request, UpdateRequest.stable)
         self.assertEquals(up.status, UpdateStatus.testing)
 
@@ -2467,6 +2472,8 @@ def test_list_updates_by_alias_and_updateid(self):
         body = res.json_body
         self.assertEquals(len(body['updates']), 1)
         up = body['updates'][0]
+        # We need to refetch the update since the call to /updates/ committed the transaction.
+        upd = self.db.query(Update).filter(Update.alias.isnot(None)).first()
         self.assertEquals(up['title'], upd.title)
         self.assertEquals(up['alias'], upd.alias)
 
@@ -2474,6 +2481,8 @@ def test_list_updates_by_alias_and_updateid(self):
         body = res.json_body
         self.assertEquals(len(body['updates']), 1)
         up = body['updates'][0]
+        # We need to refetch the update since the call to /updates/ committed the transaction.
+        upd = self.db.query(Update).filter(Update.alias.isnot(None)).first()
         self.assertEquals(up['title'], upd.title)
 
         res = self.app.get('/updates/', {"updateid": 'BLARG'})
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
@@ -25,11 +25,11 @@
 import cornice
 import mock
 
-from bodhi.server import models as model, bugs, buildsys, mail, initialize_db, Session
+from bodhi.server import models as model, buildsys, mail
 from bodhi.server.config import config
 from bodhi.server.exceptions import BodhiException
 from bodhi.server.models import (
-    Base, BugKarma, ReleaseState, UpdateRequest, UpdateSeverity, UpdateStatus,
+    BugKarma, ReleaseState, UpdateRequest, UpdateSeverity, UpdateStatus,
     UpdateSuggestion, UpdateType)
 from bodhi.tests.server.base import BaseTestCase
 
@@ -38,32 +38,28 @@ class DummyUser(object):
     name = 'guest'
 
 
-class ModelTest(object):
+class ModelTest(BaseTestCase):
     """Base unit test case for the models."""
 
     klass = None
     attrs = {}
+    _populate_db = False
 
     def setUp(self):
-        bugs.set_bugtracker()
+        super(ModelTest, self).setUp()
         buildsys.setup_buildsystem({'buildsystem': 'dev'})
-        engine = initialize_db({'sqlalchemy.url': 'sqlite://'})
-        Base.metadata.create_all(engine)
-        self.db = Session()
-        try:
-            new_attrs = {}
-            new_attrs.update(self.attrs)
-            new_attrs.update(self.do_get_dependencies())
-            self.obj = self.klass(**new_attrs)
-            self.db.add(self.obj)
-            self.db.flush()
-            return self.obj
-        except:
-            self.db.rollback()
-            raise
-
-    def tearDown(self):
-        self.db.close()
+        if type(self) != ModelTest:
+            try:
+                new_attrs = {}
+                new_attrs.update(self.attrs)
+                new_attrs.update(self.do_get_dependencies())
+                self.obj = self.klass(**new_attrs)
+                self.db.add(self.obj)
+                self.db.flush()
+                return self.obj
+            except:
+                self.db.rollback()
+                raise
 
     def do_get_dependencies(self):
         """ Use this method to pull in other objects that need to be
@@ -81,11 +77,13 @@ def test_query_obj(self):
 
     def test_json(self):
         """ Ensure our models can return valid JSON """
-        assert json.dumps(self.obj.__json__())
+        if type(self) != ModelTest:
+            assert json.dumps(self.obj.__json__())
 
     def test_get(self):
-        for col in self.obj.__get_by__:
-            eq_(self.klass.get(getattr(self.obj, col), self.db), self.obj)
+        if type(self) != ModelTest:
+            for col in self.obj.__get_by__:
+                eq_(self.klass.get(getattr(self.obj, col), self.db), self.obj)
 
 
 class TestQueryProperty(BaseTestCase):
@@ -93,7 +91,7 @@ class TestQueryProperty(BaseTestCase):
     def test_session(self):
         """Assert the session the query property uses is from the scoped session."""
         query = model.Package.query
-        self.assertTrue(Session() is query.session)
+        self.assertTrue(self.db is query.session)
 
 
 class TestComment(unittest.TestCase):
diff --git a/bodhi/tests/server/test_notifications.py b/bodhi/tests/server/test_notifications.py
--- a/bodhi/tests/server/test_notifications.py
+++ b/bodhi/tests/server/test_notifications.py
@@ -89,6 +89,7 @@ def test_with_cert_prefix(self, init, info):
 class TestPublish(base.BaseTestCase):
     """Tests for :func:`bodhi.server.notifications.publish`."""
 
+    @mock.patch.dict('bodhi.server.config.config', {'fedmsg_enabled': False})
     def test_publish_off(self, mock_init):
         """Assert publish doesn't populate the info dict when publishing is off."""
         notifications.publish('demo.topic', {'such': 'important'})
@@ -103,9 +104,9 @@ def test_publish(self, mock_init):
         session = Session()
         self.assertIn('fedmsg', session.info)
         self.assertEqual(session.info['fedmsg']['demo.topic'], [{'such': 'important'}])
-        mock_init.assert_called_once_with()
 
     @mock.patch.dict('bodhi.server.config.config', {'fedmsg_enabled': True})
+    @mock.patch('bodhi.server.notifications.fedmsg_is_initialized', mock.Mock(return_value=False))
     @mock.patch('bodhi.server.notifications.fedmsg.publish')
     def test_publish_force(self, mock_fedmsg_publish, mock_init):
         """Assert publish with the force flag sends the message immediately."""
diff --git a/bodhi/tests/server/test_push.py b/bodhi/tests/server/test_push.py
--- a/bodhi/tests/server/test_push.py
+++ b/bodhi/tests/server/test_push.py
@@ -305,7 +305,15 @@ def test_abort_push(self, publish):
 
         # The exit code is 1 when the push is aborted.
         self.assertEqual(result.exit_code, 1)
-        self.assertEqual(result.output, TEST_ABORT_PUSH_EXPECTED_OUTPUT)
+
+        # This is a terribly dirty hack that strips an SQLAlchemy warning about calling configure
+        # on a scoped session with existing sessions. This should ultimately be fixed by making
+        # sure there are no sessions when the CLI is invoked (since it calls configure)
+        if 'scoped session' in result.output:
+            doctored_output = result.output.split('\n', 2)[2]
+        else:
+            doctored_output = result.output
+        self.assertEqual(doctored_output, TEST_ABORT_PUSH_EXPECTED_OUTPUT)
         self.assertEqual(publish.call_count, 0)
 
         # The updates should not be locked
@@ -317,8 +325,9 @@ def test_abort_push(self, publish):
             self.assertFalse(u.locked)
             self.assertIsNone(u.date_locked)
 
+    @mock.patch('bodhi.server.push.bodhi.server.notifications.init')
     @mock.patch('bodhi.server.push.bodhi.server.notifications.publish')
-    def test_builds_flag(self, publish):
+    def test_builds_flag(self, publish, mock_init):
         """
         Assert correct operation when the --builds flag is given.
         """
@@ -378,12 +387,13 @@ def test_cert_prefix_flag(self, publish, init):
                  'resume': False, 'agent': 'bowlofeggs'},
             force=True)
 
+    @mock.patch('bodhi.server.push.bodhi.server.notifications.init')
     @mock.patch('bodhi.server.push.file', create=True)
     @mock.patch('bodhi.server.push.bodhi.server.notifications.publish')
     @mock.patch('bodhi.server.push.glob.glob',
                 return_value=['/mnt/koji/mash/updates/MASHING-f17-updates'])
     @mock.patch('bodhi.server.push.json.load', return_value={'updates': ['ejabberd-16.09-4.fc17']})
-    def test_locked_updates(self, load, glob, publish, mock_file):
+    def test_locked_updates(self, load, glob, publish, mock_file, mock_init):
         """
         Test correct operation when there are some locked updates.
         """
@@ -400,6 +410,7 @@ def test_locked_updates(self, load, glob, publish, mock_file):
             result = cli.invoke(push.push, ['--username', 'bowlofeggs'], input='y')
 
         self.assertEqual(result.exit_code, 0)
+        mock_init.assert_called_once_with(active=True, cert_prefix=u'shell')
         self.assertEqual(result.output, TEST_LOCKED_UPDATES_EXPECTED_OUTPUT)
         glob.assert_called_once_with('/mnt/koji/mash/updates/MASHING-*')
         publish.assert_called_once_with(
@@ -418,12 +429,13 @@ def test_locked_updates(self, load, glob, publish, mock_file):
             self.assertTrue(u.locked)
             self.assertTrue(u.date_locked <= datetime.utcnow())
 
+    @mock.patch('bodhi.server.push.bodhi.server.notifications.init')
     @mock.patch('bodhi.server.push.file', create=True)
     @mock.patch('bodhi.server.push.bodhi.server.notifications.publish')
     @mock.patch('bodhi.server.push.glob.glob',
                 return_value=['/mnt/koji/mash/updates/MASHING-f17-updates'])
     @mock.patch('bodhi.server.push.json.load', return_value={'updates': ['bodhi-2.0-1.fc17']})
-    def test_locked_updates_not_in_a_push(self, load, glob, publish, mock_file):
+    def test_locked_updates_not_in_a_push(self, load, glob, publish, mock_file, mock_init):
         """
         Test correct operation when there are some locked updates that aren't in a push.
         """
@@ -441,6 +453,7 @@ def test_locked_updates_not_in_a_push(self, load, glob, publish, mock_file):
             result = cli.invoke(push.push, ['--username', 'bowlofeggs'], input='y')
 
         self.assertEqual(result.exit_code, 0)
+        mock_init.assert_called_once_with(active=True, cert_prefix=u'shell')
         # The packages might be printed in any order and the order isn't important. So let's compare
         # the output with the package list removed to make sure that it is correct.
         self.assertEqual(
@@ -501,8 +514,9 @@ def test_no_updates_to_push(self, publish):
             self.assertFalse(u.locked)
             self.assertIsNone(u.date_locked)
 
+    @mock.patch('bodhi.server.push.bodhi.server.notifications.init')
     @mock.patch('bodhi.server.push.bodhi.server.notifications.publish')
-    def test_releases_flag(self, publish):
+    def test_releases_flag(self, publish, mock_init):
         """
         Assert correct operation from the --releases flag.
         """
@@ -547,6 +561,7 @@ def test_releases_flag(self, publish):
                                 input='y')
 
         self.assertEqual(result.exit_code, 0)
+        mock_init.assert_called_once_with(active=True, cert_prefix=u'shell')
         self.assertEqual(result.output, TEST_RELEASES_FLAG_EXPECTED_OUTPUT)
         publish.assert_called_once_with(
             topic='masher.start',
@@ -573,8 +588,9 @@ def test_releases_flag(self, publish):
         self.assertTrue(f26_python_paste_deploy.locked)
         self.assertTrue(f26_python_paste_deploy.date_locked <= datetime.utcnow())
 
+    @mock.patch('bodhi.server.push.bodhi.server.notifications.init')
     @mock.patch('bodhi.server.push.bodhi.server.notifications.publish')
-    def test_request_flag(self, publish):
+    def test_request_flag(self, publish, mock_init):
         """
         Assert that the --request flag works correctly.
         """
@@ -591,6 +607,7 @@ def test_request_flag(self, publish):
                                 input='y')
 
         self.assertEqual(result.exit_code, 0)
+        mock_init.assert_called_once_with(active=True, cert_prefix=u'shell')
         self.assertEqual(result.output, TEST_REQUEST_FLAG_EXPECTED_OUTPUT)
         publish.assert_called_once_with(
             topic='masher.start',
@@ -607,12 +624,13 @@ def test_request_flag(self, publish):
         self.assertTrue(python_paste_deploy.locked)
         self.assertTrue(python_paste_deploy.date_locked <= datetime.utcnow())
 
+    @mock.patch('bodhi.server.push.bodhi.server.notifications.init')
     @mock.patch('bodhi.server.push.file', create=True)
     @mock.patch('bodhi.server.push.bodhi.server.notifications.publish')
     @mock.patch('bodhi.server.push.glob.glob',
                 return_value=['/mnt/koji/mash/updates/MASHING-f17-updates'])
     @mock.patch('bodhi.server.push.json.load', return_value={'updates': [u'ejabberd-16.09-4.fc17']})
-    def test_resume_flag(self, load, glob, publish, mock_file):
+    def test_resume_flag(self, load, glob, publish, mock_file, mock_init):
         """
         Test correct operation when the --resume flag is given.
         """
@@ -630,6 +648,7 @@ def test_resume_flag(self, load, glob, publish, mock_file):
             result = cli.invoke(push.push, ['--username', 'bowlofeggs', '--resume'], input='y\ny')
 
         self.assertEqual(result.exit_code, 0)
+        mock_init.assert_called_once_with(active=True, cert_prefix=u'shell')
         self.assertEqual(result.output, TEST_RESUME_FLAG_EXPECTED_OUTPUT)
         glob.assert_called_once_with('/mnt/koji/mash/updates/MASHING-*')
         publish.assert_called_once_with(
@@ -652,6 +671,7 @@ def test_resume_flag(self, load, glob, publish, mock_file):
             self.assertFalse(u.locked)
             self.assertIsNone(u.date_locked)
 
+    @mock.patch('bodhi.server.push.bodhi.server.notifications.init', mock.Mock())
     @mock.patch('bodhi.server.push.file', create=True)
     @mock.patch('bodhi.server.push.bodhi.server.notifications.publish')
     @mock.patch('bodhi.server.push.glob.glob',
@@ -704,12 +724,13 @@ def test_resume_human_says_no(self, load, glob, publish, mock_file):
             self.assertFalse(u.locked)
             self.assertIsNone(u.date_locked)
 
+    @mock.patch('bodhi.server.push.bodhi.server.notifications.init')
     @mock.patch('bodhi.server.push.file', create=True)
     @mock.patch('bodhi.server.push.bodhi.server.notifications.publish')
     @mock.patch('bodhi.server.push.glob.glob',
                 return_value=['/mnt/koji/mash/updates/MASHING-f17-updates'])
     @mock.patch('bodhi.server.push.json.load', return_value={'updates': [u'ejabberd-16.09-4.fc17']})
-    def test_staging_flag(self, load, glob, publish, mock_file):
+    def test_staging_flag(self, load, glob, publish, mock_file, mock_init):
         """
         Test correct operation when the --staging flag is given. The main thing that matters is that
         the glob call happens on a different directory.
@@ -722,6 +743,7 @@ def test_staging_flag(self, load, glob, publish, mock_file):
             result = cli.invoke(push.push, ['--username', 'bowlofeggs', '--staging'], input='y')
 
         self.assertEqual(result.exit_code, 0)
+        mock_init.assert_called_once_with(active=True, cert_prefix=u'shell')
         self.assertEqual(result.output, TEST_STAGING_FLAG_EXPECTED_OUTPUT)
         glob.assert_called_once_with('/var/cache/bodhi/mashing/MASHING-*')
         publish.assert_called_once_with(
@@ -740,8 +762,9 @@ def test_staging_flag(self, load, glob, publish, mock_file):
             self.assertTrue(u.locked)
             self.assertTrue(u.date_locked <= datetime.utcnow())
 
+    @mock.patch('bodhi.server.push.bodhi.server.notifications.init')
     @mock.patch('bodhi.server.push.bodhi.server.notifications.publish')
-    def test_unsigned_updates_skipped(self, publish):
+    def test_unsigned_updates_skipped(self, publish, mock_init):
         """
         Unsigned updates should get skipped.
         """
@@ -756,6 +779,7 @@ def test_unsigned_updates_skipped(self, publish):
                         return_value=base.TransactionalSessionMaker(self.Session)):
             result = cli.invoke(push.push, ['--username', 'bowlofeggs'], input='y')
 
+        mock_init.assert_called_once_with(active=True, cert_prefix=u'shell')
         self.assertEqual(result.exit_code, 0)
         self.assertEqual(result.output, TEST_UNSIGNED_UPDATES_SKIPPED_EXPECTED_OUTPUT)
         publish.assert_called_once_with(