Repository: fedora-infra/bodhi

Issue:
Change to bugzilla updates text for quicker testing feedback
Forwarded from https://fedorahosted.org/bodhi/ticket/791

Based on the fedora-devel discussion ("Bodhi front page after login"):

What about scrapping the existing bugzilla message, and instead posting the direct link to koji to download the package (as soon as the package is signed):

"""To test the update now run:

dnf upgrade ​https://koji.fp.o/update-yyyy/path-to.rpm ​https://koji.fp.o/update-yyyy/path-to-another.

rpm ​https://koji.fp.o/update-yyyy/path-to-yet-another.rpm

After that go to ​https://bodhi.fp.o/update-yyyy/ to leave karma. """

dnf will skip packages that are not already installed with 'upgrade'. Since this would be only run manually, and the dependent packages would be downloaded from mirrors, this shouldn't cause too much load on koji servers. The advantage would be that the message would be actionable and feedback from the bug reporters would be as fast as possible.



Discussion:
@nirik any idea what the original message to change was/is?


See for example: https://bugzilla.redhat.com/show_bug.cgi?id=1463975#c2

```
python-fedimg-0.7.2-1.fc24 has been pushed to the Fedora 24 testing repository. If problems still persist, please make note of it in this bug report.
See https://fedoraproject.org/wiki/QA:Updates_Testing for
instructions on how to install test updates.
You can provide feedback for this update here: https://bodhi.fedoraproject.org/updates/FEDORA-2017-7128106ce2
```
So, Id say change the middle line to something like: 

Use 'dnf update https://kojipkgs.fedoraproject.org/packages/python-fedimg/0.7.2/1.fc24/data/signed/81b46521/noarch/python-fedimg-0.7.2-1.fc24.noarch.rpm' to install this package to test. See https://fedoraproject.org/wiki/QA:Updates_Testing for
further information on how to install test updates.

