)]}'
{"nova/db/sqlalchemy/api_migrations/migrate_repo/versions/004_add_request_spec.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"52a6ac61487366bbb8d0da8aa339437a0fdf0cf7","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    # so trying to add a second index on the host column will fail with error"},{"line_number":42,"context_line":"    # SQL0605W, so omit the index in the case of DB2."},{"line_number":43,"context_line":"    if migrate_engine.name !\u003d \u0027ibm_db_sa\u0027:"},{"line_number":44,"context_line":"        Index(\u0027request_spec_instance_uuid_idx\u0027, request_specs.c.instance_uuid)"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    request_specs.create(checkfirst\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":33,"id":"ba8a016a_9233ff61","line":44,"updated":"2015-11-18 17:39:15.000000000","message":"Does just declaring the index magically make it a thing? Don\u0027t we need to put it on the table object above?","commit_id":"12ccc515683002a7a3c781cbe996d7ced9e40eda"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"33a57bec8637c689197c42afabfa66b8b7cad8a6","unresolved":false,"context_lines":[{"line_number":41,"context_line":"    # so trying to add a second index on the host column will fail with error"},{"line_number":42,"context_line":"    # SQL0605W, so omit the index in the case of DB2."},{"line_number":43,"context_line":"    if migrate_engine.name !\u003d \u0027ibm_db_sa\u0027:"},{"line_number":44,"context_line":"        Index(\u0027request_spec_instance_uuid_idx\u0027, request_specs.c.instance_uuid)"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    request_specs.create(checkfirst\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":33,"id":"ba8a016a_6d5ec045","line":44,"in_reply_to":"ba8a016a_9233ff61","updated":"2015-11-18 18:02:36.000000000","message":"Apparently it does.  I copied this from the previous pattern established by Matt, but testing showed that this works.","commit_id":"12ccc515683002a7a3c781cbe996d7ced9e40eda"}],"nova/db/sqlalchemy/migrate_repo/versions/300_add_request_spec.py":[{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"9bc456390b81550545f6aaec4ba3bbd7fcc642d8","unresolved":false,"context_lines":[{"line_number":24,"context_line":"    meta \u003d MetaData()"},{"line_number":25,"context_line":"    meta.bind \u003d migrate_engine"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    request_specs \u003d Table(\u0027request_specs\u0027, meta,"},{"line_number":28,"context_line":"        Column(\u0027created_at\u0027, DateTime),"},{"line_number":29,"context_line":"        Column(\u0027updated_at\u0027, DateTime),"},{"line_number":30,"context_line":"        Column(\u0027id\u0027, Integer, primary_key\u003dTrue, nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":13,"id":"fa1b9901_afd7ff21","line":27,"updated":"2015-08-19 10:20:00.000000000","message":"Normally table names are singular","commit_id":"e54937c76a83d22cbd2a7f35acb14701c86ab686"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"dde4f3aee887bc1b9b38c270c25a59885c0dfbf6","unresolved":false,"context_lines":[{"line_number":24,"context_line":"    meta \u003d MetaData()"},{"line_number":25,"context_line":"    meta.bind \u003d migrate_engine"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":"    request_specs \u003d Table(\u0027request_specs\u0027, meta,"},{"line_number":28,"context_line":"        Column(\u0027created_at\u0027, DateTime),"},{"line_number":29,"context_line":"        Column(\u0027updated_at\u0027, DateTime),"},{"line_number":30,"context_line":"        Column(\u0027id\u0027, Integer, primary_key\u003dTrue, nullable\u003dFalse),"}],"source_content_type":"text/x-python","patch_set":13,"id":"fa1b9901_4f8423d3","line":27,"in_reply_to":"fa1b9901_afd7ff21","updated":"2015-08-19 10:26:23.000000000","message":"Ignore that... OpenStack doesn\u0027t seem to follow that convention","commit_id":"e54937c76a83d22cbd2a7f35acb14701c86ab686"}],"nova/db/sqlalchemy/migrate_repo/versions/313_add_request_spec.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"bcb089b28789a2b98c8297f6ca8652ef60ee8cc8","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        Column(\u0027limits\u0027, Text, nullable\u003dTrue),"},{"line_number":45,"context_line":"        Column(\u0027instance_group\u0027, Text(), nullable\u003dTrue),"},{"line_number":46,"context_line":"        Column(\u0027scheduler_hints\u0027, Text(), nullable\u003dTrue),"},{"line_number":47,"context_line":"        Column(\u0027instance_uuid\u0027, String(36), nullable\u003dFalse),"},{"line_number":48,"context_line":"        Index(\u0027request_spec_instance_uuid_idx\u0027, \u0027instance_uuid\u0027),"},{"line_number":49,"context_line":"        ForeignKeyConstraint(columns\u003d[\u0027instance_uuid\u0027],"},{"line_number":50,"context_line":"            refcolumns\u003d[instances.c.uuid]),"}],"source_content_type":"text/x-python","patch_set":28,"id":"da85f559_a781874f","line":47,"updated":"2015-11-13 18:34:16.000000000","message":"I don\u0027t think we need to persist all these separately. I was under the impression that we\u0027d store a text column for the whole requestspec object, and then a few columns for looking them  up, like maybe uuid, project, etc.\n\nNot breaking it out makes it much easier to rev this without heroics in the immediate schema change.","commit_id":"58bafab0df2ff34cd4038619275b7e04947212a4"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"498def6bf40929837219fa7330e7b24d7476389f","unresolved":false,"context_lines":[{"line_number":44,"context_line":"        Column(\u0027limits\u0027, Text, nullable\u003dTrue),"},{"line_number":45,"context_line":"        Column(\u0027instance_group\u0027, Text(), nullable\u003dTrue),"},{"line_number":46,"context_line":"        Column(\u0027scheduler_hints\u0027, Text(), nullable\u003dTrue),"},{"line_number":47,"context_line":"        Column(\u0027instance_uuid\u0027, String(36), nullable\u003dFalse),"},{"line_number":48,"context_line":"        Index(\u0027request_spec_instance_uuid_idx\u0027, \u0027instance_uuid\u0027),"},{"line_number":49,"context_line":"        ForeignKeyConstraint(columns\u003d[\u0027instance_uuid\u0027],"},{"line_number":50,"context_line":"            refcolumns\u003d[instances.c.uuid]),"}],"source_content_type":"text/x-python","patch_set":28,"id":"da85f559_fdee40b3","line":47,"in_reply_to":"da85f559_a781874f","updated":"2015-11-13 19:38:05.000000000","message":"Dan made a good point. After discussing on IRC, I feel we should just persist instance_uuid and id separately and then the whole object serialized","commit_id":"58bafab0df2ff34cd4038619275b7e04947212a4"}],"nova/db/sqlalchemy/models.py":[{"author":{"_account_id":6062,"name":"jichenjc","email":"jichenjc@cn.ibm.com","username":"jichenjc"},"change_message_id":"2cbf08c6f8b84de5bf7b88b4f0a981748a7d619c","unresolved":false,"context_lines":[{"line_number":504,"context_line":"    image \u003d Column(Text, nullable\u003dTrue)"},{"line_number":505,"context_line":"    numa_topology \u003d Column(Text, nullable\u003dTrue)"},{"line_number":506,"context_line":"    pci_requests \u003d Column(Text, nullable\u003dTrue)"},{"line_number":507,"context_line":"    instance_uuid \u003d Column(String(36), nullable\u003dFalse)"},{"line_number":508,"context_line":"    project_id \u003d Column(String(255), nullable\u003dTrue)"},{"line_number":509,"context_line":"    availability_zone \u003d Column(String(255), nullable\u003dTrue)"},{"line_number":510,"context_line":"    flavor \u003d Column(Text, nullable\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa1b9901_0cacee33","line":507,"updated":"2015-08-25 12:53:29.000000000","message":"are we going to have multiple spec for one instance or only one considering this will be created during boot phase? \nwill a FK can be considered?","commit_id":"ec23c3f4411a7e1aa48cbeff0557ea806ea5cc67"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"0c158413415f14ac5ce4d59d424f47aa9e2324ea","unresolved":false,"context_lines":[{"line_number":504,"context_line":"    image \u003d Column(Text, nullable\u003dTrue)"},{"line_number":505,"context_line":"    numa_topology \u003d Column(Text, nullable\u003dTrue)"},{"line_number":506,"context_line":"    pci_requests \u003d Column(Text, nullable\u003dTrue)"},{"line_number":507,"context_line":"    instance_uuid \u003d Column(String(36), nullable\u003dFalse)"},{"line_number":508,"context_line":"    project_id \u003d Column(String(255), nullable\u003dTrue)"},{"line_number":509,"context_line":"    availability_zone \u003d Column(String(255), nullable\u003dTrue)"},{"line_number":510,"context_line":"    flavor \u003d Column(Text, nullable\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa1b9901_ed009136","line":507,"in_reply_to":"fa1b9901_0cacee33","updated":"2015-08-25 14:16:07.000000000","message":"One spec per instance.  A foreign key would be fine with me.","commit_id":"ec23c3f4411a7e1aa48cbeff0557ea806ea5cc67"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"b495590b13ab8197e73fd0a3d5ee908b473bc7e1","unresolved":false,"context_lines":[{"line_number":515,"context_line":"    retry \u003d Column(Text, nullable\u003dTrue)"},{"line_number":516,"context_line":"    limits \u003d Column(Text, nullable\u003dTrue)"},{"line_number":517,"context_line":"    instance_group \u003d Column(Text, nullable\u003dTrue)"},{"line_number":518,"context_line":"    scheduler_hints \u003d Column(Text, nullable\u003dTrue)"},{"line_number":519,"context_line":""},{"line_number":520,"context_line":""},{"line_number":521,"context_line":"class Reservation(BASE, NovaBase):"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa1b9901_c6e7b83e","line":518,"updated":"2015-08-25 10:28:40.000000000","message":"I keep wondering if most of these fields could just be a single Text column, to reduce the size of the table, given we always fetch all the fields, and only really need the id and instance_uuid as the other fields (although the timestamp fields are probably handy too).\n\nBut this seems to follow our usual patterns, so maybe this is the correct thing to do. I would love to get Jay\u0027s eyes on this one.","commit_id":"ec23c3f4411a7e1aa48cbeff0557ea806ea5cc67"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"0c158413415f14ac5ce4d59d424f47aa9e2324ea","unresolved":false,"context_lines":[{"line_number":515,"context_line":"    retry \u003d Column(Text, nullable\u003dTrue)"},{"line_number":516,"context_line":"    limits \u003d Column(Text, nullable\u003dTrue)"},{"line_number":517,"context_line":"    instance_group \u003d Column(Text, nullable\u003dTrue)"},{"line_number":518,"context_line":"    scheduler_hints \u003d Column(Text, nullable\u003dTrue)"},{"line_number":519,"context_line":""},{"line_number":520,"context_line":""},{"line_number":521,"context_line":"class Reservation(BASE, NovaBase):"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa1b9901_8d55551f","line":518,"in_reply_to":"fa1b9901_c6e7b83e","updated":"2015-08-25 14:16:07.000000000","message":"I wouldn\u0027t feel comfortable putting all of these into a single column without a defined schema for them.  It would be setting us up for a lot of pain later if we wanted to change any of these fields.","commit_id":"ec23c3f4411a7e1aa48cbeff0557ea806ea5cc67"}],"nova/objects/request_spec.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"8c68dbd47df2942b98e5a5c3b4984ceb0f5148f3","unresolved":false,"context_lines":[{"line_number":248,"context_line":""},{"line_number":249,"context_line":"    @staticmethod"},{"line_number":250,"context_line":"    def _get_by_instance_uuid_from_db(context, instance_uuid):"},{"line_number":251,"context_line":"        # NOTE(alaski): For now this only works will the nova database but"},{"line_number":252,"context_line":"        # eventually it should read from the nova or nova_api database based"},{"line_number":253,"context_line":"        # on the context."},{"line_number":254,"context_line":"        session \u003d db.get_session()"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa1b9901_c90dfd38","line":251,"range":{"start_line":251,"start_character":48,"end_line":251,"end_character":52},"updated":"2015-08-17 12:30:49.000000000","message":"s/will/with/","commit_id":"44727ec303b760e4acca0dce708b43b3334e331f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"8c68dbd47df2942b98e5a5c3b4984ceb0f5148f3","unresolved":false,"context_lines":[{"line_number":268,"context_line":""},{"line_number":269,"context_line":"    @staticmethod"},{"line_number":270,"context_line":"    def _create_in_db(context, updates):"},{"line_number":271,"context_line":"        # NOTE(alaski): For now this only works will the nova database but"},{"line_number":272,"context_line":"        # eventually it should write to the nova or nova_api database based"},{"line_number":273,"context_line":"        # on the context."},{"line_number":274,"context_line":"        session \u003d db.get_session()"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa1b9901_e94c8178","line":271,"range":{"start_line":271,"start_character":48,"end_line":271,"end_character":52},"updated":"2015-08-17 12:30:49.000000000","message":"s/will/with/","commit_id":"44727ec303b760e4acca0dce708b43b3334e331f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"8c68dbd47df2942b98e5a5c3b4984ceb0f5148f3","unresolved":false,"context_lines":[{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    @staticmethod"},{"line_number":322,"context_line":"    def _save_in_db(context, instance_uuid, updates):"},{"line_number":323,"context_line":"        # NOTE(alaski): For now this only works will the nova database but"},{"line_number":324,"context_line":"        # eventually it should write to the nova or nova_api database based"},{"line_number":325,"context_line":"        # on the context."},{"line_number":326,"context_line":"        session \u003d db.get_session()"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa1b9901_09bf75d1","line":323,"range":{"start_line":323,"start_character":48,"end_line":323,"end_character":52},"updated":"2015-08-17 12:30:49.000000000","message":"s/will/with/","commit_id":"44727ec303b760e4acca0dce708b43b3334e331f"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"b495590b13ab8197e73fd0a3d5ee908b473bc7e1","unresolved":false,"context_lines":[{"line_number":30,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":31,"context_line":"class RequestSpec(base.NovaObject):"},{"line_number":32,"context_line":"    # Version 1.0: Initial version"},{"line_number":33,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    fields \u003d {"},{"line_number":36,"context_line":"        \u0027id\u0027: fields.IntegerField(),"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa1b9901_260f942f","line":33,"updated":"2015-08-25 10:28:40.000000000","message":"don\u0027t we need to bump the version for the new remotable methods?","commit_id":"ec23c3f4411a7e1aa48cbeff0557ea806ea5cc67"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"0c158413415f14ac5ce4d59d424f47aa9e2324ea","unresolved":false,"context_lines":[{"line_number":30,"context_line":"@base.NovaObjectRegistry.register"},{"line_number":31,"context_line":"class RequestSpec(base.NovaObject):"},{"line_number":32,"context_line":"    # Version 1.0: Initial version"},{"line_number":33,"context_line":"    VERSION \u003d \u00271.0\u0027"},{"line_number":34,"context_line":""},{"line_number":35,"context_line":"    fields \u003d {"},{"line_number":36,"context_line":"        \u0027id\u0027: fields.IntegerField(),"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa1b9901_6d1ec171","line":33,"in_reply_to":"fa1b9901_260f942f","updated":"2015-08-25 14:16:07.000000000","message":"Yep, should do that.","commit_id":"ec23c3f4411a7e1aa48cbeff0557ea806ea5cc67"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"b495590b13ab8197e73fd0a3d5ee908b473bc7e1","unresolved":false,"context_lines":[{"line_number":251,"context_line":"    def _from_db_object(context, spec, db_spec):"},{"line_number":252,"context_line":"        for key in spec.fields:"},{"line_number":253,"context_line":"            if isinstance(spec.fields[key], fields.ObjectField):"},{"line_number":254,"context_line":"                try:"},{"line_number":255,"context_line":"                    getattr(spec, \u0027_load_%s\u0027 % key)(db_spec[key])"},{"line_number":256,"context_line":"                except AttributeError:"},{"line_number":257,"context_line":"                    LOG.exception(_LE(\u0027No load handler for %s\u0027), key)"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa1b9901_5b5dc577","line":254,"updated":"2015-08-25 10:28:40.000000000","message":"I wonder if we could just maintain a list and have a generic, load json field method, then default to the over-rides?","commit_id":"ec23c3f4411a7e1aa48cbeff0557ea806ea5cc67"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"0c158413415f14ac5ce4d59d424f47aa9e2324ea","unresolved":false,"context_lines":[{"line_number":251,"context_line":"    def _from_db_object(context, spec, db_spec):"},{"line_number":252,"context_line":"        for key in spec.fields:"},{"line_number":253,"context_line":"            if isinstance(spec.fields[key], fields.ObjectField):"},{"line_number":254,"context_line":"                try:"},{"line_number":255,"context_line":"                    getattr(spec, \u0027_load_%s\u0027 % key)(db_spec[key])"},{"line_number":256,"context_line":"                except AttributeError:"},{"line_number":257,"context_line":"                    LOG.exception(_LE(\u0027No load handler for %s\u0027), key)"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa1b9901_d042043e","line":254,"in_reply_to":"fa1b9901_5b5dc577","updated":"2015-08-25 14:16:07.000000000","message":"I\u0027m not sure I understand your suggestion.  Could you sketch out an example real quick?","commit_id":"ec23c3f4411a7e1aa48cbeff0557ea806ea5cc67"},{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"b495590b13ab8197e73fd0a3d5ee908b473bc7e1","unresolved":false,"context_lines":[{"line_number":289,"context_line":""},{"line_number":290,"context_line":"    def _get_update_primitives(self):"},{"line_number":291,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":292,"context_line":"        if \u0027image\u0027 in updates:"},{"line_number":293,"context_line":"            updates[\u0027image\u0027] \u003d jsonutils.dumps("},{"line_number":294,"context_line":"                    updates[\u0027image\u0027].obj_to_primitive())"},{"line_number":295,"context_line":"        if \u0027numa_topology\u0027 in updates:"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa1b9901_db1b15c9","line":292,"updated":"2015-08-25 10:28:40.000000000","message":"should we not just maintain a list of fields that need converting to json, and iterate through that list?","commit_id":"ec23c3f4411a7e1aa48cbeff0557ea806ea5cc67"},{"author":{"_account_id":6062,"name":"jichenjc","email":"jichenjc@cn.ibm.com","username":"jichenjc"},"change_message_id":"2cbf08c6f8b84de5bf7b88b4f0a981748a7d619c","unresolved":false,"context_lines":[{"line_number":289,"context_line":""},{"line_number":290,"context_line":"    def _get_update_primitives(self):"},{"line_number":291,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":292,"context_line":"        if \u0027image\u0027 in updates:"},{"line_number":293,"context_line":"            updates[\u0027image\u0027] \u003d jsonutils.dumps("},{"line_number":294,"context_line":"                    updates[\u0027image\u0027].obj_to_primitive())"},{"line_number":295,"context_line":"        if \u0027numa_topology\u0027 in updates:"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa1b9901_e7b0b38d","line":292,"in_reply_to":"fa1b9901_db1b15c9","updated":"2015-08-25 12:53:29.000000000","message":"++","commit_id":"ec23c3f4411a7e1aa48cbeff0557ea806ea5cc67"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"0c158413415f14ac5ce4d59d424f47aa9e2324ea","unresolved":false,"context_lines":[{"line_number":289,"context_line":""},{"line_number":290,"context_line":"    def _get_update_primitives(self):"},{"line_number":291,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":292,"context_line":"        if \u0027image\u0027 in updates:"},{"line_number":293,"context_line":"            updates[\u0027image\u0027] \u003d jsonutils.dumps("},{"line_number":294,"context_line":"                    updates[\u0027image\u0027].obj_to_primitive())"},{"line_number":295,"context_line":"        if \u0027numa_topology\u0027 in updates:"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa1b9901_707a188a","line":292,"in_reply_to":"fa1b9901_e7b0b38d","updated":"2015-08-25 14:16:07.000000000","message":"Can do.","commit_id":"ec23c3f4411a7e1aa48cbeff0557ea806ea5cc67"},{"author":{"_account_id":6062,"name":"jichenjc","email":"jichenjc@cn.ibm.com","username":"jichenjc"},"change_message_id":"2cbf08c6f8b84de5bf7b88b4f0a981748a7d619c","unresolved":false,"context_lines":[{"line_number":340,"context_line":"                        instance_uuid\u003dinstance_uuid)"},{"line_number":341,"context_line":"            db_spec.update(updates)"},{"line_number":342,"context_line":"            session.add(db_spec)"},{"line_number":343,"context_line":"        return db_spec"},{"line_number":344,"context_line":""},{"line_number":345,"context_line":"    @base.remotable"},{"line_number":346,"context_line":"    def save(self):"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa1b9901_0785a7ab","line":343,"updated":"2015-08-25 12:53:29.000000000","message":"not for sure, but logically seems put them into db layer is better?","commit_id":"ec23c3f4411a7e1aa48cbeff0557ea806ea5cc67"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"0c158413415f14ac5ce4d59d424f47aa9e2324ea","unresolved":false,"context_lines":[{"line_number":340,"context_line":"                        instance_uuid\u003dinstance_uuid)"},{"line_number":341,"context_line":"            db_spec.update(updates)"},{"line_number":342,"context_line":"            session.add(db_spec)"},{"line_number":343,"context_line":"        return db_spec"},{"line_number":344,"context_line":""},{"line_number":345,"context_line":"    @base.remotable"},{"line_number":346,"context_line":"    def save(self):"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa1b9901_b0b3d04c","line":343,"in_reply_to":"fa1b9901_0785a7ab","updated":"2015-08-25 14:16:07.000000000","message":"We\u0027ve been moving away from putting more into the db layer as new objects are added.  This keeps the queries with the object that uses them, and allows for subclassing the object in order to use a different db backend.","commit_id":"ec23c3f4411a7e1aa48cbeff0557ea806ea5cc67"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"9b962bdcf6f7a9c84bd8c72df772edaed78d0d7e","unresolved":false,"context_lines":[{"line_number":342,"context_line":"                except AttributeError:"},{"line_number":343,"context_line":"                    LOG.exception(_LE(\u0027No load handler for %s\u0027), key)"},{"line_number":344,"context_line":"            else:"},{"line_number":345,"context_line":"                setattr(spec, key, db_spec[key])"},{"line_number":346,"context_line":"        spec.obj_reset_changes()"},{"line_number":347,"context_line":"        spec._context \u003d context"},{"line_number":348,"context_line":"        return spec"}],"source_content_type":"text/x-python","patch_set":22,"id":"da20952f_244a6484","line":345,"updated":"2015-09-02 15:44:01.000000000","message":"I don\u0027t see where you manage the special case for treating a ListofStrings into an SQLA Text field (by serializing it I guess) for :\n\n- force_nodes\n- force_hosts\n- ignore_hosts","commit_id":"173052f6d733452c7abe49590558031b8329c296"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"5e5ac1f2942fcb0d22cfe7e8e4227160f4b78b9f","unresolved":false,"context_lines":[{"line_number":342,"context_line":"                except AttributeError:"},{"line_number":343,"context_line":"                    LOG.exception(_LE(\u0027No load handler for %s\u0027), key)"},{"line_number":344,"context_line":"            else:"},{"line_number":345,"context_line":"                setattr(spec, key, db_spec[key])"},{"line_number":346,"context_line":"        spec.obj_reset_changes()"},{"line_number":347,"context_line":"        spec._context \u003d context"},{"line_number":348,"context_line":"        return spec"}],"source_content_type":"text/x-python","patch_set":22,"id":"da20952f_87b49235","line":345,"in_reply_to":"da20952f_244a6484","updated":"2015-09-02 15:50:03.000000000","message":"Okay, I\u0027ll have to look closer at what form these take.","commit_id":"173052f6d733452c7abe49590558031b8329c296"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"9b962bdcf6f7a9c84bd8c72df772edaed78d0d7e","unresolved":false,"context_lines":[{"line_number":376,"context_line":"    def _get_update_primitives(self):"},{"line_number":377,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":378,"context_line":"        for obj_field in [\u0027image\u0027, \u0027numa_topology\u0027, \u0027pci_requests\u0027,"},{"line_number":379,"context_line":"                \u0027flavor\u0027, \u0027retry\u0027, \u0027limits\u0027, \u0027instance_group\u0027]:"},{"line_number":380,"context_line":"            if obj_field in updates:"},{"line_number":381,"context_line":"                updates[obj_field] \u003d jsonutils.dumps("},{"line_number":382,"context_line":"                        updates[obj_field].obj_to_primitive())"}],"source_content_type":"text/x-python","patch_set":22,"id":"da20952f_c4c9287b","line":379,"updated":"2015-09-02 15:44:01.000000000","message":"nit: you could provide the same logic that you wrote L339 instead of hardcoding which fields need to be primitived separately","commit_id":"173052f6d733452c7abe49590558031b8329c296"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"5e5ac1f2942fcb0d22cfe7e8e4227160f4b78b9f","unresolved":false,"context_lines":[{"line_number":376,"context_line":"    def _get_update_primitives(self):"},{"line_number":377,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":378,"context_line":"        for obj_field in [\u0027image\u0027, \u0027numa_topology\u0027, \u0027pci_requests\u0027,"},{"line_number":379,"context_line":"                \u0027flavor\u0027, \u0027retry\u0027, \u0027limits\u0027, \u0027instance_group\u0027]:"},{"line_number":380,"context_line":"            if obj_field in updates:"},{"line_number":381,"context_line":"                updates[obj_field] \u003d jsonutils.dumps("},{"line_number":382,"context_line":"                        updates[obj_field].obj_to_primitive())"}],"source_content_type":"text/x-python","patch_set":22,"id":"da20952f_c7d84a82","line":379,"in_reply_to":"da20952f_c4c9287b","updated":"2015-09-02 15:50:03.000000000","message":"Sure.","commit_id":"173052f6d733452c7abe49590558031b8329c296"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"9b962bdcf6f7a9c84bd8c72df772edaed78d0d7e","unresolved":false,"context_lines":[{"line_number":411,"context_line":"    @base.remotable"},{"line_number":412,"context_line":"    def save(self):"},{"line_number":413,"context_line":"        updates \u003d self._get_update_primitives()"},{"line_number":414,"context_line":"        db_spec \u003d self._save_in_db(self._context, self.instance_uuid, updates)"},{"line_number":415,"context_line":"        self._from_db_object(self._context, self, db_spec)"},{"line_number":416,"context_line":"        self.obj_reset_changes()"},{"line_number":417,"context_line":""}],"source_content_type":"text/x-python","patch_set":22,"id":"da20952f_242ca449","line":414,"updated":"2015-09-02 15:44:01.000000000","message":"some comments explaining why we\u0027re decoupling those objects from their respective .save() methods would be nice. \n\nI mean, I understand *why*, but that needs to be shared to the team :-)","commit_id":"173052f6d733452c7abe49590558031b8329c296"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"8c239cb325f7e9cd44e8c60d29a22a1651c1e594","unresolved":false,"context_lines":[{"line_number":384,"context_line":"        for key in updates.keys():"},{"line_number":385,"context_line":"            if isinstance(updates[key], base.NovaObject):"},{"line_number":386,"context_line":"                updates[key] \u003d jsonutils.dumps(updates[key].obj_to_primitive())"},{"line_number":387,"context_line":"            elif key in [\u0027ignore_hosts\u0027, \u0027force_hosts\u0027, \u0027force_nodes\u0027]:"},{"line_number":388,"context_line":"                updates[key] \u003d jsonutils.dumps(updates[key])"},{"line_number":389,"context_line":"        return updates"},{"line_number":390,"context_line":""}],"source_content_type":"text/x-python","patch_set":24,"id":"da20952f_cf261416","line":387,"updated":"2015-09-02 21:07:43.000000000","message":"you also need to add scheduler_hints to the list...","commit_id":"ec56d84f7e8b9b3c08f9c0037d2184761f8c6f92"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"909d07dc1d9e1f2be674cfd015eb709a97359621","unresolved":false,"context_lines":[{"line_number":347,"context_line":"            else:"},{"line_number":348,"context_line":"                value \u003d db_spec[key]"},{"line_number":349,"context_line":"                if key in [\u0027ignore_hosts\u0027, \u0027force_hosts\u0027, \u0027force_nodes\u0027,"},{"line_number":350,"context_line":"                        \u0027scheduler_hints\u0027]:"},{"line_number":351,"context_line":"                    value \u003d jsonutils.loads(value)"},{"line_number":352,"context_line":"                setattr(spec, key, value)"},{"line_number":353,"context_line":"        spec.obj_reset_changes()"}],"source_content_type":"text/x-python","patch_set":25,"id":"da20952f_d2f55ced","line":350,"updated":"2015-09-02 23:07:24.000000000","message":"Ideally these would be a constant/global in the file so we don\u0027t have to repeat it and if it gets updated down the line","commit_id":"6b9889b9610856e5af6459debd3c59a680a0523e"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"5dec346213ee1302fc1b8337746dbd1b7eb1875b","unresolved":false,"context_lines":[{"line_number":347,"context_line":"            else:"},{"line_number":348,"context_line":"                value \u003d db_spec[key]"},{"line_number":349,"context_line":"                if key in [\u0027ignore_hosts\u0027, \u0027force_hosts\u0027, \u0027force_nodes\u0027,"},{"line_number":350,"context_line":"                        \u0027scheduler_hints\u0027]:"},{"line_number":351,"context_line":"                    value \u003d jsonutils.loads(value)"},{"line_number":352,"context_line":"                setattr(spec, key, value)"},{"line_number":353,"context_line":"        spec.obj_reset_changes()"}],"source_content_type":"text/x-python","patch_set":25,"id":"da20952f_0b8f00cd","line":350,"in_reply_to":"da20952f_d2f55ced","updated":"2015-09-03 13:17:51.000000000","message":"Fair point.","commit_id":"6b9889b9610856e5af6459debd3c59a680a0523e"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"90d14ee95fcf9054c8e5723cf05ccdc3e4aad02e","unresolved":false,"context_lines":[{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    obj_relationships \u003d {"},{"line_number":69,"context_line":"        \u0027image\u0027: [(\u00271.0\u0027, \u00271.5\u0027), (\u00271.1\u0027, \u00271.6\u0027),"},{"line_number":70,"context_line":"                  (\u00271.5\u0027, \u00271.7\u0027)],"},{"line_number":71,"context_line":"        \u0027numa_topology\u0027: [(\u00271.0\u0027, \u00271.2\u0027)],"},{"line_number":72,"context_line":"        \u0027flavor\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"},{"line_number":73,"context_line":"        \u0027pci_requests\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"}],"source_content_type":"text/x-python","patch_set":26,"id":"3a29b11f_c215139c","line":70,"updated":"2015-10-22 11:12:30.000000000","message":"this should be (\u00271.4\u0027, \u00271.7\u0027), (\u00271.5\u0027, \u00271.8\u0027) I am not 100% sure if you need to bump the imagemeta too\nWhy are we dropping the 1.4?","commit_id":"dcfa47f396bce8480f201efc53f38d3f2f11201b"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"331119cf0a2de6b5e55275321842ff21a1c3eb41","unresolved":false,"context_lines":[{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    obj_relationships \u003d {"},{"line_number":69,"context_line":"        \u0027image\u0027: [(\u00271.0\u0027, \u00271.5\u0027), (\u00271.1\u0027, \u00271.6\u0027),"},{"line_number":70,"context_line":"                  (\u00271.5\u0027, \u00271.7\u0027)],"},{"line_number":71,"context_line":"        \u0027numa_topology\u0027: [(\u00271.0\u0027, \u00271.2\u0027)],"},{"line_number":72,"context_line":"        \u0027flavor\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"},{"line_number":73,"context_line":"        \u0027pci_requests\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"}],"source_content_type":"text/x-python","patch_set":26,"id":"3a29b11f_9e9213f5","line":70,"in_reply_to":"3a29b11f_c215139c","updated":"2015-10-22 12:25:30.000000000","message":"Just my mistake, thanks","commit_id":"dcfa47f396bce8480f201efc53f38d3f2f11201b"},{"author":{"_account_id":2835,"name":"Brian Elliott","email":"bdelliott@gmail.com","username":"belliott"},"change_message_id":"e6f9d35acbc742f08f27ac447ed79c2d606dd5b2","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    # Version 1.3: InstanceGroup version 1.10"},{"line_number":40,"context_line":"    # Version 1.4: ImageMeta version 1.7"},{"line_number":41,"context_line":"    # Version 1.5: Added get_by_instance_uuid(), create(), save()"},{"line_number":42,"context_line":"    VERSION \u003d \u00271.5\u0027"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    fields \u003d {"},{"line_number":45,"context_line":"        \u0027id\u0027: fields.IntegerField(),"}],"source_content_type":"text/x-python","patch_set":27,"id":"1a26ad4f_ffab731b","line":42,"updated":"2015-10-30 01:03:16.000000000","message":"Does this need a version bump?  You haven\u0027t added any new fields.","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"c67a11d40f26d916b169168616d1a6a9b1959d34","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    # Version 1.3: InstanceGroup version 1.10"},{"line_number":40,"context_line":"    # Version 1.4: ImageMeta version 1.7"},{"line_number":41,"context_line":"    # Version 1.5: Added get_by_instance_uuid(), create(), save()"},{"line_number":42,"context_line":"    VERSION \u003d \u00271.5\u0027"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    fields \u003d {"},{"line_number":45,"context_line":"        \u0027id\u0027: fields.IntegerField(),"}],"source_content_type":"text/x-python","patch_set":27,"id":"da85f559_f6543a55","line":42,"in_reply_to":"1a26ad4f_ffab731b","updated":"2015-11-09 08:07:44.000000000","message":"i think that it does as there are new methods that have been added. but then again i may be wrong","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"5183eeedc18373a8ee7bff605a9fa558ede0afa7","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    # Version 1.3: InstanceGroup version 1.10"},{"line_number":40,"context_line":"    # Version 1.4: ImageMeta version 1.7"},{"line_number":41,"context_line":"    # Version 1.5: Added get_by_instance_uuid(), create(), save()"},{"line_number":42,"context_line":"    VERSION \u003d \u00271.5\u0027"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    fields \u003d {"},{"line_number":45,"context_line":"        \u0027id\u0027: fields.IntegerField(),"}],"source_content_type":"text/x-python","patch_set":27,"id":"da85f559_8bfe0137","line":42,"in_reply_to":"da85f559_0196564c","updated":"2015-11-12 22:11:55.000000000","message":"It does because new *remotable* methods were added.","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"dc185f44f474015b0a29f4d4de31adc0f93ff3fe","unresolved":false,"context_lines":[{"line_number":39,"context_line":"    # Version 1.3: InstanceGroup version 1.10"},{"line_number":40,"context_line":"    # Version 1.4: ImageMeta version 1.7"},{"line_number":41,"context_line":"    # Version 1.5: Added get_by_instance_uuid(), create(), save()"},{"line_number":42,"context_line":"    VERSION \u003d \u00271.5\u0027"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":"    fields \u003d {"},{"line_number":45,"context_line":"        \u0027id\u0027: fields.IntegerField(),"}],"source_content_type":"text/x-python","patch_set":27,"id":"da85f559_0196564c","line":42,"in_reply_to":"da85f559_f6543a55","updated":"2015-11-09 08:31:40.000000000","message":"Yes, it does because new methods were added.","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":2835,"name":"Brian Elliott","email":"bdelliott@gmail.com","username":"belliott"},"change_message_id":"e6f9d35acbc742f08f27ac447ed79c2d606dd5b2","unresolved":false,"context_lines":[{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    obj_relationships \u003d {"},{"line_number":69,"context_line":"        \u0027image\u0027: [(\u00271.0\u0027, \u00271.5\u0027), (\u00271.1\u0027, \u00271.6\u0027),"},{"line_number":70,"context_line":"                  (\u00271.4\u0027, \u00271.7\u0027), (\u00271.5\u0027, \u00271.8\u0027)],"},{"line_number":71,"context_line":"        \u0027numa_topology\u0027: [(\u00271.0\u0027, \u00271.2\u0027)],"},{"line_number":72,"context_line":"        \u0027flavor\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"},{"line_number":73,"context_line":"        \u0027pci_requests\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"}],"source_content_type":"text/x-python","patch_set":27,"id":"1a26ad4f_ff305303","line":70,"updated":"2015-10-30 01:03:16.000000000","message":"ImageMeta highest version is 1.7?","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":9569,"name":"Sergey Nikitin","email":"nikitinserv@gmail.com","username":"snikitin"},"change_message_id":"dc185f44f474015b0a29f4d4de31adc0f93ff3fe","unresolved":false,"context_lines":[{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    obj_relationships \u003d {"},{"line_number":69,"context_line":"        \u0027image\u0027: [(\u00271.0\u0027, \u00271.5\u0027), (\u00271.1\u0027, \u00271.6\u0027),"},{"line_number":70,"context_line":"                  (\u00271.4\u0027, \u00271.7\u0027), (\u00271.5\u0027, \u00271.8\u0027)],"},{"line_number":71,"context_line":"        \u0027numa_topology\u0027: [(\u00271.0\u0027, \u00271.2\u0027)],"},{"line_number":72,"context_line":"        \u0027flavor\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"},{"line_number":73,"context_line":"        \u0027pci_requests\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"}],"source_content_type":"text/x-python","patch_set":27,"id":"da85f559_81b6c6da","line":70,"in_reply_to":"1a26ad4f_ff305303","updated":"2015-11-09 08:31:40.000000000","message":"obj_relationships was removed by Dan Smith https://review.openstack.org/#/c/231271/9/nova/objects/request_spec.py .\n\nI think you need rebase.","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"5183eeedc18373a8ee7bff605a9fa558ede0afa7","unresolved":false,"context_lines":[{"line_number":67,"context_line":""},{"line_number":68,"context_line":"    obj_relationships \u003d {"},{"line_number":69,"context_line":"        \u0027image\u0027: [(\u00271.0\u0027, \u00271.5\u0027), (\u00271.1\u0027, \u00271.6\u0027),"},{"line_number":70,"context_line":"                  (\u00271.4\u0027, \u00271.7\u0027), (\u00271.5\u0027, \u00271.8\u0027)],"},{"line_number":71,"context_line":"        \u0027numa_topology\u0027: [(\u00271.0\u0027, \u00271.2\u0027)],"},{"line_number":72,"context_line":"        \u0027flavor\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"},{"line_number":73,"context_line":"        \u0027pci_requests\u0027: [(\u00271.0\u0027, \u00271.1\u0027)],"}],"source_content_type":"text/x-python","patch_set":27,"id":"da85f559_eb930dff","line":70,"in_reply_to":"da85f559_81b6c6da","updated":"2015-11-12 22:11:55.000000000","message":"Yeah, I done gone and removed all this :D","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":2835,"name":"Brian Elliott","email":"bdelliott@gmail.com","username":"belliott"},"change_message_id":"e6f9d35acbc742f08f27ac447ed79c2d606dd5b2","unresolved":false,"context_lines":[{"line_number":314,"context_line":"                hint) for hint in self.scheduler_hints}"},{"line_number":315,"context_line":"        return filt_props"},{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    def _load_image(self, db_image):"},{"line_number":318,"context_line":"        self.image \u003d objects.ImageMeta.obj_from_primitive("},{"line_number":319,"context_line":"                jsonutils.loads(db_image))"},{"line_number":320,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"1a26ad4f_ffae1384","line":317,"updated":"2015-10-30 01:03:16.000000000","message":"You could get away with one _load method since they are all basically the same...Something like:\n\n  def _load(self, key, db_val):\n    attr \u003d getattr(self, key)\n    from_p \u003d gettattr(obj_cls[key], \u0027obj_from_primitive\u0027)\n    setattr(self, attr, from_p(jsonutils.loads(db_val)))\n\nYour way is probably easier to read, just repetitive. :)","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"97dd83ce1ce693e6df6f4b65ab3504b8b473e77f","unresolved":false,"context_lines":[{"line_number":314,"context_line":"                hint) for hint in self.scheduler_hints}"},{"line_number":315,"context_line":"        return filt_props"},{"line_number":316,"context_line":""},{"line_number":317,"context_line":"    def _load_image(self, db_image):"},{"line_number":318,"context_line":"        self.image \u003d objects.ImageMeta.obj_from_primitive("},{"line_number":319,"context_line":"                jsonutils.loads(db_image))"},{"line_number":320,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"da85f559_cb85e907","line":317,"in_reply_to":"1a26ad4f_ffae1384","updated":"2015-11-12 21:47:34.000000000","message":"Yeah, my method is quite repetitive.  My thinking was that it would ultimately be easier that way if specific logic was ever necessary for any of these methods.  However that can be deferred for now and dealt with if it ever happens.","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":2835,"name":"Brian Elliott","email":"bdelliott@gmail.com","username":"belliott"},"change_message_id":"e6f9d35acbc742f08f27ac447ed79c2d606dd5b2","unresolved":false,"context_lines":[{"line_number":318,"context_line":"        self.image \u003d objects.ImageMeta.obj_from_primitive("},{"line_number":319,"context_line":"                jsonutils.loads(db_image))"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def _load_numa_topology(self, db_numa):"},{"line_number":322,"context_line":"        self.numa_topology \u003d objects.InstanceNUMATopology.obj_from_primitive("},{"line_number":323,"context_line":"                jsonutils.loads(db_numa))"},{"line_number":324,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"1a26ad4f_62ceec5b","line":321,"updated":"2015-10-30 01:03:16.000000000","message":"In the case of resizing really old instances, what prevents us from getting errors due to having really old forms of these sub-objects stored as dictionaries?","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"97dd83ce1ce693e6df6f4b65ab3504b8b473e77f","unresolved":false,"context_lines":[{"line_number":318,"context_line":"        self.image \u003d objects.ImageMeta.obj_from_primitive("},{"line_number":319,"context_line":"                jsonutils.loads(db_image))"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def _load_numa_topology(self, db_numa):"},{"line_number":322,"context_line":"        self.numa_topology \u003d objects.InstanceNUMATopology.obj_from_primitive("},{"line_number":323,"context_line":"                jsonutils.loads(db_numa))"},{"line_number":324,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"da85f559_2bda7518","line":321,"in_reply_to":"1a26ad4f_62ceec5b","updated":"2015-11-12 21:47:34.000000000","message":"Nothing.  This puts us in a situation where we either leave old object versions in the code to handle this, or have a migration strategy for upgrading these serialized objects.  This should be given some more thought before merging this.","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"5183eeedc18373a8ee7bff605a9fa558ede0afa7","unresolved":false,"context_lines":[{"line_number":318,"context_line":"        self.image \u003d objects.ImageMeta.obj_from_primitive("},{"line_number":319,"context_line":"                jsonutils.loads(db_image))"},{"line_number":320,"context_line":""},{"line_number":321,"context_line":"    def _load_numa_topology(self, db_numa):"},{"line_number":322,"context_line":"        self.numa_topology \u003d objects.InstanceNUMATopology.obj_from_primitive("},{"line_number":323,"context_line":"                jsonutils.loads(db_numa))"},{"line_number":324,"context_line":""}],"source_content_type":"text/x-python","patch_set":27,"id":"da85f559_6b5ddd47","line":321,"in_reply_to":"da85f559_2bda7518","updated":"2015-11-12 22:11:55.000000000","message":"Yeah, so we\u0027ve gone, what, two years now without dropping compatibility for almost all of our objects. We just recently dropped instancev1, but even that was not all that big of a deal, mostly because of the flavor migration and a couple other things.\n\nI think it\u0027s entirely possible we could go even longer without needing a major revision to requestspec. In addition, we could always drop some compat with a v2.0 object and leave the old one in place if needed. It\u0027s less of a deal to do that for things that aren\u0027t as pervasive as instance, and which doesn\u0027t get stored in a way that depends on DB schema.\n\nI think we should go forward with this, and as always, deal with the bridge when we come to it, if we need to. We can always go through and slowly convert older objects if and as necessary in a slow background task. Doing it online and on-demand will only occur when people resize something, or otherwise need scheduler help, which is much less often than the flavor case where it was needed immediately by a lot of things.","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":2835,"name":"Brian Elliott","email":"bdelliott@gmail.com","username":"belliott"},"change_message_id":"e6f9d35acbc742f08f27ac447ed79c2d606dd5b2","unresolved":false,"context_lines":[{"line_number":349,"context_line":"                try:"},{"line_number":350,"context_line":"                    getattr(spec, \u0027_load_%s\u0027 % key)(db_spec[key])"},{"line_number":351,"context_line":"                except AttributeError:"},{"line_number":352,"context_line":"                    LOG.exception(_LE(\u0027No load handler for %s\u0027), key)"},{"line_number":353,"context_line":"            else:"},{"line_number":354,"context_line":"                value \u003d db_spec[key]"},{"line_number":355,"context_line":"                if key in REQUEST_SPEC_JSON_ATTRS:"}],"source_content_type":"text/x-python","patch_set":27,"id":"1a26ad4f_1fc50f5a","line":352,"updated":"2015-10-30 01:03:16.000000000","message":"My preference is to let some exception bubble up rather than generate a potentially incomplete object.","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"97dd83ce1ce693e6df6f4b65ab3504b8b473e77f","unresolved":false,"context_lines":[{"line_number":349,"context_line":"                try:"},{"line_number":350,"context_line":"                    getattr(spec, \u0027_load_%s\u0027 % key)(db_spec[key])"},{"line_number":351,"context_line":"                except AttributeError:"},{"line_number":352,"context_line":"                    LOG.exception(_LE(\u0027No load handler for %s\u0027), key)"},{"line_number":353,"context_line":"            else:"},{"line_number":354,"context_line":"                value \u003d db_spec[key]"},{"line_number":355,"context_line":"                if key in REQUEST_SPEC_JSON_ATTRS:"}],"source_content_type":"text/x-python","patch_set":27,"id":"da85f559_8b92819e","line":352,"in_reply_to":"1a26ad4f_1fc50f5a","updated":"2015-11-12 21:47:34.000000000","message":"Yeah, this should raise.","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"26aa2e5a1db7a79b32f0d651530f0961a904a4d3","unresolved":false,"context_lines":[{"line_number":349,"context_line":"                try:"},{"line_number":350,"context_line":"                    getattr(spec, \u0027_load_%s\u0027 % key)(db_spec[key])"},{"line_number":351,"context_line":"                except AttributeError:"},{"line_number":352,"context_line":"                    LOG.exception(_LE(\u0027No load handler for %s\u0027), key)"},{"line_number":353,"context_line":"            else:"},{"line_number":354,"context_line":"                value \u003d db_spec[key]"},{"line_number":355,"context_line":"                if key in REQUEST_SPEC_JSON_ATTRS:"}],"source_content_type":"text/x-python","patch_set":27,"id":"da85f559_5aff84aa","line":352,"in_reply_to":"da85f559_261f0cb9","updated":"2015-11-12 22:25:33.000000000","message":"If we have an object field we don\u0027t want to persist then logging an exception here would be the wrong thing to do as well.  Ideally I think we\u0027d have a way to mark a field as persisted or not so we could differentiate between a non persisted field here and a dev forgetting to write a load handler.  But since that doesn\u0027t exist I\u0027m going to rework this a bit to look for a better way to handle it.","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"017c69c3e930ca05537c149088e63dca49d1c2ae","unresolved":false,"context_lines":[{"line_number":349,"context_line":"                try:"},{"line_number":350,"context_line":"                    getattr(spec, \u0027_load_%s\u0027 % key)(db_spec[key])"},{"line_number":351,"context_line":"                except AttributeError:"},{"line_number":352,"context_line":"                    LOG.exception(_LE(\u0027No load handler for %s\u0027), key)"},{"line_number":353,"context_line":"            else:"},{"line_number":354,"context_line":"                value \u003d db_spec[key]"},{"line_number":355,"context_line":"                if key in REQUEST_SPEC_JSON_ATTRS:"}],"source_content_type":"text/x-python","patch_set":27,"id":"da85f559_6a25a95a","line":352,"in_reply_to":"da85f559_5aff84aa","updated":"2015-11-13 17:19:40.000000000","message":"Yeah, good point about the exception log.\n\nI think just assuming them all for now and changing it later if it becomes a problem is the right thing to do. Not sure we\u0027ll have any non-persisting things here like we do on instance, now that I think of it.","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"5183eeedc18373a8ee7bff605a9fa558ede0afa7","unresolved":false,"context_lines":[{"line_number":349,"context_line":"                try:"},{"line_number":350,"context_line":"                    getattr(spec, \u0027_load_%s\u0027 % key)(db_spec[key])"},{"line_number":351,"context_line":"                except AttributeError:"},{"line_number":352,"context_line":"                    LOG.exception(_LE(\u0027No load handler for %s\u0027), key)"},{"line_number":353,"context_line":"            else:"},{"line_number":354,"context_line":"                value \u003d db_spec[key]"},{"line_number":355,"context_line":"                if key in REQUEST_SPEC_JSON_ATTRS:"}],"source_content_type":"text/x-python","patch_set":27,"id":"da85f559_261f0cb9","line":352,"in_reply_to":"da85f559_8b92819e","updated":"2015-11-12 22:11:55.000000000","message":"Well, the problem with this is that if you have an object field that you don\u0027t want to persist, you need to define an empty handler to skip it. We have a couple examples of this in other obejcts and it\u0027s ugly.\n\nI think that it\u0027s probably not a common enough error to land in merged code that we need to be overly concerned about it, but whatever :)","commit_id":"93f843779c1b70b1bfa22274a3d0ce40d6914f20"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"e1abe184685aac184b276fb4963996258690948b","unresolved":false,"context_lines":[{"line_number":359,"context_line":""},{"line_number":360,"context_line":"        db_spec \u003d api_models.RequestSpec()"},{"line_number":361,"context_line":"        db_spec.update(updates)"},{"line_number":362,"context_line":"        db_spec.save(session)"},{"line_number":363,"context_line":"        return db_spec"},{"line_number":364,"context_line":""},{"line_number":365,"context_line":"    def _get_update_primitives(self):"}],"source_content_type":"text/x-python","patch_set":29,"id":"ba8a016a_9d9fdd02","line":362,"updated":"2015-11-17 15:09:10.000000000","message":"(see first my comment L377) I\u0027m unsure, but is db_spec getting the ID there?","commit_id":"aac095cf21b67669ef31bc9e12a3ff140c6ac9da"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"e1abe184685aac184b276fb4963996258690948b","unresolved":false,"context_lines":[{"line_number":374,"context_line":""},{"line_number":375,"context_line":"    @base.remotable"},{"line_number":376,"context_line":"    def create(self):"},{"line_number":377,"context_line":"        if self.obj_attr_is_set(\u0027id\u0027):"},{"line_number":378,"context_line":"            raise exception.ObjectActionError(action\u003d\u0027create\u0027,"},{"line_number":379,"context_line":"                                              reason\u003d\u0027already created\u0027)"},{"line_number":380,"context_line":""}],"source_content_type":"text/x-python","patch_set":29,"id":"ba8a016a_3d735117","line":377,"updated":"2015-11-17 15:09:10.000000000","message":"that looks good, but where are you setting this field when doing the first create ? If calling twice .create(), it would try to persist twice, right ? And if so, it would raise an Exception (because of the instance_uuid UC), nope ?","commit_id":"aac095cf21b67669ef31bc9e12a3ff140c6ac9da"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"2c5e69995ffe517606e7e55cc27d2a1ec47c4da5","unresolved":false,"context_lines":[{"line_number":374,"context_line":""},{"line_number":375,"context_line":"    @base.remotable"},{"line_number":376,"context_line":"    def create(self):"},{"line_number":377,"context_line":"        if self.obj_attr_is_set(\u0027id\u0027):"},{"line_number":378,"context_line":"            raise exception.ObjectActionError(action\u003d\u0027create\u0027,"},{"line_number":379,"context_line":"                                              reason\u003d\u0027already created\u0027)"},{"line_number":380,"context_line":""}],"source_content_type":"text/x-python","patch_set":29,"id":"ba8a016a_a0b078de","line":377,"in_reply_to":"ba8a016a_3d735117","updated":"2015-11-17 15:24:30.000000000","message":"My understanding is that sqlalchemy handles this as part of the save() above.  Other objects have this same pattern.  I will double check this though.","commit_id":"aac095cf21b67669ef31bc9e12a3ff140c6ac9da"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"e1abe184685aac184b276fb4963996258690948b","unresolved":false,"context_lines":[{"line_number":382,"context_line":"        # references to these objects because we want a snapshot of the request"},{"line_number":383,"context_line":"        # at this point.  If the references changed or were deleted we would"},{"line_number":384,"context_line":"        # not be able to reschedule this instance under the same conditions as"},{"line_number":385,"context_line":"        # it was originally scheduled with."},{"line_number":386,"context_line":"        updates \u003d self._get_update_primitives()"},{"line_number":387,"context_line":""},{"line_number":388,"context_line":"        db_spec \u003d self._create_in_db(self._context, updates)"}],"source_content_type":"text/x-python","patch_set":29,"id":"ba8a016a_bdf661f7","line":385,"updated":"2015-11-17 15:09:10.000000000","message":"nit: I would put that comment within _get_update_primitives() like a docstring","commit_id":"aac095cf21b67669ef31bc9e12a3ff140c6ac9da"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"2c5e69995ffe517606e7e55cc27d2a1ec47c4da5","unresolved":false,"context_lines":[{"line_number":382,"context_line":"        # references to these objects because we want a snapshot of the request"},{"line_number":383,"context_line":"        # at this point.  If the references changed or were deleted we would"},{"line_number":384,"context_line":"        # not be able to reschedule this instance under the same conditions as"},{"line_number":385,"context_line":"        # it was originally scheduled with."},{"line_number":386,"context_line":"        updates \u003d self._get_update_primitives()"},{"line_number":387,"context_line":""},{"line_number":388,"context_line":"        db_spec \u003d self._create_in_db(self._context, updates)"}],"source_content_type":"text/x-python","patch_set":29,"id":"ba8a016a_60cb7054","line":385,"in_reply_to":"ba8a016a_bdf661f7","updated":"2015-11-17 15:24:30.000000000","message":"Okay.","commit_id":"aac095cf21b67669ef31bc9e12a3ff140c6ac9da"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"e1abe184685aac184b276fb4963996258690948b","unresolved":false,"context_lines":[{"line_number":391,"context_line":"    @staticmethod"},{"line_number":392,"context_line":"    def _save_in_db(context, instance_uuid, updates):"},{"line_number":393,"context_line":"        session \u003d db.get_api_session()"},{"line_number":394,"context_line":""},{"line_number":395,"context_line":"        with session.begin():"},{"line_number":396,"context_line":"            db_spec \u003d session.query("},{"line_number":397,"context_line":"                    api_models.RequestSpec).filter_by("},{"line_number":398,"context_line":"                            instance_uuid\u003dinstance_uuid).first()"},{"line_number":399,"context_line":"            if not db_spec:"},{"line_number":400,"context_line":"                raise exception.RequestSpecNotFound("},{"line_number":401,"context_line":"                        instance_uuid\u003dinstance_uuid)"}],"source_content_type":"text/x-python","patch_set":29,"id":"ba8a016a_7df47986","line":398,"range":{"start_line":394,"start_character":0,"end_line":398,"end_character":64},"updated":"2015-11-17 15:09:10.000000000","message":"nit: you could use the private helper you made (_get_by_instance_uuid_from_db)","commit_id":"aac095cf21b67669ef31bc9e12a3ff140c6ac9da"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"2c5e69995ffe517606e7e55cc27d2a1ec47c4da5","unresolved":false,"context_lines":[{"line_number":391,"context_line":"    @staticmethod"},{"line_number":392,"context_line":"    def _save_in_db(context, instance_uuid, updates):"},{"line_number":393,"context_line":"        session \u003d db.get_api_session()"},{"line_number":394,"context_line":""},{"line_number":395,"context_line":"        with session.begin():"},{"line_number":396,"context_line":"            db_spec \u003d session.query("},{"line_number":397,"context_line":"                    api_models.RequestSpec).filter_by("},{"line_number":398,"context_line":"                            instance_uuid\u003dinstance_uuid).first()"},{"line_number":399,"context_line":"            if not db_spec:"},{"line_number":400,"context_line":"                raise exception.RequestSpecNotFound("},{"line_number":401,"context_line":"                        instance_uuid\u003dinstance_uuid)"}],"source_content_type":"text/x-python","patch_set":29,"id":"ba8a016a_80221400","line":398,"range":{"start_line":394,"start_character":0,"end_line":398,"end_character":64},"in_reply_to":"ba8a016a_7df47986","updated":"2015-11-17 15:24:30.000000000","message":"Sure, I can do that.","commit_id":"aac095cf21b67669ef31bc9e12a3ff140c6ac9da"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"e1abe184685aac184b276fb4963996258690948b","unresolved":false,"context_lines":[{"line_number":398,"context_line":"                            instance_uuid\u003dinstance_uuid).first()"},{"line_number":399,"context_line":"            if not db_spec:"},{"line_number":400,"context_line":"                raise exception.RequestSpecNotFound("},{"line_number":401,"context_line":"                        instance_uuid\u003dinstance_uuid)"},{"line_number":402,"context_line":"            db_spec.update(updates)"},{"line_number":403,"context_line":"            session.add(db_spec)"},{"line_number":404,"context_line":"        return db_spec"}],"source_content_type":"text/x-python","patch_set":29,"id":"ba8a016a_3d5111d9","line":401,"updated":"2015-11-17 15:09:10.000000000","message":"so, I got why you prefer to raise ReqSpecNotFound if we don\u0027t find by looking up at instance_uuid (since this field is not nullable) but I wonder if we could maybe fallback using the spec.id ? You\u0027re actually using the ID field for checking if that\u0027s already persisted or not, so hence my comment.\n\nI would indeed prefer to have the same logic for getting/updating the Spec...","commit_id":"aac095cf21b67669ef31bc9e12a3ff140c6ac9da"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"2c5e69995ffe517606e7e55cc27d2a1ec47c4da5","unresolved":false,"context_lines":[{"line_number":398,"context_line":"                            instance_uuid\u003dinstance_uuid).first()"},{"line_number":399,"context_line":"            if not db_spec:"},{"line_number":400,"context_line":"                raise exception.RequestSpecNotFound("},{"line_number":401,"context_line":"                        instance_uuid\u003dinstance_uuid)"},{"line_number":402,"context_line":"            db_spec.update(updates)"},{"line_number":403,"context_line":"            session.add(db_spec)"},{"line_number":404,"context_line":"        return db_spec"}],"source_content_type":"text/x-python","patch_set":29,"id":"ba8a016a_a09f1802","line":401,"in_reply_to":"ba8a016a_3d5111d9","updated":"2015-11-17 15:24:30.000000000","message":"The \u0027id\u0027 check in create is just a fail fast check based on an invariant that should be true for the object.  I would prefer to not rely on the actual value of an id for anything, it is really just an implementation detail of the db and not part of the model that Nova should care about IMO.","commit_id":"aac095cf21b67669ef31bc9e12a3ff140c6ac9da"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"75e2f325422a5b378160e35f3cd5c08600d99e57","unresolved":false,"context_lines":[{"line_number":398,"context_line":"                            instance_uuid\u003dinstance_uuid).first()"},{"line_number":399,"context_line":"            if not db_spec:"},{"line_number":400,"context_line":"                raise exception.RequestSpecNotFound("},{"line_number":401,"context_line":"                        instance_uuid\u003dinstance_uuid)"},{"line_number":402,"context_line":"            db_spec.update(updates)"},{"line_number":403,"context_line":"            session.add(db_spec)"},{"line_number":404,"context_line":"        return db_spec"}],"source_content_type":"text/x-python","patch_set":29,"id":"ba8a016a_946d7206","line":401,"in_reply_to":"ba8a016a_a09f1802","updated":"2015-11-17 16:26:30.000000000","message":"Fair enough, I like your approach hence me giving +1 previously","commit_id":"aac095cf21b67669ef31bc9e12a3ff140c6ac9da"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"a55165f1fbd19b7fe92def90933a3b244e44900c","unresolved":false,"context_lines":[{"line_number":341,"context_line":"        if session is None:"},{"line_number":342,"context_line":"            session \u003d db.get_api_session()"},{"line_number":343,"context_line":""},{"line_number":344,"context_line":"        with session.begin():"},{"line_number":345,"context_line":"            db_spec \u003d session.query(api_models.RequestSpec).filter_by("},{"line_number":346,"context_line":"                    instance_uuid\u003dinstance_uuid).first()"},{"line_number":347,"context_line":"            if not db_spec:"}],"source_content_type":"text/x-python","patch_set":32,"id":"ba8a016a_7ba2084d","line":344,"updated":"2015-11-18 14:03:49.000000000","message":"see my comment below, you should rather check if the session began or just explain that this helper is not a transactional method, but should be wrapped rather by a transaction.","commit_id":"11bd20cdfef5944b3997e481c9ca00b9e71ec7e2"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"d3431efb1cfd321556d4a0f99196cef24b97bf77","unresolved":false,"context_lines":[{"line_number":341,"context_line":"        if session is None:"},{"line_number":342,"context_line":"            session \u003d db.get_api_session()"},{"line_number":343,"context_line":""},{"line_number":344,"context_line":"        with session.begin():"},{"line_number":345,"context_line":"            db_spec \u003d session.query(api_models.RequestSpec).filter_by("},{"line_number":346,"context_line":"                    instance_uuid\u003dinstance_uuid).first()"},{"line_number":347,"context_line":"            if not db_spec:"}],"source_content_type":"text/x-python","patch_set":32,"id":"ba8a016a_6c5d7078","line":344,"in_reply_to":"ba8a016a_7ba2084d","updated":"2015-11-18 14:40:29.000000000","message":"Yeah, woops.  I don\u0027t want to require that this be wrapped by a transaction.  I\u0027ll fix this up, or can just go back to having slight duplication but not coupling these methods.","commit_id":"11bd20cdfef5944b3997e481c9ca00b9e71ec7e2"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"a55165f1fbd19b7fe92def90933a3b244e44900c","unresolved":false,"context_lines":[{"line_number":396,"context_line":"    def _save_in_db(cls, context, instance_uuid, updates):"},{"line_number":397,"context_line":"        session \u003d db.get_api_session()"},{"line_number":398,"context_line":""},{"line_number":399,"context_line":"        with session.begin():"},{"line_number":400,"context_line":"            db_spec \u003d cls._get_by_instance_uuid_from_db(context,"},{"line_number":401,"context_line":"                    instance_uuid, session)"},{"line_number":402,"context_line":"            db_spec.update(updates)"}],"source_content_type":"text/x-python","patch_set":32,"id":"ba8a016a_9bc9ec28","line":399,"updated":"2015-11-18 14:03:49.000000000","message":"oh snap, I made you make a mistake when I said to factorize the call to _get_by_instance_uuid_from_db() because there is already a session contextmanager...","commit_id":"11bd20cdfef5944b3997e481c9ca00b9e71ec7e2"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"2444dd2607379b93ea4423da146e42da72274a75","unresolved":false,"context_lines":[{"line_number":331,"context_line":"            if key in [\u0027id\u0027, \u0027instance_uuid\u0027]:"},{"line_number":332,"context_line":"                setattr(spec, key, db_spec[key])"},{"line_number":333,"context_line":"            else:"},{"line_number":334,"context_line":"                setattr(spec, key, getattr(spec_obj, key))"},{"line_number":335,"context_line":"        spec._context \u003d context"},{"line_number":336,"context_line":"        spec.obj_reset_changes()"},{"line_number":337,"context_line":"        return spec"}],"source_content_type":"text/x-python","patch_set":33,"id":"ba8a016a_926bfff0","line":334,"updated":"2015-11-18 17:46:48.000000000","message":"Hmm, I don\u0027t think this will work anymore, will it? Either way, pulling this out should only require looking at the spec column I think. We use the others for finding one, but generating an object from it should be as easy as:\n\n spec \u003d base.NovaObject.obj_from_primitive(db_spec[\u0027spec\u0027], context\u003dcontext)\n\nright? No need to look at any of the other columns I think.","commit_id":"12ccc515683002a7a3c781cbe996d7ced9e40eda"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"5e41d7edc293368dbdcfb7f06460194cc34bf0fa","unresolved":false,"context_lines":[{"line_number":331,"context_line":"            if key in [\u0027id\u0027, \u0027instance_uuid\u0027]:"},{"line_number":332,"context_line":"                setattr(spec, key, db_spec[key])"},{"line_number":333,"context_line":"            else:"},{"line_number":334,"context_line":"                setattr(spec, key, getattr(spec_obj, key))"},{"line_number":335,"context_line":"        spec._context \u003d context"},{"line_number":336,"context_line":"        spec.obj_reset_changes()"},{"line_number":337,"context_line":"        return spec"}],"source_content_type":"text/x-python","patch_set":33,"id":"ba8a016a_2347674c","line":334,"in_reply_to":"ba8a016a_926bfff0","updated":"2015-11-18 18:18:48.000000000","message":"Yep.  I used an intermediate object which doesn\u0027t appear to actually be necessary.","commit_id":"12ccc515683002a7a3c781cbe996d7ced9e40eda"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"ff246d146059283cc83b2e3fd81c0ae7ef748ddc","unresolved":false,"context_lines":[{"line_number":333,"context_line":"    def _get_by_instance_uuid_from_db(context, instance_uuid, session\u003dNone):"},{"line_number":334,"context_line":"        def _get_in_session(session):"},{"line_number":335,"context_line":"            db_spec \u003d session.query(api_models.RequestSpec).filter_by("},{"line_number":336,"context_line":"                    instance_uuid\u003dinstance_uuid).first()"},{"line_number":337,"context_line":"            if not db_spec:"},{"line_number":338,"context_line":"                raise exception.RequestSpecNotFound("},{"line_number":339,"context_line":"                        instance_uuid\u003dinstance_uuid)"}],"source_content_type":"text/x-python","patch_set":34,"id":"ba8a016a_060b478f","line":336,"updated":"2015-11-18 23:14:53.000000000","message":"That\u0027s weird... Before saving the spec, I checked and the object was persisted by the .create() call and found using that method directly.\n\nBut when calling it from .save(), then the Spec is not found, even if the session is None...","commit_id":"50d586c324c15144e93bd7aac9004309b3592468"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"391a5e96875f45fb4e76f20aaa5475c812d89391","unresolved":false,"context_lines":[{"line_number":28,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":29,"context_line":""},{"line_number":30,"context_line":"REQUEST_SPEC_JSON_ATTRS \u003d ["},{"line_number":31,"context_line":"    \u0027ignore_hosts\u0027, \u0027force_hosts\u0027, \u0027force_nodes\u0027, \u0027scheduler_hints\u0027]"},{"line_number":32,"context_line":""},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"@base.NovaObjectRegistry.register"}],"source_content_type":"text/x-python","patch_set":36,"id":"ba8a016a_ad4dc173","line":31,"updated":"2015-11-23 17:11:16.000000000","message":"I added this when I rebased this patch while you were away, but it no longer seems to be used","commit_id":"22512c0484d824360f6d7d5898371b10c7953f6e"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"628b21272c65b35fbbe1cd527b210444865c8cf4","unresolved":false,"context_lines":[{"line_number":343,"context_line":"        db_spec \u003d cls._get_by_instance_uuid_from_db(context, instance_uuid)"},{"line_number":344,"context_line":"        return cls._from_db_object(context, cls(), db_spec)"},{"line_number":345,"context_line":""},{"line_number":346,"context_line":"    @staticmethod"},{"line_number":347,"context_line":"    def _create_in_db(context, updates):"},{"line_number":348,"context_line":"        session \u003d db.get_api_session()"},{"line_number":349,"context_line":""}],"source_content_type":"text/x-python","patch_set":38,"id":"ba8a016a_50ae1699","line":346,"updated":"2015-11-24 01:24:56.000000000","message":"You will want to use the newly-added oslo_db.enginefacade contextual decorators here, instead of calling get_api_session() and using the session directly:\n\n @staticmethod\n @db.api_context_manager.writer\n def _create_in_db(context, updates):\n    db_spec \u003d api_models.RequestSpec()\n    db_spec.update(updates)\n    db_spec.save(context.session)\n    return db_spec","commit_id":"29614caa5fb7ca510fbefddf75472cd6ba6d4205"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"628b21272c65b35fbbe1cd527b210444865c8cf4","unresolved":false,"context_lines":[{"line_number":353,"context_line":"        return db_spec"},{"line_number":354,"context_line":""},{"line_number":355,"context_line":"    def _get_update_primitives(self):"},{"line_number":356,"context_line":"        \u0027\u0027\u0027Serialize object to match the db model"},{"line_number":357,"context_line":""},{"line_number":358,"context_line":"        We store copies of embedded objects rather than"},{"line_number":359,"context_line":"        references to these objects because we want a snapshot of the request"}],"source_content_type":"text/x-python","patch_set":38,"id":"ba8a016a_d02f6686","line":356,"updated":"2015-11-24 01:24:56.000000000","message":"nit: we generally use \"\"\", not \u0027\u0027\u0027 :)","commit_id":"29614caa5fb7ca510fbefddf75472cd6ba6d4205"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"628b21272c65b35fbbe1cd527b210444865c8cf4","unresolved":false,"context_lines":[{"line_number":381,"context_line":"        db_spec \u003d self._create_in_db(self._context, updates)"},{"line_number":382,"context_line":"        self._from_db_object(self._context, self, db_spec)"},{"line_number":383,"context_line":""},{"line_number":384,"context_line":"    @classmethod"},{"line_number":385,"context_line":"    def _save_in_db(cls, context, instance_uuid, updates):"},{"line_number":386,"context_line":"        session \u003d db.get_api_session()"},{"line_number":387,"context_line":""}],"source_content_type":"text/x-python","patch_set":38,"id":"ba8a016a_9008feda","line":384,"updated":"2015-11-24 01:24:56.000000000","message":"and same here:\n\n @classmethod\n @db.api_context_manager.writer\n def _save_in_db(cls, context, instance_uuid, updates):\n     db_spec \u003d session.query(api_models.RequestSpec).filter_by(\n            instance_uuid\u003dinstance_uuid).first()\n     if not db_spec:\n         raise exception.RequestSpecNotFound(\n            instance_uuid\u003dinstance_uuid)\n     db_spec.update(values)\n     db_spec.save(context.session)\n     return db_spec","commit_id":"29614caa5fb7ca510fbefddf75472cd6ba6d4205"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"87aa9c5d137405f2d3e7c5e168277cfe6da11ba0","unresolved":false,"context_lines":[{"line_number":358,"context_line":"        references to these objects because we want a snapshot of the request"},{"line_number":359,"context_line":"        at this point.  If the references changed or were deleted we would"},{"line_number":360,"context_line":"        not be able to reschedule this instance under the same conditions as"},{"line_number":361,"context_line":"        it was originally scheduled with."},{"line_number":362,"context_line":"        \"\"\""},{"line_number":363,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":364,"context_line":"        # NOTE(alaski): The db schema is the full serialized object in a"}],"source_content_type":"text/x-python","patch_set":41,"id":"7a740942_6059365a","line":361,"updated":"2015-12-04 16:53:49.000000000","message":"I don\u0027t really understand this paragraph, although I\u0027m sure it\u0027s just Friday talking...","commit_id":"0152047a776d481db124a51cc822561bb27a75b0"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"b80005bb292493670d071b710335bde37d7298d6","unresolved":false,"context_lines":[{"line_number":358,"context_line":"        references to these objects because we want a snapshot of the request"},{"line_number":359,"context_line":"        at this point.  If the references changed or were deleted we would"},{"line_number":360,"context_line":"        not be able to reschedule this instance under the same conditions as"},{"line_number":361,"context_line":"        it was originally scheduled with."},{"line_number":362,"context_line":"        \"\"\""},{"line_number":363,"context_line":"        updates \u003d self.obj_get_changes()"},{"line_number":364,"context_line":"        # NOTE(alaski): The db schema is the full serialized object in a"}],"source_content_type":"text/x-python","patch_set":41,"id":"7a740942_5bfd0f39","line":361,"in_reply_to":"7a740942_6059365a","updated":"2015-12-04 17:08:20.000000000","message":"Basically if we linked to a flavor or image it\u0027s possible they would be deleted and those details would not be available for later scheduling requests.  We could grab flavor from the instance, but not image.  By storing them here we don\u0027t need to worry about that.  We will however need to update this during resizes/rebuilds if that data changes.","commit_id":"0152047a776d481db124a51cc822561bb27a75b0"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"b37d2ff85e8d12e296e567e1ed1fd90bd8abd60e","unresolved":false,"context_lines":[{"line_number":384,"context_line":"    @db.api_context_manager.writer"},{"line_number":385,"context_line":"    def _save_in_db(context, instance_uuid, updates):"},{"line_number":386,"context_line":"        # FIXME(sbauza): Provide a classmethod when oslo.db bug #1520195 is"},{"line_number":387,"context_line":"        # fixed and released"},{"line_number":388,"context_line":"        db_spec \u003d RequestSpec._get_by_instance_uuid_from_db(context,"},{"line_number":389,"context_line":"                                                            instance_uuid)"},{"line_number":390,"context_line":"        db_spec.update(updates)"}],"source_content_type":"text/x-python","patch_set":41,"id":"9a8ffd7b_1527f0b6","line":387,"updated":"2015-12-02 21:07:23.000000000","message":"Yeah, the issue with this is that anything that subclasses this object will need to override this method or it will return the wrong object.","commit_id":"0152047a776d481db124a51cc822561bb27a75b0"}],"nova/tests/functional/db/api/test_migrations.py":[{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"e1abe184685aac184b276fb4963996258690948b","unresolved":false,"context_lines":[{"line_number":196,"context_line":"        self.assertUniqueConstraintExists(engine, \u0027request_specs\u0027,"},{"line_number":197,"context_line":"                [\u0027instance_uuid\u0027])"},{"line_number":198,"context_line":"        self.assertIndexExists(engine, \u0027request_specs\u0027,"},{"line_number":199,"context_line":"                \u0027request_spec_instance_uuid_idx\u0027)"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"class TestNovaAPIMigrationsWalkSQLite(NovaAPIMigrationsWalk,"}],"source_content_type":"text/x-python","patch_set":29,"id":"ba8a016a_dd632519","line":199,"updated":"2015-11-17 15:09:10.000000000","message":"are we sure this test doesn\u0027t run with DB2 since you\u0027re not indexing it?","commit_id":"aac095cf21b67669ef31bc9e12a3ff140c6ac9da"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"2c5e69995ffe517606e7e55cc27d2a1ec47c4da5","unresolved":false,"context_lines":[{"line_number":196,"context_line":"        self.assertUniqueConstraintExists(engine, \u0027request_specs\u0027,"},{"line_number":197,"context_line":"                [\u0027instance_uuid\u0027])"},{"line_number":198,"context_line":"        self.assertIndexExists(engine, \u0027request_specs\u0027,"},{"line_number":199,"context_line":"                \u0027request_spec_instance_uuid_idx\u0027)"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"class TestNovaAPIMigrationsWalkSQLite(NovaAPIMigrationsWalk,"}],"source_content_type":"text/x-python","patch_set":29,"id":"ba8a016a_80ac5436","line":199,"in_reply_to":"ba8a016a_dd632519","updated":"2015-11-17 15:24:30.000000000","message":"There is nothing in infra that tests it currently.  I can add the check here to only test this if it\u0027s not DB2 though.","commit_id":"aac095cf21b67669ef31bc9e12a3ff140c6ac9da"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"a55165f1fbd19b7fe92def90933a3b244e44900c","unresolved":false,"context_lines":[{"line_number":196,"context_line":"        self.assertUniqueConstraintExists(engine, \u0027request_specs\u0027,"},{"line_number":197,"context_line":"                [\u0027instance_uuid\u0027])"},{"line_number":198,"context_line":"        self.assertIndexExists(engine, \u0027request_specs\u0027,"},{"line_number":199,"context_line":"                \u0027request_spec_instance_uuid_idx\u0027)"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"class TestNovaAPIMigrationsWalkSQLite(NovaAPIMigrationsWalk,"}],"source_content_type":"text/x-python","patch_set":32,"id":"ba8a016a_b6d7254a","line":199,"updated":"2015-11-18 14:03:49.000000000","message":"well, like we discussed in PS29, maybe just having a conditional if not DB2 but that\u0027s yakshaving...","commit_id":"11bd20cdfef5944b3997e481c9ca00b9e71ec7e2"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"d3431efb1cfd321556d4a0f99196cef24b97bf77","unresolved":false,"context_lines":[{"line_number":196,"context_line":"        self.assertUniqueConstraintExists(engine, \u0027request_specs\u0027,"},{"line_number":197,"context_line":"                [\u0027instance_uuid\u0027])"},{"line_number":198,"context_line":"        self.assertIndexExists(engine, \u0027request_specs\u0027,"},{"line_number":199,"context_line":"                \u0027request_spec_instance_uuid_idx\u0027)"},{"line_number":200,"context_line":""},{"line_number":201,"context_line":""},{"line_number":202,"context_line":"class TestNovaAPIMigrationsWalkSQLite(NovaAPIMigrationsWalk,"}],"source_content_type":"text/x-python","patch_set":32,"id":"ba8a016a_2cdbe8ed","line":199,"in_reply_to":"ba8a016a_b6d7254a","updated":"2015-11-18 14:40:29.000000000","message":"Yep, just missed this when updating.","commit_id":"11bd20cdfef5944b3997e481c9ca00b9e71ec7e2"}],"nova/tests/functional/db/test_request_spec.py":[{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"909d07dc1d9e1f2be674cfd015eb709a97359621","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                spec[\u0027instance_uuid\u0027])"},{"line_number":54,"context_line":"        for key in [key for key in self.spec_obj.fields.keys()"},{"line_number":55,"context_line":"                    if key not in [\u0027availability_zone\u0027, \u0027updated_at\u0027]]:"},{"line_number":56,"context_line":"            self.assertEqual(spec[key], db_spec[key])"}],"source_content_type":"text/x-python","patch_set":25,"id":"da20952f_38583756","line":56,"updated":"2015-09-02 23:07:24.000000000","message":"This is a little unexpected (to me) that we\u0027re asserting the things that didn\u0027t change without asserting the expected fields did change.","commit_id":"6b9889b9610856e5af6459debd3c59a680a0523e"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"5dec346213ee1302fc1b8337746dbd1b7eb1875b","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                spec[\u0027instance_uuid\u0027])"},{"line_number":54,"context_line":"        for key in [key for key in self.spec_obj.fields.keys()"},{"line_number":55,"context_line":"                    if key not in [\u0027availability_zone\u0027, \u0027updated_at\u0027]]:"},{"line_number":56,"context_line":"            self.assertEqual(spec[key], db_spec[key])"}],"source_content_type":"text/x-python","patch_set":25,"id":"da20952f_eb816c90","line":56,"in_reply_to":"da20952f_38583756","updated":"2015-09-03 13:17:51.000000000","message":"Hmm, this is odd.  \u0027updated_at\u0027 needs to be skipped because it changes, but \u0027availability_zone\u0027 certainly shouldn\u0027t be in there.","commit_id":"6b9889b9610856e5af6459debd3c59a680a0523e"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"b8c62f9ad2c0ddd897c5219f1b3c6ab00096f3b8","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                spec[\u0027instance_uuid\u0027])"},{"line_number":54,"context_line":"        for key in [key for key in self.spec_obj.fields.keys()"},{"line_number":55,"context_line":"                    if key not in [\u0027availability_zone\u0027, \u0027updated_at\u0027]]:"},{"line_number":56,"context_line":"            self.assertEqual(spec[key], db_spec[key])"}],"source_content_type":"text/x-python","patch_set":25,"id":"ba15a1d1_2153a93a","line":56,"in_reply_to":"da20952f_7561a338","updated":"2015-09-17 17:07:14.000000000","message":"Okay, yeah I\u0027m not sure what I was thinking the last time I looked at this and responded.  I see your point now and I should update this to include that test.","commit_id":"6b9889b9610856e5af6459debd3c59a680a0523e"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"04f7d1e8e8c1296b4aaf80fc069480d6326cd853","unresolved":false,"context_lines":[{"line_number":53,"context_line":"                spec[\u0027instance_uuid\u0027])"},{"line_number":54,"context_line":"        for key in [key for key in self.spec_obj.fields.keys()"},{"line_number":55,"context_line":"                    if key not in [\u0027availability_zone\u0027, \u0027updated_at\u0027]]:"},{"line_number":56,"context_line":"            self.assertEqual(spec[key], db_spec[key])"}],"source_content_type":"text/x-python","patch_set":25,"id":"da20952f_7561a338","line":56,"in_reply_to":"da20952f_eb816c90","updated":"2015-09-03 22:03:32.000000000","message":"availability_zone will be in there too because it\u0027s the thing being saved. What I meant was, this is only asserting that the other fields didn\u0027t change. I thought there should also be a couple of assertNotEqual for availability_zone and updated_at to verify they were indeed updated by the save","commit_id":"6b9889b9610856e5af6459debd3c59a680a0523e"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"4b7a9ac3551e076fd8b873f7ef812392d91b6001","unresolved":false,"context_lines":[{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def test_double_create(self):"},{"line_number":75,"context_line":"        spec \u003d self._create_spec()"},{"line_number":76,"context_line":"        self.assertRaises(exception.ObjectActionError, spec.create)"}],"source_content_type":"text/x-python","patch_set":30,"id":"ba8a016a_17642147","line":76,"updated":"2015-11-17 17:28:02.000000000","message":"Sylvain, testing the creation of the \u0027id\u0027 here.","commit_id":"5e685a3becaf8702df46466995c6fc32e9dff979"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"a55165f1fbd19b7fe92def90933a3b244e44900c","unresolved":false,"context_lines":[{"line_number":71,"context_line":"                self.assertEqual(getattr(spec, key), getattr(db_spec, key))"},{"line_number":72,"context_line":"        self.assertNotEqual(old_az, db_spec.availability_zone)"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def test_double_create(self):"},{"line_number":75,"context_line":"        spec \u003d self._create_spec()"},{"line_number":76,"context_line":"        self.assertRaises(exception.ObjectActionError, spec.create)"}],"source_content_type":"text/x-python","patch_set":32,"id":"ba8a016a_364b352c","line":74,"range":{"start_line":74,"start_character":8,"end_line":74,"end_character":26},"updated":"2015-11-18 14:03:49.000000000","message":"thanks for the test","commit_id":"11bd20cdfef5944b3997e481c9ca00b9e71ec7e2"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"2670d256f7e2b6a653d2e28ce0db5a79ee8a2524","unresolved":false,"context_lines":[{"line_number":47,"context_line":"                self.instance_uuid)"},{"line_number":48,"context_line":"        for key in self.spec_obj.fields.keys():"},{"line_number":49,"context_line":"            if isinstance(self.spec_obj.fields[key], fields.ObjectField):"},{"line_number":50,"context_line":"                # Compare primitives because object equality is not defined"},{"line_number":51,"context_line":"                self.assertEqual(getattr(spec, key).obj_to_primitive(),"},{"line_number":52,"context_line":"                        getattr(db_spec, key).obj_to_primitive())"},{"line_number":53,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba8a016a_d503dfb6","line":50,"updated":"2015-11-23 21:19:58.000000000","message":"nit: Well, that\u0027s a bit untrue https://github.com/openstack/nova/blob/110bb30d0f2a183aa54ec1289a58a15ea26b0495/nova/objects/base.py#L380","commit_id":"aa01166c949091edda8f021e5ce194e72dacbaaa"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"f5c07000721c1fff1310b8d23f50cd39640d6017","unresolved":false,"context_lines":[{"line_number":47,"context_line":"                self.instance_uuid)"},{"line_number":48,"context_line":"        for key in self.spec_obj.fields.keys():"},{"line_number":49,"context_line":"            if isinstance(self.spec_obj.fields[key], fields.ObjectField):"},{"line_number":50,"context_line":"                # Compare primitives because object equality is not defined"},{"line_number":51,"context_line":"                self.assertEqual(getattr(spec, key).obj_to_primitive(),"},{"line_number":52,"context_line":"                        getattr(db_spec, key).obj_to_primitive())"},{"line_number":53,"context_line":"            else:"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba8a016a_0a0f012f","line":50,"in_reply_to":"ba8a016a_d503dfb6","updated":"2015-11-24 00:06:56.000000000","message":"Ahh, was not aware of that.  I\u0027ll change this.","commit_id":"aa01166c949091edda8f021e5ce194e72dacbaaa"},{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"8be3539d961f005a2fd74f27eed97e722f1db617","unresolved":false,"context_lines":[{"line_number":63,"context_line":"                spec.instance_uuid)"},{"line_number":64,"context_line":"        for key in self.spec_obj.fields.keys():"},{"line_number":65,"context_line":"            if isinstance(self.spec_obj.fields[key], fields.ObjectField):"},{"line_number":66,"context_line":"                # Compare primitives because object equality is not defined"},{"line_number":67,"context_line":"                self.assertEqual(getattr(spec, key).obj_to_primitive(),"},{"line_number":68,"context_line":"                        getattr(db_spec, key).obj_to_primitive())"},{"line_number":69,"context_line":"            else:"},{"line_number":70,"context_line":"                self.assertEqual(getattr(spec, key), getattr(db_spec, key))"},{"line_number":71,"context_line":"        self.assertNotEqual(old_az, db_spec.availability_zone)"}],"source_content_type":"text/x-python","patch_set":38,"id":"9a8ffd7b_3135ec45","line":68,"range":{"start_line":66,"start_character":16,"end_line":68,"end_character":65},"updated":"2015-11-24 20:11:16.000000000","message":"While you\u0027re respinning, equal_prims could be used here too","commit_id":"29614caa5fb7ca510fbefddf75472cd6ba6d4205"}],"nova/tests/unit/db/test_migrations.py":[{"author":{"_account_id":4690,"name":"melanie witt","display_name":"melwitt","email":"melwittt@gmail.com","username":"melwitt"},"change_message_id":"909d07dc1d9e1f2be674cfd015eb709a97359621","unresolved":false,"context_lines":[{"line_number":804,"context_line":"        columns \u003d [\u0027id\u0027, \u0027image\u0027, \u0027numa_topology\u0027, \u0027pci_requests\u0027,"},{"line_number":805,"context_line":"                \u0027project_id\u0027, \u0027availability_zone\u0027, \u0027flavor\u0027, \u0027num_instances\u0027,"},{"line_number":806,"context_line":"                \u0027ignore_hosts\u0027, \u0027force_hosts\u0027, \u0027force_nodes\u0027, \u0027retry\u0027,"},{"line_number":807,"context_line":"                \u0027limits\u0027, \u0027instance_group\u0027, \u0027scheduler_hints\u0027]"},{"line_number":808,"context_line":"        for column in columns:"},{"line_number":809,"context_line":"            self.assertColumnExists(engine, \u0027request_specs\u0027, column)"},{"line_number":810,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"da20952f_95d6eec1","line":807,"updated":"2015-09-02 23:07:24.000000000","message":"Shouldn\u0027t instance_uuid be in this list too?","commit_id":"6b9889b9610856e5af6459debd3c59a680a0523e"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"5dec346213ee1302fc1b8337746dbd1b7eb1875b","unresolved":false,"context_lines":[{"line_number":804,"context_line":"        columns \u003d [\u0027id\u0027, \u0027image\u0027, \u0027numa_topology\u0027, \u0027pci_requests\u0027,"},{"line_number":805,"context_line":"                \u0027project_id\u0027, \u0027availability_zone\u0027, \u0027flavor\u0027, \u0027num_instances\u0027,"},{"line_number":806,"context_line":"                \u0027ignore_hosts\u0027, \u0027force_hosts\u0027, \u0027force_nodes\u0027, \u0027retry\u0027,"},{"line_number":807,"context_line":"                \u0027limits\u0027, \u0027instance_group\u0027, \u0027scheduler_hints\u0027]"},{"line_number":808,"context_line":"        for column in columns:"},{"line_number":809,"context_line":"            self.assertColumnExists(engine, \u0027request_specs\u0027, column)"},{"line_number":810,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"da20952f_cb34a8fc","line":807,"in_reply_to":"da20952f_4647371d","updated":"2015-09-03 13:17:51.000000000","message":"Yep.","commit_id":"6b9889b9610856e5af6459debd3c59a680a0523e"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"eee5e18ae54c1bb1d9c03cff05febd8ed0d55885","unresolved":false,"context_lines":[{"line_number":804,"context_line":"        columns \u003d [\u0027id\u0027, \u0027image\u0027, \u0027numa_topology\u0027, \u0027pci_requests\u0027,"},{"line_number":805,"context_line":"                \u0027project_id\u0027, \u0027availability_zone\u0027, \u0027flavor\u0027, \u0027num_instances\u0027,"},{"line_number":806,"context_line":"                \u0027ignore_hosts\u0027, \u0027force_hosts\u0027, \u0027force_nodes\u0027, \u0027retry\u0027,"},{"line_number":807,"context_line":"                \u0027limits\u0027, \u0027instance_group\u0027, \u0027scheduler_hints\u0027]"},{"line_number":808,"context_line":"        for column in columns:"},{"line_number":809,"context_line":"            self.assertColumnExists(engine, \u0027request_specs\u0027, column)"},{"line_number":810,"context_line":""}],"source_content_type":"text/x-python","patch_set":25,"id":"da20952f_4647371d","line":807,"in_reply_to":"da20952f_95d6eec1","updated":"2015-09-03 09:50:11.000000000","message":"Yeah... :(","commit_id":"6b9889b9610856e5af6459debd3c59a680a0523e"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"90d14ee95fcf9054c8e5723cf05ccdc3e4aad02e","unresolved":false,"context_lines":[{"line_number":808,"context_line":""},{"line_number":809,"context_line":"    def _check_313(self, engine, data):"},{"line_number":810,"context_line":"        columns \u003d [\u0027id\u0027, \u0027image\u0027, \u0027numa_topology\u0027, \u0027pci_requests\u0027,"},{"line_number":811,"context_line":"                \u0027project_id\u0027, \u0027availability_zone\u0027, \u0027flavor\u0027, \u0027num_instances\u0027,"},{"line_number":812,"context_line":"                \u0027ignore_hosts\u0027, \u0027force_hosts\u0027, \u0027force_nodes\u0027, \u0027retry\u0027,"},{"line_number":813,"context_line":"                \u0027limits\u0027, \u0027instance_group\u0027, \u0027scheduler_hints\u0027, \u0027instance_uuid\u0027]"},{"line_number":814,"context_line":"        for column in columns:"}],"source_content_type":"text/x-python","patch_set":26,"id":"3a29b11f_227c07b4","line":811,"updated":"2015-10-22 11:12:30.000000000","message":"alignment here is dodgy but it does not complain in pep8","commit_id":"dcfa47f396bce8480f201efc53f38d3f2f11201b"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"331119cf0a2de6b5e55275321842ff21a1c3eb41","unresolved":false,"context_lines":[{"line_number":808,"context_line":""},{"line_number":809,"context_line":"    def _check_313(self, engine, data):"},{"line_number":810,"context_line":"        columns \u003d [\u0027id\u0027, \u0027image\u0027, \u0027numa_topology\u0027, \u0027pci_requests\u0027,"},{"line_number":811,"context_line":"                \u0027project_id\u0027, \u0027availability_zone\u0027, \u0027flavor\u0027, \u0027num_instances\u0027,"},{"line_number":812,"context_line":"                \u0027ignore_hosts\u0027, \u0027force_hosts\u0027, \u0027force_nodes\u0027, \u0027retry\u0027,"},{"line_number":813,"context_line":"                \u0027limits\u0027, \u0027instance_group\u0027, \u0027scheduler_hints\u0027, \u0027instance_uuid\u0027]"},{"line_number":814,"context_line":"        for column in columns:"}],"source_content_type":"text/x-python","patch_set":26,"id":"3a29b11f_fed9c7f3","line":811,"in_reply_to":"3a29b11f_227c07b4","updated":"2015-10-22 12:25:30.000000000","message":"it\u0027s indented by 8, which is fine","commit_id":"dcfa47f396bce8480f201efc53f38d3f2f11201b"}],"nova/tests/unit/fake_request_spec.py":[{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"9b962bdcf6f7a9c84bd8c72df772edaed78d0d7e","unresolved":false,"context_lines":[{"line_number":70,"context_line":"            \u0027limits\u0027: jsonutils.dumps("},{"line_number":71,"context_line":"                objects.SchedulerLimits().obj_to_primitive()),"},{"line_number":72,"context_line":"            \u0027instance_group\u0027: jsonutils.dumps("},{"line_number":73,"context_line":"                objects.InstanceGroup().obj_to_primitive()),"},{"line_number":74,"context_line":"    }"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"    for name, field in objects.RequestSpec.fields.items():"}],"source_content_type":"text/x-python","patch_set":22,"id":"da20952f_64937cfb","line":73,"updated":"2015-09-02 15:44:01.000000000","message":"here you\u0027re not testing force_hosts, ignore_hosts and force_nodes, I\u0027m not totally sold it will work...","commit_id":"173052f6d733452c7abe49590558031b8329c296"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"5e5ac1f2942fcb0d22cfe7e8e4227160f4b78b9f","unresolved":false,"context_lines":[{"line_number":70,"context_line":"            \u0027limits\u0027: jsonutils.dumps("},{"line_number":71,"context_line":"                objects.SchedulerLimits().obj_to_primitive()),"},{"line_number":72,"context_line":"            \u0027instance_group\u0027: jsonutils.dumps("},{"line_number":73,"context_line":"                objects.InstanceGroup().obj_to_primitive()),"},{"line_number":74,"context_line":"    }"},{"line_number":75,"context_line":""},{"line_number":76,"context_line":"    for name, field in objects.RequestSpec.fields.items():"}],"source_content_type":"text/x-python","patch_set":22,"id":"da20952f_6755bec4","line":73,"in_reply_to":"da20952f_64937cfb","updated":"2015-09-02 15:50:03.000000000","message":"Okay, I\u0027ll add these.","commit_id":"173052f6d733452c7abe49590558031b8329c296"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"2670d256f7e2b6a653d2e28ce0db5a79ee8a2524","unresolved":false,"context_lines":[{"line_number":91,"context_line":""},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"def fake_scheduler_retries_obj(context):"},{"line_number":94,"context_line":"    retry_obj \u003d objects.Retry(context)"},{"line_number":95,"context_line":"    retry_obj.num_attempts \u003d 1"},{"line_number":96,"context_line":"    retry_obj.hosts \u003d [objects.ComputeNode(id\u003d1, local_gb\u003d1024, memory_mb\u003d1024,"},{"line_number":97,"context_line":"        vcpus\u003d1, disk_available_least\u003dNone, free_ram_mb\u003d512, vcpus_used\u003d1,"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba8a016a_55fe0f6c","line":94,"range":{"start_line":94,"start_character":16,"end_line":94,"end_character":29},"updated":"2015-11-23 21:19:58.000000000","message":"that can\u0027t work, it\u0027s now called objects.SchedulerRetries","commit_id":"aa01166c949091edda8f021e5ce194e72dacbaaa"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"f5c07000721c1fff1310b8d23f50cd39640d6017","unresolved":false,"context_lines":[{"line_number":91,"context_line":""},{"line_number":92,"context_line":""},{"line_number":93,"context_line":"def fake_scheduler_retries_obj(context):"},{"line_number":94,"context_line":"    retry_obj \u003d objects.Retry(context)"},{"line_number":95,"context_line":"    retry_obj.num_attempts \u003d 1"},{"line_number":96,"context_line":"    retry_obj.hosts \u003d [objects.ComputeNode(id\u003d1, local_gb\u003d1024, memory_mb\u003d1024,"},{"line_number":97,"context_line":"        vcpus\u003d1, disk_available_least\u003dNone, free_ram_mb\u003d512, vcpus_used\u003d1,"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba8a016a_8a85315a","line":94,"range":{"start_line":94,"start_character":16,"end_line":94,"end_character":29},"in_reply_to":"ba8a016a_55fe0f6c","updated":"2015-11-24 00:06:56.000000000","message":"Good catch.  These two fakes are never used so I\u0027m going to just remove them for now.","commit_id":"aa01166c949091edda8f021e5ce194e72dacbaaa"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"2670d256f7e2b6a653d2e28ce0db5a79ee8a2524","unresolved":false,"context_lines":[{"line_number":105,"context_line":""},{"line_number":106,"context_line":"def fake_scheduler_limits_obj(context):"},{"line_number":107,"context_line":"    limits_dict \u003d {\u0027vcpu\u0027: 2, \u0027disk_gb\u0027: 20, \u0027memory_mb\u0027: 1024}"},{"line_number":108,"context_line":"    limits_obj \u003d objects.Limits.from_dict(objects.Limits, limits_dict)"},{"line_number":109,"context_line":"    limits_obj.numa_topology \u003d INSTANCE_NUMA_TOPOLOGY"},{"line_number":110,"context_line":"    limits_obj.obj_reset_changes()"},{"line_number":111,"context_line":"    return limits_obj"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba8a016a_b52e5bf8","line":108,"range":{"start_line":108,"start_character":17,"end_line":108,"end_character":31},"updated":"2015-11-23 21:19:58.000000000","message":"same comment here, it\u0027s called SchedulerLimits","commit_id":"aa01166c949091edda8f021e5ce194e72dacbaaa"}],"nova/tests/unit/objects/test_objects.py":[{"author":{"_account_id":782,"name":"John Garbutt","email":"john@johngarbutt.com","username":"johngarbutt"},"change_message_id":"b495590b13ab8197e73fd0a3d5ee908b473bc7e1","unresolved":false,"context_lines":[{"line_number":1084,"context_line":""},{"line_number":1085,"context_line":"# NOTE(danms): The hashes in this list should only be changed if"},{"line_number":1086,"context_line":"# they come with a corresponding version bump in the affected"},{"line_number":1087,"context_line":"# objects"},{"line_number":1088,"context_line":"object_data \u003d {"},{"line_number":1089,"context_line":"    \u0027Agent\u0027: \u00271.0-c0c092abaceb6f51efe5d82175f15eba\u0027,"},{"line_number":1090,"context_line":"    \u0027AgentList\u0027: \u00271.0-5a7380d02c3aaf2a32fc8115ae7ca98c\u0027,"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa1b9901_063b70d2","line":1087,"updated":"2015-08-25 10:28:40.000000000","message":"I think we need the version bump.","commit_id":"ec23c3f4411a7e1aa48cbeff0557ea806ea5cc67"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"0c158413415f14ac5ce4d59d424f47aa9e2324ea","unresolved":false,"context_lines":[{"line_number":1084,"context_line":""},{"line_number":1085,"context_line":"# NOTE(danms): The hashes in this list should only be changed if"},{"line_number":1086,"context_line":"# they come with a corresponding version bump in the affected"},{"line_number":1087,"context_line":"# objects"},{"line_number":1088,"context_line":"object_data \u003d {"},{"line_number":1089,"context_line":"    \u0027Agent\u0027: \u00271.0-c0c092abaceb6f51efe5d82175f15eba\u0027,"},{"line_number":1090,"context_line":"    \u0027AgentList\u0027: \u00271.0-5a7380d02c3aaf2a32fc8115ae7ca98c\u0027,"}],"source_content_type":"text/x-python","patch_set":19,"id":"fa1b9901_7088d871","line":1087,"in_reply_to":"fa1b9901_063b70d2","updated":"2015-08-25 14:16:07.000000000","message":"Yep.","commit_id":"ec23c3f4411a7e1aa48cbeff0557ea806ea5cc67"}],"nova/tests/unit/objects/test_request_spec.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"8c68dbd47df2942b98e5a5c3b4984ceb0f5148f3","unresolved":false,"context_lines":[{"line_number":243,"context_line":""},{"line_number":244,"context_line":"        self.assertEqual(1, req_obj.num_instances)"},{"line_number":245,"context_line":"        self.assertEqual(2, req_obj.root_gb)"},{"line_number":246,"context_line":"        self.assertIsNone(None, req_obj.ignore_hosts)"},{"line_number":247,"context_line":"        self.assertIsNone(None, req_obj.project_id)"},{"line_number":248,"context_line":"        self.assertIsNone(None, req_obj.scheduler_hints)"},{"line_number":249,"context_line":"        self.assertEqual(2, req_obj.ephemeral_gb)"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa1b9901_e9ed618f","line":246,"updated":"2015-08-17 12:30:49.000000000","message":"Should it be self.assertIsNone(req_obj.ignore_hosts) as current line is always True.","commit_id":"44727ec303b760e4acca0dce708b43b3334e331f"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"463e12202ba324f2abed09fa31ac9738097197e0","unresolved":false,"context_lines":[{"line_number":243,"context_line":""},{"line_number":244,"context_line":"        self.assertEqual(1, req_obj.num_instances)"},{"line_number":245,"context_line":"        self.assertEqual(2, req_obj.root_gb)"},{"line_number":246,"context_line":"        self.assertIsNone(None, req_obj.ignore_hosts)"},{"line_number":247,"context_line":"        self.assertIsNone(None, req_obj.project_id)"},{"line_number":248,"context_line":"        self.assertIsNone(None, req_obj.scheduler_hints)"},{"line_number":249,"context_line":"        self.assertEqual(2, req_obj.ephemeral_gb)"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa1b9901_9a798232","line":246,"in_reply_to":"fa1b9901_e9ed618f","updated":"2015-08-17 14:17:51.000000000","message":"Woops, good catch.  It was assertEqual previously and pep8 complained so I changed it to assertIsNone and forgot to update the params.","commit_id":"44727ec303b760e4acca0dce708b43b3334e331f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"8c68dbd47df2942b98e5a5c3b4984ceb0f5148f3","unresolved":false,"context_lines":[{"line_number":300,"context_line":"        fake_spec \u003d fake_request_spec.fake_db_spec()"},{"line_number":301,"context_line":"        req_obj \u003d fake_request_spec.fake_spec_obj(self.context, fake_spec)"},{"line_number":302,"context_line":""},{"line_number":303,"context_line":"        def _test_save_args(self2, context, instance_uuid, changes):"},{"line_number":304,"context_line":"            # This is being tested this way because the json strings for the"},{"line_number":305,"context_line":"            # object fields don\u0027t always match even when the object primitives"},{"line_number":306,"context_line":"            # do."}],"source_content_type":"text/x-python","patch_set":11,"id":"fa1b9901_b4c900af","line":303,"range":{"start_line":303,"start_character":12,"end_line":303,"end_character":27},"updated":"2015-08-17 12:30:49.000000000","message":"it seems to be a duplicate of the function defined in L270. Can we factor it out?","commit_id":"44727ec303b760e4acca0dce708b43b3334e331f"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"4e47b66753f9643d49625f90f9d53ba37132e46e","unresolved":false,"context_lines":[{"line_number":300,"context_line":"        fake_spec \u003d fake_request_spec.fake_db_spec()"},{"line_number":301,"context_line":"        req_obj \u003d fake_request_spec.fake_spec_obj(self.context, fake_spec)"},{"line_number":302,"context_line":""},{"line_number":303,"context_line":"        def _test_save_args(self2, context, instance_uuid, changes):"},{"line_number":304,"context_line":"            # This is being tested this way because the json strings for the"},{"line_number":305,"context_line":"            # object fields don\u0027t always match even when the object primitives"},{"line_number":306,"context_line":"            # do."}],"source_content_type":"text/x-python","patch_set":11,"id":"fa1b9901_50dbc91b","line":303,"range":{"start_line":303,"start_character":12,"end_line":303,"end_character":27},"in_reply_to":"fa1b9901_1a17b2a4","updated":"2015-08-17 14:54:08.000000000","message":"I missed this when I was replying earlier but it can\u0027t be factored out to a class method because it relies on being able to pull fake_spec into scope.  Fake_spec could be moved into setUp but that\u0027s overkill when only three tests need it.","commit_id":"44727ec303b760e4acca0dce708b43b3334e331f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e770b8c47b789c5cac8e0838ac2b98492283baf5","unresolved":false,"context_lines":[{"line_number":300,"context_line":"        fake_spec \u003d fake_request_spec.fake_db_spec()"},{"line_number":301,"context_line":"        req_obj \u003d fake_request_spec.fake_spec_obj(self.context, fake_spec)"},{"line_number":302,"context_line":""},{"line_number":303,"context_line":"        def _test_save_args(self2, context, instance_uuid, changes):"},{"line_number":304,"context_line":"            # This is being tested this way because the json strings for the"},{"line_number":305,"context_line":"            # object fields don\u0027t always match even when the object primitives"},{"line_number":306,"context_line":"            # do."}],"source_content_type":"text/x-python","patch_set":11,"id":"fa1b9901_6126136a","line":303,"range":{"start_line":303,"start_character":12,"end_line":303,"end_character":27},"in_reply_to":"fa1b9901_50dbc91b","updated":"2015-08-18 12:21:59.000000000","message":"You can use a lambda around _test_save_args to pass in fake_spec in every test but keep the _test_save_args abstract.\n \nSomething like http://paste.openstack.org/show/420402/","commit_id":"44727ec303b760e4acca0dce708b43b3334e331f"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"463e12202ba324f2abed09fa31ac9738097197e0","unresolved":false,"context_lines":[{"line_number":300,"context_line":"        fake_spec \u003d fake_request_spec.fake_db_spec()"},{"line_number":301,"context_line":"        req_obj \u003d fake_request_spec.fake_spec_obj(self.context, fake_spec)"},{"line_number":302,"context_line":""},{"line_number":303,"context_line":"        def _test_save_args(self2, context, instance_uuid, changes):"},{"line_number":304,"context_line":"            # This is being tested this way because the json strings for the"},{"line_number":305,"context_line":"            # object fields don\u0027t always match even when the object primitives"},{"line_number":306,"context_line":"            # do."}],"source_content_type":"text/x-python","patch_set":11,"id":"fa1b9901_1a17b2a4","line":303,"range":{"start_line":303,"start_character":12,"end_line":303,"end_character":27},"in_reply_to":"fa1b9901_b4c900af","updated":"2015-08-17 14:17:51.000000000","message":"It could be factored out, but I\u0027m not sure it would be any cleaner.  I\u0027ll play with it.","commit_id":"44727ec303b760e4acca0dce708b43b3334e331f"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"76ea77fb7f5d363072d918a5d10cb27f6a03b48a","unresolved":false,"context_lines":[{"line_number":282,"context_line":"        fake_spec \u003d fake_request_spec.fake_db_spec()"},{"line_number":283,"context_line":"        req_obj \u003d fake_request_spec.fake_spec_obj(self.context, fake_spec)"},{"line_number":284,"context_line":""},{"line_number":285,"context_line":"        def _test_save_args(self2, context, instance_uuid, changes):"},{"line_number":286,"context_line":"            # This is being tested this way because the json strings for the"},{"line_number":287,"context_line":"            # object fields don\u0027t always match even when the object primitives"},{"line_number":288,"context_line":"            # do."}],"source_content_type":"text/x-python","patch_set":20,"id":"da20952f_5f5b712e","line":285,"updated":"2015-08-28 13:14:43.000000000","message":"I still think that the helper function at L253 and L285 are duplicate and we can easily use a single instance of this code in both test. See my comment in patch set 11","commit_id":"4cccd46138f1549f3756e35d7204ba5b8b595da1"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"e97b631bbafd5aa719d1ac7b40fe96c6d0f569b4","unresolved":false,"context_lines":[{"line_number":282,"context_line":"        fake_spec \u003d fake_request_spec.fake_db_spec()"},{"line_number":283,"context_line":"        req_obj \u003d fake_request_spec.fake_spec_obj(self.context, fake_spec)"},{"line_number":284,"context_line":""},{"line_number":285,"context_line":"        def _test_save_args(self2, context, instance_uuid, changes):"},{"line_number":286,"context_line":"            # This is being tested this way because the json strings for the"},{"line_number":287,"context_line":"            # object fields don\u0027t always match even when the object primitives"},{"line_number":288,"context_line":"            # do."}],"source_content_type":"text/x-python","patch_set":20,"id":"da20952f_68617da8","line":285,"in_reply_to":"da20952f_5f5b712e","updated":"2015-08-31 18:13:41.000000000","message":"I started playing with doing this and I don\u0027t think it\u0027s the right way to go right now.  If I were to pull this out into a helper I would want to pass in a list of changed fields and not assume that every field will be set each time.  This means duplicating each field and ending up with something like http://paste.openstack.org/show/435348/.","commit_id":"4cccd46138f1549f3756e35d7204ba5b8b595da1"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"cfde42f3b189114310609f62403c3a36868ea456","unresolved":false,"context_lines":[{"line_number":282,"context_line":"        fake_spec \u003d fake_request_spec.fake_db_spec()"},{"line_number":283,"context_line":"        req_obj \u003d fake_request_spec.fake_spec_obj(self.context, fake_spec)"},{"line_number":284,"context_line":""},{"line_number":285,"context_line":"        def _test_save_args(self2, context, instance_uuid, changes):"},{"line_number":286,"context_line":"            # This is being tested this way because the json strings for the"},{"line_number":287,"context_line":"            # object fields don\u0027t always match even when the object primitives"},{"line_number":288,"context_line":"            # do."}],"source_content_type":"text/x-python","patch_set":20,"id":"da20952f_5b9eaa63","line":285,"in_reply_to":"da20952f_68617da8","updated":"2015-09-01 08:30:13.000000000","message":"Ok I see your point. Thanks","commit_id":"4cccd46138f1549f3756e35d7204ba5b8b595da1"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"90d14ee95fcf9054c8e5723cf05ccdc3e4aad02e","unresolved":false,"context_lines":[{"line_number":361,"context_line":"                fake_spec[\u0027instance_uuid\u0027])"},{"line_number":362,"context_line":""},{"line_number":363,"context_line":"        self.assertEqual(1, req_obj.num_instances)"},{"line_number":364,"context_line":"        self.assertIsNone(None, req_obj.ignore_hosts)"},{"line_number":365,"context_line":"        self.assertIsNone(None, req_obj.project_id)"},{"line_number":366,"context_line":"        self.assertIsNone(None, req_obj.scheduler_hints)"},{"line_number":367,"context_line":"        self.assertIsNone(None, req_obj.force_hosts)"}],"source_content_type":"text/x-python","patch_set":26,"id":"3a29b11f_c21bd37f","line":364,"updated":"2015-10-22 11:12:30.000000000","message":"self.assertIsNone(req_obj.ignore_hosts)","commit_id":"dcfa47f396bce8480f201efc53f38d3f2f11201b"},{"author":{"_account_id":8688,"name":"Alexis Lee","email":"openstack@lxsli.co.uk","username":"lxsli"},"change_message_id":"331119cf0a2de6b5e55275321842ff21a1c3eb41","unresolved":false,"context_lines":[{"line_number":361,"context_line":"                fake_spec[\u0027instance_uuid\u0027])"},{"line_number":362,"context_line":""},{"line_number":363,"context_line":"        self.assertEqual(1, req_obj.num_instances)"},{"line_number":364,"context_line":"        self.assertIsNone(None, req_obj.ignore_hosts)"},{"line_number":365,"context_line":"        self.assertIsNone(None, req_obj.project_id)"},{"line_number":366,"context_line":"        self.assertIsNone(None, req_obj.scheduler_hints)"},{"line_number":367,"context_line":"        self.assertIsNone(None, req_obj.force_hosts)"}],"source_content_type":"text/x-python","patch_set":26,"id":"3a29b11f_7e9b7718","line":364,"in_reply_to":"3a29b11f_c21bd37f","updated":"2015-10-22 12:25:30.000000000","message":"Done","commit_id":"dcfa47f396bce8480f201efc53f38d3f2f11201b"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"90d14ee95fcf9054c8e5723cf05ccdc3e4aad02e","unresolved":false,"context_lines":[{"line_number":362,"context_line":""},{"line_number":363,"context_line":"        self.assertEqual(1, req_obj.num_instances)"},{"line_number":364,"context_line":"        self.assertIsNone(None, req_obj.ignore_hosts)"},{"line_number":365,"context_line":"        self.assertIsNone(None, req_obj.project_id)"},{"line_number":366,"context_line":"        self.assertIsNone(None, req_obj.scheduler_hints)"},{"line_number":367,"context_line":"        self.assertIsNone(None, req_obj.force_hosts)"},{"line_number":368,"context_line":"        self.assertIsNone(None, req_obj.availability_zone)"}],"source_content_type":"text/x-python","patch_set":26,"id":"3a29b11f_82115b5f","line":365,"updated":"2015-10-22 11:12:30.000000000","message":"ditto for the rest below","commit_id":"dcfa47f396bce8480f201efc53f38d3f2f11201b"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"90d14ee95fcf9054c8e5723cf05ccdc3e4aad02e","unresolved":false,"context_lines":[{"line_number":390,"context_line":""},{"line_number":391,"context_line":"            # primitive fields"},{"line_number":392,"context_line":"            for field in [\u0027instance_uuid\u0027, \u0027num_instances\u0027, \u0027ignore_hosts\u0027,"},{"line_number":393,"context_line":"                    \u0027project_id\u0027, \u0027scheduler_hints\u0027, \u0027force_hosts\u0027,"},{"line_number":394,"context_line":"                    \u0027availability_zone\u0027, \u0027force_nodes\u0027]:"},{"line_number":395,"context_line":"                self.assertEqual(fake_spec[field], changes[field])"},{"line_number":396,"context_line":""}],"source_content_type":"text/x-python","patch_set":26,"id":"3a29b11f_22016706","line":393,"updated":"2015-10-22 11:12:30.000000000","message":"dodgy indentation","commit_id":"dcfa47f396bce8480f201efc53f38d3f2f11201b"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"90d14ee95fcf9054c8e5723cf05ccdc3e4aad02e","unresolved":false,"context_lines":[{"line_number":395,"context_line":"                self.assertEqual(fake_spec[field], changes[field])"},{"line_number":396,"context_line":""},{"line_number":397,"context_line":"            # object fields"},{"line_number":398,"context_line":"            for field in [\u0027image\u0027, \u0027numa_topology\u0027, \u0027pci_requests\u0027, \u0027flavor\u0027,"},{"line_number":399,"context_line":"                    \u0027retry\u0027, \u0027limits\u0027, \u0027instance_group\u0027]:"},{"line_number":400,"context_line":"                self.assertDictEqual(jsonutils.loads(fake_spec[field]),"},{"line_number":401,"context_line":"                        jsonutils.loads(changes[field]))"}],"source_content_type":"text/x-python","patch_set":26,"id":"3a29b11f_bd027808","line":398,"updated":"2015-10-22 11:12:30.000000000","message":"ditto","commit_id":"dcfa47f396bce8480f201efc53f38d3f2f11201b"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"90d14ee95fcf9054c8e5723cf05ccdc3e4aad02e","unresolved":false,"context_lines":[{"line_number":422,"context_line":""},{"line_number":423,"context_line":"            # primitive fields"},{"line_number":424,"context_line":"            for field in [\u0027instance_uuid\u0027, \u0027num_instances\u0027,"},{"line_number":425,"context_line":"                    \u0027ignore_hosts\u0027, \u0027project_id\u0027, \u0027scheduler_hints\u0027,"},{"line_number":426,"context_line":"                    \u0027force_hosts\u0027, \u0027availability_zone\u0027, \u0027force_nodes\u0027]:"},{"line_number":427,"context_line":"                self.assertEqual(fake_spec[field], changes[field])"},{"line_number":428,"context_line":""}],"source_content_type":"text/x-python","patch_set":26,"id":"3a29b11f_9d0bfc23","line":425,"updated":"2015-10-22 11:12:30.000000000","message":"ditto","commit_id":"dcfa47f396bce8480f201efc53f38d3f2f11201b"},{"author":{"_account_id":1653,"name":"garyk","email":"gkotton@vmware.com","username":"garyk"},"change_message_id":"90d14ee95fcf9054c8e5723cf05ccdc3e4aad02e","unresolved":false,"context_lines":[{"line_number":428,"context_line":""},{"line_number":429,"context_line":"            # object fields"},{"line_number":430,"context_line":"            for field in [\u0027image\u0027, \u0027numa_topology\u0027, \u0027pci_requests\u0027, \u0027flavor\u0027,"},{"line_number":431,"context_line":"                    \u0027retry\u0027, \u0027limits\u0027, \u0027instance_group\u0027]:"},{"line_number":432,"context_line":"                self.assertDictEqual(jsonutils.loads(fake_spec[field]),"},{"line_number":433,"context_line":"                        jsonutils.loads(changes[field]))"},{"line_number":434,"context_line":"            return fake_spec"}],"source_content_type":"text/x-python","patch_set":26,"id":"3a29b11f_3d174849","line":431,"updated":"2015-10-22 11:12:30.000000000","message":"ditto","commit_id":"dcfa47f396bce8480f201efc53f38d3f2f11201b"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"2670d256f7e2b6a653d2e28ce0db5a79ee8a2524","unresolved":false,"context_lines":[{"line_number":420,"context_line":"        self.assertIsInstance(req_obj.flavor, objects.Flavor)"},{"line_number":421,"context_line":"        self.assertIsInstance(req_obj.retry, objects.SchedulerRetries)"},{"line_number":422,"context_line":"        self.assertIsInstance(req_obj.limits, objects.SchedulerLimits)"},{"line_number":423,"context_line":"        self.assertIsInstance(req_obj.instance_group, objects.InstanceGroup)"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":"    def _check_update_primitive(self, req_obj, changes):"},{"line_number":426,"context_line":"        self.assertEqual(req_obj.instance_uuid, changes[\u0027instance_uuid\u0027])"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba8a016a_b5989b1c","line":423,"updated":"2015-11-23 21:19:58.000000000","message":"well, since you mock _get_by_instance_uuid_from_db, you just need to verify that this mock was called.\n\nHere, it would mean we would have to change this unittest anytime we change an object field (for sure it\u0027s not something we do lots of time - rather only when bumping a major version -, but it creates a relationship between the object itself and that test)\n\nThat said, we can land a change later for that.","commit_id":"aa01166c949091edda8f021e5ce194e72dacbaaa"},{"author":{"_account_id":5441,"name":"Andrew Laski","email":"andrew@lascii.com","username":"alaski"},"change_message_id":"f5c07000721c1fff1310b8d23f50cd39640d6017","unresolved":false,"context_lines":[{"line_number":420,"context_line":"        self.assertIsInstance(req_obj.flavor, objects.Flavor)"},{"line_number":421,"context_line":"        self.assertIsInstance(req_obj.retry, objects.SchedulerRetries)"},{"line_number":422,"context_line":"        self.assertIsInstance(req_obj.limits, objects.SchedulerLimits)"},{"line_number":423,"context_line":"        self.assertIsInstance(req_obj.instance_group, objects.InstanceGroup)"},{"line_number":424,"context_line":""},{"line_number":425,"context_line":"    def _check_update_primitive(self, req_obj, changes):"},{"line_number":426,"context_line":"        self.assertEqual(req_obj.instance_uuid, changes[\u0027instance_uuid\u0027])"}],"source_content_type":"text/x-python","patch_set":37,"id":"ba8a016a_ca5019d7","line":423,"in_reply_to":"ba8a016a_b5989b1c","updated":"2015-11-24 00:06:56.000000000","message":"This is indirectly testing _from_db_object to ensure that the object is hydrated correct from _get_by_instance_uuid.  However I could just test that _get_by_instance_uuid is called here and test _from_db_object more directly.  It could be a followup as well.","commit_id":"aa01166c949091edda8f021e5ce194e72dacbaaa"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"921f9eadb497aa392290f8b6ba635fa2946b262e","unresolved":false,"context_lines":[{"line_number":466,"context_line":"        def _test_save_args(self2, context, instance_uuid, changes):"},{"line_number":467,"context_line":"            self._check_update_primitive(req_obj, changes)"},{"line_number":468,"context_line":"            # DB creation would have set an id"},{"line_number":469,"context_line":"            changes[\u0027id\u0027] \u003d 42"},{"line_number":470,"context_line":"            return changes"},{"line_number":471,"context_line":""},{"line_number":472,"context_line":"        with mock.patch.object(request_spec.RequestSpec, \u0027_save_in_db\u0027,"}],"source_content_type":"text/x-python","patch_set":41,"id":"7a740942_846e96ff","line":469,"updated":"2015-12-06 14:38:00.000000000","message":"The above is not needed in this case since remove_id parameter to fake_spec_obj() is False.","commit_id":"0152047a776d481db124a51cc822561bb27a75b0"}]}
