)]}'
{"nova/cmd/manage.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"10b0ce1df758f96444b1f7b6125ddebbcc86a100","unresolved":false,"context_lines":[{"line_number":918,"context_line":"        admin_context \u003d context.get_admin_context()"},{"line_number":919,"context_line":"        db.archive_deleted_rows(admin_context, max_rows)"},{"line_number":920,"context_line":""},{"line_number":921,"context_line":"    @args(\u0027--delete\u0027, action\u003d\u0027store_true\u0027, dest\u003d\u0027delete\u0027,"},{"line_number":922,"context_line":"          help\u003d\u0027Delete records where instance_uuid is NULL?\u0027)"},{"line_number":923,"context_line":"    def null_instance_uuid_scan(self, delete\u003dFalse):"},{"line_number":924,"context_line":"        \"\"\"Lists and optionally deletes database records where"}],"source_content_type":"text/x-python","patch_set":18,"id":"baa201ad_d89785ea","line":921,"updated":"2014-10-16 17:03:29.000000000","message":"Maybe this should be --delete-null-uuids ?","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ff883b63ad2f810397607228959192e0a6234eba","unresolved":false,"context_lines":[{"line_number":918,"context_line":"        admin_context \u003d context.get_admin_context()"},{"line_number":919,"context_line":"        db.archive_deleted_rows(admin_context, max_rows)"},{"line_number":920,"context_line":""},{"line_number":921,"context_line":"    @args(\u0027--delete\u0027, action\u003d\u0027store_true\u0027, dest\u003d\u0027delete\u0027,"},{"line_number":922,"context_line":"          help\u003d\u0027Delete records where instance_uuid is NULL?\u0027)"},{"line_number":923,"context_line":"    def null_instance_uuid_scan(self, delete\u003dFalse):"},{"line_number":924,"context_line":"        \"\"\"Lists and optionally deletes database records where"}],"source_content_type":"text/x-python","patch_set":18,"id":"baa201ad_1e5735cb","line":921,"in_reply_to":"baa201ad_3e0b1925","updated":"2014-10-16 17:40:41.000000000","message":"Yeah, I don\u0027t think I got that this would be --delete against a specific scan-for-uuids command. So, sure.","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6b110302b435f5831badece973702721c234c93a","unresolved":false,"context_lines":[{"line_number":918,"context_line":"        admin_context \u003d context.get_admin_context()"},{"line_number":919,"context_line":"        db.archive_deleted_rows(admin_context, max_rows)"},{"line_number":920,"context_line":""},{"line_number":921,"context_line":"    @args(\u0027--delete\u0027, action\u003d\u0027store_true\u0027, dest\u003d\u0027delete\u0027,"},{"line_number":922,"context_line":"          help\u003d\u0027Delete records where instance_uuid is NULL?\u0027)"},{"line_number":923,"context_line":"    def null_instance_uuid_scan(self, delete\u003dFalse):"},{"line_number":924,"context_line":"        \"\"\"Lists and optionally deletes database records where"}],"source_content_type":"text/x-python","patch_set":18,"id":"baa201ad_3e0b1925","line":921,"in_reply_to":"baa201ad_d89785ea","updated":"2014-10-16 17:35:48.000000000","message":"With the proposed help text change does that make this better?  I feel that --delete-null-uuids is redundant with the name of the command a bit.","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"10b0ce1df758f96444b1f7b6125ddebbcc86a100","unresolved":false,"context_lines":[{"line_number":919,"context_line":"        db.archive_deleted_rows(admin_context, max_rows)"},{"line_number":920,"context_line":""},{"line_number":921,"context_line":"    @args(\u0027--delete\u0027, action\u003d\u0027store_true\u0027, dest\u003d\u0027delete\u0027,"},{"line_number":922,"context_line":"          help\u003d\u0027Delete records where instance_uuid is NULL?\u0027)"},{"line_number":923,"context_line":"    def null_instance_uuid_scan(self, delete\u003dFalse):"},{"line_number":924,"context_line":"        \"\"\"Lists and optionally deletes database records where"},{"line_number":925,"context_line":"        instance_uuid is NULL."}],"source_content_type":"text/x-python","patch_set":18,"id":"baa201ad_788699ba","line":922,"updated":"2014-10-16 17:03:29.000000000","message":"This seems weird to have a ? at the end of this. Maybe I\u0027m missing other commands here that use ? in their help text?","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e1ad2e9b30dc31b23197f8cad4f97fecdb5c5e6f","unresolved":false,"context_lines":[{"line_number":919,"context_line":"        db.archive_deleted_rows(admin_context, max_rows)"},{"line_number":920,"context_line":""},{"line_number":921,"context_line":"    @args(\u0027--delete\u0027, action\u003d\u0027store_true\u0027, dest\u003d\u0027delete\u0027,"},{"line_number":922,"context_line":"          help\u003d\u0027Delete records where instance_uuid is NULL?\u0027)"},{"line_number":923,"context_line":"    def null_instance_uuid_scan(self, delete\u003dFalse):"},{"line_number":924,"context_line":"        \"\"\"Lists and optionally deletes database records where"},{"line_number":925,"context_line":"        instance_uuid is NULL."}],"source_content_type":"text/x-python","patch_set":18,"id":"baa201ad_6c289be2","line":922,"in_reply_to":"baa201ad_3e5a39f2","updated":"2014-10-16 18:53:10.000000000","message":"Done","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6b110302b435f5831badece973702721c234c93a","unresolved":false,"context_lines":[{"line_number":919,"context_line":"        db.archive_deleted_rows(admin_context, max_rows)"},{"line_number":920,"context_line":""},{"line_number":921,"context_line":"    @args(\u0027--delete\u0027, action\u003d\u0027store_true\u0027, dest\u003d\u0027delete\u0027,"},{"line_number":922,"context_line":"          help\u003d\u0027Delete records where instance_uuid is NULL?\u0027)"},{"line_number":923,"context_line":"    def null_instance_uuid_scan(self, delete\u003dFalse):"},{"line_number":924,"context_line":"        \"\"\"Lists and optionally deletes database records where"},{"line_number":925,"context_line":"        instance_uuid is NULL."}],"source_content_type":"text/x-python","patch_set":18,"id":"baa201ad_bbff1b01","line":922,"in_reply_to":"baa201ad_788699ba","updated":"2014-10-16 17:35:48.000000000","message":"Maybe this is better:\n\n\"If specified, automatically delete any records found where instance_uuid is NULL.\"","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ff883b63ad2f810397607228959192e0a6234eba","unresolved":false,"context_lines":[{"line_number":919,"context_line":"        db.archive_deleted_rows(admin_context, max_rows)"},{"line_number":920,"context_line":""},{"line_number":921,"context_line":"    @args(\u0027--delete\u0027, action\u003d\u0027store_true\u0027, dest\u003d\u0027delete\u0027,"},{"line_number":922,"context_line":"          help\u003d\u0027Delete records where instance_uuid is NULL?\u0027)"},{"line_number":923,"context_line":"    def null_instance_uuid_scan(self, delete\u003dFalse):"},{"line_number":924,"context_line":"        \"\"\"Lists and optionally deletes database records where"},{"line_number":925,"context_line":"        instance_uuid is NULL."}],"source_content_type":"text/x-python","patch_set":18,"id":"baa201ad_3e5a39f2","line":922,"in_reply_to":"baa201ad_bbff1b01","updated":"2014-10-16 17:40:41.000000000","message":"Yeah.","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"}],"nova/db/sqlalchemy/migrate_repo/null_instance_uuid_scan.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"227530d2de8096ef4ba1fe597fd92d874c708c12","unresolved":false,"context_lines":[{"line_number":74,"context_line":"    # have to do this explicitly because the foreign keys in nova aren\u0027t"},{"line_number":75,"context_line":"    # defined with cascading deletes."},{"line_number":76,"context_line":"    meta.reflect(engine)"},{"line_number":77,"context_line":"    for table in reversed(meta.sorted_tables()):"},{"line_number":78,"context_line":"        # Ignore the fixed_ips table by design."},{"line_number":79,"context_line":"        if table.name !\u003d \u0027fixed_ips\u0027:"},{"line_number":80,"context_line":"            process_null_records(meta, table, \u0027instance_uuid\u0027, delete)"}],"source_content_type":"text/x-python","patch_set":5,"id":"baada198_bc7dc2b3","line":77,"updated":"2014-07-02 21:08:06.000000000","message":"sorted_tables() doesn\u0027t work as a method call, has to be accessed as an attribute.","commit_id":"7f3918cdca3baa0349ef010e423dc41ff099749a"}],"nova/db/sqlalchemy/migrate_repo/versions/246_instance_uuid_non_nullable.py":[{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"05a6f547cc2cb3cc7471a5969c4ed5b3864c1143","unresolved":false,"context_lines":[{"line_number":24,"context_line":"UC_NAME \u003d \u0027uniq_instances0uuid\u0027"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"def delete_null_records(table, col_name):"},{"line_number":28,"context_line":"    \"\"\"Deletes records from the table where column \u003d\u003d None.\"\"\""},{"line_number":29,"context_line":"    if col_name in table.columns:"},{"line_number":30,"context_line":"        # NOTE(mriedem): Per the spec, fail the migration telling the user to"}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_da445d1d","line":27,"updated":"2014-07-09 23:07:05.000000000","message":"This function doesn\u0027t appear to delete anything, just warn?","commit_id":"f4e3c47854bc91ddfaef8c3aa553144d217a80df"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"84a14f6af889550b50edfcf7ca17894dd063644d","unresolved":false,"context_lines":[{"line_number":24,"context_line":"UC_NAME \u003d \u0027uniq_instances0uuid\u0027"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"def delete_null_records(table, col_name):"},{"line_number":28,"context_line":"    \"\"\"Deletes records from the table where column \u003d\u003d None.\"\"\""},{"line_number":29,"context_line":"    if col_name in table.columns:"},{"line_number":30,"context_line":"        # NOTE(mriedem): Per the spec, fail the migration telling the user to"}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_c8c3a288","line":27,"in_reply_to":"baada198_8ab614db","updated":"2014-07-10 13:37:23.000000000","message":"Done","commit_id":"f4e3c47854bc91ddfaef8c3aa553144d217a80df"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9327727a4793ba528ee0cda7e35ba4e8c51df94d","unresolved":false,"context_lines":[{"line_number":24,"context_line":"UC_NAME \u003d \u0027uniq_instances0uuid\u0027"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"def delete_null_records(table, col_name):"},{"line_number":28,"context_line":"    \"\"\"Deletes records from the table where column \u003d\u003d None.\"\"\""},{"line_number":29,"context_line":"    if col_name in table.columns:"},{"line_number":30,"context_line":"        # NOTE(mriedem): Per the spec, fail the migration telling the user to"}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_8ab614db","line":27,"in_reply_to":"baada198_da445d1d","updated":"2014-07-10 01:10:56.000000000","message":"Ha, well I apparently lost that at some point...","commit_id":"f4e3c47854bc91ddfaef8c3aa553144d217a80df"},{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"05a6f547cc2cb3cc7471a5969c4ed5b3864c1143","unresolved":false,"context_lines":[{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    # Drop records where uuid is None and make the uuid column non-nullable."},{"line_number":63,"context_line":"    for table_name in (\u0027instances\u0027, \u0027shadow_instances\u0027):"},{"line_number":64,"context_line":"        table \u003d Table(table_name, meta, autoload\u003dTrue)"},{"line_number":65,"context_line":"        delete_null_records(table, \u0027uuid\u0027)"},{"line_number":66,"context_line":"        table.columns.uuid.alter(nullable\u003dFalse)"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_da29bd38","line":64,"updated":"2014-07-09 23:07:05.000000000","message":"Not worth changing, but the tables are already loaded from the reflect call earlier:\n\n    table \u003d meta.tables[table_name]","commit_id":"f4e3c47854bc91ddfaef8c3aa553144d217a80df"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"84a14f6af889550b50edfcf7ca17894dd063644d","unresolved":false,"context_lines":[{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    # Drop records where uuid is None and make the uuid column non-nullable."},{"line_number":63,"context_line":"    for table_name in (\u0027instances\u0027, \u0027shadow_instances\u0027):"},{"line_number":64,"context_line":"        table \u003d Table(table_name, meta, autoload\u003dTrue)"},{"line_number":65,"context_line":"        delete_null_records(table, \u0027uuid\u0027)"},{"line_number":66,"context_line":"        table.columns.uuid.alter(nullable\u003dFalse)"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_e8bea6ff","line":64,"in_reply_to":"baada198_4aaddc87","updated":"2014-07-10 13:37:23.000000000","message":"Done","commit_id":"f4e3c47854bc91ddfaef8c3aa553144d217a80df"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9327727a4793ba528ee0cda7e35ba4e8c51df94d","unresolved":false,"context_lines":[{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    # Drop records where uuid is None and make the uuid column non-nullable."},{"line_number":63,"context_line":"    for table_name in (\u0027instances\u0027, \u0027shadow_instances\u0027):"},{"line_number":64,"context_line":"        table \u003d Table(table_name, meta, autoload\u003dTrue)"},{"line_number":65,"context_line":"        delete_null_records(table, \u0027uuid\u0027)"},{"line_number":66,"context_line":"        table.columns.uuid.alter(nullable\u003dFalse)"},{"line_number":67,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_4aaddc87","line":64,"in_reply_to":"baada198_da29bd38","updated":"2014-07-10 01:10:56.000000000","message":"OK, never seen that before, if I respin I can update this.","commit_id":"f4e3c47854bc91ddfaef8c3aa553144d217a80df"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"3732b6c58bbe547218b38b842eb1b3051a54d2b7","unresolved":false,"context_lines":[{"line_number":10,"context_line":"#    distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT"},{"line_number":11,"context_line":"#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":12,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"#    under the License."},{"line_number":14,"context_line":"from migrate import UniqueConstraint"},{"line_number":15,"context_line":"from sqlalchemy import MetaData"},{"line_number":16,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_2ac82ba7","line":13,"updated":"2014-07-21 12:12:35.000000000","message":"I think you should add here blank line","commit_id":"ebba653b8c46478d5a9728903acabda71fa854bb"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"702eb062c0b55c5215d7fd739af846321600e293","unresolved":false,"context_lines":[{"line_number":10,"context_line":"#    distributed under the License is distributed on an \"AS IS\" BASIS, WITHOUT"},{"line_number":11,"context_line":"#    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the"},{"line_number":12,"context_line":"#    License for the specific language governing permissions and limitations"},{"line_number":13,"context_line":"#    under the License."},{"line_number":14,"context_line":"from migrate import UniqueConstraint"},{"line_number":15,"context_line":"from sqlalchemy import MetaData"},{"line_number":16,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_dadf7a64","line":13,"in_reply_to":"baada198_2ac82ba7","updated":"2014-07-21 14:29:10.000000000","message":"Done","commit_id":"ebba653b8c46478d5a9728903acabda71fa854bb"}],"nova/db/sqlalchemy/migrate_repo/versions/247_instance_uuid_non_nullable.py":[{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"c198f32c5aad32c0cbdf532a849d464216c193a7","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    process_null_records(meta, delete\u003dTrue)"},{"line_number":99,"context_line":"    # Create a unique constraint on instances.uuid for foreign keys."},{"line_number":100,"context_line":"    instances \u003d meta.tables[\u0027instances\u0027]"},{"line_number":101,"context_line":"    UniqueConstraint(\u0027uuid\u0027, table\u003dinstances, name\u003dUC_NAME).create()"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"def downgrade(migrate_engine):"}],"source_content_type":"text/x-python","patch_set":9,"id":"baada198_fe001cad","line":101,"updated":"2014-07-23 18:56:07.000000000","message":"The 216 migration already creates a unique index (using Index(..., unique\u003dTrue)) on line 1073. This will create a duplicate index, but with a different name.","commit_id":"1b17da8fca3a6b23d03d8d867c653977163309e7"},{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"ae5f530594936e001f10093763a6ff5e48389397","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    process_null_records(meta, delete\u003dTrue)"},{"line_number":99,"context_line":"    # Create a unique constraint on instances.uuid for foreign keys."},{"line_number":100,"context_line":"    instances \u003d meta.tables[\u0027instances\u0027]"},{"line_number":101,"context_line":"    UniqueConstraint(\u0027uuid\u0027, table\u003dinstances, name\u003dUC_NAME).create()"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"def downgrade(migrate_engine):"}],"source_content_type":"text/x-python","patch_set":9,"id":"baada198_bc676924","line":101,"in_reply_to":"baada198_0edadfe8","updated":"2014-07-24 15:46:10.000000000","message":"Yeah, this appears to be one of those cases where MySQL is too accepting of input and now causing us problems.\n\nI don\u0027t understand why the DB2 blueprint can\u0027t just change the 216 migration to make it a UniqueConstraint instead of a unique Index? The DB2 blueprint needs to change the 216 migration anyway.\n\nIt\u0027s certainly backwards compatible with MySQL and I\u0027m pretty sure it is for SQLite and PostrgreSQL, but I\u0027ll confirm that.\n\nIf we can do that, it might be the easiest way.","commit_id":"1b17da8fca3a6b23d03d8d867c653977163309e7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"11d5f26e0af99c542815d201454a8ee57789b576","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    process_null_records(meta, delete\u003dTrue)"},{"line_number":99,"context_line":"    # Create a unique constraint on instances.uuid for foreign keys."},{"line_number":100,"context_line":"    instances \u003d meta.tables[\u0027instances\u0027]"},{"line_number":101,"context_line":"    UniqueConstraint(\u0027uuid\u0027, table\u003dinstances, name\u003dUC_NAME).create()"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"def downgrade(migrate_engine):"}],"source_content_type":"text/x-python","patch_set":9,"id":"baada198_7dd781bf","line":101,"in_reply_to":"baada198_3d27c964","updated":"2014-07-24 20:56:03.000000000","message":"The sqlite unique constraint stuff for migrations is actually hacked into sqlalchemy-migrate, see this:\n\nhttps://review.openstack.org/#/c/87773/\n\nI think Mike Bayer has said before that there are a lot of things lacking for sqlite in sqlalchemy, but that\u0027s probably due to it only being a database for test/dev and not production deployments, so doesn\u0027t get all the same features.","commit_id":"1b17da8fca3a6b23d03d8d867c653977163309e7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"882d06428441b431b68429c06953a63dbbe110b3","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    process_null_records(meta, delete\u003dTrue)"},{"line_number":99,"context_line":"    # Create a unique constraint on instances.uuid for foreign keys."},{"line_number":100,"context_line":"    instances \u003d meta.tables[\u0027instances\u0027]"},{"line_number":101,"context_line":"    UniqueConstraint(\u0027uuid\u0027, table\u003dinstances, name\u003dUC_NAME).create()"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"def downgrade(migrate_engine):"}],"source_content_type":"text/x-python","patch_set":9,"id":"baada198_0edadfe8","line":101,"in_reply_to":"baada198_50349049","updated":"2014-07-24 14:57:52.000000000","message":"I can tell you this isn\u0027t the same thing for DB2, that\u0027s basically what prompted this blueprint in the first place, because I can\u0027t create the FKeys in DB2 with a unique index, it has to be a unique constraint.\n\nSo ideas, we could leave this and have both a unique index and constraint (if sqlalchemy or the backing DB engine ignores this if it already exists, even better), I\u0027m not sure that would have any negative affect.  Another idea is I could move the UC creation to the DB2 blueprint and the migration there which adds the missing FKeys, then it\u0027s a DB2-only thing if it\u0027s a DB2-only requirement.\n\nThe fact that mysql/postgresql let you create a unique index in the 216 migration when the column is not nullable indicates some dumbness to me, but maybe besides the point.","commit_id":"1b17da8fca3a6b23d03d8d867c653977163309e7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2ae3bb38edf7931b50eacd6df24feca1e7e0d743","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    process_null_records(meta, delete\u003dTrue)"},{"line_number":99,"context_line":"    # Create a unique constraint on instances.uuid for foreign keys."},{"line_number":100,"context_line":"    instances \u003d meta.tables[\u0027instances\u0027]"},{"line_number":101,"context_line":"    UniqueConstraint(\u0027uuid\u0027, table\u003dinstances, name\u003dUC_NAME).create()"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"def downgrade(migrate_engine):"}],"source_content_type":"text/x-python","patch_set":9,"id":"baada198_7d08612d","line":101,"in_reply_to":"baada198_7dd781bf","updated":"2014-07-24 21:01:20.000000000","message":"As for making the unique index in 216 a unique constraint, anyone past that won\u0027t get the change but as noted for mysql/postgresql it probably doesn\u0027t matter as they are effectively treated the same.\n\nThe problem in the 216 script for DB2 is you can\u0027t create the UC if instances.uuid is nullable, so I\u0027d also have to change that in the 216 script which is what this is doing, so doing that in 216 would have to be DB2 only, and then we\u0027d have to skip this script for DB2 or something, which is equally ugly it seems.","commit_id":"1b17da8fca3a6b23d03d8d867c653977163309e7"},{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"a6a4a217acab0a24eed991b76a6c523fa2a94a16","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    process_null_records(meta, delete\u003dTrue)"},{"line_number":99,"context_line":"    # Create a unique constraint on instances.uuid for foreign keys."},{"line_number":100,"context_line":"    instances \u003d meta.tables[\u0027instances\u0027]"},{"line_number":101,"context_line":"    UniqueConstraint(\u0027uuid\u0027, table\u003dinstances, name\u003dUC_NAME).create()"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"def downgrade(migrate_engine):"}],"source_content_type":"text/x-python","patch_set":9,"id":"baada198_50349049","line":101,"in_reply_to":"baada198_b0c32c38","updated":"2014-07-23 21:46:56.000000000","message":"AFAICT, there is no difference between a unique index and unique constraint in SQLAlchemy. Both generate the same exact same statements for MySQL at least.\n\nI\u0027ll check out SQLite and PostgreSQL as well to see if there is something I\u0027m missing.","commit_id":"1b17da8fca3a6b23d03d8d867c653977163309e7"},{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"20706ebdb6c9447796594f8af2ad92bb75768d00","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    process_null_records(meta, delete\u003dTrue)"},{"line_number":99,"context_line":"    # Create a unique constraint on instances.uuid for foreign keys."},{"line_number":100,"context_line":"    instances \u003d meta.tables[\u0027instances\u0027]"},{"line_number":101,"context_line":"    UniqueConstraint(\u0027uuid\u0027, table\u003dinstances, name\u003dUC_NAME).create()"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"def downgrade(migrate_engine):"}],"source_content_type":"text/x-python","patch_set":9,"id":"baada198_3d27c964","line":101,"in_reply_to":"baada198_bc676924","updated":"2014-07-24 20:45:51.000000000","message":"Sorry for the length of this comment, dealing with SQL servers gets complicated.\n\nFor reference, I tried creating this table with mysql, postgresql and sqlite:\n\n    table \u003d Table(\u0027test_unique_constraint\u0027, meta,\n        Column(\u0027id\u0027, Integer, primary_key\u003dTrue, nullable\u003dFalse),\n        Column(\u0027s\u0027, String(length\u003d30)),\n        Column(\u0027r\u0027, String(length\u003d30)),\n        UniqueConstraint(\u0027s\u0027, name\u003d\u0027test_uc_1\u0027),\n        Index(\u0027test_ui_1\u0027, \u0027r\u0027, unique\u003dTrue))\n\nMySQL behaves the way that I mentioned earlier. Both unique indexes and unique constraints are identical (using SHOW CREATE TABLE):\n\n  CREATE TABLE `test_unique_constraint` (\n    `id` int(11) NOT NULL AUTO_INCREMENT,\n    `s` varchar(30) DEFAULT NULL,\n    `r` varchar(30) DEFAULT NULL,\n    PRIMARY KEY (`id`),\n    UNIQUE KEY `test_uc_1` (`s`),\n    UNIQUE KEY `test_ui_1` (`r`)\n  ) ENGINE\u003dInnoDB DEFAULT CHARSET\u003dutf8\n\nPostgreSQL treats unique indexes differently than unique constraints (using pg_dump):\n\n  CREATE TABLE test_unique_constraint (\n      id integer NOT NULL,\n      s character varying(30),\n      r character varying(30)\n  );\n  ALTER TABLE ONLY test_unique_constraint\n      ADD CONSTRAINT test_uc_1 UNIQUE (s);\n  CREATE UNIQUE INDEX test_ui_1 ON test_unique_constraint USING btree (r);\n\nSQLite also treats unique indexes differently than unique constraints (using .schema):\n\n  CREATE TABLE test_unique_constraint (\n          id INTEGER NOT NULL,\n          s VARCHAR(30),\n          r VARCHAR(30),\n          PRIMARY KEY (id),\n          CONSTRAINT test_uc_1 UNIQUE (s)\n  );\n  CREATE UNIQUE INDEX test_ui_1 ON test_unique_constraint (r);\n\nSQLAlchemy appears to be a bit fuzzy on the differences since it reflects unique constraints as unique indexes (except for SQLite which doesn\u0027t reflect any constraints, I think this is a bug in SQLAlchemy).\n\nI can\u0027t find many practical differences between unique indexes and unique constraints for PostgreSQL or SQLite. It appears the difference is mostly in language, with constraints being more declarative. They function identically for both it seems.\n\nAnyway, I think this all boils down to that we could use UniqueConstraint as a replacement for Index(..., unique\u003dTrue) on MySQL, PostgreSQL and SQLite without any practical differences.\n\nSo I think we should drop the extra UniqueConstraint in this patch, and then in the DB2 patch, we should be able to change the Index to a UniqueConstraint without any problems.","commit_id":"1b17da8fca3a6b23d03d8d867c653977163309e7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"f2f9d7cc0dca16e754d27e28d17f5e63e54a2a85","unresolved":false,"context_lines":[{"line_number":98,"context_line":"    process_null_records(meta, delete\u003dTrue)"},{"line_number":99,"context_line":"    # Create a unique constraint on instances.uuid for foreign keys."},{"line_number":100,"context_line":"    instances \u003d meta.tables[\u0027instances\u0027]"},{"line_number":101,"context_line":"    UniqueConstraint(\u0027uuid\u0027, table\u003dinstances, name\u003dUC_NAME).create()"},{"line_number":102,"context_line":""},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"def downgrade(migrate_engine):"}],"source_content_type":"text/x-python","patch_set":9,"id":"baada198_b0c32c38","line":101,"in_reply_to":"baada198_fe001cad","updated":"2014-07-23 21:42:13.000000000","message":"I realize there is a unique index created in 216, but it\u0027s not a unique constraint, and that\u0027s needed for foreign keys, at least in the DB2 case which is the dependent patch on this.\n\nIs there some other way to deal with this?","commit_id":"1b17da8fca3a6b23d03d8d867c653977163309e7"}],"nova/db/sqlalchemy/migrate_repo/versions/251_instance_uuid_non_nullable.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e12c0bc575fbe860ecf4385bc8b6e9e3053e003a","unresolved":false,"context_lines":[{"line_number":18,"context_line":""},{"line_number":19,"context_line":"from nova import exception"},{"line_number":20,"context_line":"from nova.i18n import _, _LI"},{"line_number":21,"context_line":"from nova.openstack.common.db.sqlalchemy import utils"},{"line_number":22,"context_line":"from nova.openstack.common import log as logging"},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"LOG \u003d logging.getLogger(__name__)"}],"source_content_type":"text/x-python","patch_set":14,"id":"baa201ad_469eb9b9","line":21,"updated":"2014-10-13 22:04:27.000000000","message":"This is in oslo.db now.","commit_id":"23ba7eacdd66acc0a1ba770f49f17a06d076bf90"}],"nova/db/sqlalchemy/migrate_repo/versions/266_instance_uuid_non_nullable.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"a1a52c181d982940163864003a383bd10c0517f5","unresolved":false,"context_lines":[{"line_number":95,"context_line":"    # Scan the database first and fail if any NULL records found."},{"line_number":96,"context_line":"    process_null_records(meta, delete\u003dFalse)"},{"line_number":97,"context_line":"    # Now run the deletes."},{"line_number":98,"context_line":"    process_null_records(meta, delete\u003dTrue)"},{"line_number":99,"context_line":"    # Create a unique constraint on instances.uuid for foreign keys."},{"line_number":100,"context_line":"    instances \u003d meta.tables[\u0027instances\u0027]"},{"line_number":101,"context_line":"    UniqueConstraint(\u0027uuid\u0027, table\u003dinstances, name\u003dUC_NAME).create()"}],"source_content_type":"text/x-python","patch_set":15,"id":"baa201ad_0200daa9","line":98,"updated":"2014-10-15 18:21:31.000000000","message":"We never get here, right? We fail if we find null records, we require them to delete with the tool, so there\u0027s no reason for us to run deletes and issue a bunch of queries against the DB, which won\u0027t return anything anyway...","commit_id":"340c8239390d8d9646cc2ad57c1050a7bc6b997a"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"05d0323ac561cdeb7540dbf005ba18e9345b966a","unresolved":false,"context_lines":[{"line_number":95,"context_line":"    # Scan the database first and fail if any NULL records found."},{"line_number":96,"context_line":"    process_null_records(meta, delete\u003dFalse)"},{"line_number":97,"context_line":"    # Now run the deletes."},{"line_number":98,"context_line":"    process_null_records(meta, delete\u003dTrue)"},{"line_number":99,"context_line":"    # Create a unique constraint on instances.uuid for foreign keys."},{"line_number":100,"context_line":"    instances \u003d meta.tables[\u0027instances\u0027]"},{"line_number":101,"context_line":"    UniqueConstraint(\u0027uuid\u0027, table\u003dinstances, name\u003dUC_NAME).create()"}],"source_content_type":"text/x-python","patch_set":15,"id":"baa201ad_452d8c45","line":98,"in_reply_to":"baa201ad_0200daa9","updated":"2014-10-15 19:04:29.000000000","message":"Yeah, derp.  This is probably just a carry over from how the migration worked before the CLI existed...I\u0027ll remove it so the migration is cleaner.","commit_id":"340c8239390d8d9646cc2ad57c1050a7bc6b997a"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"7f969f923d7a99e031a9c1994573cb57d066c449","unresolved":false,"context_lines":[{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    for table_name in (\u0027instances\u0027, \u0027shadow_instances\u0027):"},{"line_number":66,"context_line":"        table \u003d meta.tables[table_name]"},{"line_number":67,"context_line":"        if delete:"},{"line_number":68,"context_line":"            # The record is gone so make the uuid column non-nullable."},{"line_number":69,"context_line":"            table.columns.uuid.alter(nullable\u003dFalse)"},{"line_number":70,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":16,"id":"baa201ad_709b2c18","line":67,"updated":"2014-10-15 20:05:13.000000000","message":"Hmm, this is confusing now. Maybe just call this parameter \"do_eet\" or something? \"delete\" is... not quite accurate.","commit_id":"a85c040da22eb927fad3c405c09ed85115540d6b"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"3c9fb9bf93c4a0329141cc2eed325c847db9db15","unresolved":false,"context_lines":[{"line_number":64,"context_line":""},{"line_number":65,"context_line":"    for table_name in (\u0027instances\u0027, \u0027shadow_instances\u0027):"},{"line_number":66,"context_line":"        table \u003d meta.tables[table_name]"},{"line_number":67,"context_line":"        if delete:"},{"line_number":68,"context_line":"            # The record is gone so make the uuid column non-nullable."},{"line_number":69,"context_line":"            table.columns.uuid.alter(nullable\u003dFalse)"},{"line_number":70,"context_line":"        else:"}],"source_content_type":"text/x-python","patch_set":16,"id":"baa201ad_5cad5e83","line":67,"in_reply_to":"baa201ad_709b2c18","updated":"2014-10-16 01:35:54.000000000","message":"Yeah I don\u0027t like it either.  I think I\u0027m going to change the delete parameter to \u0027scan\u0027 and default to True, so the first pass is scan\u003dTrue to look for null records and fail if we find them (run the tool), otherwise we don\u0027t need to scan and we just alter the instance.uuid column to be non-nullable.  That would get rid of the first for loop in the non-scan case also since we\u0027re doing it twice right now but it\u0027s not used in the 2nd case (the alter one).","commit_id":"a85c040da22eb927fad3c405c09ed85115540d6b"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"81888bb59cad9fecc90b259b44a5f9e9535908df","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    # Scan the database first and fail if any NULL records found."},{"line_number":85,"context_line":"    process_null_records(meta, scan\u003dFalse)"},{"line_number":86,"context_line":"    # Now run the alter statements."},{"line_number":87,"context_line":"    process_null_records(meta, scan\u003dTrue)"},{"line_number":88,"context_line":"    # Create a unique constraint on instances.uuid for foreign keys."},{"line_number":89,"context_line":"    instances \u003d meta.tables[\u0027instances\u0027]"},{"line_number":90,"context_line":"    UniqueConstraint(\u0027uuid\u0027, table\u003dinstances, name\u003dUC_NAME).create()"}],"source_content_type":"text/x-python","patch_set":17,"id":"baa201ad_583c75c8","line":87,"updated":"2014-10-16 16:33:01.000000000","message":"Doesn\u0027t this run the alter before the scan? I think you want scan\u003dTrue first and then scan\u003dFalse second, right?\n\nFWIW, \u0027do_alter\u0027 or \u0027just_scan\u0027 would make more sense to me I think, but scan works.","commit_id":"b497908d73738078964acda12b49cd400c416d08"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"aa82f53dad550e579acda8710b7277419ab1cf2f","unresolved":false,"context_lines":[{"line_number":84,"context_line":"    # Scan the database first and fail if any NULL records found."},{"line_number":85,"context_line":"    process_null_records(meta, scan\u003dFalse)"},{"line_number":86,"context_line":"    # Now run the alter statements."},{"line_number":87,"context_line":"    process_null_records(meta, scan\u003dTrue)"},{"line_number":88,"context_line":"    # Create a unique constraint on instances.uuid for foreign keys."},{"line_number":89,"context_line":"    instances \u003d meta.tables[\u0027instances\u0027]"},{"line_number":90,"context_line":"    UniqueConstraint(\u0027uuid\u0027, table\u003dinstances, name\u003dUC_NAME).create()"}],"source_content_type":"text/x-python","patch_set":17,"id":"baa201ad_180e6de5","line":87,"in_reply_to":"baa201ad_583c75c8","updated":"2014-10-16 16:39:31.000000000","message":"Yeah, this is wrong, I\u0027m not paying close enough attention when making changes here, doing it on the side while doing several other things at once.  The switch from delete to scan in the process method changes how those were used logically, but I forgot to change this, I just simply renamed the var, which is obviously wrong.","commit_id":"b497908d73738078964acda12b49cd400c416d08"},{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"44f8e1cb54ea00771ab343386bdc134b1f3b2460","unresolved":false,"context_lines":[{"line_number":62,"context_line":"            # skip the fixed_ips table otherwise we\u0027ll wipeout the pool of"},{"line_number":63,"context_line":"            # fixed IPs."},{"line_number":64,"context_line":"            if table.name not in (\u0027fixed_ips\u0027, \u0027shadow_fixed_ips\u0027):"},{"line_number":65,"context_line":"                scan_for_null_records(table, \u0027instance_uuid\u0027)"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    for table_name in (\u0027instances\u0027, \u0027shadow_instances\u0027):"},{"line_number":68,"context_line":"        table \u003d meta.tables[table_name]"}],"source_content_type":"text/x-python","patch_set":22,"id":"5a890539_3704a17a","line":65,"updated":"2014-11-11 22:42:23.000000000","message":"So this will scan every table that has an \u0027instance_uuid column\u0027. Some of these tables don\u0027t have a foreign key back to the instances table (volumes, volume_usage_cache and pci_devices). Those won\u0027t potentially block the migration, should we raise an exception in those cases?\n\nAlso, there are some tables that don\u0027t use \u0027instance_uuid\u0027, but just \u0027uuid\u0027 (bw_usage_cache and instance_id_mapping). Should we check these too if we\u0027re also checking tables with an \u0027instance_uuid\u0027 column but no foreign key?","commit_id":"1503449a8ac5fd416e76f1023b5e375e9b8c5a7d"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e0bd184404c9fae03312d14052eba898a4b0e17c","unresolved":false,"context_lines":[{"line_number":62,"context_line":"            # skip the fixed_ips table otherwise we\u0027ll wipeout the pool of"},{"line_number":63,"context_line":"            # fixed IPs."},{"line_number":64,"context_line":"            if table.name not in (\u0027fixed_ips\u0027, \u0027shadow_fixed_ips\u0027):"},{"line_number":65,"context_line":"                scan_for_null_records(table, \u0027instance_uuid\u0027)"},{"line_number":66,"context_line":""},{"line_number":67,"context_line":"    for table_name in (\u0027instances\u0027, \u0027shadow_instances\u0027):"},{"line_number":68,"context_line":"        table \u003d meta.tables[table_name]"}],"source_content_type":"text/x-python","patch_set":22,"id":"5a890539_0ffb97c1","line":65,"in_reply_to":"5a890539_3704a17a","updated":"2014-11-14 22:50:04.000000000","message":"If we only want to filter on foreign keys back to the instances table with an instance_uuid column, then I\u0027d be fine with adding that filtering.\n\nWe don\u0027t have cascading deletes in our foreign keys anyway, so anything goes kind of already.  I think I was initially just making it very dumb and straight-forward but I missed the non-instance_uuid cases in those other tables.","commit_id":"1503449a8ac5fd416e76f1023b5e375e9b8c5a7d"}],"nova/db/sqlalchemy/migrate_repo/versions/267_instance_uuid_non_nullable.py":[{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"8bf5e45b6f895b86cfa5d6b1eaa7bc96f88f860d","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        if records:"},{"line_number":55,"context_line":"            msg \u003d _(\"There are %(records)d records in the \""},{"line_number":56,"context_line":"                    \"\u0027%(table_name)s\u0027 table where the uuid or \""},{"line_number":57,"context_line":"                    \"instance_uuid column is NULL. These must be \""},{"line_number":58,"context_line":"                    \"manually cleaned up before the migration will pass. \""},{"line_number":59,"context_line":"                    \"Consider running the \""},{"line_number":60,"context_line":"                    \"\u0027nova-manage db null_instance_uuid_scan\u0027 command.\") % ("}],"source_content_type":"text/x-python","patch_set":27,"id":"5a890539_fca9637c","line":57,"updated":"2014-12-04 21:38:12.000000000","message":"Probably could have just used col_name here to make it clearer for operators. Not worth a new spin however :)","commit_id":"c0ea53ce353684b48303fc59393930c3fa5ade58"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6f86a0a18fe327ec3efc021df0a8bc5de2787b88","unresolved":false,"context_lines":[{"line_number":54,"context_line":"        if records:"},{"line_number":55,"context_line":"            msg \u003d _(\"There are %(records)d records in the \""},{"line_number":56,"context_line":"                    \"\u0027%(table_name)s\u0027 table where the uuid or \""},{"line_number":57,"context_line":"                    \"instance_uuid column is NULL. These must be \""},{"line_number":58,"context_line":"                    \"manually cleaned up before the migration will pass. \""},{"line_number":59,"context_line":"                    \"Consider running the \""},{"line_number":60,"context_line":"                    \"\u0027nova-manage db null_instance_uuid_scan\u0027 command.\") % ("}],"source_content_type":"text/x-python","patch_set":27,"id":"5a890539_b07c5f21","line":57,"in_reply_to":"5a890539_fca9637c","updated":"2014-12-04 22:22:42.000000000","message":"True, I can change if I respin for some reason.","commit_id":"c0ea53ce353684b48303fc59393930c3fa5ade58"}],"nova/db/sqlalchemy/migration.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e12c0bc575fbe860ecf4385bc8b6e9e3053e003a","unresolved":false,"context_lines":[{"line_number":25,"context_line":"from nova.db.sqlalchemy import api as db_session"},{"line_number":26,"context_line":"from nova import exception"},{"line_number":27,"context_line":"from nova.i18n import _"},{"line_number":28,"context_line":"from nova.openstack.common.db.sqlalchemy import utils as db_utils"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"INIT_VERSION \u003d 215"},{"line_number":31,"context_line":"_REPOSITORY \u003d None"}],"source_content_type":"text/x-python","patch_set":14,"id":"baa201ad_66a57d03","line":28,"updated":"2014-10-13 22:04:27.000000000","message":"oslo.db","commit_id":"23ba7eacdd66acc0a1ba770f49f17a06d076bf90"},{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"44f8e1cb54ea00771ab343386bdc134b1f3b2460","unresolved":false,"context_lines":[{"line_number":94,"context_line":"    return records"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"def db_null_instance_uuid_scan(delete\u003dFalse):"},{"line_number":98,"context_line":"    \"\"\"Scans the database for NULL instance_uuid records."},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"    :param delete: If true, delete NULL instance_uuid records found, else"}],"source_content_type":"text/x-python","patch_set":22,"id":"5a890539_573f6d25","line":97,"updated":"2014-11-11 22:42:23.000000000","message":"I should dig into why this code needs to be duplicated since I don\u0027t completely understand the problem, but the same questions from the migration implementation apply here.","commit_id":"1503449a8ac5fd416e76f1023b5e375e9b8c5a7d"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e0bd184404c9fae03312d14052eba898a4b0e17c","unresolved":false,"context_lines":[{"line_number":94,"context_line":"    return records"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"def db_null_instance_uuid_scan(delete\u003dFalse):"},{"line_number":98,"context_line":"    \"\"\"Scans the database for NULL instance_uuid records."},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"    :param delete: If true, delete NULL instance_uuid records found, else"}],"source_content_type":"text/x-python","patch_set":22,"id":"5a890539_af3363a9","line":97,"in_reply_to":"5a890539_573f6d25","updated":"2014-11-14 22:50:04.000000000","message":"I could try importing this into the migration script and trying again, it wasn\u0027t working before, but maybe that was related to how I was testing the code.","commit_id":"1503449a8ac5fd416e76f1023b5e375e9b8c5a7d"},{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"8bf5e45b6f895b86cfa5d6b1eaa7bc96f88f860d","unresolved":false,"context_lines":[{"line_number":123,"context_line":"    # to the instances table and we want to cleanup those records first. We"},{"line_number":124,"context_line":"    # have to do this explicitly because the foreign keys in nova aren\u0027t"},{"line_number":125,"context_line":"    # defined with cascading deletes."},{"line_number":126,"context_line":"    meta.reflect(engine)"},{"line_number":127,"context_line":"    # Keep track of all of the tables that had hits in the query."},{"line_number":128,"context_line":"    processed \u003d {}"},{"line_number":129,"context_line":"    for table in reversed(meta.sorted_tables):"}],"source_content_type":"text/x-python","patch_set":27,"id":"5a890539_5c16f7a7","line":126,"updated":"2014-12-04 21:38:12.000000000","message":"Passing engine here shouldn\u0027t be necessary since the MetaData object is bound with engine above, but it won\u0027t hurt either.","commit_id":"c0ea53ce353684b48303fc59393930c3fa5ade58"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6f86a0a18fe327ec3efc021df0a8bc5de2787b88","unresolved":false,"context_lines":[{"line_number":123,"context_line":"    # to the instances table and we want to cleanup those records first. We"},{"line_number":124,"context_line":"    # have to do this explicitly because the foreign keys in nova aren\u0027t"},{"line_number":125,"context_line":"    # defined with cascading deletes."},{"line_number":126,"context_line":"    meta.reflect(engine)"},{"line_number":127,"context_line":"    # Keep track of all of the tables that had hits in the query."},{"line_number":128,"context_line":"    processed \u003d {}"},{"line_number":129,"context_line":"    for table in reversed(meta.sorted_tables):"}],"source_content_type":"text/x-python","patch_set":27,"id":"5a890539_9099236f","line":126,"in_reply_to":"5a890539_5c16f7a7","updated":"2014-12-04 22:22:42.000000000","message":"Yeah, force of habit from seeing it done like this many times before.","commit_id":"c0ea53ce353684b48303fc59393930c3fa5ade58"}],"nova/db/sqlalchemy/models.py":[{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"05a6f547cc2cb3cc7471a5969c4ed5b3864c1143","unresolved":false,"context_lines":[{"line_number":164,"context_line":"              \u0027task_state\u0027, \u0027updated_at\u0027),"},{"line_number":165,"context_line":"        Index(\u0027instances_host_node_deleted_idx\u0027,"},{"line_number":166,"context_line":"              \u0027host\u0027, \u0027node\u0027, \u0027deleted\u0027),"},{"line_number":167,"context_line":"        Index(\u0027instances_host_deleted_cleaned_idx\u0027,"},{"line_number":168,"context_line":"              \u0027host\u0027, \u0027deleted\u0027, \u0027cleaned\u0027),"},{"line_number":169,"context_line":"    )"},{"line_number":170,"context_line":"    injected_files \u003d []"}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_ba8249fe","line":167,"updated":"2014-07-09 23:07:05.000000000","message":"Can you put the new unique index here too? It\u0027ll keep the model closer to what the migration actually does.","commit_id":"f4e3c47854bc91ddfaef8c3aa553144d217a80df"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9327727a4793ba528ee0cda7e35ba4e8c51df94d","unresolved":false,"context_lines":[{"line_number":164,"context_line":"              \u0027task_state\u0027, \u0027updated_at\u0027),"},{"line_number":165,"context_line":"        Index(\u0027instances_host_node_deleted_idx\u0027,"},{"line_number":166,"context_line":"              \u0027host\u0027, \u0027node\u0027, \u0027deleted\u0027),"},{"line_number":167,"context_line":"        Index(\u0027instances_host_deleted_cleaned_idx\u0027,"},{"line_number":168,"context_line":"              \u0027host\u0027, \u0027deleted\u0027, \u0027cleaned\u0027),"},{"line_number":169,"context_line":"    )"},{"line_number":170,"context_line":"    injected_files \u003d []"}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_cae72ce3","line":167,"in_reply_to":"baada198_ba8249fe","updated":"2014-07-10 01:10:56.000000000","message":"The unique index is on line 153, did you mean a UniqueConstraint with name \"uniq_instances0uuid\"?","commit_id":"f4e3c47854bc91ddfaef8c3aa553144d217a80df"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"84a14f6af889550b50edfcf7ca17894dd063644d","unresolved":false,"context_lines":[{"line_number":164,"context_line":"              \u0027task_state\u0027, \u0027updated_at\u0027),"},{"line_number":165,"context_line":"        Index(\u0027instances_host_node_deleted_idx\u0027,"},{"line_number":166,"context_line":"              \u0027host\u0027, \u0027node\u0027, \u0027deleted\u0027),"},{"line_number":167,"context_line":"        Index(\u0027instances_host_deleted_cleaned_idx\u0027,"},{"line_number":168,"context_line":"              \u0027host\u0027, \u0027deleted\u0027, \u0027cleaned\u0027),"},{"line_number":169,"context_line":"    )"},{"line_number":170,"context_line":"    injected_files \u003d []"}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_a8cd8eb9","line":167,"in_reply_to":"baada198_cae72ce3","updated":"2014-07-10 13:37:23.000000000","message":"Done","commit_id":"f4e3c47854bc91ddfaef8c3aa553144d217a80df"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9327727a4793ba528ee0cda7e35ba4e8c51df94d","unresolved":false,"context_lines":[{"line_number":293,"context_line":"    \"\"\"Represents a cache of information about an instance"},{"line_number":294,"context_line":"    \"\"\""},{"line_number":295,"context_line":"    __tablename__ \u003d \u0027instance_info_caches\u0027"},{"line_number":296,"context_line":"    __table_args__ \u003d ("},{"line_number":297,"context_line":"        schema.UniqueConstraint("},{"line_number":298,"context_line":"            \"instance_uuid\","},{"line_number":299,"context_line":"            name\u003d\"uniq_instance_info_caches0instance_uuid\"),)"}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_eaea30ab","line":296,"updated":"2014-07-10 01:10:56.000000000","message":"Like this I suppose.","commit_id":"f4e3c47854bc91ddfaef8c3aa553144d217a80df"}],"nova/tests/db/test_migrations.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"a6f22dbff411eb9e8f7c66ea7edfd396a220950f","unresolved":false,"context_lines":[{"line_number":723,"context_line":"        # Make sure the column is non-nullable and the UC exists."},{"line_number":724,"context_line":"        fixed_ips \u003d oslodbutils.get_table(engine, \u0027fixed_ips\u0027)"},{"line_number":725,"context_line":"        fixed_ip \u003d fixed_ips.select(fixed_ips.c.id \u003d\u003d 1).execute().first()"},{"line_number":726,"context_line":"        self.assertIsNone(fixed_ip.instance_uuid)"},{"line_number":727,"context_line":""},{"line_number":728,"context_line":"        instances \u003d oslodbutils.get_table(engine, \u0027instances\u0027)"},{"line_number":729,"context_line":"        self.assertFalse(instances.c.uuid.nullable)"}],"source_content_type":"text/x-python","patch_set":3,"id":"baada198_eee36003","line":726,"updated":"2014-06-30 20:13:21.000000000","message":"Should probably also make sure this column is nullable\u003dTrue.","commit_id":"bd0bcd7ebd86121fd81c308d9a3ba055793bdad6"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"10b0ce1df758f96444b1f7b6125ddebbcc86a100","unresolved":false,"context_lines":[{"line_number":890,"context_line":"        # NOTE(mriedem): we can\u0027t test the case that we fail the migration"},{"line_number":891,"context_line":"        # with a null instance_uuid entry since that will kill the migration"},{"line_number":892,"context_line":"        # and the tests will not be able to get past it. We really need a way"},{"line_number":893,"context_line":"        # to run multiple passes at the migration script in unit test."},{"line_number":894,"context_line":"        fixed_ips \u003d oslodbutils.get_table(engine, \u0027fixed_ips\u0027)"},{"line_number":895,"context_line":"        fake_fixed_ip \u003d {\u0027id\u0027: 1}"},{"line_number":896,"context_line":"        fixed_ips.insert().execute(fake_fixed_ip)"}],"source_content_type":"text/x-python","patch_set":18,"id":"baa201ad_1b566706","line":893,"updated":"2014-10-16 17:03:29.000000000","message":"We definitely do for other migrations. However, this one is pretty important to make sure we got it right. How about we write a custom test for this one to make sure it does in fact stop?","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6b110302b435f5831badece973702721c234c93a","unresolved":false,"context_lines":[{"line_number":890,"context_line":"        # NOTE(mriedem): we can\u0027t test the case that we fail the migration"},{"line_number":891,"context_line":"        # with a null instance_uuid entry since that will kill the migration"},{"line_number":892,"context_line":"        # and the tests will not be able to get past it. We really need a way"},{"line_number":893,"context_line":"        # to run multiple passes at the migration script in unit test."},{"line_number":894,"context_line":"        fixed_ips \u003d oslodbutils.get_table(engine, \u0027fixed_ips\u0027)"},{"line_number":895,"context_line":"        fake_fixed_ip \u003d {\u0027id\u0027: 1}"},{"line_number":896,"context_line":"        fixed_ips.insert().execute(fake_fixed_ip)"}],"source_content_type":"text/x-python","patch_set":18,"id":"baa201ad_9e6085d0","line":893,"in_reply_to":"baa201ad_1b566706","updated":"2014-10-16 17:35:48.000000000","message":"Do you have an example, it\u0027s not obvious to me how to write a test that runs the migration outside of in here, and in here I thought the name of the test has to be specific to the point of you can\u0027t run multiples.","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"bf3af2648fda3ea016c3d6ce60e7993831fb1290","unresolved":false,"context_lines":[{"line_number":890,"context_line":"        # NOTE(mriedem): we can\u0027t test the case that we fail the migration"},{"line_number":891,"context_line":"        # with a null instance_uuid entry since that will kill the migration"},{"line_number":892,"context_line":"        # and the tests will not be able to get past it. We really need a way"},{"line_number":893,"context_line":"        # to run multiple passes at the migration script in unit test."},{"line_number":894,"context_line":"        fixed_ips \u003d oslodbutils.get_table(engine, \u0027fixed_ips\u0027)"},{"line_number":895,"context_line":"        fake_fixed_ip \u003d {\u0027id\u0027: 1}"},{"line_number":896,"context_line":"        fixed_ips.insert().execute(fake_fixed_ip)"}],"source_content_type":"text/x-python","patch_set":18,"id":"baa201ad_e10734c8","line":893,"in_reply_to":"baa201ad_9e18851f","updated":"2014-10-16 18:03:19.000000000","message":"OK, thinking it would be some one-off version of _walk_versions but with only migrating up from 266 to 267 and then stopping, and throw the wrench in there with the null instance uuid so we can assert we fail.","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"ff883b63ad2f810397607228959192e0a6234eba","unresolved":false,"context_lines":[{"line_number":890,"context_line":"        # NOTE(mriedem): we can\u0027t test the case that we fail the migration"},{"line_number":891,"context_line":"        # with a null instance_uuid entry since that will kill the migration"},{"line_number":892,"context_line":"        # and the tests will not be able to get past it. We really need a way"},{"line_number":893,"context_line":"        # to run multiple passes at the migration script in unit test."},{"line_number":894,"context_line":"        fixed_ips \u003d oslodbutils.get_table(engine, \u0027fixed_ips\u0027)"},{"line_number":895,"context_line":"        fake_fixed_ip \u003d {\u0027id\u0027: 1}"},{"line_number":896,"context_line":"        fixed_ips.insert().execute(fake_fixed_ip)"}],"source_content_type":"text/x-python","patch_set":18,"id":"baa201ad_9e18851f","line":893,"in_reply_to":"baa201ad_9e6085d0","updated":"2014-10-16 17:40:41.000000000","message":"it\u0027d be some work to replicate what is in here. Just enough to set up and test that single migration from X-\u003eY. I can help try to figure out what should be done if you want. This just feels like a sufficiently risky migration that it\u0027s worth being very cautious, but if I\u0027m the only one then that\u0027s fine.","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"10b0ce1df758f96444b1f7b6125ddebbcc86a100","unresolved":false,"context_lines":[{"line_number":908,"context_line":"        inspector \u003d reflection.Inspector.from_engine(engine)"},{"line_number":909,"context_line":"        constraints \u003d inspector.get_unique_constraints(\u0027instances\u0027)"},{"line_number":910,"context_line":"        constraint_names \u003d [constraint[\u0027name\u0027] for constraint in constraints]"},{"line_number":911,"context_line":"        self.assertIn(\u0027uniq_instances0uuid\u0027, constraint_names)"},{"line_number":912,"context_line":""},{"line_number":913,"context_line":"    def _post_downgrade_266(self, engine):"},{"line_number":914,"context_line":"        # Make sure the UC is gone and the column is nullable again."}],"source_content_type":"text/x-python","patch_set":18,"id":"baa201ad_9b497762","line":911,"updated":"2014-10-16 17:03:29.000000000","message":"Shouldn\u0027t we also make sure that an instance that is in the DB with a valid uuid is *not* deleted as part of this? I\u0027m just thinking it would be pretty horrific if this deleted all instances by accident. Obviously the grenade test should catch that, but.. we should probably just be extra careful here, don\u0027tchathink?","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e1ad2e9b30dc31b23197f8cad4f97fecdb5c5e6f","unresolved":false,"context_lines":[{"line_number":908,"context_line":"        inspector \u003d reflection.Inspector.from_engine(engine)"},{"line_number":909,"context_line":"        constraints \u003d inspector.get_unique_constraints(\u0027instances\u0027)"},{"line_number":910,"context_line":"        constraint_names \u003d [constraint[\u0027name\u0027] for constraint in constraints]"},{"line_number":911,"context_line":"        self.assertIn(\u0027uniq_instances0uuid\u0027, constraint_names)"},{"line_number":912,"context_line":""},{"line_number":913,"context_line":"    def _post_downgrade_266(self, engine):"},{"line_number":914,"context_line":"        # Make sure the UC is gone and the column is nullable again."}],"source_content_type":"text/x-python","patch_set":18,"id":"baa201ad_4c0e778d","line":911,"in_reply_to":"baa201ad_1ea49506","updated":"2014-10-16 18:53:10.000000000","message":"Done","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6b110302b435f5831badece973702721c234c93a","unresolved":false,"context_lines":[{"line_number":908,"context_line":"        inspector \u003d reflection.Inspector.from_engine(engine)"},{"line_number":909,"context_line":"        constraints \u003d inspector.get_unique_constraints(\u0027instances\u0027)"},{"line_number":910,"context_line":"        constraint_names \u003d [constraint[\u0027name\u0027] for constraint in constraints]"},{"line_number":911,"context_line":"        self.assertIn(\u0027uniq_instances0uuid\u0027, constraint_names)"},{"line_number":912,"context_line":""},{"line_number":913,"context_line":"    def _post_downgrade_266(self, engine):"},{"line_number":914,"context_line":"        # Make sure the UC is gone and the column is nullable again."}],"source_content_type":"text/x-python","patch_set":18,"id":"baa201ad_1ea49506","line":911,"in_reply_to":"baa201ad_9b497762","updated":"2014-10-16 17:35:48.000000000","message":"I can add that.","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c82f8a4d6fcef7e9156a94c29c3ae05e62a141c6","unresolved":false,"context_lines":[{"line_number":530,"context_line":"            # a null instance_uuid entry."},{"line_number":531,"context_line":"            try:"},{"line_number":532,"context_line":"                self.migration_api.upgrade(engine, self.REPOSITORY, version)"},{"line_number":533,"context_line":"            except exception.ValidationError as e:"},{"line_number":534,"context_line":"                # This should only happen on the 266 migration."},{"line_number":535,"context_line":"                self.assertEqual(266, version)"},{"line_number":536,"context_line":"                self.assertIn(\"There are 1 records in the \""}],"source_content_type":"text/x-python","patch_set":21,"id":"5a890539_773709e4","line":533,"updated":"2014-11-11 21:55:18.000000000","message":"Need to add a check to make sure we actually hit this.","commit_id":"6dbbc483bfe8fecced24d8b1ee33cd23c059ca3f"},{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"44f8e1cb54ea00771ab343386bdc134b1f3b2460","unresolved":false,"context_lines":[{"line_number":535,"context_line":"                              \u0027upgrade.\u0027)"},{"line_number":536,"context_line":"            except exception.ValidationError as e:"},{"line_number":537,"context_line":"                # This should only happen on the 266 migration."},{"line_number":538,"context_line":"                self.assertEqual(266, version)"},{"line_number":539,"context_line":"                self.assertIn(\"There are 1 records in the \""},{"line_number":540,"context_line":"                              \"\u0027block_device_mapping\u0027 table where the uuid or \""},{"line_number":541,"context_line":"                              \"instance_uuid column is NULL.\","}],"source_content_type":"text/x-python","patch_set":22,"id":"5a890539_b77411fe","line":538,"updated":"2014-11-11 22:42:23.000000000","message":"If the ValidationError happened in a migration other than 266, this will change the exception to an AssertionError. Maybe this should just be:\n\n    if version !\u003d 266:\n        raise\n\nThis will keep the original traceback and make troubleshooting easier.","commit_id":"1503449a8ac5fd416e76f1023b5e375e9b8c5a7d"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e0bd184404c9fae03312d14052eba898a4b0e17c","unresolved":false,"context_lines":[{"line_number":535,"context_line":"                              \u0027upgrade.\u0027)"},{"line_number":536,"context_line":"            except exception.ValidationError as e:"},{"line_number":537,"context_line":"                # This should only happen on the 266 migration."},{"line_number":538,"context_line":"                self.assertEqual(266, version)"},{"line_number":539,"context_line":"                self.assertIn(\"There are 1 records in the \""},{"line_number":540,"context_line":"                              \"\u0027block_device_mapping\u0027 table where the uuid or \""},{"line_number":541,"context_line":"                              \"instance_uuid column is NULL.\","}],"source_content_type":"text/x-python","patch_set":22,"id":"5a890539_ef29eb37","line":538,"in_reply_to":"5a890539_b77411fe","updated":"2014-11-14 22:50:04.000000000","message":"Good point, I\u0027ll change that.","commit_id":"1503449a8ac5fd416e76f1023b5e375e9b8c5a7d"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c776a0e0b46d0973a3a5307c70e62397ced69e48","unresolved":false,"context_lines":[{"line_number":535,"context_line":"                              \u0027upgrade.\u0027)"},{"line_number":536,"context_line":"            except exception.ValidationError as e:"},{"line_number":537,"context_line":"                # This should only happen on the 266 migration."},{"line_number":538,"context_line":"                self.assertEqual(266, version)"},{"line_number":539,"context_line":"                self.assertIn(\"There are 1 records in the \""},{"line_number":540,"context_line":"                              \"\u0027block_device_mapping\u0027 table where the uuid or \""},{"line_number":541,"context_line":"                              \"instance_uuid column is NULL.\","}],"source_content_type":"text/x-python","patch_set":22,"id":"5a890539_54e56ba6","line":538,"in_reply_to":"5a890539_ef29eb37","updated":"2014-11-21 18:38:55.000000000","message":"This is going to be replaced with https://review.openstack.org/#/c/135635/","commit_id":"1503449a8ac5fd416e76f1023b5e375e9b8c5a7d"}],"nova/tests/db/test_sqlalchemy_migration.py":[{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"05a6f547cc2cb3cc7471a5969c4ed5b3864c1143","unresolved":false,"context_lines":[{"line_number":75,"context_line":"        do_test()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def test_scan_readonly(self):"},{"line_number":78,"context_line":"        self._test_scan(delete\u003dFalse)"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def test_scan_delete(self):"},{"line_number":81,"context_line":"        self._test_scan(delete\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_7ab6f1dd","line":78,"updated":"2014-07-09 23:07:05.000000000","message":"What is the goal with this test? I see assertions that certain functions were called but nothing that asserts they did what they were supposed to.","commit_id":"f4e3c47854bc91ddfaef8c3aa553144d217a80df"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"4444149ff269c93d3b6d12272657207989612ef9","unresolved":false,"context_lines":[{"line_number":75,"context_line":"        do_test()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def test_scan_readonly(self):"},{"line_number":78,"context_line":"        self._test_scan(delete\u003dFalse)"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def test_scan_delete(self):"},{"line_number":81,"context_line":"        self._test_scan(delete\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_b74ebbbf","line":78,"in_reply_to":"baada198_3f5b6f88","updated":"2014-07-10 19:20:07.000000000","message":"The point of the scan tests are to assert how the scan method works, not how the process method works, that\u0027s left to the process tests.  So the scan test mocks out the process method and makes sure it\u0027s called as expected, number of times, and with the proper args, etc.\n\nThe process tests are the ones that verify if things are deleted or not and mocks out the underlying sqlalchemy bits.","commit_id":"f4e3c47854bc91ddfaef8c3aa553144d217a80df"},{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"6e88379b292e668e3fe076bb646efdfd9978cd3c","unresolved":false,"context_lines":[{"line_number":75,"context_line":"        do_test()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def test_scan_readonly(self):"},{"line_number":78,"context_line":"        self._test_scan(delete\u003dFalse)"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def test_scan_delete(self):"},{"line_number":81,"context_line":"        self._test_scan(delete\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_3f5b6f88","line":78,"in_reply_to":"baada198_6a4460b7","updated":"2014-07-10 16:18:55.000000000","message":"I mean these new tests in this file in general.\n\nThis seems to be testing more the implementation than the interface.\n\nFor instance, all of the assertions test that it calls particular functions and a specific number of times. This can make the test brittle in the future and cause a lot of extra work if the implementation needs to be changed.\n\nSome of the assertions are relatively low value (is it important that we assert it calls reflect with our engine?) whereas some important assertions seem to be missing (asserting that test_scan_readonly never deletes anything for instance).\n\nThe only effective difference between test_scan_readonly and test_scan_delete is that they don\u0027t raise an exception in their different code paths. They don\u0027t seem to test that they do or don\u0027t delete something.\n\nI don\u0027t want to come down too hard on these tests since Nova has accepted tests similar to these before and there is *some* value in them. I\u0027ve just run into similar tests while working on Nova and they can be frustrating.","commit_id":"f4e3c47854bc91ddfaef8c3aa553144d217a80df"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9327727a4793ba528ee0cda7e35ba4e8c51df94d","unresolved":false,"context_lines":[{"line_number":75,"context_line":"        do_test()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def test_scan_readonly(self):"},{"line_number":78,"context_line":"        self._test_scan(delete\u003dFalse)"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def test_scan_delete(self):"},{"line_number":81,"context_line":"        self._test_scan(delete\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_6a4460b7","line":78,"in_reply_to":"baada198_7ab6f1dd","updated":"2014-07-10 01:10:56.000000000","message":"Do you mean the readonly test specifically or the _test_scan tests altogether?  The goal is to make sure things are called as expected with the proper columns and number of times - you can\u0027t imagine how many times the process_mock.call_count wasn\u0027t what I expected.\n\nIs there something else you were expecting with this?","commit_id":"f4e3c47854bc91ddfaef8c3aa553144d217a80df"},{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"43bbe994667cd8eb4dbc79eb7bd6bd1020c2f4a6","unresolved":false,"context_lines":[{"line_number":75,"context_line":"        do_test()"},{"line_number":76,"context_line":""},{"line_number":77,"context_line":"    def test_scan_readonly(self):"},{"line_number":78,"context_line":"        self._test_scan(delete\u003dFalse)"},{"line_number":79,"context_line":""},{"line_number":80,"context_line":"    def test_scan_delete(self):"},{"line_number":81,"context_line":"        self._test_scan(delete\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":6,"id":"baada198_272de846","line":78,"in_reply_to":"baada198_b74ebbbf","updated":"2014-07-11 21:55:59.000000000","message":"I guess my point is that these tests are closely coupled to the implementation (what gets called, number of many times, etc) making it harder to maintain in the future.\n\nGenerally we want to test the results not necessarily how it does it.","commit_id":"f4e3c47854bc91ddfaef8c3aa553144d217a80df"},{"author":{"_account_id":8412,"name":"Mike Durnosvistov","email":"glacierr.dev@gmail.com","username":"mdurnosvistov"},"change_message_id":"30a7a9afeddaef53ef7bcd3e8b4fa3141884148c","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class TestNullInstanceUuidScan(test.NoDBTestCase):"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def _test_scan(self, delete):"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"        engine \u003d mock.Mock()"},{"line_number":28,"context_line":"        # Load up some fake tables."}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_b3df5a65","line":25,"updated":"2014-07-21 09:51:37.000000000","message":"Please make this test without function `do_test`","commit_id":"ebba653b8c46478d5a9728903acabda71fa854bb"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"702eb062c0b55c5215d7fd739af846321600e293","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class TestNullInstanceUuidScan(test.NoDBTestCase):"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def _test_scan(self, delete):"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"        engine \u003d mock.Mock()"},{"line_number":28,"context_line":"        # Load up some fake tables."}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_8d694e27","line":25,"in_reply_to":"baada198_b3df5a65","updated":"2014-07-21 14:29:10.000000000","message":"Why?  The reason I don\u0027t do that is because then the public tests that are calling this would have to pass in values, so I\u0027d have to move the mocks to those public tests which would duplicate the mocks and I wanted to avoid the code duplication since I\u0027m using a common private test method.\n\nThe do_test nested method approach is common in other places where we can\u0027t decorate the test method itself, but don\u0027t want to do a bunch of mocks in a nested context like:\n\nwith contextlib.nested(\n    mock.patch.object(...),\n    mock.patch.object(...),\n) as (\n    mockA,\n    mockB,\n):\n\netc","commit_id":"ebba653b8c46478d5a9728903acabda71fa854bb"},{"author":{"_account_id":8412,"name":"Mike Durnosvistov","email":"glacierr.dev@gmail.com","username":"mdurnosvistov"},"change_message_id":"ef4d80ff2eef2257ca2b2d2abdfff146f6f2870c","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class TestNullInstanceUuidScan(test.NoDBTestCase):"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def _test_scan(self, delete):"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"        engine \u003d mock.Mock()"},{"line_number":28,"context_line":"        # Load up some fake tables."}],"source_content_type":"text/x-python","patch_set":9,"id":"baada198_7347654c","line":25,"updated":"2014-07-28 10:31:10.000000000","message":"Please use mock-decorators here, like:\n\n    @mock.patch.object(migration, \u0027get_engine\u0027)\n    @mock.patch.object(MetaData, \u0027reflect\u0027)\n    @mock.patch.object(MetaData, \u0027sorted_tables\u0027,\n                       new_callable\u003dmock.PropertyMock)\n    @mock.patch.object(migration, \u0027_process_null_records\u0027)\n    @mock.patch.object(db_utils, \u0027get_table\u0027)\n    def _test_scan(self, mock_get_table, process_mock, sorted_tables_mock,\n                   reflect_mock, get_engine_mock, delete):\n        ...\n\nthen you don\u0027t need make function do_test(...)","commit_id":"1b17da8fca3a6b23d03d8d867c653977163309e7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"9434fd538b7b1b432a585a319c8475ee5e4e74ec","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class TestNullInstanceUuidScan(test.NoDBTestCase):"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def _test_scan(self, delete):"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"        engine \u003d mock.Mock()"},{"line_number":28,"context_line":"        # Load up some fake tables."}],"source_content_type":"text/x-python","patch_set":9,"id":"baada198_2cbf44cb","line":25,"in_reply_to":"baada198_2690464d","updated":"2014-07-28 15:59:02.000000000","message":"But....lots of copy/paste code also sucks, so that\u0027s why I\u0027m using a common private test method with parameters for the public test methods.\n\nLike I said before, the alternative is using a nested context for the mocks but that\u0027s dinged me in the past from other reviewers on the core team that like the nested test method approach with decorators.","commit_id":"1b17da8fca3a6b23d03d8d867c653977163309e7"},{"author":{"_account_id":8412,"name":"Mike Durnosvistov","email":"glacierr.dev@gmail.com","username":"mdurnosvistov"},"change_message_id":"5bc422220ddfca7a0fa25a7ca725088190df52f6","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class TestNullInstanceUuidScan(test.NoDBTestCase):"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def _test_scan(self, delete):"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"        engine \u003d mock.Mock()"},{"line_number":28,"context_line":"        # Load up some fake tables."}],"source_content_type":"text/x-python","patch_set":9,"id":"baada198_2690464d","line":25,"in_reply_to":"baada198_3bba1f0b","updated":"2014-07-28 14:07:24.000000000","message":"Ohhh... sorry for that I didn\u0027t response on your response. :)\n\nMy reason in that test cases should be clearly for understanding what happens in the test case. It will be better if each test-case displays which `mock` they used. And","commit_id":"1b17da8fca3a6b23d03d8d867c653977163309e7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"2d84e7020d2157af9a7d4c25c15f354c47e8b883","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class TestNullInstanceUuidScan(test.NoDBTestCase):"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def _test_scan(self, delete):"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"        engine \u003d mock.Mock()"},{"line_number":28,"context_line":"        # Load up some fake tables."}],"source_content_type":"text/x-python","patch_set":9,"id":"baada198_3bba1f0b","line":25,"in_reply_to":"baada198_7347654c","updated":"2014-07-28 13:40:46.000000000","message":"See the response to the same comment (from you) in patch set 7...\n\nhttps://review.openstack.org/#/c/97946/7/nova/tests/db/test_sqlalchemy_migration.py","commit_id":"1b17da8fca3a6b23d03d8d867c653977163309e7"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e12c0bc575fbe860ecf4385bc8b6e9e3053e003a","unresolved":false,"context_lines":[{"line_number":16,"context_line":"from sqlalchemy import MetaData"},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"from nova.db.sqlalchemy import migration"},{"line_number":19,"context_line":"from nova.openstack.common.db.sqlalchemy import utils as db_utils"},{"line_number":20,"context_line":"from nova import test"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":""}],"source_content_type":"text/x-python","patch_set":14,"id":"baa201ad_26829552","line":19,"updated":"2014-10-13 22:04:27.000000000","message":"oslo.db","commit_id":"23ba7eacdd66acc0a1ba770f49f17a06d076bf90"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"10b0ce1df758f96444b1f7b6125ddebbcc86a100","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from nova import test"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class TestNullInstanceUuidScan(test.NoDBTestCase):"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def _test_scan(self, delete):"},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"baa201ad_db84df5f","line":23,"updated":"2014-10-16 17:03:29.000000000","message":"I kinda wonder if it wouldn\u0027t be better to make this one a real test that worked against the DB. You\u0027re mocking out a lot of SA stuff here, which if you got it wrong, could have some pretty disastrous consequences. What do you think?","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"60a835c7effe8306bafce1c52896ee2b0f151dff","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from nova import test"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class TestNullInstanceUuidScan(test.NoDBTestCase):"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def _test_scan(self, delete):"},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"5a890539_3e41de5a","line":23,"in_reply_to":"baa201ad_5edffd68","updated":"2014-11-11 20:09:36.000000000","message":"So....the problem here is when this runs, we\u0027re already past the 266 migration which means the model says you can\u0027t have a null instances.uuid entry, so I can\u0027t insert a record with that kind of entry to test it.  I can do this with fixed_ips though, but it kind of defeats the purpose given test_migrations already tests that.\n\nI could update the schema to make instances.uuid nullable in setUp and then change it in tearDown...","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6b110302b435f5831badece973702721c234c93a","unresolved":false,"context_lines":[{"line_number":20,"context_line":"from nova import test"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":""},{"line_number":23,"context_line":"class TestNullInstanceUuidScan(test.NoDBTestCase):"},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"    def _test_scan(self, delete):"},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":18,"id":"baa201ad_5edffd68","line":23,"in_reply_to":"baa201ad_db84df5f","updated":"2014-10-16 17:35:48.000000000","message":"I\u0027m not opposed to that, would have to hack on it a bit.","commit_id":"0ba24b3caf209c75c663245e861a2d37a1a92f33"}],"nova/tests/test_nova_manage.py":[{"author":{"_account_id":8412,"name":"Mike Durnosvistov","email":"glacierr.dev@gmail.com","username":"mdurnosvistov"},"change_message_id":"30a7a9afeddaef53ef7bcd3e8b4fa3141884148c","unresolved":false,"context_lines":[{"line_number":426,"context_line":"        self.commands.null_instance_uuid_scan()"},{"line_number":427,"context_line":"        self.assertIn(\"There were no records found\", sys.stdout.getvalue())"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    def _test_null_instance_uuid_scan(self, delete):"},{"line_number":430,"context_line":""},{"line_number":431,"context_line":"        @mock.patch.object(migration, \u0027db_null_instance_uuid_scan\u0027,"},{"line_number":432,"context_line":"                           return_value\u003d{\u0027foo\u0027: 1, \u0027bar\u0027: 0})"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_42954de2","line":429,"updated":"2014-07-21 09:51:37.000000000","message":"You don\u0027t need function `do_test`, you can use mock-decorator for `_test_null_instance_uuid_scan` test-case:\n\n    @mock.patch.object(migration, \u0027db_null_instance_uuid_scan\u0027,\n                       return_value\u003d{\u0027foo\u0027: 1, \u0027bar\u0027: 0})\n    def _test_null_instance_uuid_scan(self, mock_scan, delete):\n        ...","commit_id":"ebba653b8c46478d5a9728903acabda71fa854bb"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"702eb062c0b55c5215d7fd739af846321600e293","unresolved":false,"context_lines":[{"line_number":426,"context_line":"        self.commands.null_instance_uuid_scan()"},{"line_number":427,"context_line":"        self.assertIn(\"There were no records found\", sys.stdout.getvalue())"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    def _test_null_instance_uuid_scan(self, delete):"},{"line_number":430,"context_line":""},{"line_number":431,"context_line":"        @mock.patch.object(migration, \u0027db_null_instance_uuid_scan\u0027,"},{"line_number":432,"context_line":"                           return_value\u003d{\u0027foo\u0027: 1, \u0027bar\u0027: 0})"}],"source_content_type":"text/x-python","patch_set":7,"id":"baada198_ad7452fe","line":429,"in_reply_to":"baada198_42954de2","updated":"2014-07-21 14:29:10.000000000","message":"See response in the other test module.","commit_id":"ebba653b8c46478d5a9728903acabda71fa854bb"},{"author":{"_account_id":8412,"name":"Mike Durnosvistov","email":"glacierr.dev@gmail.com","username":"mdurnosvistov"},"change_message_id":"ef4d80ff2eef2257ca2b2d2abdfff146f6f2870c","unresolved":false,"context_lines":[{"line_number":426,"context_line":"        self.commands.null_instance_uuid_scan()"},{"line_number":427,"context_line":"        self.assertIn(\"There were no records found\", sys.stdout.getvalue())"},{"line_number":428,"context_line":""},{"line_number":429,"context_line":"    def _test_null_instance_uuid_scan(self, delete):"},{"line_number":430,"context_line":""},{"line_number":431,"context_line":"        @mock.patch.object(migration, \u0027db_null_instance_uuid_scan\u0027,"},{"line_number":432,"context_line":"                           return_value\u003d{\u0027foo\u0027: 1, \u0027bar\u0027: 0})"}],"source_content_type":"text/x-python","patch_set":9,"id":"baada198_5346e121","line":429,"updated":"2014-07-28 10:31:10.000000000","message":"the same about mock-decorator","commit_id":"1b17da8fca3a6b23d03d8d867c653977163309e7"},{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"44f8e1cb54ea00771ab343386bdc134b1f3b2460","unresolved":false,"context_lines":[{"line_number":348,"context_line":"    def _test_null_instance_uuid_scan(self, delete):"},{"line_number":349,"context_line":""},{"line_number":350,"context_line":"        @mock.patch.object(migration, \u0027db_null_instance_uuid_scan\u0027,"},{"line_number":351,"context_line":"                           return_value\u003d{\u0027foo\u0027: 1, \u0027bar\u0027: 0})"},{"line_number":352,"context_line":"        def do_test(mock_scan):"},{"line_number":353,"context_line":"            self.useFixture(fixtures.MonkeyPatch(\u0027sys.stdout\u0027,"},{"line_number":354,"context_line":"                                                 StringIO.StringIO()))"}],"source_content_type":"text/x-python","patch_set":22,"id":"5a890539_57dbedec","line":351,"updated":"2014-11-11 22:42:23.000000000","message":"Can\u0027t this just be a decorator on self._test_null_instance_uuid_scan? It looks like the nested function is unnecessary here.","commit_id":"1503449a8ac5fd416e76f1023b5e375e9b8c5a7d"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"e0bd184404c9fae03312d14052eba898a4b0e17c","unresolved":false,"context_lines":[{"line_number":348,"context_line":"    def _test_null_instance_uuid_scan(self, delete):"},{"line_number":349,"context_line":""},{"line_number":350,"context_line":"        @mock.patch.object(migration, \u0027db_null_instance_uuid_scan\u0027,"},{"line_number":351,"context_line":"                           return_value\u003d{\u0027foo\u0027: 1, \u0027bar\u0027: 0})"},{"line_number":352,"context_line":"        def do_test(mock_scan):"},{"line_number":353,"context_line":"            self.useFixture(fixtures.MonkeyPatch(\u0027sys.stdout\u0027,"},{"line_number":354,"context_line":"                                                 StringIO.StringIO()))"}],"source_content_type":"text/x-python","patch_set":22,"id":"5a890539_6f717b43","line":351,"in_reply_to":"5a890539_57dbedec","updated":"2014-11-14 22:50:04.000000000","message":"I\u0027d have to play with it.","commit_id":"1503449a8ac5fd416e76f1023b5e375e9b8c5a7d"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"c776a0e0b46d0973a3a5307c70e62397ced69e48","unresolved":false,"context_lines":[{"line_number":348,"context_line":"    def _test_null_instance_uuid_scan(self, delete):"},{"line_number":349,"context_line":""},{"line_number":350,"context_line":"        @mock.patch.object(migration, \u0027db_null_instance_uuid_scan\u0027,"},{"line_number":351,"context_line":"                           return_value\u003d{\u0027foo\u0027: 1, \u0027bar\u0027: 0})"},{"line_number":352,"context_line":"        def do_test(mock_scan):"},{"line_number":353,"context_line":"            self.useFixture(fixtures.MonkeyPatch(\u0027sys.stdout\u0027,"},{"line_number":354,"context_line":"                                                 StringIO.StringIO()))"}],"source_content_type":"text/x-python","patch_set":22,"id":"5a890539_c3efda1c","line":351,"in_reply_to":"5a890539_6f717b43","updated":"2014-11-21 18:38:55.000000000","message":"Done","commit_id":"1503449a8ac5fd416e76f1023b5e375e9b8c5a7d"}],"nova/tests/unit/db/test_migrations.py":[{"author":{"_account_id":2750,"name":"Sean Dague","email":"sean@dague.net","username":"sdague"},"change_message_id":"e0ad39609896f07516413aa17486c220d0405cd4","unresolved":false,"context_lines":[{"line_number":459,"context_line":"        # Add a null instance_uuid entry for the volumes table"},{"line_number":460,"context_line":"        # since it doesn\u0027t have a foreign key back to the instances table."},{"line_number":461,"context_line":"        volumes \u003d oslodbutils.get_table(engine, \u0027volumes\u0027)"},{"line_number":462,"context_line":"        fake_volume \u003d {\u0027id\u0027: 1}"},{"line_number":463,"context_line":"        volumes.insert().execute(fake_volume)"},{"line_number":464,"context_line":""},{"line_number":465,"context_line":"    def _check_267(self, engine, data):"}],"source_content_type":"text/x-python","patch_set":26,"id":"5a890539_1bc5625b","line":462,"updated":"2014-12-04 15:27:16.000000000","message":"this needs to be \"1\"","commit_id":"f929abb9e5e2e31d4b6564bd5f6267d9ec47f3be"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"fe35a354ab1ae0e992b590d8a6c994c8d93c4df2","unresolved":false,"context_lines":[{"line_number":459,"context_line":"        # Add a null instance_uuid entry for the volumes table"},{"line_number":460,"context_line":"        # since it doesn\u0027t have a foreign key back to the instances table."},{"line_number":461,"context_line":"        volumes \u003d oslodbutils.get_table(engine, \u0027volumes\u0027)"},{"line_number":462,"context_line":"        fake_volume \u003d {\u0027id\u0027: 1}"},{"line_number":463,"context_line":"        volumes.insert().execute(fake_volume)"},{"line_number":464,"context_line":""},{"line_number":465,"context_line":"    def _check_267(self, engine, data):"}],"source_content_type":"text/x-python","patch_set":26,"id":"5a890539_dbf83a7e","line":462,"in_reply_to":"5a890539_1bc5625b","updated":"2014-12-04 15:33:17.000000000","message":"Thanks, that lines up with the 216 migration, which I hadn\u0027t looked at yet:\n\nhttp://git.openstack.org/cgit/openstack/nova/tree/nova/db/sqlalchemy/migrate_repo/versions/216_havana.py#n1020\n\nI didn\u0027t realize it was a UUID yet (hadn\u0027t dug in).\n\nI had also just copied the above fixed_ips stuff assuming that id was the same (integer) and it was fine on sqlite but I guess pg is more strict with types (assuming DB2 would be also so a good catch).","commit_id":"f929abb9e5e2e31d4b6564bd5f6267d9ec47f3be"},{"author":{"_account_id":100,"name":"Johannes Erdfelt","email":"johannes@erdfelt.com","username":"johannes.erdfelt"},"change_message_id":"8bf5e45b6f895b86cfa5d6b1eaa7bc96f88f860d","unresolved":false,"context_lines":[{"line_number":463,"context_line":"        volumes.insert().execute(fake_volume)"},{"line_number":464,"context_line":""},{"line_number":465,"context_line":"    def _check_267(self, engine, data):"},{"line_number":466,"context_line":"        # Make sure the column is non-nullable and the UC exists."},{"line_number":467,"context_line":"        fixed_ips \u003d oslodbutils.get_table(engine, \u0027fixed_ips\u0027)"},{"line_number":468,"context_line":"        self.assertTrue(fixed_ips.c.instance_uuid.nullable)"},{"line_number":469,"context_line":"        fixed_ip \u003d fixed_ips.select(fixed_ips.c.id \u003d\u003d 1).execute().first()"}],"source_content_type":"text/x-python","patch_set":27,"id":"5a890539_3cef6b88","line":466,"updated":"2014-12-04 21:38:12.000000000","message":"This comment seems to reference the code between lines 472-478. Especially since the code on line 468 is the opposite of the comment","commit_id":"c0ea53ce353684b48303fc59393930c3fa5ade58"},{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"6f86a0a18fe327ec3efc021df0a8bc5de2787b88","unresolved":false,"context_lines":[{"line_number":463,"context_line":"        volumes.insert().execute(fake_volume)"},{"line_number":464,"context_line":""},{"line_number":465,"context_line":"    def _check_267(self, engine, data):"},{"line_number":466,"context_line":"        # Make sure the column is non-nullable and the UC exists."},{"line_number":467,"context_line":"        fixed_ips \u003d oslodbutils.get_table(engine, \u0027fixed_ips\u0027)"},{"line_number":468,"context_line":"        self.assertTrue(fixed_ips.c.instance_uuid.nullable)"},{"line_number":469,"context_line":"        fixed_ip \u003d fixed_ips.select(fixed_ips.c.id \u003d\u003d 1).execute().first()"}],"source_content_type":"text/x-python","patch_set":27,"id":"5a890539_1388dd69","line":466,"in_reply_to":"5a890539_3cef6b88","updated":"2014-12-04 22:22:42.000000000","message":"Yeah, these tests changed quite a bit in the last few patch sets so things probably got moved around and I missed moving the comment, or it was just originally meant as a docstring type comment for the purpose of the test and then blew up with more validation after that.","commit_id":"c0ea53ce353684b48303fc59393930c3fa5ade58"}],"nova/tests/unit/db/test_sqlalchemy_migration.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"11cbd145cd83021dd0259b790cb7c9040e60c4b4","unresolved":false,"context_lines":[{"line_number":76,"context_line":"        record \u003d fixed_ips.select(fixed_ips.c.id \u003d\u003d 1).execute().first()"},{"line_number":77,"context_line":"        self.assertIsNotNone(record)"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        bdms \u003d db_utils.get_table(self.engine, \u0027consoles\u0027)"},{"line_number":80,"context_line":"        record \u003d bdms.select(bdms.c.id \u003d\u003d 1).execute().first()"},{"line_number":81,"context_line":"        self.assertIsNone(record)"},{"line_number":82,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"5a890539_372c4599","line":79,"updated":"2014-12-03 00:19:42.000000000","message":"s/bdms/consoles/","commit_id":"8043ab6544478a33a71bc076137a32147403dd59"}],"tools/db/null_instance_uuid_scan.py":[{"author":{"_account_id":6873,"name":"Matt Riedemann","email":"mriedem.os@gmail.com","username":"mriedem"},"change_message_id":"296a29b8d1b76d5008702008946d0e0da95cc8d5","unresolved":false,"context_lines":[{"line_number":38,"context_line":"        description\u003d\u0027Lists and optionally deletes database records where \u0027"},{"line_number":39,"context_line":"                    \u0027instance_uuid is NULL.\u0027)"},{"line_number":40,"context_line":"    parser.add_argument(\u0027-d\u0027, \u0027--delete\u0027, help\u003d\u0027Delete records?\u0027,"},{"line_number":41,"context_line":"                        default\u003dFalse)"},{"line_number":42,"context_line":"    return parser.parse_args()"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":""}],"source_content_type":"text/x-python","patch_set":4,"id":"baada198_21cb7ba6","line":41,"updated":"2014-07-01 20:28:49.000000000","message":"This probably needs to be action\u003d\u0027store_false\u0027.","commit_id":"caa796435889fd8938c8548fd39ae83f1600e48d"}]}
