Repository: fedora-infra/bodhi

Issue:
Implement nagmail script
We need a job that comments on updates once they meet the minimum amount of time in testing, etc.

https://github.com/fedora-infra/bodhi/blob/master/bodhi/jobs.py#L74



Discussion:
We would run this with cron now, right?

Yeah, similar to `bodhi/scripts/expire_overrides.py`

+1 for nagmails

Freeze should lift on Tuesday, so we'll get another shot at this after that.


Resolving patch:
diff --git a/bodhi/models/models.py b/bodhi/models/models.py
--- a/bodhi/models/models.py
+++ b/bodhi/models/models.py
@@ -1706,9 +1706,8 @@ def met_testing_requirements(self):
         simply return True.
         """
         min_num_days = self.release.mandatory_days_in_testing
-        num_days = self.days_in_testing
         if min_num_days:
-            if num_days < min_num_days:
+            if not self.meets_testing_requirements:
                 return False
         else:
             return True
diff --git a/setup.py b/setup.py
--- a/setup.py
+++ b/setup.py
@@ -113,6 +113,7 @@
       bodhi-push = bodhi.push:push
       bodhi-expire-overrides = bodhi.scripts.expire_overrides:main
       bodhi-untag-branched = bodhi.scripts.untag_branched:main
+      bodhi-approve-testing = bodhi.scripts.approve_testing:main
       [moksha.consumer]
       masher = bodhi.consumers.masher:Masher
       updates = bodhi.consumers.updates:UpdatesHandler


Test patch:
diff --git a/bodhi/scripts/approve_testing.py b/bodhi/scripts/approve_testing.py
new file mode 100644
--- /dev/null
+++ b/bodhi/scripts/approve_testing.py
@@ -0,0 +1,66 @@
+# This program is free software; you can redistribute it and/or
+# modify it under the terms of the GNU General Public License
+# as published by the Free Software Foundation; either version 2
+# of the License, or (at your option) any later version.
+#
+# This program is distributed in the hope that it will be useful,
+# but WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program; if not, write to the Free Software
+# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+"""
+This script is responsible for commenting on updates after they reach the
+mandatory amount of time spent in the testing repository.
+"""
+
+import os
+import sys
+
+from pyramid.paster import get_appsettings
+from sqlalchemy import engine_from_config
+from sqlalchemy.orm import scoped_session, sessionmaker
+from zope.sqlalchemy import ZopeTransactionExtension
+
+import transaction
+
+from ..models import Base, Update, UpdateStatus
+from ..config import config
+
+
+def usage(argv):
+    cmd = os.path.basename(argv[0])
+    print('usage: %s <config_uri>\n'
+          '(example: "%s development.ini")' % (cmd, cmd))
+    sys.exit(1)
+
+
+def main(argv=sys.argv):
+    if len(argv) != 2:
+        usage(argv)
+
+    config_uri = argv[1]
+
+    settings = get_appsettings(config_uri)
+    engine = engine_from_config(settings, 'sqlalchemy.')
+    Session = scoped_session(sessionmaker(extension=ZopeTransactionExtension()))
+    Session.configure(bind=engine)
+    db = Session()
+
+    with transaction.manager:
+        testing = db.query(Update).filter_by(status=UpdateStatus.testing,
+                                             request=None)
+        for update in testing:
+            # If this release does not have any testing requirements, skip it
+            if not update.release.mandatory_days_in_testing:
+                print('%s doesn\'t have mandatory days in testing' % update.release.name)
+                continue
+            # If this has already met testing requirements, skip it
+            if update.met_testing_requirements:
+                continue
+            if update.meets_testing_requirements:
+                print('%s now meets testing requirements' % update.title)
+                text = config.get('testing_approval_msg') % update.days_in_testing
+                update.comment(db, text, author='bodhi')
diff --git a/bodhi/tests/models/test_models.py b/bodhi/tests/models/test_models.py
--- a/bodhi/tests/models/test_models.py
+++ b/bodhi/tests/models/test_models.py
@@ -429,6 +429,30 @@ def test_set_request_stable_after_week_in_testing(self, publish):
         publish.assert_called_once_with(
             topic='update.request.stable', msg=mock.ANY)
 
+    @mock.patch('bodhi.notifications.publish')
+    def test_set_meets_then_met_requirements(self, publish):
+        req = DummyRequest()
+        req.errors = cornice.Errors()
+        req.koji = buildsys.get_session()
+        req.user = model.User(name='bob')
+
+        self.obj.status = UpdateStatus.testing
+        self.obj.request = None
+
+        # Pretend it's been in testing for a week
+        self.obj.comment(
+            self.db, u'This update has been pushed to testing.', author=u'bodhi')
+        self.obj.date_testing = self.obj.comments[-1].timestamp - timedelta(days=7)
+        eq_(self.obj.days_in_testing, 7)
+        eq_(self.obj.meets_testing_requirements, True)
+        eq_(self.obj.met_testing_requirements, False)
+
+        text = config.get('testing_approval_msg') % self.obj.days_in_testing
+        self.obj.comment(self.db, text, author=u'bodhi')
+
+        eq_(self.obj.meets_testing_requirements, True)
+        eq_(self.obj.met_testing_requirements, True)
+
     @mock.patch('bodhi.notifications.publish')
     def test_set_request_obsolete(self, publish):
         req = DummyRequest(user=DummyUser())