Resolving patch:
diff --git a/bodhi/server/config.py b/bodhi/server/config.py
--- a/bodhi/server/config.py
+++ b/bodhi/server/config.py
@@ -510,8 +510,8 @@ class BodhiConfig(dict):
             'value': 'postgresql://localhost/bodhi',
             'validator': str},
         'stable_bug_msg': {
-            'value': ('%s has been pushed to the %s repository. If problems still persist, please '
-                      'make note of it in this bug report.'),
+            'value': ('{update_alias} has been pushed to the {repo} repository.\n'
+                      'If problem still persists, please make note of it in this bug report.'),
             'validator': str},
         'stats_blacklist': {
             'value': ['bodhi', 'anonymous', 'autoqa', 'taskotron'],
@@ -527,13 +527,19 @@ class BodhiConfig(dict):
             'validator': str},
         'testing_bug_epel_msg': {
             'value': (
-                '\nSee https://fedoraproject.org/wiki/QA:Updates_Testing for\ninstructions on how '
-                'to install test updates.\nYou can provide feedback for this update here: %s'),
+                '{update_alias} has been pushed to the {repo} repository.\n'
+                '{install_instructions}\n'
+                'You can provide feedback for this update here: {update_url}\n\n'
+                'See also https://fedoraproject.org/wiki/QA:Updates_Testing for more '
+                'information on how to test updates.'),
             'validator': str},
         'testing_bug_msg': {
             'value': (
-                '\nSee https://fedoraproject.org/wiki/QA:Updates_Testing for\ninstructions on how '
-                'to install test updates.\nYou can provide feedback for this update here: %s'),
+                '{update_alias} has been pushed to the {repo} repository.\n'
+                '{install_instructions}\n'
+                'You can provide feedback for this update here: {update_url}\n\n'
+                'See also https://fedoraproject.org/wiki/QA:Updates_Testing for more '
+                'information on how to test updates.'),
             'validator': str},
         'top_testers_timeframe': {
             'value': 7,
diff --git a/bodhi/server/models.py b/bodhi/server/models.py
--- a/bodhi/server/models.py
+++ b/bodhi/server/models.py
@@ -4370,19 +4370,32 @@ def default_message(self, update: Update) -> str:
         Returns:
             The default comment to add to the bug related to the given update.
         """
-        message = config['stable_bug_msg'] % (
-            update.get_title(delim=', '), "%s %s" % (
-                update.release.long_name, update.status.description))
-        if update.status is UpdateStatus.testing:
-            template = config['testing_bug_msg']
-
+        install_msg = (
+            f'In short time you\'ll be able to install the update with the following '
+            f'command:\n`{update.install_command}`') if update.install_command else ''
+        msg_data = {'update_title': update.get_title(delim=", ", nvr=True),
+                    'update_beauty_title': update.get_title(beautify=True, nvr=True),
+                    'update_alias': update.alias,
+                    'repo': f'{update.release.long_name} {update.status.description}',
+                    'install_instructions': install_msg,
+                    'update_url': f'{config.get("base_address")}{update.get_url()}'}
+
+        if update.status is UpdateStatus.stable:
+            message = config['stable_bug_msg'].format(**msg_data)
+        elif update.status is UpdateStatus.testing:
             if update.release.id_prefix == "FEDORA-EPEL":
                 if 'testing_bug_epel_msg' in config:
                     template = config['testing_bug_epel_msg']
                 else:
+                    template = config['testing_bug_msg']
                     log.warning("No 'testing_bug_epel_msg' found in the config.")
+            else:
+                template = config['testing_bug_msg']
+            message = template.format(**msg_data)
+        else:
+            raise ValueError(f'Trying to post a default comment to a bug, but '
+                             f'{update.alias} is not in Stable or Testing status.')
 
-            message += template % (config.get('base_address') + update.get_url())
         return message
 
     def add_comment(self, update: Update, comment: typing.Optional[str] = None) -> None:


Test patch:
diff --git a/bodhi/tests/server/tasks/test_composer.py b/bodhi/tests/server/tasks/test_composer.py
--- a/bodhi/tests/server/tasks/test_composer.py
+++ b/bodhi/tests/server/tasks/test_composer.py
@@ -1792,14 +1792,15 @@ def test_modify_testing_bugs(self, on_qa, modified, *args):
             self.handler.run(api_version, task)
 
         expected_message = (
-            'bodhi-2.0-1.fc17 has been pushed to the Fedora 17 testing repository. If problems '
-            'still persist, please make note of it in this bug report.\nSee '
-            'https://fedoraproject.org/wiki/QA:Updates_Testing for\ninstructions on how to '
-            'install test updates.\nYou can provide feedback for this update here: {}')
+            'FEDORA-{}-a3bbe1a8f2 has been pushed to the Fedora 17 testing repository.\n\n'
+            'You can provide feedback for this update here: {}\n\n'
+            'See also https://fedoraproject.org/wiki/QA:Updates_Testing for more information '
+            'on how to test updates.')
         expected_message = expected_message.format(
+            time.strftime('%Y'),
             urlparse.urljoin(
                 config['base_address'],
-                '/updates/FEDORA-{}-a3bbe1a8f2'.format(datetime.datetime.now().year)))
+                f'/updates/FEDORA-{time.strftime("%Y")}-a3bbe1a8f2'))
         on_qa.assert_called_once_with(12345, expected_message)
 
     @mock.patch(**mock_taskotron_results)
@@ -1827,8 +1828,9 @@ def test_modify_stable_bugs(self, close, comment, *args):
         close.assert_called_with(
             12345,
             versions=dict(bodhi='bodhi-2.0-1.fc17'),
-            comment=('bodhi-2.0-1.fc17 has been pushed to the Fedora 17 stable repository. If '
-                     'problems still persist, please make note of it in this bug report.'))
+            comment=(f'FEDORA-{time.strftime("%Y")}-a3bbe1a8f2 has been pushed to the '
+                     f'Fedora 17 stable repository.\nIf problem still persists, '
+                     f'please make note of it in this bug report.'))
 
     @mock.patch(**mock_taskotron_results)
     @mock.patch('bodhi.server.tasks.composer.PungiComposerThread._wait_for_pungi')
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
@@ -233,7 +233,47 @@ def test_parent_security_bug(self, debug, comment):
 class TestBugDefaultMessage(BasePyTestCase):
     """Test Bug.default_message()."""
 
-    @mock.patch.dict(config, {'testing_bug_epel_msg': 'cool stuff %s'})
+    def test_default_msg_error(self):
+        """Test we raise a ValueError if the update is not in stable or testing."""
+        bug = model.Bug()
+        update = model.Update.query.first()
+        update.status = UpdateStatus.pending
+
+        with pytest.raises(ValueError) as exc:
+            bug.default_message(update)
+            assert str(exc.exception) == (
+                f'Trying to post a default comment to a bug, but '
+                f'{update.alias} is not in Stable or Testing status.')
+
+    @mock.patch.dict(config, {'stable_bug_msg': 'cool fedora stuff {update_alias}',
+                              'testing_bug_msg': 'not here'})
+    def test_stable_bug_msg(self):
+        """Test default message when update is in stable."""
+        bug = model.Bug()
+        update = model.Update.query.first()
+        update.release.id_prefix = 'FEDORA'
+        update.status = UpdateStatus.stable
+
+        message = bug.default_message(update)
+
+        assert 'cool fedora stuff {}'.format(update.alias) == message
+        assert 'not here' not in message
+
+    @mock.patch.dict(config, {'stable_bug_msg': 'not here',
+                              'testing_bug_msg': 'cool fedora stuff {update_alias}'})
+    def test_testing_bug_msg(self):
+        """Test default message when update is in testing."""
+        bug = model.Bug()
+        update = model.Update.query.first()
+        update.release.id_prefix = 'FEDORA'
+        update.status = UpdateStatus.testing
+
+        message = bug.default_message(update)
+
+        assert 'cool fedora stuff {}'.format(update.alias) == message
+        assert 'not here' not in message
+
+    @mock.patch.dict(config, {'testing_bug_epel_msg': 'cool epel stuff {update_url}'})
     def test_epel_with_testing_bug_epel_msg(self):
         """Test with testing_bug_epel_msg defined."""
         bug = model.Bug()
@@ -243,16 +283,12 @@ def test_epel_with_testing_bug_epel_msg(self):
 
         message = bug.default_message(update)
 
-        assert 'cool stuff {}'.format(config['base_address'] + update.get_url()) in message
-        assert update.builds[0].nvr in message
-        assert update.release.long_name in message
-        assert update.status.description in message
-        assert update.get_url() in message
+        assert 'cool epel stuff {}'.format(config['base_address'] + update.get_url()) == message
 
     @mock.patch('bodhi.server.models.log.warning')
     @mock.patch.dict(
         config,
-        {'stable_bug_msg': '%s%s', 'testing_bug_msg': '%s', 'base_address': 'b',
+        {'testing_bug_msg': 'cool fedora stuff {update_url}', 'base_address': 'b',
          'critpath.min_karma': 1, 'fedora_epel.mandatory_days_in_testing': 0},
         clear=True)
     def test_epel_without_testing_bug_epel_msg(self, warning):
@@ -265,10 +301,7 @@ def test_epel_without_testing_bug_epel_msg(self, warning):
         message = bug.default_message(update)
 
         warning.assert_called_once_with("No 'testing_bug_epel_msg' found in the config.")
-        assert update.builds[0].nvr in message
-        assert update.release.long_name in message
-        assert update.status.description in message
-        assert update.get_url() in message
+        assert 'cool fedora stuff {}'.format(config['base_address'] + update.get_url()) == message
 
 
 class TestBugModified(BasePyTestCase):
@@ -3703,11 +3736,15 @@ def test_get_url(self):
     def test_bug(self):
         bug = self.obj.bugs[0]
         assert bug.url == 'https://bugzilla.redhat.com/show_bug.cgi?id=1'
+        with pytest.raises(ValueError) as exc:
+            bug.testing(self.obj)
+            assert 'is not in Stable or Testing status' in str(exc.exception)
+        self.obj.status = UpdateStatus.testing
         bug.testing(self.obj)
         bug.add_comment(self.obj)
         bug.add_comment(self.obj, comment='testing')
         bug.close_bug(self.obj)
-        self.obj.status = UpdateStatus.testing
+        self.obj.status = UpdateStatus.stable
         bug.add_comment(self.obj)
 
     def test_expand_messages(self):