Repository: fedora-infra/bodhi

Issue:
The push to stable button should appear when a critpath non-autopush update reaches its karma threshold
Laura Abbott reported to me today that [this update](https://bodhi.fedoraproject.org/updates/FEDORA-2019-48b34fc991) didn't show a push to stable button when it reached its karma threshold of 3. The kernel tends to set autopushing off, so the push to stable button should be appearing when the update reached its karma threshold.

It seems likely that the template code (and tests) are wrong.


Discussion:
It turns out that this only affects critpath updates.

Resolving patch:
diff --git a/bodhi/server/models.py b/bodhi/server/models.py
--- a/bodhi/server/models.py
+++ b/bodhi/server/models.py
@@ -815,6 +815,24 @@ class Release(Base):
     package_manager = Column(PackageManager.db_type(), default=PackageManager.unspecified)
     testing_repository = Column(UnicodeText, nullable=True)
 
+    @property
+    def critpath_min_karma(self) -> int:
+        """
+        Return the min_karma for critpath updates for this release.
+
+        If the release doesn't specify a min_karma, the default critpath.min_karma setting is used
+        instead.
+
+        Returns:
+            The minimum karma required for critical path updates for this release.
+        """
+        if self.setting_status:
+            min_karma = config.get(
+                f'{self.setting_prefix}.{self.setting_status}.critpath.min_karma', None)
+            if min_karma:
+                return int(min_karma)
+        return config.get('critpath.min_karma')
+
     @property
     def version_int(self):
         """
@@ -925,6 +943,31 @@ def from_tags(cls, tags, session):
             if release:
                 return release
 
+    @property
+    def setting_prefix(self) -> str:
+        """
+        Return the prefix for settings that pertain to this Release.
+
+        Returns:
+            The Release's setting prefix.
+        """
+        return self.name.lower().replace('-', '')
+
+    @property
+    def setting_status(self) -> typing.Optional[str]:
+        """
+        Return the status of the Release from settings.
+
+        Return the Release's status setting from the config. For example, if the release is f30,
+        this will return the value of f30.status from the config file.
+
+        Note: This is not the same as Release.state.
+
+        Returns:
+            The status of the release.
+        """
+        return config.get(f'{self.setting_prefix}.status', None)
+
 
 class TestCase(Base):
     """
@@ -3355,18 +3398,16 @@ def critpath_approved(self):
         # https://fedorahosted.org/bodhi/ticket/642
         if self.meets_testing_requirements:
             return True
-        release_name = self.release.name.lower().replace('-', '')
-        status = config.get('%s.status' % release_name, None)
-        if status:
-            num_admin_approvals = config.get('%s.%s.critpath.num_admin_approvals' % (
-                release_name, status), None)
-            min_karma = config.get('%s.%s.critpath.min_karma' % (
-                release_name, status), None)
+        min_karma = self.release.critpath_min_karma
+        if self.release.setting_status:
+            num_admin_approvals = config.get(
+                f'{self.release.setting_prefix}.{self.release.setting_status}'
+                '.critpath.num_admin_approvals')
             if num_admin_approvals is not None and min_karma:
                 return self.num_admin_approvals >= int(num_admin_approvals) and \
-                    self.karma >= int(min_karma)
+                    self.karma >= min_karma
         return self.num_admin_approvals >= config.get('critpath.num_admin_approvals') and \
-            self.karma >= config.get('critpath.min_karma')
+            self.karma >= min_karma
 
     @property
     def meets_testing_requirements(self):
@@ -3384,6 +3425,9 @@ def meets_testing_requirements(self):
         if config.get('test_gating.required') and not self.test_gating_passed:
             return False
 
+        if self.karma >= self.release.critpath_min_karma:
+            return True
+
         if self.critpath:
             # Ensure there is no negative karma. We're looking at the sum of
             # each users karma for this update, which takes into account
@@ -3395,9 +3439,7 @@ def meets_testing_requirements(self):
         if not num_days:
             return True
 
-        # non-autokarma updates have met the testing requirements if they've reached the karma
-        # threshold.
-        if not self.autokarma and self.karma >= self.stable_karma:
+        if self.karma >= self.stable_karma:
             return True
 
         # Any update that reaches num_days has met the testing requirements.


Test patch:
diff --git a/bodhi/tests/server/scripts/test_approve_testing.py b/bodhi/tests/server/scripts/test_approve_testing.py
--- a/bodhi/tests/server/scripts/test_approve_testing.py
+++ b/bodhi/tests/server/scripts/test_approve_testing.py
@@ -256,9 +256,6 @@ def test_non_autokarma_critpath_update_not_meeting_time_requirements_gets_no_com
         update.request = None
         update.stable_karma = 1
         update.status = models.UpdateStatus.testing
-        update.comment(self.db, 'testing', author='hunter2', karma=1)
-        with fml_testing.mock_sends(api.Message):
-            self.db.commit()
 
         with patch('bodhi.server.scripts.approve_testing.initialize_db'):
             with patch('bodhi.server.scripts.approve_testing.get_appsettings', return_value=''):
@@ -268,14 +265,17 @@ def test_non_autokarma_critpath_update_not_meeting_time_requirements_gets_no_com
                 # further comments.
                 approve_testing.main(['nosetests', 'some_config.ini'])
 
+        # The update should have one +1, which is as much as the stable karma but not as much as the
+        # required +2 to go stable.
+        self.assertEqual(update._composite_karma, (1, 0))
         # The bodhi user shouldn't exist, since it shouldn't have made any comments
         self.assertEqual(self.db.query(models.User).filter_by(name='bodhi').count(), 0)
-        # There are three comments, but none from the non-existing bodhi user.
-        self.assertEqual(self.db.query(models.Comment).count(), 3)
+        # There are two comments, but none from the non-existing bodhi user.
+        self.assertEqual(self.db.query(models.Comment).count(), 2)
         usernames = [
             c.user.name
             for c in self.db.query(models.Comment).order_by(models.Comment.timestamp).all()]
-        self.assertEqual(usernames, ['guest', 'anonymous', 'hunter2'])
+        self.assertEqual(usernames, ['guest', 'anonymous'])
 
     def test_non_autokarma_update_meeting_karma_requirements_gets_one_comment(self):
         """
@@ -360,23 +360,22 @@ def test_non_autokarma_update_with_unmet_karma_requirement(self):
         update.request = None
         update.stable_karma = 10
         update.status = models.UpdateStatus.testing
-        update.comment(self.db, 'testing', author='hunter2', karma=1)
-        with fml_testing.mock_sends(api.Message):
-            self.db.commit()
 
         with patch('bodhi.server.scripts.approve_testing.initialize_db'):
             with patch('bodhi.server.scripts.approve_testing.get_appsettings', return_value=''):
                 with fml_testing.mock_sends():
                     approve_testing.main(['nosetests', 'some_config.ini'])
 
+        # The update should have one positive karma and no negative karmas
+        self.assertEqual(update._composite_karma, (1, 0))
         # The bodhi user shouldn't exist, since it shouldn't have made any comments
         self.assertEqual(self.db.query(models.User).filter_by(name='bodhi').count(), 0)
-        # There are three comments, but none from the non-existing bodhi user.
-        self.assertEqual(self.db.query(models.Comment).count(), 3)
+        # There are two comments, but none from the non-existing bodhi user.
+        self.assertEqual(self.db.query(models.Comment).count(), 2)
         usernames = [
             c.user.name
             for c in self.db.query(models.Comment).order_by(models.Comment.timestamp).all()]
-        self.assertEqual(usernames, ['guest', 'anonymous', 'hunter2'])
+        self.assertEqual(usernames, ['guest', 'anonymous'])
 
     def test_non_autokarma_update_with_unmet_karma_requirement_after_time_met(self):
         """
@@ -392,15 +391,15 @@ def test_non_autokarma_update_with_unmet_karma_requirement_after_time_met(self):
         update.stable_karma = 10
         update.status = models.UpdateStatus.testing
         update.date_testing = datetime.utcnow() - timedelta(days=7)
-        update.comment(self.db, 'testing', author='hunter2', karma=1)
-        with fml_testing.mock_sends(api.Message):
-            self.db.commit()
+        self.db.flush()
 
         with patch('bodhi.server.scripts.approve_testing.initialize_db'):
             with patch('bodhi.server.scripts.approve_testing.get_appsettings', return_value=''):
                 with fml_testing.mock_sends(api.Message):
                     approve_testing.main(['nosetests', 'some_config.ini'])
 
+        # The update should have one positive karma and no negative karmas
+        self.assertEqual(update._composite_karma, (1, 0))
         bodhi = self.db.query(models.User).filter_by(name='bodhi').one()
         comment_q = self.db.query(models.Comment).filter_by(update_id=update.id, user_id=bodhi.id)
         self.assertEqual(comment_q.count(), 1)
@@ -419,22 +418,21 @@ def test_non_autokarma_update_without_mandatory_days_in_testing(self):
         update.request = None
         update.stable_karma = 1
         update.status = models.UpdateStatus.testing
-        update.comment(self.db, 'testing', author='hunter2', karma=1)
-        with fml_testing.mock_sends(api.Message):
-            self.db.commit()
 
         with patch('bodhi.server.scripts.approve_testing.initialize_db'):
             with patch('bodhi.server.scripts.approve_testing.get_appsettings', return_value=''):
                 approve_testing.main(['nosetests', 'some_config.ini'])
 
+        # The update should have one positive karma and no negative karmas
+        self.assertEqual(update._composite_karma, (1, 0))
         # The bodhi user shouldn't exist, since it shouldn't have made any comments
         self.assertEqual(self.db.query(models.User).filter_by(name='bodhi').count(), 0)
-        # There are three comments, but none from the non-existing bodhi user.
-        self.assertEqual(self.db.query(models.Comment).count(), 3)
+        # There are two comments, but none from the non-existing bodhi user.
+        self.assertEqual(self.db.query(models.Comment).count(), 2)
         usernames = [
             c.user.name
             for c in self.db.query(models.Comment).order_by(models.Comment.timestamp).all()]
-        self.assertEqual(usernames, ['guest', 'anonymous', 'hunter2'])
+        self.assertEqual(usernames, ['guest', 'anonymous'])
 
     @patch.dict(config, [('fedora.mandatory_days_in_testing', 14)])
     def test_subsequent_comments_after_initial_push_comment(self):
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
@@ -710,6 +710,24 @@ def test_mandatory_days_in_testing_status_truthy(self):
         """Test mandatory_days_in_testing() with a value that is truthy."""
         self.assertEqual(self.obj.mandatory_days_in_testing, 42)
 
+    def test_setting_prefix(self):
+        """Assert correct return value from the setting_prefix property."""
+        self.assertEqual(self.obj.setting_prefix, 'f11')
+
+        # Try putting a - into the name of the release, which should get removed
+        self.obj.name = 'f-11'
+
+        self.assertEqual(self.obj.setting_prefix, 'f11')
+
+    @mock.patch.dict(config, {'f11.status': "It's doing just fine, thanks for asking"})
+    def test_setting_status_found(self):
+        """Assert correct return value from the setting_status property when config is found."""
+        self.assertEqual(self.obj.setting_status, "It's doing just fine, thanks for asking")
+
+    def test_setting_status_not_found(self):
+        """Assert correct return value from the setting_status property when config not found."""
+        self.assertEqual(self.obj.setting_status, None)
+
     def test_version_int(self):
         self.assertEqual(self.obj.version_int, 11)
 
@@ -722,6 +740,34 @@ def test_all_releases(self):
         self.assertIs(releases, model.Release.all_releases())
 
 
+class TestReleaseCritpathMinKarma(BaseTestCase):
+    """Tests for the Release.critpath_min_karma property."""
+
+    @mock.patch.dict(
+        config, {'critpath.min_karma': 2, 'f17.beta.critpath.min_karma': 42, 'f17.status': "beta"})
+    def test_setting_status_min(self):
+        """If a min is defined for the release, it should be returned."""
+        release = model.Release.query.first()
+
+        self.assertEqual(release.critpath_min_karma, 42)
+
+    @mock.patch.dict(
+        config, {'critpath.min_karma': 25, 'f17.status': "beta"})
+    def test_setting_status_no_min(self):
+        """If no min is defined for the release, the general min karma config should be returned."""
+        release = model.Release.query.first()
+
+        self.assertEqual(release.critpath_min_karma, 25)
+
+    @mock.patch.dict(
+        config, {'critpath.min_karma': 72})
+    def test_setting_status_no_setting_status(self):
+        """If no status is defined for the release, the general min karma should be returned."""
+        release = model.Release.query.first()
+
+        self.assertEqual(release.critpath_min_karma, 72)
+
+
 class TestReleaseModular(ModelTest):
     """Unit test case for the ``Release`` model for modular releases."""
     klass = model.Release
@@ -1980,6 +2026,234 @@ def test_backref_different_build_types(self):
         self.assertEqual(str(cm.exception), 'An update must contain builds of the same type.')
 
 
+class TestUpdateMeetsTestingRequirements(BaseTestCase):
+    """Test the Update.meets_testing_requirements() method."""
+
+    def test_autokarma_update_reaching_stable_karma(self):
+        """
+        Assert that meets_testing_requirements() correctly returns True for autokarma updates
+        that haven't reached the days in testing but have reached the stable_karma threshold.
+        """
+        update = model.Update.query.first()
+        update.autokarma = True
+        update.status = UpdateStatus.testing
+        update.stable_karma = 1
+        # Now let's add some karma to get it to the required threshold
+        update.comment(self.db, 'testing', author='hunter2', karma=1)
+
+        # meets_testing_requirement() should return True since the karma threshold has been reached
+        self.assertEqual(update.meets_testing_requirements, True)
+
+    def test_critpath_14_days_negative_karma(self):
+        """critpath packages in testing for 14 days shouldn't go stable with negative karma."""
+        update = model.Update.query.first()
+        update.critpath = True
+        update.status = model.UpdateStatus.testing
+        update.request = None
+        update.date_testing = datetime.utcnow() - timedelta(days=15)
+        update.stable_karma = 1
+        update.comment(self.db, 'testing', author='enemy', karma=-1)
+        # This gets the update to positive karma, but not to the required 2 karma needed for
+        # critpath.
+        update.comment(self.db, 'testing', author='bro', karma=1)
+
+        self.assertEqual(update.meets_testing_requirements, False)
+
+    def test_critpath_14_days_no_negative_karma(self):
+        """critpath packages in testing for 14 days can go stable without negative karma."""
+        update = model.Update.query.first()
+        update.critpath = True
+        update.status = model.UpdateStatus.testing
+        update.request = None
+        update.date_testing = datetime.utcnow() - timedelta(days=15)
+        update.stable_karma = 1
+
+        self.assertEqual(update.meets_testing_requirements, True)
+
+    def test_critpath_karma_2_met(self):
+        """critpath packages should be allowed to go stable when meeting required karma."""
+        update = model.Update.query.first()
+        update.critpath = True
+        update.stable_karma = 1
+        update.comment(self.db, 'testing', author='enemy', karma=-1)
+        update.comment(self.db, 'testing', author='bro', karma=1)
+        # Despite meeting the stable_karma, the function should still not mark this as meeting
+        # testing requirements because critpath packages have a higher requirement for minimum
+        # karma. So let's get it a second one.
+        update.comment(self.db, 'testing', author='ham', karma=1)
+
+        self.assertEqual(update.meets_testing_requirements, True)
+
+    def test_critpath_karma_2_required(self):
+        """critpath packages should require a minimum karma."""
+        update = model.Update.query.first()
+        update.critpath = True
+        update.stable_karma = 1
+
+        # Despite meeting the stable_karma, the function should still not mark this as meeting
+        # testing requirements because critpath packages have a higher requirement for minimum
+        # karma.
+        self.assertEqual(update.meets_testing_requirements, False)
+
+    def test_critpath_negative_karma(self):
+        """
+        Assert that meets_testing_requirements() correctly returns False for critpath updates
+        with negative karma.
+        """
+        update = model.Update.query.first()
+        update.critpath = True
+        update.comment(self.db, 'testing', author='enemy', karma=-1)
+        self.assertEqual(update.meets_testing_requirements, False)
+
+    def test_karma_2_met(self):
+        """Regular packages should be allowed to go stable when meeting required karma."""
+        update = model.Update.query.first()
+        update.stable_karma = 3
+        update.comment(self.db, 'testing', author='enemy', karma=-1)
+        update.comment(self.db, 'testing', author='bro', karma=1)
+        # Despite meeting the stable_karma, the function should still not mark this as meeting
+        # testing requirements because critpath packages have a higher requirement for minimum
+        # karma. So let's get it a second one.
+        update.comment(self.db, 'testing', author='ham', karma=1)
+
+        self.assertEqual(update.meets_testing_requirements, True)
+
+    def test_non_autokarma_update_below_stable_karma(self):
+        """It should return False for non-autokarma updates below stable karma and time."""
+        update = model.Update.query.first()
+        update.autokarma = False
+        update.comments = []
+        update.status = UpdateStatus.testing
+        update.stable_karma = 1
+
+        # meets_testing_requirement() should return False since the karma threshold has not been
+        # reached (note that this Update does not have any karma).
+        self.assertEqual(update.meets_testing_requirements, False)
+
+    def test_non_autokarma_update_reaching_stable_karma(self):
+        """
+        Assert that meets_testing_requirements() correctly returns True for non-autokarma updates
+        that haven't reached the days in testing but have reached the stable_karma threshold.
+        """
+        update = model.Update.query.first()
+        update.autokarma = False
+        update.status = UpdateStatus.testing
+        update.stable_karma = 1
+
+        # meets_testing_requirement() should return True since the karma threshold has been reached
+        self.assertEqual(update.meets_testing_requirements, True)
+
+    @mock.patch.dict('bodhi.server.config.config', {'test_gating.required': True})
+    def test_test_gating_faild_no_testing_requirements(self):
+        """
+        The Update.meets_testing_requirements() should return False, if the test gating
+        status of an update is failed.
+        """
+        update = model.Update.query.first()
+        update.autokarma = False
+        update.stable_karma = 1
+        update.test_gating_status = TestGatingStatus.failed
+        update.comment(self.db, 'I found $100 after applying this update.', karma=1,
+                       author='bowlofeggs')
+        # Assert that our preconditions from the docblock are correct.
+        self.assertEqual(update.meets_testing_requirements, False)
+
+    @mock.patch.dict('bodhi.server.config.config', {'test_gating.required': True})
+    def test_test_gating_queued_no_testing_requirements(self):
+        """
+        The Update.meets_testing_requirements() should return False, if the test gating
+        status of an update is queued.
+        """
+        update = model.Update.query.first()
+        update.autokarma = False
+        update.stable_karma = 1
+        update.test_gating_status = TestGatingStatus.queued
+        update.comment(self.db, 'I found $100 after applying this update.', karma=1,
+                       author='bowlofeggs')
+        # Assert that our preconditions from the docblock are correct.
+        self.assertEqual(update.meets_testing_requirements, False)
+
+    @mock.patch.dict('bodhi.server.config.config', {'test_gating.required': True})
+    def test_test_gating_running_no_testing_requirements(self):
+        """
+        The Update.meets_testing_requirements() should return False, if the test gating
+        status of an update is running.
+        """
+        update = model.Update.query.first()
+        update.autokarma = False
+        update.stable_karma = 1
+        update.test_gating_status = TestGatingStatus.running
+        update.comment(self.db, 'I found $100 after applying this update.', karma=1,
+                       author='bowlofeggs')
+        # Assert that our preconditions from the docblock are correct.
+        self.assertEqual(update.meets_testing_requirements, False)
+
+    @mock.patch.dict('bodhi.server.config.config', {'test_gating.required': True})
+    def test_test_gating_missing_testing_requirements(self):
+        """
+        The Update.meets_testing_requirements() should return True, if the test gating
+        status of an update is missing.
+        """
+        update = model.Update.query.first()
+        update.autokarma = False
+        update.stable_karma = 1
+        update.test_gating_status = None
+        update.comment(self.db, 'I found $100 after applying this update.', karma=1,
+                       author='bowlofeggs')
+        # Assert that our preconditions from the docblock are correct.
+        self.assertEqual(update.meets_testing_requirements, True)
+
+    @mock.patch.dict('bodhi.server.config.config', {'test_gating.required': True})
+    def test_test_gating_waiting_testing_requirements(self):
+        """
+        The Update.meets_testing_requirements() should return False, if the test gating
+        status of an update is waiting.
+        """
+        update = model.Update.query.first()
+        update.autokarma = False
+        update.stable_karma = 1
+        update.test_gating_status = TestGatingStatus.waiting
+        update.comment(self.db, 'I found $100 after applying this update.', karma=1,
+                       author='bowlofeggs')
+        # Assert that our preconditions from the docblock are correct.
+        self.assertEqual(update.meets_testing_requirements, False)
+
+    @mock.patch.dict('bodhi.server.config.config', {'test_gating.required': False})
+    def test_test_gating_off(self):
+        """
+        The Update.meets_testing_requirements() should return True if the
+        testing gating is not required, regardless of its test gating status.
+        """
+        update = model.Update.query.first()
+        update.autokarma = False
+        update.stable_karma = 1
+        update.test_gating_status = TestGatingStatus.running
+        update.comment(self.db, 'I found $100 after applying this update.', karma=1,
+                       author='bowlofeggs')
+        # Assert that our preconditions from the docblock are correct.
+        self.assertEqual(update.meets_testing_requirements, True)
+
+    def test_time_in_testing_met(self):
+        """It should return True for non-critpath updates that meet time in testing."""
+        update = model.Update.query.first()
+        update.status = model.UpdateStatus.testing
+        update.request = None
+        update.date_testing = datetime.utcnow() - timedelta(days=8)
+        update.stable_karma = 10
+
+        self.assertEqual(update.meets_testing_requirements, True)
+
+    def test_time_in_testing_unmet(self):
+        """It should return False for non-critpath updates that don't yet meet time in testing."""
+        update = model.Update.query.first()
+        update.status = model.UpdateStatus.testing
+        update.request = None
+        update.date_testing = datetime.utcnow() - timedelta(days=6)
+        update.stable_karma = 10
+
+        self.assertEqual(update.meets_testing_requirements, False)
+
+
 class TestUpdate(ModelTest):
     """Unit test case for the ``Update`` model."""
     klass = model.Update
@@ -2287,96 +2561,6 @@ def test_side_tag_locked_true(self):
 
         self.assertIs(self.obj.side_tag_locked, True)
 
-    @mock.patch.dict('bodhi.server.config.config', {'test_gating.required': True})
-    def test_test_gating_faild_no_testing_requirements(self):
-        """
-        The Update.meets_testing_requirements() should return False, if the test gating
-        status of an update is failed.
-        """
-        update = self.obj
-        update.autokarma = False
-        update.stable_karma = 1
-        update.test_gating_status = TestGatingStatus.failed
-        update.comment(self.db, 'I found $100 after applying this update.', karma=1,
-                       author='bowlofeggs')
-        # Assert that our preconditions from the docblock are correct.
-        self.assertEqual(update.meets_testing_requirements, False)
-
-    @mock.patch.dict('bodhi.server.config.config', {'test_gating.required': True})
-    def test_test_gating_queued_no_testing_requirements(self):
-        """
-        The Update.meets_testing_requirements() should return False, if the test gating
-        status of an update is queued.
-        """
-        update = self.obj
-        update.autokarma = False
-        update.stable_karma = 1
-        update.test_gating_status = TestGatingStatus.queued
-        update.comment(self.db, 'I found $100 after applying this update.', karma=1,
-                       author='bowlofeggs')
-        # Assert that our preconditions from the docblock are correct.
-        self.assertEqual(update.meets_testing_requirements, False)
-
-    @mock.patch.dict('bodhi.server.config.config', {'test_gating.required': True})
-    def test_test_gating_running_no_testing_requirements(self):
-        """
-        The Update.meets_testing_requirements() should return False, if the test gating
-        status of an update is running.
-        """
-        update = self.obj
-        update.autokarma = False
-        update.stable_karma = 1
-        update.test_gating_status = TestGatingStatus.running
-        update.comment(self.db, 'I found $100 after applying this update.', karma=1,
-                       author='bowlofeggs')
-        # Assert that our preconditions from the docblock are correct.
-        self.assertEqual(update.meets_testing_requirements, False)
-
-    @mock.patch.dict('bodhi.server.config.config', {'test_gating.required': True})
-    def test_test_gating_missing_testing_requirements(self):
-        """
-        The Update.meets_testing_requirements() should return True, if the test gating
-        status of an update is missing.
-        """
-        update = self.obj
-        update.autokarma = False
-        update.stable_karma = 1
-        update.test_gating_status = None
-        update.comment(self.db, 'I found $100 after applying this update.', karma=1,
-                       author='bowlofeggs')
-        # Assert that our preconditions from the docblock are correct.
-        self.assertEqual(update.meets_testing_requirements, True)
-
-    @mock.patch.dict('bodhi.server.config.config', {'test_gating.required': True})
-    def test_test_gating_waiting_testing_requirements(self):
-        """
-        The Update.meets_testing_requirements() should return False, if the test gating
-        status of an update is waiting.
-        """
-        update = self.obj
-        update.autokarma = False
-        update.stable_karma = 1
-        update.test_gating_status = TestGatingStatus.waiting
-        update.comment(self.db, 'I found $100 after applying this update.', karma=1,
-                       author='bowlofeggs')
-        # Assert that our preconditions from the docblock are correct.
-        self.assertEqual(update.meets_testing_requirements, False)
-
-    @mock.patch.dict('bodhi.server.config.config', {'test_gating.required': False})
-    def test_test_gating_off(self):
-        """
-        The Update.meets_testing_requirements() should return True if the
-        testing gating is not required, regardless of its test gating status.
-        """
-        update = self.obj
-        update.autokarma = False
-        update.stable_karma = 1
-        update.test_gating_status = TestGatingStatus.running
-        update.comment(self.db, 'I found $100 after applying this update.', karma=1,
-                       author='bowlofeggs')
-        # Assert that our preconditions from the docblock are correct.
-        self.assertEqual(update.meets_testing_requirements, True)
-
     @mock.patch('bodhi.server.models.bugs.bugtracker.close')
     @mock.patch('bodhi.server.models.bugs.bugtracker.comment')
     def test_modify_bugs_stable_close(self, comment, close):
@@ -3183,43 +3367,6 @@ def test_has_stable_comment_at_7_days_before_bodhi_comment(self):
         # Since bodhi hasn't added the testing_approval_message yet, this should be False.
         self.assertEqual(self.obj.has_stable_comment, False)
 
-    def test_meets_testing_requirements_with_non_autokarma_update_below_stable_karma(self):
-        """
-        Assert that meets_testing_requirements() correctly returns True for non-autokarma updates
-        that haven't reached the days in testing but have reached the stable_karma threshold.
-        """
-        self.obj.autokarma = False
-        self.obj.status = UpdateStatus.testing
-        self.obj.stable_karma = 1
-
-        # meets_testing_requirement() should return False since the karma threshold has not been
-        # reached (note that this Update does not have any karma).
-        self.assertEqual(self.obj.meets_testing_requirements, False)
-
-    def test_meets_testing_requirements_with_non_autokarma_update_reaching_stable_karma(self):
-        """
-        Assert that meets_testing_requirements() correctly returns True for non-autokarma updates
-        that haven't reached the days in testing but have reached the stable_karma threshold.
-        """
-        self.obj.autokarma = False
-        self.obj.status = UpdateStatus.testing
-        self.obj.stable_karma = 1
-        # Now let's add some karma to get it to the required threshold
-        self.obj.comment(self.db, 'testing', author='hunter2', karma=1)
-
-        # meets_testing_requirement() should return True since the karma threshold has been reached
-        self.assertEqual(self.obj.meets_testing_requirements, True)
-
-    def test_meets_testing_requirements_critpath_negative_karma(self):
-        """
-        Assert that meets_testing_requirements() correctly returns False for critpath updates
-        with negative karma.
-        """
-        update = self.obj
-        update.critpath = True
-        update.comment(self.db, 'testing', author='enemy', karma=-1)
-        self.assertEqual(update.meets_testing_requirements, False)
-
     def test_has_stable_comment_with_karma_after_bodhi_comment(self):
         """
         Ensure a correct True return value from Update.has_stable_comment() after a