Repository: fedora-infra/bodhi

Issue:
Test failure due to integrity error
The recent merges of pull requests combined to cause a test to fail that didn't fail on any individual pull request:

```
Error Message

IntegrityError: (sqlite3.IntegrityError) NOT NULL constraint failed: updates.release_id [SQL: u'UPDATE updates SET release_id=? WHERE updates.id = ?'] [parameters: (None, 1)]
Stacktrace

self = <bodhi.tests.server.services.test_updates.TestUpdatesService testMethod=test_edit_missing_release>

    def test_edit_missing_release(self):
        """Editing an update that is missing a release should report an error."""
        update = self.db.query(Update).one()
        update.release = None
        update_json = self.get_update(update.title)
        update_json['csrf_token'] = self.get_csrf_token()
        update_json['notes'] = u'testing!!!'
        update_json['edited'] = update.title
        # This will cause an extra error in the output that we aren't testing here, so delete it.
        del update_json['requirements']
    
>       res = self.app.post_json('/updates/', update_json, status=400)

bodhi/tests/server/services/test_updates.py:732: 
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 
/usr/lib/python2.7/site-packages/webtest/utils.py:36: in wrapper
    return self._gen_request(method, url, **kw)
/usr/lib/python2.7/site-packages/webtest/app.py:740: in _gen_request
    expect_errors=expect_errors)
/usr/lib/python2.7/site-packages/webtest/app.py:610: in do_request
    res = req.get_response(app, catch_exc_info=True)
/usr/lib/python2.7/site-packages/webob/request.py:1323: in send
    application, catch_exc_info=True)
/usr/lib/python2.7/site-packages/webob/request.py:1291: in call_application
    app_iter = application(self.environ, start_response)
/usr/lib/python2.7/site-packages/webtest/lint.py:198: in lint_app
    iterator = application(environ, start_response_wrapper)
/usr/lib/python2.7/site-packages/pyramid/router.py:270: in __call__
    response = self.execution_policy(environ, self)
/usr/lib/python2.7/site-packages/pyramid/router.py:278: in default_execution_policy
    return request.invoke_exception_view(reraise=True)
/usr/lib/python2.7/site-packages/pyramid/view.py:748: in invoke_exception_view
    reraise_(*exc_info)
/usr/lib/python2.7/site-packages/pyramid/router.py:276: in default_execution_policy
    return router.invoke_request(request)
/usr/lib/python2.7/site-packages/pyramid/router.py:260: in invoke_request
    request._process_finished_callbacks()
/usr/lib/python2.7/site-packages/pyramid/request.py:147: in _process_finished_callbacks
    callback(self)
bodhi/tests/server/base.py:171: in cleanup
    Session().commit()
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/session.py:896: in commit
    self.transaction.commit()
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/session.py:455: in commit
    self._prepare_impl()
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/session.py:435: in _prepare_impl
    self.session.flush()
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/session.py:2112: in flush
    self._flush(objects)
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/session.py:2230: in _flush
    transaction.rollback(_capture_exception=True)
/usr/lib64/python2.7/site-packages/sqlalchemy/util/langhelpers.py:60: in __exit__
    compat.reraise(exc_type, exc_value, exc_tb)
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/session.py:2194: in _flush
    flush_context.execute()
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/unitofwork.py:373: in execute
    rec.execute(self)
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/unitofwork.py:532: in execute
    uow
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/persistence.py:174: in save_obj
    mapper, table, update)
/usr/lib64/python2.7/site-packages/sqlalchemy/orm/persistence.py:710: in _emit_update_statements
    execute(statement, multiparams)
/usr/lib64/python2.7/site-packages/sqlalchemy/engine/base.py:914: in execute
    return meth(self, multiparams, params)
/usr/lib64/python2.7/site-packages/sqlalchemy/sql/elements.py:323: in _execute_on_connection
    return connection._execute_clauseelement(self, multiparams, params)
/usr/lib64/python2.7/site-packages/sqlalchemy/engine/base.py:1010: in _execute_clauseelement
    compiled_sql, distilled_params
/usr/lib64/python2.7/site-packages/sqlalchemy/engine/base.py:1146: in _execute_context
    context)
/usr/lib64/python2.7/site-packages/sqlalchemy/engine/base.py:1341: in _handle_dbapi_exception
    exc_info
/usr/lib64/python2.7/site-packages/sqlalchemy/util/compat.py:203: in raise_from_cause
    reraise(type(exception), exception, tb=exc_tb, cause=cause)
/usr/lib64/python2.7/site-packages/sqlalchemy/engine/base.py:1139: in _execute_context
    context)
_ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ _ 

self = <sqlalchemy.dialects.sqlite.pysqlite.SQLiteDialect_pysqlite object at 0x7fd67441da10>
cursor = <sqlite3.Cursor object at 0x7fd671fae5e0>
statement = 'UPDATE updates SET release_id=? WHERE updates.id = ?'
parameters = (None, 1)
context = <sqlalchemy.dialects.sqlite.base.SQLiteExecutionContext object at 0x7fd672d06550>

    def do_execute(self, cursor, statement, parameters, context=None):
>       cursor.execute(statement, parameters)
E       IntegrityError: (sqlite3.IntegrityError) NOT NULL constraint failed: updates.release_id [SQL: u'UPDATE updates SET release_id=? WHERE updates.id = ?'] [parameters: (None, 1)]

/usr/lib64/python2.7/site-packages/sqlalchemy/engine/default.py:450: IntegrityError
```


