#111 Filter bugs harder in the compose/push request templates
Merged 4 years ago by adamwill. Opened 4 years ago by adamwill.
fedora-qa/ adamwill/blockerbugs fix-requests-filtering  into  develop

@@ -22,7 +22,7 @@ 

  

  from flask import Blueprint, render_template, redirect, url_for, abort, g, flash, make_response, request

  import datetime

- from sqlalchemy import func, desc, or_

+ from sqlalchemy import func, desc, or_, and_

  import bugzilla

  from flask_fas_openid import fas_login_required

  
@@ -131,8 +131,14 @@ 

          m_alias.id == milestone.id, ~Update.status.in_(['obsolete', 'deleted', 'unpushed']),

          or_(Update.status != 'stable', Update.pending == True),

          Update.bugs.any(

-             or_(Bug.accepted_blocker == True, Bug.accepted_0day == True,

-                 Bug.accepted_prevrel == True))).all()

+             and_(

+                 Bug.milestone_id == milestone.id,

+                 or_(

+                     Bug.accepted_blocker == True, Bug.accepted_0day == True

+                 )

+             )

+         )

+     ).all()

      return updates

  

  def get_milestone_all_nonstable_fe_fixes(milestone):
@@ -144,7 +150,13 @@ 

      updates = Update.query.join(m_alias, Update.milestones).filter(

          m_alias.id == milestone.id,  ~Update.status.in_(['obsolete', 'deleted', 'unpushed']),

          or_(Update.status != 'stable', Update.pending == True),

-         Update.bugs.any(Bug.accepted_fe == True)).all()

+         Update.bugs.any(

+             and_(

+                 Bug.milestone_id == milestone.id,

+                 Bug.accepted_fe == True

+             )

+         )

+     ).all()

      return updates

  

  
@@ -258,7 +270,7 @@ 

      # if an update fixes both blockers and fes, drop it from fe list

      fes = [fe for fe in fes if fe not in blockers]

  

-     response = make_response(render_template('requests.txt', blockers=blockers, fes=fes, info=milestone_info))

+     response = make_response(render_template('requests.txt', blockers=blockers, fes=fes, milestone=milestone.id))

      response.mimetype = 'text/plain'

      return response

  

@@ -3,12 +3,12 @@ 

  

  == Blockers ==

  {% for update in blockers %}

