)]}'
{"nova/exception.py":[{"author":{"_account_id":14614,"name":"Kyrylo Romanenko","display_name":"K.Romanenko","email":"romanenko-kv@hotmail.com","username":"kromanenko"},"change_message_id":"f8c38a6b223d98e0eda1d685bbe580ff77d026ef","unresolved":false,"context_lines":[{"line_number":2103,"context_line":""},{"line_number":2104,"context_line":""},{"line_number":2105,"context_line":"class ResourceProviderNotFound(NotFound):"},{"line_number":2106,"context_line":"    msg_fmt \u003d _(\"Resource provider %s not found.\")"},{"line_number":2107,"context_line":""},{"line_number":2108,"context_line":""},{"line_number":2109,"context_line":"class ResourceProviderInUse(NovaException):"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_e2ec2af5","line":2106,"range":{"start_line":2106,"start_character":35,"end_line":2106,"end_character":37},"updated":"2016-12-15 16:30:55.000000000","message":"For which variable is this formatter?","commit_id":"40851810056ea96537050bdec2f77dad8a42ac13"},{"author":{"_account_id":13692,"name":"Roman Dobosz","email":"gryf73@gmail.com","username":"gryf"},"change_message_id":"7225e547365344aefde51eefc002a648ee6bdfb1","unresolved":false,"context_lines":[{"line_number":2103,"context_line":""},{"line_number":2104,"context_line":""},{"line_number":2105,"context_line":"class ResourceProviderNotFound(NotFound):"},{"line_number":2106,"context_line":"    msg_fmt \u003d _(\"Resource provider %s not found.\")"},{"line_number":2107,"context_line":""},{"line_number":2108,"context_line":""},{"line_number":2109,"context_line":"class ResourceProviderInUse(NovaException):"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_ae8e9976","line":2106,"range":{"start_line":2106,"start_character":35,"end_line":2106,"end_character":37},"in_reply_to":"1a6eadb0_e2ec2af5","updated":"2016-12-15 17:39:05.000000000","message":"For the class in the ancestor. Please take a look at NovaException class which NotFound is derived from. Although to be consistent with most message formats here, it should be a mapping name. Will change it in next iteration.","commit_id":"40851810056ea96537050bdec2f77dad8a42ac13"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"0c389fcd2e9756143ea140869b9443e38a6bc26c","unresolved":false,"context_lines":[{"line_number":2103,"context_line":""},{"line_number":2104,"context_line":""},{"line_number":2105,"context_line":"class ResourceProviderNotFound(NotFound):"},{"line_number":2106,"context_line":"    msg_fmt \u003d _(\"Resource provider %s not found.\")"},{"line_number":2107,"context_line":""},{"line_number":2108,"context_line":""},{"line_number":2109,"context_line":"class ResourceProviderInUse(NovaException):"}],"source_content_type":"text/x-python","patch_set":24,"id":"ba5201f7_bce8c3e3","line":2106,"updated":"2017-01-04 12:47:28.000000000","message":"Looks like this should have a %(uuid)s and be called as uuid\u003duuid when raised, to follow existing conventions?","commit_id":"ce0463e4f79d5314fa3785988f08c211f65863d8"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"bcf35d2f965d9b543ca7836cabf8d4155d86adc6","unresolved":false,"context_lines":[{"line_number":2063,"context_line":""},{"line_number":2064,"context_line":""},{"line_number":2065,"context_line":"class ResourceProviderNotFound(NotFound):"},{"line_number":2066,"context_line":"    msg_fmt \u003d _(\"Resource provider %s not found.\")"},{"line_number":2067,"context_line":""},{"line_number":2068,"context_line":""},{"line_number":2069,"context_line":"class ResourceProviderInUse(NovaException):"}],"source_content_type":"text/x-python","patch_set":43,"id":"7f515b1d_25758cfa","line":2066,"updated":"2017-10-01 15:45:55.000000000","message":"Not strictly necessary, but most NotFound exceptions name the thing being interpolated (see above and below).","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"bf9533647be944d84d23316f240ed8599afe8a5a","unresolved":false,"context_lines":[{"line_number":2063,"context_line":""},{"line_number":2064,"context_line":""},{"line_number":2065,"context_line":"class ResourceProviderNotFound(NotFound):"},{"line_number":2066,"context_line":"    msg_fmt \u003d _(\"Resource provider %s not found.\")"},{"line_number":2067,"context_line":""},{"line_number":2068,"context_line":""},{"line_number":2069,"context_line":"class ResourceProviderInUse(NovaException):"}],"source_content_type":"text/x-python","patch_set":43,"id":"5f4e5783_5c970e92","line":2066,"in_reply_to":"7f515b1d_25758cfa","updated":"2017-10-10 15:47:33.000000000","message":"Done. Removed this exception in latest revision.","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"}],"nova/objects/resource_provider.py":[{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"1e89e83b126e85aed84ce654bef2666fc78527d0","unresolved":false,"context_lines":[{"line_number":523,"context_line":"        query \u003d context.session.query(models.ResourceProvider)"},{"line_number":524,"context_line":"        # TODO(jaypipes): Remove this OR condition when root_provider_uuid is"},{"line_number":525,"context_line":"        # not nullable in the database and all resource provider records have"},{"line_number":526,"context_line":"        # populated the root provider UUID."},{"line_number":527,"context_line":"        where_cond \u003d sa.or_("},{"line_number":528,"context_line":"            models.ResourceProvider.uuid \u003d\u003d root_uuid,"},{"line_number":529,"context_line":"            models.ResourceProvider.root_provider_uuid \u003d\u003d root_uuid,"}],"source_content_type":"text/x-python","patch_set":1,"id":"5a8bc5a2_6d433c6d","line":526,"updated":"2016-09-28 11:23:37.000000000","message":"When? :)","commit_id":"76b9162828bfd881d5da81a30fc3e0b0342e212f"},{"author":{"_account_id":12171,"name":"Moshe Levi","email":"moshele@nvidia.com","username":"moshele"},"change_message_id":"b095260a0450973ee2f73675c574d4c95279c9a5","unresolved":false,"context_lines":[{"line_number":559,"context_line":"    }"},{"line_number":560,"context_line":""},{"line_number":561,"context_line":"    allowed_filters \u003d ("},{"line_number":562,"context_line":"        \u0027name\u0027, \u0027uuid\u0027, \u0027tree\u0027"},{"line_number":563,"context_line":"    )"},{"line_number":564,"context_line":""},{"line_number":565,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":18,"id":"7a77a97e_b01f6108","line":562,"range":{"start_line":562,"start_character":24,"end_line":562,"end_character":30},"updated":"2016-11-22 02:05:48.000000000","message":"I think you don\u0027t need tree in the allowed_filters, because in Line 495 you do getattr(models.ResourceProvider, attr) which will raise AttributeError. maybe you should rename to allowed_filters to allowed_attribute_filters","commit_id":"c8e413a9ce461f3d576dacf6dcc8b612dd79c11f"},{"author":{"_account_id":12171,"name":"Moshe Levi","email":"moshele@nvidia.com","username":"moshele"},"change_message_id":"3a4c682ef99359a286ebce4940802b91e6e878fc","unresolved":false,"context_lines":[{"line_number":559,"context_line":"    }"},{"line_number":560,"context_line":""},{"line_number":561,"context_line":"    allowed_filters \u003d ("},{"line_number":562,"context_line":"        \u0027name\u0027, \u0027uuid\u0027, \u0027tree\u0027"},{"line_number":563,"context_line":"    )"},{"line_number":564,"context_line":""},{"line_number":565,"context_line":"    @staticmethod"}],"source_content_type":"text/x-python","patch_set":18,"id":"7a77a97e_e6e4bfad","line":562,"range":{"start_line":562,"start_character":24,"end_line":562,"end_character":30},"in_reply_to":"7a77a97e_b01f6108","updated":"2016-11-22 03:21:22.000000000","message":"Ok so I just saw you pop the \u0027tree\u0027 so nevermind","commit_id":"c8e413a9ce461f3d576dacf6dcc8b612dd79c11f"},{"author":{"_account_id":14614,"name":"Kyrylo Romanenko","display_name":"K.Romanenko","email":"romanenko-kv@hotmail.com","username":"kromanenko"},"change_message_id":"f8c38a6b223d98e0eda1d685bbe580ff77d026ef","unresolved":false,"context_lines":[{"line_number":822,"context_line":"                                  objects.ResourceProvider, resource_providers)"},{"line_number":823,"context_line":""},{"line_number":824,"context_line":"    @staticmethod"},{"line_number":825,"context_line":"    def _get_root_provider_uuid(ctx, uuid):"},{"line_number":826,"context_line":"        \"\"\"Returns root_provider_uuid value of provider with supplied uuid."},{"line_number":827,"context_line":""},{"line_number":828,"context_line":"        :param uuid: UUID of the resource provider you wish to get the"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_a20b1229","line":825,"range":{"start_line":825,"start_character":32,"end_line":825,"end_character":35},"updated":"2016-12-15 16:30:55.000000000","message":"Please describe this param in docstring also.","commit_id":"40851810056ea96537050bdec2f77dad8a42ac13"},{"author":{"_account_id":13692,"name":"Roman Dobosz","email":"gryf73@gmail.com","username":"gryf"},"change_message_id":"7225e547365344aefde51eefc002a648ee6bdfb1","unresolved":false,"context_lines":[{"line_number":822,"context_line":"                                  objects.ResourceProvider, resource_providers)"},{"line_number":823,"context_line":""},{"line_number":824,"context_line":"    @staticmethod"},{"line_number":825,"context_line":"    def _get_root_provider_uuid(ctx, uuid):"},{"line_number":826,"context_line":"        \"\"\"Returns root_provider_uuid value of provider with supplied uuid."},{"line_number":827,"context_line":""},{"line_number":828,"context_line":"        :param uuid: UUID of the resource provider you wish to get the"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_2eb28906","line":825,"range":{"start_line":825,"start_character":32,"end_line":825,"end_character":35},"in_reply_to":"1a6eadb0_a20b1229","updated":"2016-12-15 17:39:05.000000000","message":"Done","commit_id":"40851810056ea96537050bdec2f77dad8a42ac13"},{"author":{"_account_id":14614,"name":"Kyrylo Romanenko","display_name":"K.Romanenko","email":"romanenko-kv@hotmail.com","username":"kromanenko"},"change_message_id":"f8c38a6b223d98e0eda1d685bbe580ff77d026ef","unresolved":false,"context_lines":[{"line_number":826,"context_line":"        \"\"\"Returns root_provider_uuid value of provider with supplied uuid."},{"line_number":827,"context_line":""},{"line_number":828,"context_line":"        :param uuid: UUID of the resource provider you wish to get the"},{"line_number":829,"context_line":"                     root provider uuid for."},{"line_number":830,"context_line":"        :raises: ResourceProviderNotFound if no such provider with the supplied"},{"line_number":831,"context_line":"                 uuid is found"},{"line_number":832,"context_line":"        \"\"\""},{"line_number":833,"context_line":"        # Grab the root provider UUID of the supplied resource provider UUID"},{"line_number":834,"context_line":"        with db_api.api_context_manager.reader.connection.using(ctx) as conn:"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_4d5a6f2b","line":831,"range":{"start_line":829,"start_character":43,"end_line":831,"end_character":30},"updated":"2016-12-15 16:30:55.000000000","message":"Let\u0027s end both strings with dots or both without.","commit_id":"40851810056ea96537050bdec2f77dad8a42ac13"},{"author":{"_account_id":13692,"name":"Roman Dobosz","email":"gryf73@gmail.com","username":"gryf"},"change_message_id":"7225e547365344aefde51eefc002a648ee6bdfb1","unresolved":false,"context_lines":[{"line_number":826,"context_line":"        \"\"\"Returns root_provider_uuid value of provider with supplied uuid."},{"line_number":827,"context_line":""},{"line_number":828,"context_line":"        :param uuid: UUID of the resource provider you wish to get the"},{"line_number":829,"context_line":"                     root provider uuid for."},{"line_number":830,"context_line":"        :raises: ResourceProviderNotFound if no such provider with the supplied"},{"line_number":831,"context_line":"                 uuid is found"},{"line_number":832,"context_line":"        \"\"\""},{"line_number":833,"context_line":"        # Grab the root provider UUID of the supplied resource provider UUID"},{"line_number":834,"context_line":"        with db_api.api_context_manager.reader.connection.using(ctx) as conn:"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_4eb7c5f4","line":831,"range":{"start_line":829,"start_character":43,"end_line":831,"end_character":30},"in_reply_to":"1a6eadb0_4d5a6f2b","updated":"2016-12-15 17:39:05.000000000","message":"Done","commit_id":"40851810056ea96537050bdec2f77dad8a42ac13"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9df35da822a8eb69d22ede584edb22c620031a71","unresolved":false,"context_lines":[{"line_number":1236,"context_line":"    }"},{"line_number":1237,"context_line":""},{"line_number":1238,"context_line":"    @staticmethod"},{"line_number":1239,"context_line":"    @db_api.api_context_manager.reader"},{"line_number":1240,"context_line":"    def _get_all_by_filters_from_db(context, filters):"},{"line_number":1241,"context_line":"        # Eg. filters can be:"},{"line_number":1242,"context_line":"        #  filters \u003d {"}],"source_content_type":"text/x-python","patch_set":39,"id":"5f201791_018197c3","side":"PARENT","line":1239,"range":{"start_line":1239,"start_character":0,"end_line":1239,"end_character":38},"updated":"2017-06-26 14:50:38.000000000","message":"This is gone because it\u0027s a caller of the function (get_all_by_filters) now uses the \u0027writer\u0027 permission, right?","commit_id":"63577e9677654d1ee22b21e44d456eaec272187a"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9df35da822a8eb69d22ede584edb22c620031a71","unresolved":false,"context_lines":[{"line_number":1268,"context_line":"            query \u003d query.filter(models.ResourceProvider.name \u003d\u003d name)"},{"line_number":1269,"context_line":"        if uuid:"},{"line_number":1270,"context_line":"            query \u003d query.filter(models.ResourceProvider.uuid \u003d\u003d uuid)"},{"line_number":1271,"context_line":"        if \u0027tree\u0027 in filters:"},{"line_number":1272,"context_line":"            tree_uuid \u003d filters.pop(\u0027tree\u0027)"},{"line_number":1273,"context_line":"            try:"},{"line_number":1274,"context_line":"                root \u003d ResourceProviderList._get_root_provider_uuid("}],"source_content_type":"text/x-python","patch_set":39,"id":"5f201791_814da7c5","line":1271,"updated":"2017-06-26 14:50:38.000000000","message":"nit: Could you insert a space before this, as this block isn\u0027t really related to the latter","commit_id":"7a1362e4af6f05a07dae35a4bea01eb6be92fa8e"},{"author":{"_account_id":15334,"name":"Stephen Finucane","display_name":"stephenfin","email":"stephenfin@redhat.com","username":"sfinucan"},"change_message_id":"9df35da822a8eb69d22ede584edb22c620031a71","unresolved":false,"context_lines":[{"line_number":1430,"context_line":""},{"line_number":1431,"context_line":"        if root_uuid is None:"},{"line_number":1432,"context_line":"            # TODO(jaypipes): Remove this once all resource provider records"},{"line_number":1433,"context_line":"            # have their root_provider_uuid field value set. (Pike)"},{"line_number":1434,"context_line":"            root_uuid \u003d uuid"},{"line_number":1435,"context_line":""},{"line_number":1436,"context_line":"        return root_uuid"}],"source_content_type":"text/x-python","patch_set":39,"id":"5f201791_89382da0","line":1433,"range":{"start_line":1433,"start_character":62,"end_line":1433,"end_character":66},"updated":"2017-06-26 14:50:38.000000000","message":"Queens","commit_id":"7a1362e4af6f05a07dae35a4bea01eb6be92fa8e"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"076e8b226cd2138681b677943f638d8c7625eb98","unresolved":false,"context_lines":[{"line_number":1275,"context_line":"                    context,"},{"line_number":1276,"context_line":"                    tree_uuid,"},{"line_number":1277,"context_line":"                )"},{"line_number":1278,"context_line":"            except exception.ResourceProviderNotFound:"},{"line_number":1279,"context_line":"                # List operations should simply return an empty list when a"},{"line_number":1280,"context_line":"                # non-existing resource provider UUID is given."},{"line_number":1281,"context_line":"                return []"},{"line_number":1282,"context_line":"            # TODO(jaypipes): Remove this OR condition when root_provider_uuid"},{"line_number":1283,"context_line":"            # is not nullable in the database and all resource provider records"},{"line_number":1284,"context_line":"            # have populated the root provider UUID."}],"source_content_type":"text/x-python","patch_set":40,"id":"9f436f4f_44398cf0","line":1281,"range":{"start_line":1278,"start_character":12,"end_line":1281,"end_character":25},"updated":"2017-08-17 17:10:01.000000000","message":"using exceptions as control flow is rarely a good pattern to use for this kind of error even in python. it might be better to extend _get_root_provider_uuid to take a default value when the resource is not found and then test if root \u003d\u003d [] and return if it is.","commit_id":"93cba8e2d8500a103f2f6ae36fbf85600ba5475c"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"076e8b226cd2138681b677943f638d8c7625eb98","unresolved":false,"context_lines":[{"line_number":1411,"context_line":"                                  objects.ResourceProvider, resource_providers)"},{"line_number":1412,"context_line":""},{"line_number":1413,"context_line":"    @staticmethod"},{"line_number":1414,"context_line":"    def _get_root_provider_uuid(ctx, uuid):"},{"line_number":1415,"context_line":"        \"\"\"Returns root_provider_uuid value of provider with supplied uuid."},{"line_number":1416,"context_line":""},{"line_number":1417,"context_line":"        :param uuid: UUID of the resource provider you wish to get the"}],"source_content_type":"text/x-python","patch_set":40,"id":"9f436f4f_a402780a","line":1414,"range":{"start_line":1414,"start_character":4,"end_line":1414,"end_character":43},"updated":"2017-08-17 17:10:01.000000000","message":"basically change this to  _get_root_provider_uuid(ctx, uuid, default\u003dNone):","commit_id":"93cba8e2d8500a103f2f6ae36fbf85600ba5475c"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"076e8b226cd2138681b677943f638d8c7625eb98","unresolved":false,"context_lines":[{"line_number":1425,"context_line":"                _RP_TBL.c.uuid \u003d\u003d uuid)"},{"line_number":1426,"context_line":"            res \u003d conn.execute(sel_stmt).fetchall()"},{"line_number":1427,"context_line":"            if not res:"},{"line_number":1428,"context_line":"                raise exception.ResourceProviderNotFound(uuid)"},{"line_number":1429,"context_line":"            root_uuid \u003d res[0][0]"},{"line_number":1430,"context_line":""},{"line_number":1431,"context_line":"        if root_uuid is None:"}],"source_content_type":"text/x-python","patch_set":40,"id":"9f436f4f_58072c1a","line":1428,"range":{"start_line":1428,"start_character":16,"end_line":1428,"end_character":62},"updated":"2017-08-17 17:10:01.000000000","message":"return default\n\nthen we don\u0027t need to introduce a new exception.","commit_id":"93cba8e2d8500a103f2f6ae36fbf85600ba5475c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"12e724035c3275bdcc1679a9c844dea6327d8c2f","unresolved":false,"context_lines":[{"line_number":1389,"context_line":"        return query.all()"},{"line_number":1390,"context_line":""},{"line_number":1391,"context_line":"    @classmethod"},{"line_number":1392,"context_line":"    # TODO(jaypipes): This needs to be a WRITER context, not a READER context"},{"line_number":1393,"context_line":"    # because the ResourceProvider._from_db_object() has an online data"},{"line_number":1394,"context_line":"    # migration in it to populate the root_provider_uuid value. Make this a"},{"line_number":1395,"context_line":"    # READER context once the online data migration is no longer necessary in"},{"line_number":1396,"context_line":"    # Pike."},{"line_number":1397,"context_line":"    @db_api.api_context_manager.writer"},{"line_number":1398,"context_line":"    def get_all_by_filters(cls, context, filters\u003dNone):"},{"line_number":1399,"context_line":"        \"\"\"Returns a list of `ResourceProvider` objects that have sufficient"},{"line_number":1400,"context_line":"        resources in their inventories to satisfy the amounts specified in the"}],"source_content_type":"text/x-python","patch_set":42,"id":"7f515b1d_1490244e","line":1397,"range":{"start_line":1392,"start_character":0,"end_line":1397,"end_character":38},"updated":"2017-09-25 13:44:13.000000000","message":"Do we already need this in the previous patch where the online data migration is introduced? I also feel like we missed it there because of missing test coverage.","commit_id":"4e711351bf1c83e4b7a0abb2ba4d8f48f75e5319"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"605596df39a35fd278b220beeb2ad6a6c2f31a7f","unresolved":false,"context_lines":[{"line_number":1389,"context_line":"        return query.all()"},{"line_number":1390,"context_line":""},{"line_number":1391,"context_line":"    @classmethod"},{"line_number":1392,"context_line":"    # TODO(jaypipes): This needs to be a WRITER context, not a READER context"},{"line_number":1393,"context_line":"    # because the ResourceProvider._from_db_object() has an online data"},{"line_number":1394,"context_line":"    # migration in it to populate the root_provider_uuid value. Make this a"},{"line_number":1395,"context_line":"    # READER context once the online data migration is no longer necessary in"},{"line_number":1396,"context_line":"    # Pike."},{"line_number":1397,"context_line":"    @db_api.api_context_manager.writer"},{"line_number":1398,"context_line":"    def get_all_by_filters(cls, context, filters\u003dNone):"},{"line_number":1399,"context_line":"        \"\"\"Returns a list of `ResourceProvider` objects that have sufficient"},{"line_number":1400,"context_line":"        resources in their inventories to satisfy the amounts specified in the"}],"source_content_type":"text/x-python","patch_set":42,"id":"7f515b1d_3a6730c0","line":1397,"range":{"start_line":1392,"start_character":0,"end_line":1397,"end_character":38},"in_reply_to":"7f515b1d_1490244e","updated":"2017-09-27 19:09:05.000000000","message":"possible. I\u0027ll look into it.","commit_id":"4e711351bf1c83e4b7a0abb2ba4d8f48f75e5319"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"12e724035c3275bdcc1679a9c844dea6327d8c2f","unresolved":false,"context_lines":[{"line_number":1417,"context_line":"                                  ResourceProvider, resource_providers)"},{"line_number":1418,"context_line":""},{"line_number":1419,"context_line":"    @staticmethod"},{"line_number":1420,"context_line":"    def _get_root_provider_uuid(ctx, uuid):"},{"line_number":1421,"context_line":"        \"\"\"Returns root_provider_uuid value of provider with supplied uuid."},{"line_number":1422,"context_line":""},{"line_number":1423,"context_line":"        :param uuid: UUID of the resource provider you wish to get the"}],"source_content_type":"text/x-python","patch_set":42,"id":"7f515b1d_b162823d","line":1420,"range":{"start_line":1420,"start_character":8,"end_line":1420,"end_character":31},"updated":"2017-09-25 13:44:13.000000000","message":"Having this static method on the ResourceProviderList is a bit strange. I think it more belongs to the ResourceProvider class. But it is a private method so it is more like a util than an interface method so I guess it is OK.","commit_id":"4e711351bf1c83e4b7a0abb2ba4d8f48f75e5319"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"605596df39a35fd278b220beeb2ad6a6c2f31a7f","unresolved":false,"context_lines":[{"line_number":1417,"context_line":"                                  ResourceProvider, resource_providers)"},{"line_number":1418,"context_line":""},{"line_number":1419,"context_line":"    @staticmethod"},{"line_number":1420,"context_line":"    def _get_root_provider_uuid(ctx, uuid):"},{"line_number":1421,"context_line":"        \"\"\"Returns root_provider_uuid value of provider with supplied uuid."},{"line_number":1422,"context_line":""},{"line_number":1423,"context_line":"        :param uuid: UUID of the resource provider you wish to get the"}],"source_content_type":"text/x-python","patch_set":42,"id":"7f515b1d_ba49e031","line":1420,"range":{"start_line":1420,"start_character":8,"end_line":1420,"end_character":31},"in_reply_to":"7f515b1d_b162823d","updated":"2017-09-27 19:09:05.000000000","message":"ack. I\u0027ll move it into a little util function in the module space.","commit_id":"4e711351bf1c83e4b7a0abb2ba4d8f48f75e5319"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"bcf35d2f965d9b543ca7836cabf8d4155d86adc6","unresolved":false,"context_lines":[{"line_number":1254,"context_line":"        #      \u0027resources\u0027: {"},{"line_number":1255,"context_line":"        #          \u0027VCPU\u0027: 1,"},{"line_number":1256,"context_line":"        #          \u0027MEMORY_MB\u0027: 1024"},{"line_number":1257,"context_line":"        #      }"},{"line_number":1258,"context_line":"        #  }"},{"line_number":1259,"context_line":"        if not filters:"},{"line_number":1260,"context_line":"            filters \u003d {}"}],"source_content_type":"text/x-python","patch_set":43,"id":"7f515b1d_65582487","line":1257,"updated":"2017-10-01 15:45:55.000000000","message":"add tree here for sake of completeness?","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"bf9533647be944d84d23316f240ed8599afe8a5a","unresolved":false,"context_lines":[{"line_number":1254,"context_line":"        #      \u0027resources\u0027: {"},{"line_number":1255,"context_line":"        #          \u0027VCPU\u0027: 1,"},{"line_number":1256,"context_line":"        #          \u0027MEMORY_MB\u0027: 1024"},{"line_number":1257,"context_line":"        #      }"},{"line_number":1258,"context_line":"        #  }"},{"line_number":1259,"context_line":"        if not filters:"},{"line_number":1260,"context_line":"            filters \u003d {}"}],"source_content_type":"text/x-python","patch_set":43,"id":"5f4e5783_3c70d272","line":1257,"in_reply_to":"7f515b1d_65582487","updated":"2017-10-10 15:47:33.000000000","message":"Done","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":25625,"name":"Tetsuro Nakamura","email":"tetsuro.nakamura.bc@hco.ntt.co.jp","username":"tetsuro0907"},"change_message_id":"98bcd13602569e4c676d2d7299c20afdd6370fbd","unresolved":false,"context_lines":[{"line_number":1277,"context_line":"        if uuid:"},{"line_number":1278,"context_line":"            query \u003d query.filter(models.ResourceProvider.uuid \u003d\u003d uuid)"},{"line_number":1279,"context_line":"        if \u0027tree\u0027 in filters:"},{"line_number":1280,"context_line":"            tree_uuid \u003d filters.pop(\u0027tree\u0027)"},{"line_number":1281,"context_line":"            try:"},{"line_number":1282,"context_line":"                root \u003d ResourceProviderList._get_root_provider_uuid("},{"line_number":1283,"context_line":"                    context,"}],"source_content_type":"text/x-python","patch_set":43,"id":"7f515b1d_d8f861c5","line":1280,"range":{"start_line":1280,"start_character":12,"end_line":1280,"end_character":21},"updated":"2017-10-06 08:27:12.000000000","message":"nit: due to my ignorance, but at first sight this confused me if there was a \"tree\" entity which has its own uuid.","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"bf9533647be944d84d23316f240ed8599afe8a5a","unresolved":false,"context_lines":[{"line_number":1277,"context_line":"        if uuid:"},{"line_number":1278,"context_line":"            query \u003d query.filter(models.ResourceProvider.uuid \u003d\u003d uuid)"},{"line_number":1279,"context_line":"        if \u0027tree\u0027 in filters:"},{"line_number":1280,"context_line":"            tree_uuid \u003d filters.pop(\u0027tree\u0027)"},{"line_number":1281,"context_line":"            try:"},{"line_number":1282,"context_line":"                root \u003d ResourceProviderList._get_root_provider_uuid("},{"line_number":1283,"context_line":"                    context,"}],"source_content_type":"text/x-python","patch_set":43,"id":"5f4e5783_dcb77ed8","line":1280,"range":{"start_line":1280,"start_character":12,"end_line":1280,"end_character":21},"in_reply_to":"7f515b1d_d8f861c5","updated":"2017-10-10 15:47:33.000000000","message":"Done. Added a comment explaining this section.","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"d23e59e64f6a7aac7bdd72b368c86cff7c3829a4","unresolved":false,"context_lines":[{"line_number":1282,"context_line":"                root \u003d ResourceProviderList._get_root_provider_uuid("},{"line_number":1283,"context_line":"                    context,"},{"line_number":1284,"context_line":"                    tree_uuid,"},{"line_number":1285,"context_line":"                )"},{"line_number":1286,"context_line":"            except exception.ResourceProviderNotFound:"},{"line_number":1287,"context_line":"                # List operations should simply return an empty list when a"},{"line_number":1288,"context_line":"                # non-existing resource provider UUID is given."}],"source_content_type":"text/x-python","patch_set":43,"id":"7f515b1d_f2ed23b7","line":1285,"updated":"2017-09-28 17:27:32.000000000","message":"Dangling paren.","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"bf9533647be944d84d23316f240ed8599afe8a5a","unresolved":false,"context_lines":[{"line_number":1282,"context_line":"                root \u003d ResourceProviderList._get_root_provider_uuid("},{"line_number":1283,"context_line":"                    context,"},{"line_number":1284,"context_line":"                    tree_uuid,"},{"line_number":1285,"context_line":"                )"},{"line_number":1286,"context_line":"            except exception.ResourceProviderNotFound:"},{"line_number":1287,"context_line":"                # List operations should simply return an empty list when a"},{"line_number":1288,"context_line":"                # non-existing resource provider UUID is given."}],"source_content_type":"text/x-python","patch_set":43,"id":"5f4e5783_1c02b6b5","line":1285,"in_reply_to":"7f515b1d_484c4641","updated":"2017-10-10 15:47:33.000000000","message":"Done","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"b403dddfc34af5b504702d3943b124e21bbd6ef1","unresolved":false,"context_lines":[{"line_number":1282,"context_line":"                root \u003d ResourceProviderList._get_root_provider_uuid("},{"line_number":1283,"context_line":"                    context,"},{"line_number":1284,"context_line":"                    tree_uuid,"},{"line_number":1285,"context_line":"                )"},{"line_number":1286,"context_line":"            except exception.ResourceProviderNotFound:"},{"line_number":1287,"context_line":"                # List operations should simply return an empty list when a"},{"line_number":1288,"context_line":"                # non-existing resource provider UUID is given."}],"source_content_type":"text/x-python","patch_set":43,"id":"7f515b1d_484c4641","line":1285,"in_reply_to":"7f515b1d_f2ed23b7","updated":"2017-09-28 18:47:47.000000000","message":"heh, this series predates my torturous acquiecience to the gods of paren dangling. You\u0027ll have to forgive me.","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"d23e59e64f6a7aac7bdd72b368c86cff7c3829a4","unresolved":false,"context_lines":[{"line_number":1289,"context_line":"                return []"},{"line_number":1290,"context_line":"            # TODO(jaypipes): Remove this OR condition when root_provider_uuid"},{"line_number":1291,"context_line":"            # is not nullable in the database and all resource provider records"},{"line_number":1292,"context_line":"            # have populated the root provider UUID."},{"line_number":1293,"context_line":"            where_cond \u003d sa.or_("},{"line_number":1294,"context_line":"                models.ResourceProvider.uuid \u003d\u003d root,"},{"line_number":1295,"context_line":"                models.ResourceProvider.root_provider_uuid \u003d\u003d root,"}],"source_content_type":"text/x-python","patch_set":43,"id":"7f515b1d_92326f5d","line":1292,"updated":"2017-09-28 17:27:32.000000000","message":"I assume somewhere in this process we\u0027ll heal those up?","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"b403dddfc34af5b504702d3943b124e21bbd6ef1","unresolved":false,"context_lines":[{"line_number":1289,"context_line":"                return []"},{"line_number":1290,"context_line":"            # TODO(jaypipes): Remove this OR condition when root_provider_uuid"},{"line_number":1291,"context_line":"            # is not nullable in the database and all resource provider records"},{"line_number":1292,"context_line":"            # have populated the root provider UUID."},{"line_number":1293,"context_line":"            where_cond \u003d sa.or_("},{"line_number":1294,"context_line":"                models.ResourceProvider.uuid \u003d\u003d root,"},{"line_number":1295,"context_line":"                models.ResourceProvider.root_provider_uuid \u003d\u003d root,"}],"source_content_type":"text/x-python","patch_set":43,"id":"7f515b1d_28490a30","line":1292,"in_reply_to":"7f515b1d_92326f5d","updated":"2017-09-28 18:47:47.000000000","message":"yeah, once I add the data migration stopper patch.","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"d23e59e64f6a7aac7bdd72b368c86cff7c3829a4","unresolved":false,"context_lines":[{"line_number":1293,"context_line":"            where_cond \u003d sa.or_("},{"line_number":1294,"context_line":"                models.ResourceProvider.uuid \u003d\u003d root,"},{"line_number":1295,"context_line":"                models.ResourceProvider.root_provider_uuid \u003d\u003d root,"},{"line_number":1296,"context_line":"            )"},{"line_number":1297,"context_line":"            query \u003d query.filter(where_cond)"},{"line_number":1298,"context_line":""},{"line_number":1299,"context_line":"        # If \u0027member_of\u0027 has values join with the PlacementAggregates to"}],"source_content_type":"text/x-python","patch_set":43,"id":"7f515b1d_92802fc1","line":1296,"updated":"2017-09-28 17:27:32.000000000","message":"DANGLING PAREN.","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"bf9533647be944d84d23316f240ed8599afe8a5a","unresolved":false,"context_lines":[{"line_number":1293,"context_line":"            where_cond \u003d sa.or_("},{"line_number":1294,"context_line":"                models.ResourceProvider.uuid \u003d\u003d root,"},{"line_number":1295,"context_line":"                models.ResourceProvider.root_provider_uuid \u003d\u003d root,"},{"line_number":1296,"context_line":"            )"},{"line_number":1297,"context_line":"            query \u003d query.filter(where_cond)"},{"line_number":1298,"context_line":""},{"line_number":1299,"context_line":"        # If \u0027member_of\u0027 has values join with the PlacementAggregates to"}],"source_content_type":"text/x-python","patch_set":43,"id":"5f4e5783_fcfebaac","line":1296,"in_reply_to":"7f515b1d_92802fc1","updated":"2017-10-10 15:47:33.000000000","message":"Done","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"d23e59e64f6a7aac7bdd72b368c86cff7c3829a4","unresolved":false,"context_lines":[{"line_number":1392,"context_line":""},{"line_number":1393,"context_line":"    @classmethod"},{"line_number":1394,"context_line":"    # TODO(jaypipes): This needs to be a WRITER context, not a READER context"},{"line_number":1395,"context_line":"    # because the ResourceProvider._from_db_object() has an online data"},{"line_number":1396,"context_line":"    # migration in it to populate the root_provider_uuid value. Make this a"},{"line_number":1397,"context_line":"    # READER context once the online data migration is no longer necessary in"},{"line_number":1398,"context_line":"    # Pike."}],"source_content_type":"text/x-python","patch_set":43,"id":"7f515b1d_f21be3c6","line":1395,"updated":"2017-09-28 17:27:32.000000000","message":"Hmm, and because the object remains linked to the session we get in the decorator? I wonder if it wouldn\u0027t be easier to just have a method to stab the parent into a RP row via id that has the writer on it. Then we can just remove that later when we need to.","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"b403dddfc34af5b504702d3943b124e21bbd6ef1","unresolved":false,"context_lines":[{"line_number":1392,"context_line":""},{"line_number":1393,"context_line":"    @classmethod"},{"line_number":1394,"context_line":"    # TODO(jaypipes): This needs to be a WRITER context, not a READER context"},{"line_number":1395,"context_line":"    # because the ResourceProvider._from_db_object() has an online data"},{"line_number":1396,"context_line":"    # migration in it to populate the root_provider_uuid value. Make this a"},{"line_number":1397,"context_line":"    # READER context once the online data migration is no longer necessary in"},{"line_number":1398,"context_line":"    # Pike."}],"source_content_type":"text/x-python","patch_set":43,"id":"7f515b1d_48756663","line":1395,"in_reply_to":"7f515b1d_f21be3c6","updated":"2017-09-28 18:47:47.000000000","message":"I\u0027m reworking this in an earlier patch so this is prolly gonna go bye bye.","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"96c4536107b6fcc2f9602bed5dc087a957d50929","unresolved":false,"context_lines":[{"line_number":1419,"context_line":"                                  ResourceProvider, resource_providers)"},{"line_number":1420,"context_line":""},{"line_number":1421,"context_line":"    @staticmethod"},{"line_number":1422,"context_line":"    def _get_root_provider_uuid(ctx, uuid):"},{"line_number":1423,"context_line":"        \"\"\"Returns root_provider_uuid value of provider with supplied uuid."},{"line_number":1424,"context_line":""},{"line_number":1425,"context_line":"        :param uuid: UUID of the resource provider you wish to get the"}],"source_content_type":"text/x-python","patch_set":43,"id":"7f515b1d_deb6498b","line":1422,"range":{"start_line":1422,"start_character":8,"end_line":1422,"end_character":31},"updated":"2017-10-04 16:31:22.000000000","message":"IMO, this should replace _root_provider_uuid_from_parent (L392, introduced in the previous patch) - see comments there.  In any case, we don\u0027t need both methods.","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"bf9533647be944d84d23316f240ed8599afe8a5a","unresolved":false,"context_lines":[{"line_number":1419,"context_line":"                                  ResourceProvider, resource_providers)"},{"line_number":1420,"context_line":""},{"line_number":1421,"context_line":"    @staticmethod"},{"line_number":1422,"context_line":"    def _get_root_provider_uuid(ctx, uuid):"},{"line_number":1423,"context_line":"        \"\"\"Returns root_provider_uuid value of provider with supplied uuid."},{"line_number":1424,"context_line":""},{"line_number":1425,"context_line":"        :param uuid: UUID of the resource provider you wish to get the"}],"source_content_type":"text/x-python","patch_set":43,"id":"5f4e5783_3c69f224","line":1422,"range":{"start_line":1422,"start_character":8,"end_line":1422,"end_character":31},"in_reply_to":"7f515b1d_deb6498b","updated":"2017-10-10 15:47:33.000000000","message":"This method is gone in the latest rev.","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"96c4536107b6fcc2f9602bed5dc087a957d50929","unresolved":false,"context_lines":[{"line_number":1433,"context_line":"                _RP_TBL.c.uuid \u003d\u003d uuid)"},{"line_number":1434,"context_line":"            res \u003d conn.execute(sel_stmt).fetchall()"},{"line_number":1435,"context_line":"            if not res:"},{"line_number":1436,"context_line":"                raise exception.ResourceProviderNotFound(uuid)"},{"line_number":1437,"context_line":"            root_uuid \u003d res[0][0]"},{"line_number":1438,"context_line":""},{"line_number":1439,"context_line":"        if root_uuid is None:"}],"source_content_type":"text/x-python","patch_set":43,"id":"7f515b1d_d97c2374","line":1436,"range":{"start_line":1436,"start_character":32,"end_line":1436,"end_character":56},"updated":"2017-10-04 16:31:22.000000000","message":"Do we need this?  It\u0027s being ignored in the current usage.  Save a delta in exception.py","commit_id":"533f0d46875c8eb46e82f65579813d063889132e"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"8207fbdcfaf0e0a5d1ceeeeca5f6589f9d331d05","unresolved":false,"context_lines":[{"line_number":1272,"context_line":"        # resource providers for this resource class"},{"line_number":1273,"context_line":"        joiner \u003d sa.join"},{"line_number":1274,"context_line":"        if sps:"},{"line_number":1275,"context_line":"            joiner \u003d sa.outerjoin"},{"line_number":1276,"context_line":"        # Add a join condition winnowing this copy of inventories table"},{"line_number":1277,"context_line":"        # to only the resource class being analyzed in this loop..."},{"line_number":1278,"context_line":"        inv_join \u003d joiner(rp_link, it,"}],"source_content_type":"text/x-python","patch_set":48,"id":"5f4e5783_decee42b","line":1275,"updated":"2017-10-13 17:35:24.000000000","message":"all the formatting cleanup between here and 1314 appears unrelated to adding the \u0027tree\u0027 functionality.\n\nAnd while I\u0027m sure many people will cheer with joy about this change, this doesn\u0027t seem like it is the right place for it.","commit_id":"1e5c67d9ecc5d741859285aa1db4b62b17bd847b"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"208714fe3a90057b80dd371f97389153068bd92b","unresolved":false,"context_lines":[{"line_number":1272,"context_line":"        # resource providers for this resource class"},{"line_number":1273,"context_line":"        joiner \u003d sa.join"},{"line_number":1274,"context_line":"        if sps:"},{"line_number":1275,"context_line":"            joiner \u003d sa.outerjoin"},{"line_number":1276,"context_line":"        # Add a join condition winnowing this copy of inventories table"},{"line_number":1277,"context_line":"        # to only the resource class being analyzed in this loop..."},{"line_number":1278,"context_line":"        inv_join \u003d joiner(rp_link, it,"}],"source_content_type":"text/x-python","patch_set":48,"id":"5f4e5783_63d94320","line":1275,"in_reply_to":"5f4e5783_decee42b","updated":"2017-10-17 19:21:00.000000000","message":"Done, moved to https://review.openstack.org/512799","commit_id":"1e5c67d9ecc5d741859285aa1db4b62b17bd847b"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"48541a6eedd79928fe96e24d2ffcf8d01fce055d","unresolved":false,"context_lines":[{"line_number":1518,"context_line":"    # because the ResourceProvider._from_db_object() has an online data"},{"line_number":1519,"context_line":"    # migration in it to populate the root_provider_id value. Make this a"},{"line_number":1520,"context_line":"    # READER context once the online data migration is no longer necessary in"},{"line_number":1521,"context_line":"    # Pike."},{"line_number":1522,"context_line":"    @db_api.api_context_manager.writer"},{"line_number":1523,"context_line":"    def get_all_by_filters(cls, context, filters\u003dNone):"},{"line_number":1524,"context_line":"        \"\"\"Returns a list of `ResourceProvider` objects that have sufficient"}],"source_content_type":"text/x-python","patch_set":52,"id":"3f4b6375_3651dd63","line":1521,"updated":"2017-10-20 12:20:12.000000000","message":"The previous patch added the online data migration and in that patch the _from_db_object() has a WRITER decorator. Do we still need the WRITER decorator here? If yes then I think this needs to be done in the previous patch","commit_id":"6dddbe0bf5a89a4d0fd6925a3a640f446ac4088c"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"522e15525c5ab9afba77de242dee391d47cb5f85","unresolved":false,"context_lines":[{"line_number":1518,"context_line":"    # because the ResourceProvider._from_db_object() has an online data"},{"line_number":1519,"context_line":"    # migration in it to populate the root_provider_id value. Make this a"},{"line_number":1520,"context_line":"    # READER context once the online data migration is no longer necessary in"},{"line_number":1521,"context_line":"    # Pike."},{"line_number":1522,"context_line":"    @db_api.api_context_manager.writer"},{"line_number":1523,"context_line":"    def get_all_by_filters(cls, context, filters\u003dNone):"},{"line_number":1524,"context_line":"        \"\"\"Returns a list of `ResourceProvider` objects that have sufficient"}],"source_content_type":"text/x-python","patch_set":52,"id":"3f4b6375_e24c9f9f","line":1521,"in_reply_to":"3f4b6375_02e0db95","updated":"2017-10-20 21:12:53.000000000","message":"Yeah, sorry, I should have removed this decorator since the writer context is on the _from_db_obj method... will fix up.","commit_id":"6dddbe0bf5a89a4d0fd6925a3a640f446ac4088c"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"b7c1c1af3383d6f88d24946e73b8a055f9b17ac1","unresolved":false,"context_lines":[{"line_number":1518,"context_line":"    # because the ResourceProvider._from_db_object() has an online data"},{"line_number":1519,"context_line":"    # migration in it to populate the root_provider_id value. Make this a"},{"line_number":1520,"context_line":"    # READER context once the online data migration is no longer necessary in"},{"line_number":1521,"context_line":"    # Pike."},{"line_number":1522,"context_line":"    @db_api.api_context_manager.writer"},{"line_number":1523,"context_line":"    def get_all_by_filters(cls, context, filters\u003dNone):"},{"line_number":1524,"context_line":"        \"\"\"Returns a list of `ResourceProvider` objects that have sufficient"}],"source_content_type":"text/x-python","patch_set":52,"id":"3f4b6375_87a85ddb","line":1521,"in_reply_to":"3f4b6375_3651dd63","updated":"2017-10-20 13:55:38.000000000","message":"No, I actually still need to write the nova-manage online data migration. The previous patch added the single-object in-line data migration on the object getter/setters, but did not add a nova-manage command to read all resource providers from placement in batches (thereby updating the new fields).","commit_id":"6dddbe0bf5a89a4d0fd6925a3a640f446ac4088c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"7457df59c36f83a7d394a6def13c8a6ec2352462","unresolved":false,"context_lines":[{"line_number":1518,"context_line":"    # because the ResourceProvider._from_db_object() has an online data"},{"line_number":1519,"context_line":"    # migration in it to populate the root_provider_id value. Make this a"},{"line_number":1520,"context_line":"    # READER context once the online data migration is no longer necessary in"},{"line_number":1521,"context_line":"    # Pike."},{"line_number":1522,"context_line":"    @db_api.api_context_manager.writer"},{"line_number":1523,"context_line":"    def get_all_by_filters(cls, context, filters\u003dNone):"},{"line_number":1524,"context_line":"        \"\"\"Returns a list of `ResourceProvider` objects that have sufficient"}],"source_content_type":"text/x-python","patch_set":52,"id":"3f4b6375_02e0db95","line":1521,"in_reply_to":"3f4b6375_87a85ddb","updated":"2017-10-20 14:47:06.000000000","message":"Then, does the WRITER context needed here only when you add  that nova-manage command? \nIn that case having the WRITER context added here does not cause any direct problem just seems a bit unrelated to this patch.","commit_id":"6dddbe0bf5a89a4d0fd6925a3a640f446ac4088c"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"7f8e1ca85287811a65f79524a9c5967a2c4ba72d","unresolved":false,"context_lines":[{"line_number":1453,"context_line":"                # List operations should simply return an empty list when a"},{"line_number":1454,"context_line":"                # non-existing resource provider UUID is given."},{"line_number":1455,"context_line":"                return []"},{"line_number":1456,"context_line":"            root_id \u003d tree_ids.root_id"},{"line_number":1457,"context_line":"            # TODO(jaypipes): Remove this OR condition when root_provider_id"},{"line_number":1458,"context_line":"            # is not nullable in the database and all resource provider records"},{"line_number":1459,"context_line":"            # have populated the root provider ID."},{"line_number":1460,"context_line":"            where_cond \u003d sa.or_(rp.c.id \u003d\u003d root_id,"},{"line_number":1461,"context_line":"                rp.c.root_provider_id \u003d\u003d root_id)"},{"line_number":1462,"context_line":"            query \u003d query.where(where_cond)"}],"source_content_type":"text/x-python","patch_set":58,"id":"3f4b6375_a66af816","line":1459,"range":{"start_line":1456,"start_character":0,"end_line":1459,"end_character":50},"updated":"2017-11-02 13:57:34.000000000","message":"Yeah, or if _provider_ids_from_uuid did that coalesce()...","commit_id":"9142983bfe2ec913647914ae025117f65bcc7f3d"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"e93b08549d82909c4103693f102e37fca407360f","unresolved":false,"context_lines":[{"line_number":1466,"context_line":"            query \u003d query.where(rp.c.name \u003d\u003d name)"},{"line_number":1467,"context_line":"        if uuid:"},{"line_number":1468,"context_line":"            query \u003d query.where(rp.c.uuid \u003d\u003d uuid)"},{"line_number":1469,"context_line":"        if \u0027tree\u0027 in filters:"},{"line_number":1470,"context_line":"            # The \u0027tree\u0027 parameter is the UUID of a resource provider that the"},{"line_number":1471,"context_line":"            # caller wants to limit the returned providers to only those within"},{"line_number":1472,"context_line":"            # its \"provider tree\". So, we look up the resource provider having"},{"line_number":1473,"context_line":"            # the UUID specified by the \u0027tree\u0027 parameter and grab the"},{"line_number":1474,"context_line":"            # root_provider_id value of that record. We can then ask for only"},{"line_number":1475,"context_line":"            # those resource providers having a root_provider_id of that value."},{"line_number":1476,"context_line":"            tree_uuid \u003d filters.pop(\u0027tree\u0027)"},{"line_number":1477,"context_line":"            tree_ids \u003d _provider_ids_from_uuid(context, tree_uuid)"},{"line_number":1478,"context_line":"            if tree_ids is None:"},{"line_number":1479,"context_line":"                # List operations should simply return an empty list when a"},{"line_number":1480,"context_line":"                # non-existing resource provider UUID is given."},{"line_number":1481,"context_line":"                return []"},{"line_number":1482,"context_line":"            root_id \u003d tree_ids.root_id"},{"line_number":1483,"context_line":"            # TODO(jaypipes): Remove this OR condition when root_provider_id"},{"line_number":1484,"context_line":"            # is not nullable in the database and all resource provider records"},{"line_number":1485,"context_line":"            # have populated the root provider ID."},{"line_number":1486,"context_line":"            where_cond \u003d sa.or_(rp.c.id \u003d\u003d root_id,"},{"line_number":1487,"context_line":"                rp.c.root_provider_id \u003d\u003d root_id)"},{"line_number":1488,"context_line":"            query \u003d query.where(where_cond)"},{"line_number":1489,"context_line":""},{"line_number":1490,"context_line":"        # If \u0027member_of\u0027 has values join with the PlacementAggregates to"},{"line_number":1491,"context_line":"        # get those resource providers that are associated with any of the"}],"source_content_type":"text/x-python","patch_set":65,"id":"df87a7cf_976c5837","line":1488,"range":{"start_line":1469,"start_character":8,"end_line":1488,"end_character":43},"updated":"2017-12-04 08:17:56.000000000","message":"The SQL for filtering a tree looks good. But I don\u0027t think the tree filter will work well with \u0027member_of\u0027 and \u0027resources\u0027 filtering.\n\nSo I think we should deny the user to do that? I also didn\u0027t found we deny that from the API layer https://review.openstack.org/#/c/384807.","commit_id":"d2d264ee53a5aeafb5896f3b64cc43658496538a"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"7cf73001d296341931f7fd05c5cd78cad6a01221","unresolved":false,"context_lines":[{"line_number":1466,"context_line":"            query \u003d query.where(rp.c.name \u003d\u003d name)"},{"line_number":1467,"context_line":"        if uuid:"},{"line_number":1468,"context_line":"            query \u003d query.where(rp.c.uuid \u003d\u003d uuid)"},{"line_number":1469,"context_line":"        if \u0027tree\u0027 in filters:"},{"line_number":1470,"context_line":"            # The \u0027tree\u0027 parameter is the UUID of a resource provider that the"},{"line_number":1471,"context_line":"            # caller wants to limit the returned providers to only those within"},{"line_number":1472,"context_line":"            # its \"provider tree\". So, we look up the resource provider having"},{"line_number":1473,"context_line":"            # the UUID specified by the \u0027tree\u0027 parameter and grab the"},{"line_number":1474,"context_line":"            # root_provider_id value of that record. We can then ask for only"},{"line_number":1475,"context_line":"            # those resource providers having a root_provider_id of that value."},{"line_number":1476,"context_line":"            tree_uuid \u003d filters.pop(\u0027tree\u0027)"},{"line_number":1477,"context_line":"            tree_ids \u003d _provider_ids_from_uuid(context, tree_uuid)"},{"line_number":1478,"context_line":"            if tree_ids is None:"},{"line_number":1479,"context_line":"                # List operations should simply return an empty list when a"},{"line_number":1480,"context_line":"                # non-existing resource provider UUID is given."},{"line_number":1481,"context_line":"                return []"},{"line_number":1482,"context_line":"            root_id \u003d tree_ids.root_id"},{"line_number":1483,"context_line":"            # TODO(jaypipes): Remove this OR condition when root_provider_id"},{"line_number":1484,"context_line":"            # is not nullable in the database and all resource provider records"},{"line_number":1485,"context_line":"            # have populated the root provider ID."},{"line_number":1486,"context_line":"            where_cond \u003d sa.or_(rp.c.id \u003d\u003d root_id,"},{"line_number":1487,"context_line":"                rp.c.root_provider_id \u003d\u003d root_id)"},{"line_number":1488,"context_line":"            query \u003d query.where(where_cond)"},{"line_number":1489,"context_line":""},{"line_number":1490,"context_line":"        # If \u0027member_of\u0027 has values join with the PlacementAggregates to"},{"line_number":1491,"context_line":"        # get those resource providers that are associated with any of the"}],"source_content_type":"text/x-python","patch_set":65,"id":"df87a7cf_8b91879c","line":1488,"range":{"start_line":1469,"start_character":8,"end_line":1488,"end_character":43},"in_reply_to":"df87a7cf_6ba2049d","updated":"2017-12-04 14:45:40.000000000","message":"I concur.\n\nUsing \u0027tree\u0027 with resource filters is definitely needed.  Consider a setup where I\u0027ve got e.g. multiple SR-IOV PFs and I want to get my VFs from any of them: ?tree\u003d{compute_rp}\u0026resources\u003dSRIOV_NET_VF:1\n\nIf you were to use both \u0027uuid\u0027 and \u0027tree\u0027, you\u0027ll get zero results if the \u0027uuid\u0027 isn\u0027t a member of the nested tree; and one result if it is.\n\nIf you use \u0027tree\u0027 with \u0027member_of\u0027, you ought to get only those providers in the tree which are *also* members of the specified aggregate.\n\nI don\u0027t see any discrepancies here.","commit_id":"d2d264ee53a5aeafb5896f3b64cc43658496538a"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"dd6fb4f15c374798530869ef0e0fd4b65e61fc9a","unresolved":false,"context_lines":[{"line_number":1466,"context_line":"            query \u003d query.where(rp.c.name \u003d\u003d name)"},{"line_number":1467,"context_line":"        if uuid:"},{"line_number":1468,"context_line":"            query \u003d query.where(rp.c.uuid \u003d\u003d uuid)"},{"line_number":1469,"context_line":"        if \u0027tree\u0027 in filters:"},{"line_number":1470,"context_line":"            # The \u0027tree\u0027 parameter is the UUID of a resource provider that the"},{"line_number":1471,"context_line":"            # caller wants to limit the returned providers to only those within"},{"line_number":1472,"context_line":"            # its \"provider tree\". So, we look up the resource provider having"},{"line_number":1473,"context_line":"            # the UUID specified by the \u0027tree\u0027 parameter and grab the"},{"line_number":1474,"context_line":"            # root_provider_id value of that record. We can then ask for only"},{"line_number":1475,"context_line":"            # those resource providers having a root_provider_id of that value."},{"line_number":1476,"context_line":"            tree_uuid \u003d filters.pop(\u0027tree\u0027)"},{"line_number":1477,"context_line":"            tree_ids \u003d _provider_ids_from_uuid(context, tree_uuid)"},{"line_number":1478,"context_line":"            if tree_ids is None:"},{"line_number":1479,"context_line":"                # List operations should simply return an empty list when a"},{"line_number":1480,"context_line":"                # non-existing resource provider UUID is given."},{"line_number":1481,"context_line":"                return []"},{"line_number":1482,"context_line":"            root_id \u003d tree_ids.root_id"},{"line_number":1483,"context_line":"            # TODO(jaypipes): Remove this OR condition when root_provider_id"},{"line_number":1484,"context_line":"            # is not nullable in the database and all resource provider records"},{"line_number":1485,"context_line":"            # have populated the root provider ID."},{"line_number":1486,"context_line":"            where_cond \u003d sa.or_(rp.c.id \u003d\u003d root_id,"},{"line_number":1487,"context_line":"                rp.c.root_provider_id \u003d\u003d root_id)"},{"line_number":1488,"context_line":"            query \u003d query.where(where_cond)"},{"line_number":1489,"context_line":""},{"line_number":1490,"context_line":"        # If \u0027member_of\u0027 has values join with the PlacementAggregates to"},{"line_number":1491,"context_line":"        # get those resource providers that are associated with any of the"}],"source_content_type":"text/x-python","patch_set":65,"id":"df87a7cf_6ba2049d","line":1488,"range":{"start_line":1469,"start_character":8,"end_line":1488,"end_character":43},"in_reply_to":"df87a7cf_976c5837","updated":"2017-12-04 14:13:44.000000000","message":"I don\u0027t believe the uuid and tree filters are in opposition to each other. The uuid filter removes providers that don\u0027t match a specific UUID whereas the tree filter removes providers not in a specific root provider UUID.\n\nAs for member_of, that\u0027s entirely different since that looks at aggregates, not provider trees.","commit_id":"d2d264ee53a5aeafb5896f3b64cc43658496538a"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"ac78fe4d6522ab53fd5a9fe74d15469e60e8ec53","unresolved":false,"context_lines":[{"line_number":1466,"context_line":"            query \u003d query.where(rp.c.name \u003d\u003d name)"},{"line_number":1467,"context_line":"        if uuid:"},{"line_number":1468,"context_line":"            query \u003d query.where(rp.c.uuid \u003d\u003d uuid)"},{"line_number":1469,"context_line":"        if \u0027tree\u0027 in filters:"},{"line_number":1470,"context_line":"            # The \u0027tree\u0027 parameter is the UUID of a resource provider that the"},{"line_number":1471,"context_line":"            # caller wants to limit the returned providers to only those within"},{"line_number":1472,"context_line":"            # its \"provider tree\". So, we look up the resource provider having"},{"line_number":1473,"context_line":"            # the UUID specified by the \u0027tree\u0027 parameter and grab the"},{"line_number":1474,"context_line":"            # root_provider_id value of that record. We can then ask for only"},{"line_number":1475,"context_line":"            # those resource providers having a root_provider_id of that value."},{"line_number":1476,"context_line":"            tree_uuid \u003d filters.pop(\u0027tree\u0027)"},{"line_number":1477,"context_line":"            tree_ids \u003d _provider_ids_from_uuid(context, tree_uuid)"},{"line_number":1478,"context_line":"            if tree_ids is None:"},{"line_number":1479,"context_line":"                # List operations should simply return an empty list when a"},{"line_number":1480,"context_line":"                # non-existing resource provider UUID is given."},{"line_number":1481,"context_line":"                return []"},{"line_number":1482,"context_line":"            root_id \u003d tree_ids.root_id"},{"line_number":1483,"context_line":"            # TODO(jaypipes): Remove this OR condition when root_provider_id"},{"line_number":1484,"context_line":"            # is not nullable in the database and all resource provider records"},{"line_number":1485,"context_line":"            # have populated the root provider ID."},{"line_number":1486,"context_line":"            where_cond \u003d sa.or_(rp.c.id \u003d\u003d root_id,"},{"line_number":1487,"context_line":"                rp.c.root_provider_id \u003d\u003d root_id)"},{"line_number":1488,"context_line":"            query \u003d query.where(where_cond)"},{"line_number":1489,"context_line":""},{"line_number":1490,"context_line":"        # If \u0027member_of\u0027 has values join with the PlacementAggregates to"},{"line_number":1491,"context_line":"        # get those resource providers that are associated with any of the"}],"source_content_type":"text/x-python","patch_set":65,"id":"df87a7cf_a9d01ccb","line":1488,"range":{"start_line":1469,"start_character":8,"end_line":1488,"end_character":43},"in_reply_to":"df87a7cf_976c5837","updated":"2017-12-04 10:17:55.000000000","message":"Yup, I agree with Alex, I think we should probably use member_of for verifying if it\u0027s in a tree (and probably use a separate key for saying it\u0027s for a root RP)","commit_id":"d2d264ee53a5aeafb5896f3b64cc43658496538a"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"eb07fbadfd89184d9254c94554629057644ad521","unresolved":false,"context_lines":[{"line_number":1412,"context_line":"        #          \u0027VCPU\u0027: 1,"},{"line_number":1413,"context_line":"        #          \u0027MEMORY_MB\u0027: 1024"},{"line_number":1414,"context_line":"        #      },"},{"line_number":1415,"context_line":"        #      \u0027tree\u0027: \u003cuuid\u003e,"},{"line_number":1416,"context_line":"        #  }"},{"line_number":1417,"context_line":"        if not filters:"},{"line_number":1418,"context_line":"            filters \u003d {}"}],"source_content_type":"text/x-python","patch_set":71,"id":"df87a7cf_2af7dff7","line":1415,"range":{"start_line":1415,"start_character":15,"end_line":1415,"end_character":22},"updated":"2017-12-06 08:37:51.000000000","message":"I don\u0027t want to overthink of the naming here, but looks like \u0027tree\u0027 is maybe a bit confusing.\nSince we want to return for a specific UUID the tree of all RPs having the same root RP than the specific UUID, it\u0027s more a \u0027tree_node\u0027 that we ask.","commit_id":"65205fdaa731d82e6393f5a9346ab91945d37fb1"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"eb07fbadfd89184d9254c94554629057644ad521","unresolved":false,"context_lines":[{"line_number":1474,"context_line":"            # have populated the root provider ID."},{"line_number":1475,"context_line":"            where_cond \u003d sa.or_(rp.c.id \u003d\u003d root_id,"},{"line_number":1476,"context_line":"                rp.c.root_provider_id \u003d\u003d root_id)"},{"line_number":1477,"context_line":"            query \u003d query.where(where_cond)"},{"line_number":1478,"context_line":""},{"line_number":1479,"context_line":"        # If \u0027member_of\u0027 has values join with the PlacementAggregates to"},{"line_number":1480,"context_line":"        # get those resource providers that are associated with any of the"}],"source_content_type":"text/x-python","patch_set":71,"id":"df87a7cf_8ae70b41","line":1477,"updated":"2017-12-06 08:37:51.000000000","message":"the SQL query looks good to me.","commit_id":"65205fdaa731d82e6393f5a9346ab91945d37fb1"}],"nova/tests/functional/db/test_resource_provider.py":[{"author":{"_account_id":12171,"name":"Moshe Levi","email":"moshele@nvidia.com","username":"moshele"},"change_message_id":"b095260a0450973ee2f73675c574d4c95279c9a5","unresolved":false,"context_lines":[{"line_number":721,"context_line":"        self.useFixture(fixtures.Database(database\u003d\u0027api\u0027))"},{"line_number":722,"context_line":"        self.context \u003d context.RequestContext(\u0027fake-user\u0027, \u0027fake-project\u0027)"},{"line_number":723,"context_line":""},{"line_number":724,"context_line":"    def test_get_all_by_filters(self):"},{"line_number":725,"context_line":"        for rp_i in [\u00271\u0027, \u00272\u0027]:"},{"line_number":726,"context_line":"            uuid \u003d getattr(uuidsentinel, \u0027rp_uuid_\u0027 + rp_i)"},{"line_number":727,"context_line":"            name \u003d \u0027rp_name_\u0027 + rp_i"}],"source_content_type":"text/x-python","patch_set":18,"id":"7a77a97e_b0cda188","line":724,"range":{"start_line":724,"start_character":4,"end_line":724,"end_character":38},"updated":"2016-11-22 02:05:48.000000000","message":"missing test for tree filter","commit_id":"c8e413a9ce461f3d576dacf6dcc8b612dd79c11f"},{"author":{"_account_id":12171,"name":"Moshe Levi","email":"moshele@nvidia.com","username":"moshele"},"change_message_id":"3a4c682ef99359a286ebce4940802b91e6e878fc","unresolved":false,"context_lines":[{"line_number":721,"context_line":"        self.useFixture(fixtures.Database(database\u003d\u0027api\u0027))"},{"line_number":722,"context_line":"        self.context \u003d context.RequestContext(\u0027fake-user\u0027, \u0027fake-project\u0027)"},{"line_number":723,"context_line":""},{"line_number":724,"context_line":"    def test_get_all_by_filters(self):"},{"line_number":725,"context_line":"        for rp_i in [\u00271\u0027, \u00272\u0027]:"},{"line_number":726,"context_line":"            uuid \u003d getattr(uuidsentinel, \u0027rp_uuid_\u0027 + rp_i)"},{"line_number":727,"context_line":"            name \u003d \u0027rp_name_\u0027 + rp_i"}],"source_content_type":"text/x-python","patch_set":18,"id":"7a77a97e_a68807c8","line":724,"range":{"start_line":724,"start_character":4,"end_line":724,"end_character":38},"in_reply_to":"7a77a97e_b0cda188","updated":"2016-11-22 03:21:22.000000000","message":"nevermind I see it covered","commit_id":"c8e413a9ce461f3d576dacf6dcc8b612dd79c11f"},{"author":{"_account_id":14614,"name":"Kyrylo Romanenko","display_name":"K.Romanenko","email":"romanenko-kv@hotmail.com","username":"kromanenko"},"change_message_id":"f8c38a6b223d98e0eda1d685bbe580ff77d026ef","unresolved":false,"context_lines":[{"line_number":292,"context_line":"        self.assertEqual(3, len(rps))"},{"line_number":293,"context_line":""},{"line_number":294,"context_line":"    def test_get_all_in_tree_old_records(self):"},{"line_number":295,"context_line":"        \"\"\"Simulate an old resource provider record in the database that has no"},{"line_number":296,"context_line":"        root_provider_uuid set and ensure that when selecting all providers in"},{"line_number":297,"context_line":"        a tree, passing in that old resource provider, that we still get that"},{"line_number":298,"context_line":"        provider returned."}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_6db1eb46","line":295,"range":{"start_line":295,"start_character":11,"end_line":295,"end_character":79},"updated":"2016-12-15 16:30:55.000000000","message":"First line of docstring should be one-lined.\nThen empty line. And then multi-line part.","commit_id":"40851810056ea96537050bdec2f77dad8a42ac13"},{"author":{"_account_id":13692,"name":"Roman Dobosz","email":"gryf73@gmail.com","username":"gryf"},"change_message_id":"7225e547365344aefde51eefc002a648ee6bdfb1","unresolved":false,"context_lines":[{"line_number":292,"context_line":"        self.assertEqual(3, len(rps))"},{"line_number":293,"context_line":""},{"line_number":294,"context_line":"    def test_get_all_in_tree_old_records(self):"},{"line_number":295,"context_line":"        \"\"\"Simulate an old resource provider record in the database that has no"},{"line_number":296,"context_line":"        root_provider_uuid set and ensure that when selecting all providers in"},{"line_number":297,"context_line":"        a tree, passing in that old resource provider, that we still get that"},{"line_number":298,"context_line":"        provider returned."}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_8ecd5d87","line":295,"range":{"start_line":295,"start_character":11,"end_line":295,"end_character":79},"in_reply_to":"1a6eadb0_6db1eb46","updated":"2016-12-15 17:39:05.000000000","message":"Done","commit_id":"40851810056ea96537050bdec2f77dad8a42ac13"},{"author":{"_account_id":14614,"name":"Kyrylo Romanenko","display_name":"K.Romanenko","email":"romanenko-kv@hotmail.com","username":"kromanenko"},"change_message_id":"f8c38a6b223d98e0eda1d685bbe580ff77d026ef","unresolved":false,"context_lines":[{"line_number":300,"context_line":"        rp_tbl \u003d rp_obj._RP_TBL"},{"line_number":301,"context_line":"        conn \u003d self.api_db.get_engine().connect()"},{"line_number":302,"context_line":""},{"line_number":303,"context_line":"        # First, set up a record for an \"old-style\" resource provider with no"},{"line_number":304,"context_line":"        # root provider UUID."},{"line_number":305,"context_line":"        ins_stmt \u003d rp_tbl.insert().values("},{"line_number":306,"context_line":"            id\u003d1,"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_6d980bc1","line":303,"range":{"start_line":303,"start_character":7,"end_line":303,"end_character":77},"updated":"2016-12-15 16:30:55.000000000","message":"It\u0027s much better to describe test steps in docstring.","commit_id":"40851810056ea96537050bdec2f77dad8a42ac13"},{"author":{"_account_id":13692,"name":"Roman Dobosz","email":"gryf73@gmail.com","username":"gryf"},"change_message_id":"7225e547365344aefde51eefc002a648ee6bdfb1","unresolved":false,"context_lines":[{"line_number":300,"context_line":"        rp_tbl \u003d rp_obj._RP_TBL"},{"line_number":301,"context_line":"        conn \u003d self.api_db.get_engine().connect()"},{"line_number":302,"context_line":""},{"line_number":303,"context_line":"        # First, set up a record for an \"old-style\" resource provider with no"},{"line_number":304,"context_line":"        # root provider UUID."},{"line_number":305,"context_line":"        ins_stmt \u003d rp_tbl.insert().values("},{"line_number":306,"context_line":"            id\u003d1,"}],"source_content_type":"text/x-python","patch_set":22,"id":"1a6eadb0_2ea9a990","line":303,"range":{"start_line":303,"start_character":7,"end_line":303,"end_character":77},"in_reply_to":"1a6eadb0_6d980bc1","updated":"2016-12-15 17:39:05.000000000","message":"I tend to disagree. It is a common approach for documenting in code what code blocks are.","commit_id":"40851810056ea96537050bdec2f77dad8a42ac13"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"0c389fcd2e9756143ea140869b9443e38a6bc26c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":24,"id":"ba5201f7_dc47471b","updated":"2017-01-04 12:47:28.000000000","message":"Should there be a test somewhere (here or unit?) of the case that will case the ResourceProviderNotFound to raise?","commit_id":"ce0463e4f79d5314fa3785988f08c211f65863d8"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"04eff2fc90f8d8eac2d721c5aedb9be98fe5602f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":24,"id":"ba5201f7_582fc387","in_reply_to":"ba5201f7_dc47471b","updated":"2017-01-11 19:25:35.000000000","message":"I\u0027ll add a test case for the get_all_by_filters() passing a non-existing resource provider UUID (which should return [])","commit_id":"ce0463e4f79d5314fa3785988f08c211f65863d8"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"12e724035c3275bdcc1679a9c844dea6327d8c2f","unresolved":false,"context_lines":[{"line_number":301,"context_line":"        a tree, passing in that old resource provider, that we still get that"},{"line_number":302,"context_line":"        provider returned."},{"line_number":303,"context_line":"        \"\"\""},{"line_number":304,"context_line":"        # Passing a non-existing resource provider UUID should return an empty"},{"line_number":305,"context_line":"        # list"},{"line_number":306,"context_line":"        rps \u003d rp_obj.ResourceProviderList.get_all_by_filters("},{"line_number":307,"context_line":"            self.ctx,"},{"line_number":308,"context_line":"            filters\u003d{"},{"line_number":309,"context_line":"                \u0027tree\u0027: uuidsentinel.rp1,"},{"line_number":310,"context_line":"            }"},{"line_number":311,"context_line":"        )"},{"line_number":312,"context_line":"        self.assertEqual([], rps.objects)"},{"line_number":313,"context_line":""},{"line_number":314,"context_line":"        rp_tbl \u003d rp_obj._RP_TBL"},{"line_number":315,"context_line":"        conn \u003d self.api_db.get_engine().connect()"}],"source_content_type":"text/x-python","patch_set":42,"id":"7f515b1d_f40228b4","line":312,"range":{"start_line":304,"start_character":1,"end_line":312,"end_character":41},"updated":"2017-09-25 13:44:13.000000000","message":"It feels like a separate test case.","commit_id":"4e711351bf1c83e4b7a0abb2ba4d8f48f75e5319"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"48541a6eedd79928fe96e24d2ffcf8d01fce055d","unresolved":false,"context_lines":[{"line_number":342,"context_line":"        )"},{"line_number":343,"context_line":"        conn.execute(ins_stmt)"},{"line_number":344,"context_line":""},{"line_number":345,"context_line":"        # NOTE(jaypipes): This is just disabling the online data migration"},{"line_number":346,"context_line":"        # that occurs to ensure we don\u0027t have any migrations messing with"},{"line_number":347,"context_line":"        # the end result."},{"line_number":348,"context_line":"        with mock.patch(\u0027nova.objects.resource_provider.ResourceProvider.\u0027"},{"line_number":349,"context_line":"                        \u0027_update_in_db\u0027):"},{"line_number":350,"context_line":"            rps \u003d rp_obj.ResourceProviderList.get_all_by_filters("}],"source_content_type":"text/x-python","patch_set":52,"id":"3f4b6375_767075dd","line":347,"range":{"start_line":345,"start_character":0,"end_line":347,"end_character":25},"updated":"2017-10-20 12:20:12.000000000","message":"But in reality this migration will run during the get_all_by_filters() call and will add parent to the old-style provider. So I don\u0027t see why we need to turn it off in this test. I feel this makes the test unrealistic.","commit_id":"6dddbe0bf5a89a4d0fd6925a3a640f446ac4088c"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"b7c1c1af3383d6f88d24946e73b8a055f9b17ac1","unresolved":false,"context_lines":[{"line_number":342,"context_line":"        )"},{"line_number":343,"context_line":"        conn.execute(ins_stmt)"},{"line_number":344,"context_line":""},{"line_number":345,"context_line":"        # NOTE(jaypipes): This is just disabling the online data migration"},{"line_number":346,"context_line":"        # that occurs to ensure we don\u0027t have any migrations messing with"},{"line_number":347,"context_line":"        # the end result."},{"line_number":348,"context_line":"        with mock.patch(\u0027nova.objects.resource_provider.ResourceProvider.\u0027"},{"line_number":349,"context_line":"                        \u0027_update_in_db\u0027):"},{"line_number":350,"context_line":"            rps \u003d rp_obj.ResourceProviderList.get_all_by_filters("}],"source_content_type":"text/x-python","patch_set":52,"id":"3f4b6375_479385a4","line":347,"range":{"start_line":345,"start_character":0,"end_line":347,"end_character":25},"in_reply_to":"3f4b6375_767075dd","updated":"2017-10-20 13:55:38.000000000","message":"Crap, yeah, you\u0027re right. The code previously centralized the migration to the _update_in_db() method so this worked properly. Will fix up.","commit_id":"6dddbe0bf5a89a4d0fd6925a3a640f446ac4088c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"cf75cba5701ed6f5ee62fc521c0373f568a114ad","unresolved":false,"context_lines":[{"line_number":384,"context_line":"        )"},{"line_number":385,"context_line":"        conn.execute(ins_stmt)"},{"line_number":386,"context_line":""},{"line_number":387,"context_line":"        # NOTE(jaypipes): This is just disabling the online data migration that"},{"line_number":388,"context_line":"        # occurs in _from_db_object() that sets root provider ID to ensure we"},{"line_number":389,"context_line":"        # don\u0027t have any migrations messing with the end result."},{"line_number":390,"context_line":"        with mock.patch(\u0027nova.objects.resource_provider.\u0027"},{"line_number":391,"context_line":"                        \u0027_set_root_provider_id\u0027):"},{"line_number":392,"context_line":"            rps \u003d rp_obj.ResourceProviderList.get_all_by_filters("},{"line_number":393,"context_line":"                self.ctx,"},{"line_number":394,"context_line":"                filters\u003d{"}],"source_content_type":"text/x-python","patch_set":53,"id":"3f4b6375_1f4d69c3","line":391,"range":{"start_line":387,"start_character":1,"end_line":391,"end_character":49},"updated":"2017-10-25 11:35:55.000000000","message":"Now it mocks the proper function handling the migration. But I don\u0027t see why we need to mock that. I commented this out and the test still passes.\n\nYou could even use this test to verify the on the fly data migration of the old style ports.","commit_id":"0d6a93a1107d5cc5e4e0c99d886676787b5c99e7"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"7c049703044a422b5e301a90eeb8afb494158a9f","unresolved":false,"context_lines":[{"line_number":384,"context_line":"        )"},{"line_number":385,"context_line":"        conn.execute(ins_stmt)"},{"line_number":386,"context_line":""},{"line_number":387,"context_line":"        # NOTE(jaypipes): This is just disabling the online data migration that"},{"line_number":388,"context_line":"        # occurs in _from_db_object() that sets root provider ID to ensure we"},{"line_number":389,"context_line":"        # don\u0027t have any migrations messing with the end result."},{"line_number":390,"context_line":"        with mock.patch(\u0027nova.objects.resource_provider.\u0027"},{"line_number":391,"context_line":"                        \u0027_set_root_provider_id\u0027):"},{"line_number":392,"context_line":"            rps \u003d rp_obj.ResourceProviderList.get_all_by_filters("},{"line_number":393,"context_line":"                self.ctx,"},{"line_number":394,"context_line":"                filters\u003d{"}],"source_content_type":"text/x-python","patch_set":53,"id":"3f4b6375_bbbf825f","line":391,"range":{"start_line":387,"start_character":1,"end_line":391,"end_character":49},"in_reply_to":"3f4b6375_1f4d69c3","updated":"2017-10-25 15:07:32.000000000","message":"Gibi, please see the comment above. The mock above isn\u0027t enabling the test to pass. Rather, it\u0027s preventing the online data migration from setting root_provider_id on the resource provider record that is inserted in the database above on line 385. This test is checking that the following WHERE condition in the SQL generated behind the scenes works properly:\n\n WHERE root_provider_id \u003d $tree_id\n OR id \u003d $tree_id\n\nIt\u0027s the \"OR id \u003d $tree_id\" part of the condition that we\u0027re checking here, and we\u0027re just ensuring that no online data migration changes the value of root_provider_id to a non-NULL value that would cause the \"OR id \u003d $tree_id\" part of the condition to be exercised.\n\nMake more sense now?\n\n-jay","commit_id":"0d6a93a1107d5cc5e4e0c99d886676787b5c99e7"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"32dead07ecc90648f3a1207467d79d798b2738d3","unresolved":false,"context_lines":[{"line_number":384,"context_line":"        )"},{"line_number":385,"context_line":"        conn.execute(ins_stmt)"},{"line_number":386,"context_line":""},{"line_number":387,"context_line":"        # NOTE(jaypipes): This is just disabling the online data migration that"},{"line_number":388,"context_line":"        # occurs in _from_db_object() that sets root provider ID to ensure we"},{"line_number":389,"context_line":"        # don\u0027t have any migrations messing with the end result."},{"line_number":390,"context_line":"        with mock.patch(\u0027nova.objects.resource_provider.\u0027"},{"line_number":391,"context_line":"                        \u0027_set_root_provider_id\u0027):"},{"line_number":392,"context_line":"            rps \u003d rp_obj.ResourceProviderList.get_all_by_filters("},{"line_number":393,"context_line":"                self.ctx,"},{"line_number":394,"context_line":"                filters\u003d{"}],"source_content_type":"text/x-python","patch_set":53,"id":"3f4b6375_dd521d13","line":391,"range":{"start_line":387,"start_character":1,"end_line":391,"end_character":49},"in_reply_to":"3f4b6375_bbbf825f","updated":"2017-10-26 07:59:10.000000000","message":"I think I\u0027m still lost. As far as I understand the query having the WHERE clause runs _before_ the _from_db_object() call sets the root_provider_id so the data migration cannot interfere with the execution of the query having this WHERE clause.","commit_id":"0d6a93a1107d5cc5e4e0c99d886676787b5c99e7"},{"author":{"_account_id":11564,"name":"Chris Dent","email":"cdent@anticdent.org","username":"chdent"},"change_message_id":"861c97bab938060575aa1bea027022877ff8973a","unresolved":false,"context_lines":[{"line_number":325,"context_line":"        )"},{"line_number":326,"context_line":"        grandchild_rp.set_inventory(inv_list)"},{"line_number":327,"context_line":""},{"line_number":328,"context_line":"        # Check all providers returned when getting by root UUID"},{"line_number":329,"context_line":"        rps \u003d rp_obj.ResourceProviderList.get_all_by_filters("},{"line_number":330,"context_line":"            self.ctx,"},{"line_number":331,"context_line":"            filters\u003d{"}],"source_content_type":"text/x-python","patch_set":62,"id":"ff82abbf_6b9f9165","line":328,"updated":"2017-11-30 11:57:14.000000000","message":"Is this missing a test for the case where the value of \u0027tree\u0027 is a child?\n\nA get_all_by_filters(filters\u003d{\u0027tree\u0027: grandchild_rp.uuid}) perhaps?","commit_id":"0460017fbca8be718ca0ffa8870bd67e983d203c"},{"author":{"_account_id":7,"name":"Jay Pipes","email":"jaypipes@gmail.com","username":"jaypipes"},"change_message_id":"2e251aee396d3dfbda87ed997a173314167dbc6c","unresolved":false,"context_lines":[{"line_number":325,"context_line":"        )"},{"line_number":326,"context_line":"        grandchild_rp.set_inventory(inv_list)"},{"line_number":327,"context_line":""},{"line_number":328,"context_line":"        # Check all providers returned when getting by root UUID"},{"line_number":329,"context_line":"        rps \u003d rp_obj.ResourceProviderList.get_all_by_filters("},{"line_number":330,"context_line":"            self.ctx,"},{"line_number":331,"context_line":"            filters\u003d{"}],"source_content_type":"text/x-python","patch_set":62,"id":"ff82abbf_18d972f3","line":328,"in_reply_to":"ff82abbf_6b9f9165","updated":"2017-11-30 18:03:14.000000000","message":"Done","commit_id":"0460017fbca8be718ca0ffa8870bd67e983d203c"},{"author":{"_account_id":5754,"name":"Alex Xu","email":"hejie.xu@intel.com","username":"xuhj"},"change_message_id":"e93b08549d82909c4103693f102e37fca407360f","unresolved":false,"context_lines":[{"line_number":347,"context_line":"        rps \u003d rp_obj.ResourceProviderList.get_all_by_filters("},{"line_number":348,"context_line":"            self.ctx,"},{"line_number":349,"context_line":"            filters\u003d{"},{"line_number":350,"context_line":"                \u0027tree\u0027: uuidsentinel.grandchild_rp,"},{"line_number":351,"context_line":"            }"},{"line_number":352,"context_line":"        )"},{"line_number":353,"context_line":"        self.assertEqual(3, len(rps))"}],"source_content_type":"text/x-python","patch_set":65,"id":"df87a7cf_574fb0bc","line":350,"updated":"2017-12-04 08:17:56.000000000","message":"we only test the case there is only tree filter, based on my reading, it shouldn\u0027t work well with member_of and resources filter.","commit_id":"d2d264ee53a5aeafb5896f3b64cc43658496538a"},{"author":{"_account_id":14070,"name":"Eric Fried","email":"openstack@fried.cc","username":"efried"},"change_message_id":"15e75240117b443e1b4a8d61bf614ce7e2002bea","unresolved":false,"context_lines":[{"line_number":420,"context_line":"        rps \u003d rp_obj.ResourceProviderList.get_all_by_filters("},{"line_number":421,"context_line":"            self.ctx,"},{"line_number":422,"context_line":"            filters\u003d{"},{"line_number":423,"context_line":"                \u0027tree\u0027: uuidsentinel.grandchild_rp,"},{"line_number":424,"context_line":"                \u0027resources\u0027: {"},{"line_number":425,"context_line":"                    \u0027VCPU\u0027: 1,"},{"line_number":426,"context_line":"                }"}],"source_content_type":"text/x-python","patch_set":69,"id":"df87a7cf_878ddc32","line":423,"updated":"2017-12-05 14:10:17.000000000","message":"And the same test with a `tree` UUID that\u0027s somewhere else in the tree.  I.e. this test *looks* the same as the one that does uuid+resources.","commit_id":"43c785e0939b4880f3ae8f8afaea9895a2507514"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"eb07fbadfd89184d9254c94554629057644ad521","unresolved":false,"context_lines":[{"line_number":378,"context_line":"            }"},{"line_number":379,"context_line":"        )"},{"line_number":380,"context_line":"        self.assertEqual(1, len(rps))"},{"line_number":381,"context_line":"        self.assertEqual(uuidsentinel.grandchild_rp, rps[0].uuid)"},{"line_number":382,"context_line":""},{"line_number":383,"context_line":"        # Try filtering on an unknown UUID and verify no results"},{"line_number":384,"context_line":"        rps \u003d rp_obj.ResourceProviderList.get_all_by_filters("}],"source_content_type":"text/x-python","patch_set":71,"id":"df87a7cf_aabbef0b","line":381,"updated":"2017-12-06 08:37:51.000000000","message":"thanks for those tests.","commit_id":"65205fdaa731d82e6393f5a9346ab91945d37fb1"}]}