Discussion:

Resolving patch:
diff --git a/bodhi/server/validators.py b/bodhi/server/validators.py
--- a/bodhi/server/validators.py
+++ b/bodhi/server/validators.py
@@ -260,17 +260,6 @@ def validate_build_tags(request, **kwargs):
             return
 
         release = update.release
-        if not release:
-            # If the edited update has no release, something went wrong a while
-            # ago.  We're already in a corrupt state.  We can't perform the
-            # check further down as to whether or not the user is submitting
-            # builds that do or do not match the release of this update...
-            # because we don't know the release of this update.
-            request.errors.add('body', 'edited',
-                               'Pre-existing update %s has no associated '
-                               '"release" object.  Please submit a ticket to '
-                               'resolve this.' % edited)
-            return
     else:
         valid_tags = tag_types['candidate']
 


Test patch:
diff --git a/bodhi/tests/server/services/test_updates.py b/bodhi/tests/server/services/test_updates.py
--- a/bodhi/tests/server/services/test_updates.py
+++ b/bodhi/tests/server/services/test_updates.py
@@ -718,30 +718,6 @@ def test_edit_koji_error(self):
         self.assertEqual(res.json, expected_json)
         listTags.assert_called_once_with(update.title)
 
-    def test_edit_missing_release(self):
-        """Editing an update that is missing a release should report an error."""
-        update = self.db.query(Update).one()
-        update.release = None
-        update_json = self.get_update(update.title)
-        update_json['csrf_token'] = self.get_csrf_token()
-        update_json['notes'] = u'testing!!!'
-        update_json['edited'] = update.title
-        # This will cause an extra error in the output that we aren't testing here, so delete it.
-        del update_json['requirements']
-
-        res = self.app.post_json('/updates/', update_json, status=400)
-
-        expected_json = {
-            u'status': u'error',
-            u'errors': [
-                {u'description': (u'Pre-existing update bodhi-2.0-1.fc17 has no associated '
-                                  u'"release" object.  Please submit a ticket to resolve this.'),
-                 u'location': u'body', u'name': u'edited'},
-                {u'description': (u'Cannot find release associated with build: bodhi-2.0-1.fc17, '
-                                  u'tags: []'),
-                 u'location': u'body', u'name': u'builds'}]}
-        self.assertEqual(res.json, expected_json)
-
     def test_edit_untagged_build(self):
         """Editing an update that references untagged builds should raise an error."""
         update = self.db.query(Update).one()