From cdc259d194b20456a27c540709dd20f6af055da8 Mon Sep 17 00:00:00 2001 From: Kamil Páral Date: Aug 14 2017 12:02:08 +0000 Subject: Merge branch 'develop' --- diff --git a/.arcconfig b/.arcconfig deleted file mode 100644 index 250d11d..0000000 --- a/.arcconfig +++ /dev/null @@ -1,5 +0,0 @@ -{ - "project_id" : "blockerbugs", - "conduit_uri" : "https://phab.qadevel.cloud.fedoraproject.org", - "arc.land.onto.default" : "develop" -} diff --git a/.gitignore b/.gitignore index 095c535..ea67979 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,4 @@ conf/settings.py .idea docs/_build/* blockerbugs_db.sqlite +/.cache/ diff --git a/README.md b/README.md new file mode 100644 index 0000000..2a58892 --- /dev/null +++ b/README.md @@ -0,0 +1,31 @@ +# Fedora Blockerbugs App + +The blockerbugs app is used to propose and track release blocking and freeze +exception bugs and related updates in Fedora releases currently under +development. + +The Fedora instance is running at: +https://qa.fedoraproject.org/blockerbugs + +If you notice bugs or have suggestions on how we can make this app better, +please report or discuss them in any of the following places: + +* [Blockerbugs project page](https://pagure.io/fedora-qa/blockerbugs) +* Via email on the [qa-devel list](https://lists.fedoraproject.org/archives/list/qa-devel@lists.fedoraproject.org/) +* In #fedora-qa on Freenode IRC + +## Documentation + +To see complete documentation of this project, run this command in the base of +the source tree: +``` +make docs +``` + +You can then see the docs in ``./docs/_build/html/index.html``. + +## Deployment + +If you're trying to deploy Blockerbugs, you might find some helpful instructions +in the +[Fedora infra docs](https://pagure.io/infra-docs/blob/master/f/docs/sysadmin-guide/sops/blockerbugs.rst). diff --git a/alembic/versions/cad797ffa042_add_request_to_update_model.py b/alembic/versions/cad797ffa042_add_request_to_update_model.py new file mode 100644 index 0000000..bdf8db2 --- /dev/null +++ b/alembic/versions/cad797ffa042_add_request_to_update_model.py @@ -0,0 +1,22 @@ +"""add request to update model + +Revision ID: cad797ffa042 +Revises: 230e79315bd +Create Date: 2016-11-09 10:09:17.410474 + +""" + +# revision identifiers, used by Alembic. +revision = 'cad797ffa042' +down_revision = '230e79315bd' + +from alembic import op +import sqlalchemy as sa + + +def upgrade(): + op.add_column(u'update', sa.Column('request', sa.String(length=80), nullable=True)) + + +def downgrade(): + op.drop_column(u'update', u'request') diff --git a/blockerbugs.spec b/blockerbugs.spec index f9b2587..c5f1dfa 100644 --- a/blockerbugs.spec +++ b/blockerbugs.spec @@ -3,13 +3,15 @@ %{!?python_sitearch: %global python_sitearch %(%{__python} -c "from distutils.sysconfig import get_python_lib; print(get_python_lib(1))")} Name: blockerbugs -Version: 0.4.4.12 +# NOTE: if you update version, *make sure* to also update +# `libtaskotron/__init__.py` and `docs/source/conf.py` +Version: 0.4.13 Release: 1%{?dist} Summary: Fedora QA Blocker Tracking Application License: GPLv2+ -URL: https://fedorahosted.org/fedora-qa -Source0: http://git.fedorahosted.org/cgit/blockerbugs.git/snapshot/blockerbugs-%{version}.tar.gz +URL: https://pagure.io/fedora-qa/blockerbugs +Source0: https://releases.pagure.org/fedora-qa/blockerbugs/blockerbugs-%{version}.tar.gz BuildArch: noarch @@ -131,6 +133,12 @@ cp -v docs/_build/man/*.1 %{buildroot}/%{_mandir}/man1/ %changelog +* Mon Aug 14 2017 Kamil Páral - 0.4.13-1 +- Correct update URLs +- Add tab for candidate compose / stable push request text +- project moved to Pagure +- enable release switcher to show more releases + * Tue Nov 8 2016 Tim Flink - 0.4.4.12-1 - limit cleanup to specified release (D1049) diff --git a/blockerbugs/__init__.py b/blockerbugs/__init__.py index ab7268f..7676145 100644 --- a/blockerbugs/__init__.py +++ b/blockerbugs/__init__.py @@ -9,7 +9,7 @@ import os from util.login import FakeFas # the version as used in setup.py and docs -__version__ = "0.4.4.12" +__version__ = "0.4.13" # Flask App diff --git a/blockerbugs/controllers/main.py b/blockerbugs/controllers/main.py index f611fd7..ee606a6 100644 --- a/blockerbugs/controllers/main.py +++ b/blockerbugs/controllers/main.py @@ -26,7 +26,7 @@ from sqlalchemy import func, desc, or_ import bugzilla from flask_fas_openid import fas_login_required -from blockerbugs import app, db +from blockerbugs import app, db, __version__ from blockerbugs.util.bz_interface import BlockerProposal, BZInterfaceError from blockerbugs.models.bug import Bug from blockerbugs.models.milestone import Milestone @@ -42,6 +42,7 @@ main = Blueprint('main', __name__) @app.before_request def before_request(): g.milestones = Milestone.query.filter_by(active=True).order_by(Milestone.name).all() + g.version = __version__ def get_recent_modifications(milestoneid): @@ -118,6 +119,32 @@ def get_milestone_updates_testing(milestone): Bug.proposed_fe == True, Bug.proposed_blocker == True))).all() return updates +def get_milestone_all_nonstable_blocker_fixes(milestone): + """ + return list of all non-stable, non-obsolete updates which are + marked as fixing any accepted blocker bug for milestone + """ + m_alias = db.aliased(Milestone) + updates = Update.query.join(m_alias, Update.milestones).filter( + m_alias.id == milestone.id, ~Update.status.in_(['obsolete', 'deleted']), + or_(Update.status != 'stable', Update.pending == True), + Update.bugs.any( + or_(Bug.accepted_blocker == True, Bug.accepted_0day == True, + Bug.accepted_prevrel == True))).all() + return updates + +def get_milestone_all_nonstable_fe_fixes(milestone): + """ + return list of all non-stable, non-obsolete updates which are + marked as fixing any accepted FE bug for milestone + """ + m_alias = db.aliased(Milestone) + updates = Update.query.join(m_alias, Update.milestones).filter( + m_alias.id == milestone.id, ~Update.status.in_(['obsolete', 'deleted']), + or_(Update.status != 'stable', Update.pending == True), + Update.bugs.any(Bug.accepted_fe == True)).all() + return updates + def get_current_milestone(): current_milestone = Milestone.query.filter_by(current=True).first() @@ -214,6 +241,21 @@ def display_release_updates(num, release_name): updates=updates, title="Fedora %s %s Blocker Bug Updates" % (milestone_info['number'], milestone_info['phase'])) +@main.route('/milestone///requests') +def display_release_requests(num, release_name): + release = Release.query.filter_by(number=num).first() + milestone = Milestone.query.filter_by(release=release, version=release_name).first() + if not milestone: + abort(404) + milestone_info = get_milestone_info(milestone) + blockers = get_milestone_all_nonstable_blocker_fixes(milestone) + fes = get_milestone_all_nonstable_fe_fixes(milestone) + # 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.mimetype = 'text/plain' + return response @main.route('/milestone///need_testing') def display_updates_need_testing(num, milestone_name): diff --git a/blockerbugs/models/update.py b/blockerbugs/models/update.py index 777beec..2cfbe31 100644 --- a/blockerbugs/models/update.py +++ b/blockerbugs/models/update.py @@ -43,6 +43,7 @@ class Update(db.Model): karma = db.Column(db.Integer, unique=False) stable_karma = db.Column(db.Integer, unique=False) status = db.Column(db.String(80), unique=False) + request = db.Column(db.String(80), unique=False, nullable=True) pending = db.Column(db.Boolean, unique=False) date_submitted = db.Column(db.DateTime) date_pushed_testing = db.Column(db.DateTime, nullable=True) @@ -65,6 +66,7 @@ class Update(db.Model): self.url = url self.karma = karma self.status = status + self.request = None self.bugs = bugs self.date_submitted = date_submitted self.release = release @@ -83,6 +85,7 @@ class Update(db.Model): self.karma = updateinfo['karma'] self.stable_karma = updateinfo['stable_karma'] self.status = updateinfo['status'] + self.request = updateinfo['request'] self.date_submitted = updateinfo['date_submitted'] if updateinfo['date_pushed_testing']: self.date_pushed_testing = updateinfo['date_pushed_testing'] diff --git a/blockerbugs/templates/base_nav.html b/blockerbugs/templates/base_nav.html index 9f011d3..44390b9 100644 --- a/blockerbugs/templates/base_nav.html +++ b/blockerbugs/templates/base_nav.html @@ -12,14 +12,13 @@ class="active" {%- endmacro %} {% block navigation %} -
- {% endblock %} {% endblock %} @@ -44,8 +42,9 @@ class="active" Not synced with Red Hat Bugzilla. {% endif %}
- This application is open source! Get the code - or look at development plans. + This application is open source! Visit its project page. +
+ Version {{ g.version }}
diff --git a/blockerbugs/templates/index.html b/blockerbugs/templates/index.html index b2398b0..0aab11f 100644 --- a/blockerbugs/templates/index.html +++ b/blockerbugs/templates/index.html @@ -23,11 +23,10 @@ places: @@ -82,8 +81,9 @@
- This application is open source! Get the code - or look at development plans. + This application is open source! Visit its project page. +
+ Version {{ g.version }}
diff --git a/blockerbugs/templates/milestone_base.html b/blockerbugs/templates/milestone_base.html index 5237934..7373e33 100644 --- a/blockerbugs/templates/milestone_base.html +++ b/blockerbugs/templates/milestone_base.html @@ -16,6 +16,7 @@ class="active"
  • Spins
  • Stats
  • IRC Format
  • +
  • Requests
  • diff --git a/blockerbugs/templates/requests.txt b/blockerbugs/templates/requests.txt new file mode 100644 index 0000000..f4a5252 --- /dev/null +++ b/blockerbugs/templates/requests.txt @@ -0,0 +1,27 @@ +{% autoescape false -%} +### CANDIDATE COMPOSE ### + +== 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 %} +{%- 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 %} +{%- endfor %} + + +### FREEZE PUSH ### + + +== 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 %} +{%- 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 %} +{%- endfor %} +{% endautoescape %} diff --git a/blockerbugs/util/update_sync.py b/blockerbugs/util/update_sync.py index 5432a02..48573de 100644 --- a/blockerbugs/util/update_sync.py +++ b/blockerbugs/util/update_sync.py @@ -50,6 +50,8 @@ class UpdateSync(object): updateinfo['date_pushed_testing'] = None updateinfo['date_pushed_stable'] = None updateinfo['pending'] = False + # this will be None if there is no request + updateinfo['request'] = update.request if update.status == 'pending': updateinfo['pending'] = True @@ -70,12 +72,7 @@ class UpdateSync(object): updateinfo['title'] = str(update.title) updateinfo['karma'] = update.karma updateinfo['stable_karma'] = update.stable_karma - - if update.updateid is None: - urlsufix = updateinfo['title'] - else: - urlsufix = str(update.updateid) - updateinfo['url'] = '%s%s' % (bodhi_baseurl, urlsufix) + updateinfo['url'] = update.url updateinfo['date_submitted'] = datetime.strptime(update.date_submitted, '%Y-%m-%d %H:%M:%S') @@ -98,19 +95,21 @@ class UpdateSync(object): return False def clean_updates(self, updates, relid): + """Remove updates for this release which are no longer related + to any blocker or freeze exception bug from the database. + """ query_updates = Update.query.filter( - Update.status != 'obsolete', - Update.status != 'deleted', Update.release_id == relid, ).all() db_updates = set(update.title for update in query_updates) bodhi_updates = set(update['title'] for update in updates) - deleted_updates = db_updates.difference(bodhi_updates) + unneeded_updates = db_updates.difference(bodhi_updates) for update in query_updates: - if update.title in deleted_updates: - update.status = 'deleted' - self.db.session.add(update) + if update.title in unneeded_updates: + self.log.debug("Removing no longer relevant update %s" % + update.title) + self.db.session.delete(update) self.db.session.commit() def search_updates(self, bugids, release_num): @@ -166,7 +165,7 @@ class UpdateSync(object): e=ex, r=release)) return - # mark deleted updates + # remove no longer relevant updates from the database self.clean_updates(updates, release.id) for update in updates: diff --git a/docs/source/conf.py b/docs/source/conf.py index 1e58d4a..f127364 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -50,7 +50,7 @@ copyright = u'2016, Fedora QA' # The short X.Y version. version = '0.4' # The full version, including alpha/beta/rc tags. -release = '0.4.4.12' +release = '0.4.13' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/source/development.rst b/docs/source/development.rst index 24bcbf1..d7ed44b 100644 --- a/docs/source/development.rst +++ b/docs/source/development.rst @@ -15,14 +15,12 @@ The instructions here will use virtualenv so that there are no potential conflicts with system libs. At a bare minimum, you will need: * python-virtualenv - * libcurl-devel - * koji - * rpm-python - * pyOpenSSL +* python2-fedora-flask (as a workaround for `python-fedora bug + `_) If you plan on developing against a database other than sqlite, you will need to have that installed and configured, similarly to the production install @@ -33,12 +31,7 @@ Create a Virtualenv Create a new virtualenv in the base of the source tree:: - virtualenv --distribute env_blockerbugs - pushd env_blockerbugs/lib/python2.7/site-packages - ln -s /usr/lib/python2.7/site-packages/koji - ln -s /usr/lib64/python2.7/site-packages/rpm - ln -s /usr/lib64/python2.7/site-packages/OpenSSL - popd + virtualenv --system-site-packages env_blockerbugs In order to install python packages into the virtualenv or use the packages inside the virtualenv, it must be activated:: @@ -129,4 +122,3 @@ from the root project directory with:: The ``TEST='true'`` part is rather important as some of the tests will wipe the database and fill it with less useful data. The ``TEST`` configuration forces the use of an in-memory SQLite3 database. - diff --git a/docs/source/development_tasks.rst b/docs/source/development_tasks.rst index 61d9957..86f8d4e 100644 --- a/docs/source/development_tasks.rst +++ b/docs/source/development_tasks.rst @@ -12,52 +12,20 @@ in Fedora as ``gitflow``). Released code is kept in ``master`` and yet-to-be-released code is in ``develop``. Generally, new code is submitted as feature branches of the form -``feature/tXXX-$FEATURE`` where ``XXX`` is the feature's ticket number in trac +``feature/tXXX-$FEATURE`` where ``XXX`` is the feature's ticket number and ``$FEATURE`` is a short human-recognizable phrase to identify the branch without needing to memorize ticket numbers. + Submitting Code =============== -Code can be submitted in one of two ways: through pushing to a feature branch or -submitting a patch to `our reviewboard instance `_ -Either way, the process is similar: - - * Create a review request on reviewboard - - Please fill out the relevant fields (description, testing done, bugs fixed etc.) - - Make sure you select the 'blockerbugs' group for the review request - this - will email the ``qa-devel`` list and notify other developers of the review - - * Once the review is complete, merge the code into the ``develop`` branch. - - If you do not have write privileges, this will be done for you - -Creating a Review Request with post-review ------------------------------------------- - -An easy method for creating a review request involves using the ``post-review`` -tool which is written by the reviewboard developers (Fedora package ``RBTools``). - -If you're submitting a review request for the feature branch ``$FEATURE``, you -would use the following command from the repository's root directory to start -a minimal review request **after** pushing your branch to origin:: - - post-review --tracking-branch=origin/develop --branch origin/feature/$FEATURE - -This doesn't fill out all of the required fields and you will need to login to -the reviewboard instance in order to finish the review submission process but this -is at least a start. - -Updating a Review Request with post-review ------------------------------------------- - -We wouldn't have a need for code reviews if the code never changed after initial -review. Many times, an update is needed to code before the review process is -complete. +Create a pull request for review on the project page: +https://pagure.io/fedora-qa/blockerbugs -To update an existing review request ``$ID`` (the id number of the review request -in reviewboard), use the following command **after** pushing your code to origin:: +Once the review is complete, merge the code into the ``develop`` branch. If you +do not have write privileges, this will be done for you - post-review -r $REVIEW --tracking-branch=origin/develop --branch origin/feature/$FEATURE Release Process =============== diff --git a/setup.py b/setup.py index 2422de2..4d6fef4 100644 --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ setup(name='blockerbugs', author='Tim Flink', author_email='tflink@fedoraproject.org', license='GPLv2+', - url='https://fedorahosted.org/fedora-qa', + url='https://pagure.io/fedora-qa/blockerbugs', packages=['blockerbugs', 'blockerbugs.controllers', 'blockerbugs.util', 'blockerbugs.models', 'blockerbugs.controllers.api', diff --git a/testing/test_controllers.py b/testing/test_controllers.py index bf0fd00..b312a4a 100644 --- a/testing/test_controllers.py +++ b/testing/test_controllers.py @@ -200,29 +200,29 @@ class TestGetFunctions(object): db.session.rollback() db.drop_all() db.create_all() - release = add_release(99) - cls.milestone = add_milestone(release, 'final', 100, 101, + cls.release = add_release(99) + cls.milestone = add_milestone(cls.release, 'final', 100, 101, '99-final', True) - add_milestone(release, 'beta', 200, 201, '99-beta') + add_milestone(cls.release, 'beta', 200, 201, '99-beta') add_spin('test-spin1', SpinType.TC, [], cls.milestone, state=SpinState.built) 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], - release, [cls.milestone]) + cls.release, [cls.milestone]) cls.update_pending_stable.pending = True cls.update_stable = add_update(u'test-stable1.fc99', u'stable', [bug1], - release, [cls.milestone]) + cls.release, [cls.milestone]) cls.update_stable = add_update(u'test-stable2.fc99', u'stable', [bug2], - release, [cls.milestone]) + cls.release, [cls.milestone]) cls.update_pending_testing = add_update(u'test-pending-testing.fc99', u'testing', [bug1], - release, [cls.milestone]) + cls.release, [cls.milestone]) cls.update_pending_testing.pending = True cls.update_testing1 = add_update(u'test-testing1.fc99', u'testing', [bug1], - release, [cls.milestone]) + cls.release, [cls.milestone]) cls.update_testing2 = add_update(u'test-testing2.fc99', u'testing', [bug2], - release, [cls.milestone]) + cls.release, [cls.milestone]) db.session.commit() @classmethod @@ -242,3 +242,22 @@ class TestGetFunctions(object): assert len(updates) == 1 update = updates[0] assert self.update_testing1 == update + + def test_get_milestone_all_nonstable_blocker_fixes(self): + updates = main.get_milestone_all_nonstable_blocker_fixes(self.milestone) + assert len(updates) == 3 + 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) + assert len(updates) == 1 + update = updates[0] + assert update_testing3 == update diff --git a/testing/test_updatesync_extract_information.py b/testing/test_updatesync_extract_information.py index f83c4a6..2fdab5b 100644 --- a/testing/test_updatesync_extract_information.py +++ b/testing/test_updatesync_extract_information.py @@ -21,6 +21,7 @@ basicupdate = Bunch( karma=1, unstable_karma=-3, updateid=u'FEDORA-2012-13902', + url=u'https://bodhi.stg.fedoraproject.org/FEDORA-2012-13902', bugs=[Bunch(bug_id=856836, parent=False, security=False, title=u'/etc/fstab is not written correctly after live install (F18 Alpha RC2+)')], builds=[Bunch(nvr=u'anaconda-18.6.8-1.fc18', @@ -137,15 +138,6 @@ class TestUpdateSyncExtractInformation(object): assert (updateinfo['url'] == 'https://bodhi.stg.fedoraproject.org/%s' % self.testupdate.updateid) - def test_extract_url_no_updateid(self): - ref_title = u'magic-fixall-update-1.1-0' - self.testupdate.title = ref_title - self.testupdate.updateid = None - - updateinfo = self.testsync.extract_information(self.testupdate) - - assert (updateinfo['url'] == 'https://bodhi.stg.fedoraproject.org/%s' % ref_title) - def test_extract_date_pushed_testing_intesting(self): self.testupdate.status = u'testing' self.testupdate.request = None diff --git a/testing/testfunc_update_sync.py b/testing/testfunc_update_sync.py index d43ea4e..40ee6a2 100644 --- a/testing/testfunc_update_sync.py +++ b/testing/testfunc_update_sync.py @@ -31,6 +31,7 @@ base_update = Bunch( release=Bunch(dist_tag=u'f99', id_prefix=u'FEDORA', locked=True, long_name=u'Fedora 99', name=u'F99'), updateid='FEDORA-2012-13902', + url=u'https://bodhi.stg.fedoraproject.org/FEDORA-2012-13902', ) update_for_bugs_2000_2001 = copy(base_update) @@ -195,16 +196,31 @@ class TestfuncUpdateSync(object): assert 'Internal Server Error' in log_error.call_args[0][0] def test_sync_clean_updates(self): - add_bug(3000, 'testbug1', self.test_milestone99alpha) + bug1 = add_bug(3000, 'testbug1', self.test_milestone99alpha) self.update_sync.sync_updates(self.test_release99) - updates = Update.query.filter(Update.status == 'deleted').all() - assert len(updates) == 0 + updates = Update.query.all() + # by default we have two updates for bug #3000 + assert len(updates) == 2 + # now we do a sync with only *one* update for bug #3000 b = FakeBodhiInterface b.updates[('f99', '3000')] = [update1_for_bug_3000] update_sync = UpdateSync(db, b) - update_sync.sync_updates(self.test_release99) - updates = Update.query.filter(Update.status == 'deleted').all() + + # so now we should have just *one* update in the db, the other + # update should disappear. This is testing the (no longer + # likely) case where an update disappears entirely from Bodhi + updates = Update.query.all() assert len(updates) == 1 + + # Now let's mark the bug as closed and sync again. + bug1.active = False + add_bug(4000, 'testbug2', self.test_milestone99alpha) + self.update_sync.sync_updates(self.test_release99) + + # Now the other update should be removed from the db, as it + # no longer relates to an open blocker/FE bug + updates = Update.query.all() + assert len(updates) == 0