- * [{{ update.title }}]({{ update.url }}) for {%- for bug in update.bugs %} [#{{ bug.bugid }}](https://bugzilla.redhat.com/show_bug.cgi?id={{ bug.bugid }}){% if bug.accepted_fe and not bug.accepted_blocker and not bug.accepted_prevrel and not bug.accepted_0day %} (FE){% endif %}{% endfor %}

+ * [{{ update.title }}]({{ update.url }}) for {%- for bug in update.bugs if bug.milestone_id == milestone and (bug.accepted_blocker or bug.accepted_0day or bug.accepted_fe) %} [#{{ bug.bugid }}](https://bugzilla.redhat.com/show_bug.cgi?id={{ bug.bugid }}){% if bug.accepted_fe and not bug.accepted_blocker and not bug.accepted_prevrel and not bug.accepted_0day %} (FE){% endif %}{% endfor %}

  {%- endfor %}

  

  == Freeze exceptions ==

  {% for update in fes %}

- * [{{ update.title }}]({{ update.url }}) for {%- for bug in update.bugs %} [#{{ bug.bugid }}](https://bugzilla.redhat.com/show_bug.cgi?id={{ bug.bugid }}){% endfor %}

+ * [{{ update.title }}]({{ update.url }}) for {%- for bug in update.bugs if bug.milestone_id == milestone and (bug.accepted_blocker or bug.accepted_0day or bug.accepted_fe) %} [#{{ bug.bugid }}](https://bugzilla.redhat.com/show_bug.cgi?id={{ bug.bugid }}){% endfor %}

  {%- endfor %}

  

  
@@ -17,11 +17,11 @@ 

  

  == Blockers ==

  {% for update in blockers if update.request == 'stable' %}

- * [{{ update.title }}]({{ update.url }}) for {%- for bug in update.bugs %} [#{{ bug.bugid }}](https://bugzilla.redhat.com/show_bug.cgi?id={{ bug.bugid }}){% if bug.accepted_fe and not bug.accepted_blocker and not bug.accepted_prevrel and not bug.accepted_0day %} (FE){% endif %}{% endfor %}

+ * [{{ update.title }}]({{ update.url }}) for {%- for bug in update.bugs if bug.milestone_id == milestone and (bug.accepted_blocker or bug.accepted_0day or bug.accepted_fe) %} [#{{ bug.bugid }}](https://bugzilla.redhat.com/show_bug.cgi?id={{ bug.bugid }}){% if bug.accepted_fe and not bug.accepted_blocker and not bug.accepted_prevrel and not bug.accepted_0day %} (FE){% endif %}{% endfor %}

  {%- endfor %}

  

  == Freeze exceptions ==

  {% for update in fes if update.request == 'stable' %}

- * [{{ update.title }}]({{ update.url }}) for {%- for bug in update.bugs %} [#{{ bug.bugid }}](https://bugzilla.redhat.com/show_bug.cgi?id={{ bug.bugid }}){% endfor %}

+ * [{{ update.title }}]({{ update.url }}) for {%- for bug in update.bugs if bug.milestone_id == milestone and (bug.accepted_blocker or bug.accepted_0day or bug.accepted_fe) %} [#{{ bug.bugid }}](https://bugzilla.redhat.com/show_bug.cgi?id={{ bug.bugid }}){% endfor %}

  {%- endfor %}

  {% endautoescape %}

file modified
+81 -14
@@ -1,5 +1,7 @@ 

  import datetime

  

+ from flask import render_template

+ 

  from blockerbugs.models.milestone import Milestone

  from blockerbugs.models.release import Release

  from blockerbugs.models.bug import Bug
@@ -170,14 +172,20 @@ 

          db.drop_all()

          db.create_all()

          cls.release = add_release(99)

-         cls.milestone = add_milestone(cls.release, 'final', 100, 101,

-                                         '99-final', True)

-         add_milestone(cls.release, 'beta', 200, 201, '99-beta')

+         cls.milestone = add_milestone(cls.release, 'beta', 100, 101,

+                                         '99-beta', True)

          bug1 = add_bug(9000, 'testbug1', cls.milestone)

          bug2 = add_bug(9001, 'testbug2', cls.milestone)

          bug2.accepted_blocker = False

-         cls.update_pending_stable = add_update(u'test-pending-stable.fc99', u'stable', [bug1],

-                             cls.release, [cls.milestone])

+         # a bug that fixes a Final blocker

+         finalmile = add_milestone(cls.release, 'final', 200, 201, '99-final')

+         finalbug = add_bug(9002, 'finalbug', finalmile)

+         # we add finalbug to this update for requests.txt testing:

+         # it should *not* show in the generated request, the update

+         # will be in the request but it should only list bug1, not

+         # finalbug, as bug1 is for Beta and finalbug for Final

+         cls.update_pending_stable = add_update(u'test-pending-stable.fc99', u'stable',

+                             [bug1, finalbug], cls.release, [cls.milestone])

          cls.update_pending_stable.pending = True

          cls.update_stable = add_update(u'test-stable1.fc99', u'stable', [bug1],

                               cls.release, [cls.milestone])
@@ -190,6 +198,27 @@ 

                                          cls.release, [cls.milestone])

          cls.update_testing2 = add_update(u'test-testing2.fc99', u'testing', [bug2],

                                           cls.release, [cls.milestone])

+         # add an update that fixes a bug which is an accepted Beta FE

+         # and a proposed Beta blocker, and another bug which is an

+         # accepted Final blocker, for fix function tests

+         betafebug = add_bug(9003, 'betafebug', cls.milestone)

+         betafebug.accepted_blocker = False

+         betafebug.proposed_blocker = True

+         betafebug.accepted_fe = True

+         cls.update_complex = add_update(u'test-complex.fc99', u'testing',

+                                         [betafebug, finalbug],

+                                         cls.release, [cls.milestone, finalmile])

+         # also an update that fixes a proposed Beta FE and an accepted

+         # Final FE for the same purpose

+         propbetafebug = add_bug(9004, 'propbetafebug', cls.milestone)

+         propbetafebug.accepted_blocker = False

+         propbetafebug.proposed_fe = True

+         finalfebug = add_bug(9005, 'finalfebug', finalmile)

+         finalfebug.accepted_blocker = False

+         finalfebug.accepted_fe = True

+         cls.update_complexfe = add_update(u'test-complexfe.fc99', u'testing',

+                                           [propbetafebug, finalfebug],

+                                           cls.release, [cls.milestone, finalmile])

          db.session.commit()

  

      @classmethod
@@ -206,25 +235,63 @@ 

  

      def test_get_testing_status_and_has_bugs_updates(self):

          updates = main.get_milestone_updates_testing(self.milestone)

-         assert len(updates) == 1

-         update = updates[0]

-         assert self.update_testing1 == update

+         assert len(updates) == 3

+         expected = [self.update_testing1, self.update_complex, self.update_complexfe]

+         updates.sort(key=lambda x: x.title)

+         expected.sort(key=lambda x: x.title)

+         assert updates == expected

  

      def test_get_milestone_all_nonstable_blocker_fixes(self):

          updates = main.get_milestone_all_nonstable_blocker_fixes(self.milestone)

          assert len(updates) == 3

+         # we should NOT find complex or complexfe here!

          expected = [self.update_pending_stable, self.update_pending_testing, self.update_testing1]

          updates.sort(key=lambda x: x.title)

          expected.sort(key=lambda x: x.title)

          assert updates == expected

  

      def test_get_milestone_all_nonstable_fe_fixes(self):

-         bug3 = add_bug(9002, 'testbug3', self.milestone)

-         bug3.accepted_blocker = False

-         bug3.accepted_fe = True

-         update_testing3 = add_update(u'test-testing3.fc99', u'testing', [bug3],

-                                      self.release, [self.milestone])

          updates = main.get_milestone_all_nonstable_fe_fixes(self.milestone)

+         # we should find complex (as it fixes an accepted Beta FE) but

+         # NOT complexfe here!

          assert len(updates) == 1

          update = updates[0]

-         assert update_testing3 == update

+         assert self.update_complex == update

+ 

+     def test_requests(self):

+         # we also test the requests template generation here, as it's

+         # what the _fixes queries back and it makes sense to do it

+         # with all these bits in place

+         blockers = main.get_milestone_all_nonstable_blocker_fixes(self.milestone)

+         fes = main.get_milestone_all_nonstable_fe_fixes(self.milestone)

+         with app.app_context():

+             rendered = render_template('requests.txt', blockers=blockers,

+                                        fes=fes, milestone=self.milestone.id)

+         # split up the text a bit

+         separator = rendered.index("== Freeze exceptions")

+         blockers = rendered[:separator]

+         fes = rendered[separator:]

+         # check all the right updates and bugs are and are not in the

+         # correct sections

+         assert "test-pending-stable" in blockers

+         assert "test-stable" not in rendered

+         assert "test-pending-testing" in blockers

+         assert "test-testing1" in blockers

+         assert "test-testing2" not in rendered

+         assert "test-complex." not in blockers

+         assert "test-complex." in fes

+         assert "test-complexfe" not in rendered

+         # bug 1 id

+         assert "9000" in blockers

+         assert "9000" not in fes

+         # bug 2 id

+         assert "9001" not in rendered

+         # finalbug id

+         assert "9002" not in rendered

+         # betafebug id

+         assert "9003" not in blockers

+         assert "9003" in fes

+         # propbetafebug id

+         assert "9004" not in rendered

+         # finalfebug id

+         assert "9005" not in rendered

There were a few issues affecting the 'requests' tab.

First, the underlying queries had a slight bug: they filtered
the updates by milestone, then further filtered by whether any
bug associated with the update was an accepted blocker or
accepted FE. But this is wrong for the case where an update is
associated with Beta milestone because of a proposed blocker
or FE, and also fixes an accepted blocker or FE for Final:
the queries would return the update in this case, where they
should not. The blocker query also included accepted_prevrel
bugs, when it probably shouldn't: prevrel blockers should be
fixed in previous releases, not the Branched release. An update
for Branched marked as fixing an AcceptedPreviousRelease bug
is probably a mistake, and we shouldn't include it in this
query or the stable push/compose requests.

Second, when generating the list of bugs that each update would
resolve, the requests.txt template itself just iterated over
all bugs associated with the update, without considering their
milestone or whether they were accepted. So it includes Final
blocker/FE bugs in the list for a Beta request, if the update
fixes any, and it also includes proposed blockers/FEs if the
update fixes some of those along with accepted blockers/FEs.
That's wrong. This is not very important - the list is only
informational - but it is incorrect and confusing, so we should
fix it.

We enhance the tests to cover some of this. It doesn't cover all
possible scenarios - that'd get pretty messy without a heavy
rewrite of this stuff using parametrization or something - but
it's definitely better.

Signed-off-by: Adam Williamson awilliam@redhat.com

rebased onto 8fa2e47

4 years ago

@mohanboddu just FYI, this should fix some things you may have noticed in the requests (bugs being listed that shouldn't be and stuff). I've been manually checking to make sure we don't pull in updates we shouldn't be, but sometimes I didn't bother manually editing out bugs that shouldn't be listed as it didn't really matter much.

@adamwill LGTM, feel free to merge :)

I'll deploy it to openshift instance as soon as it's merged, so you can use that for push requests during freeze.

Pull-Request has been merged by adamwill

4 years ago

@mohanboddu just FYI, this should fix some things you may have noticed in the requests (bugs being listed that shouldn't be and stuff). I've been manually checking to make sure we don't pull in updates we shouldn't be, but sometimes I didn't bother manually editing out bugs that shouldn't be listed as it didn't really matter much.

Thanks @adamwill , this definitely helps.