)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"994e44fb43c02c4f51cdb56acd9483a2c8c7ec4d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"e1387ee4_d4970971","updated":"2026-07-15 15:54:28.000000000","message":"lgtm","commit_id":"9103dec080d6a65fad4a98abf1393b0115ce4bee"}],"cyborg/accelerator/drivers/pci/devspec.py":[{"author":{"_account_id":39344,"name":"Gihong Lee","display_name":"gamio","email":"gh9231@gmail.com","username":"gamio"},"change_message_id":"a24e6063795b915ee425742c1ba05f9bb377d529","unresolved":true,"context_lines":[{"line_number":326,"context_line":"            raise exception.PciConfigInvalidWhitelist("},{"line_number":327,"context_line":"                reason\u003d_("},{"line_number":328,"context_line":"                    \"Invalid managed value \u0027%(val)s\u0027. Accepted values: \""},{"line_number":329,"context_line":"                    \"true, false, yes, no, 1, 0.\""},{"line_number":330,"context_line":"                )"},{"line_number":331,"context_line":"                % {\u0027val\u0027: managed_raw}"},{"line_number":332,"context_line":"            )"}],"source_content_type":"text/x-python","patch_set":5,"id":"47557f71_eacf60a0","line":329,"updated":"2026-08-12 14:49:31.000000000","message":"`normalize_managed` uses `strutils.bool_from_string(strict\u003dTrue)`, which also accepts on, off, t, f, y, n. How about we list the full set here so the message matches the behaviour?","commit_id":"4d324e6d76ec6e4fdf28cd53e1646181a857900a"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"eb80148a60d8f7758f737d328df9283a50763cf0","unresolved":true,"context_lines":[{"line_number":326,"context_line":"            raise exception.PciConfigInvalidWhitelist("},{"line_number":327,"context_line":"                reason\u003d_("},{"line_number":328,"context_line":"                    \"Invalid managed value \u0027%(val)s\u0027. Accepted values: \""},{"line_number":329,"context_line":"                    \"true, false, yes, no, 1, 0.\""},{"line_number":330,"context_line":"                )"},{"line_number":331,"context_line":"                % {\u0027val\u0027: managed_raw}"},{"line_number":332,"context_line":"            )"}],"source_content_type":"text/x-python","patch_set":5,"id":"a0292fab_c974943a","line":329,"in_reply_to":"47557f71_eacf60a0","updated":"2026-08-12 19:03:16.000000000","message":"i am using strutils.bool_from_string as a convince or operator but i really only want to suprpot `true` and `false`\n\ni woudl prefer not to leak the oslo details into the cofnig contract so fi anything\ni shoudl remote the other accpaved values. because really the devspec/whitelist is intended to be json and were lirally json booleans woudl be all that is supproted.\n\nallowing\n\n```\npassthrough_whitelist \u003d {\"vendor_id\":\"10de\", \"product_id\":\"27b8\", \"managed\":\"false\"}\n```\n\ninstead of requiring\n```\npassthrough_whitelist \u003d {\"vendor_id\":\"10de\", \"product_id\":\"27b8\", \"managed\":false}\n```\nis sole implemnte dbecasue nova allows that.\n\nbut each object `{}` in the config is a json blob and normalize_managed is just cohesing it into a boolean whild be flexable to allow strings\n\nin cybrog we are mor laxs today in what the config is and how we process it here.\n\nwe are treaing it as a dict of stings.\n\nwith that siad it does rasie  question about if i shoudl update the doc string to to be more explict \n\nhttps://github.com/openstack/cyborg/blob/master/cyborg/conf/devices.py#L20\n\nis honestly terrible\n\ni should proagbly add propper doc string\n\nhttps://github.com/openstack/nova/blob/master/nova/conf/pci.py#L178-L359\n\nto show that true/false and yes/no are the prefer ed values when json bools are not used.\n\ni also think i have a bug\ni inded normalize_managed to return a bool\nhttps://review.opendev.org/c/openstack/cyborg/+/994575/5/cyborg/common/attach_handle.py#82\nnot a string.\n\nit will work today but the type is wrong\n\ni think i regress that when i decied i wanted to keep the api resouce for the attachemnt hadel as a dict of stings in the 2.4 microverison since all other values in that are curnetly strings.\nin python the sting \"false\" is consifred true\n```\n\u003e\u003e\u003e bool(\"false\")\nTrue\n```\n\nand i do not want that to bite us later","commit_id":"4d324e6d76ec6e4fdf28cd53e1646181a857900a"}],"cyborg/accelerator/drivers/pci/pci/sysinfo.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"eb80148a60d8f7758f737d328df9283a50763cf0","unresolved":true,"context_lines":[{"line_number":82,"context_line":"    return attr_list"},{"line_number":83,"context_line":""},{"line_number":84,"context_line":""},{"line_number":85,"context_line":"def _generate_attach_handle(pci):"},{"line_number":86,"context_line":"    driver_ah \u003d driver_attach_handle.DriverAttachHandle()"},{"line_number":87,"context_line":"    driver_ah.in_use \u003d False"},{"line_number":88,"context_line":"    driver_ah.attach_type \u003d constants.AH_TYPE_PCI"},{"line_number":89,"context_line":"    attach_info \u003d jsonutils.loads(utils.pci_str_to_json(pci[\"devices\"]))"},{"line_number":90,"context_line":"    # PciDeviceSpec normalizes configured values during driver startup."},{"line_number":91,"context_line":"    if \u0027managed\u0027 in pci:"},{"line_number":92,"context_line":"        attach_info[\u0027managed\u0027] \u003d pci[\u0027managed\u0027]"},{"line_number":93,"context_line":"    driver_ah.attach_info \u003d jsonutils.dumps(attach_info)"},{"line_number":94,"context_line":"    return driver_ah"},{"line_number":95,"context_line":""},{"line_number":96,"context_line":""},{"line_number":97,"context_line":"def _generate_dep_list(pci):"}],"source_content_type":"text/x-python","patch_set":5,"id":"a8c80672_cd4378ea","line":94,"range":{"start_line":85,"start_character":0,"end_line":94,"end_character":20},"updated":"2026-08-12 19:03:16.000000000","message":"i need to look at this more clsoely.\n\n\nutils.pci_str_to_json(pci[\"devices\"]) is passing \npci[\"devices\"] as pci_address\n\n```\ndef pci_str_to_json(pci_address, physnet\u003dNone):\n    dbs, func \u003d pci_address.split(\u0027.\u0027)\n    domain, bus, slot \u003d dbs.split(\u0027:\u0027)\n    keys \u003d [\"domain\", \"bus\", \"device\", \"function\"]\n    values \u003d [domain, bus, slot, func]\n    if physnet:\n        keys.append(\"physical_network\")\n        values.append(physnet)\n    bdf_dict \u003d dict(zip(keys, values))\n    ordered_dict \u003d collections.OrderedDict(sorted(bdf_dict.items()))\n    bdf_json \u003d jsonutils.dumps(ordered_dict)\n    return bdf_json\n```\n\nso \n```\nattach_info \u003d jsonutils.loads(utils.pci_str_to_json(pci[\"devices\"]))\n```\n\nis taking whatever `pci[\"devices\"]`  as a string and truning it into json by calling pci_str_to_json and then convrting that into a dict by calling jsonutils.loads\n\nso that we can add managed  if that in the orginal pci dict then finally converting it back to a sting with  jsonutils.dumps(attach_info)\n\n\nthat is valid but ineffienct\n\npci_str_to_json is really a serisiation function over a pci adress\n\nconverting for example `0000:21:01.3` to \n`{\"domain\":\"0000\", \"bus\": \"21\", \"device\":\"01, \"function\":\"3\"}`\n\noptially adding phsnet if you pass one and then sortign the keys and configitn the dict back to a sting.\n\nthis curren code then confvert the sting to a dict again to optionall append a other key and serialsie it again.\n\n\nwe shoudl jsut add managed as a opetional arg to pci_str_to_json\n\nthat avoid a second round trip to a dict and back to a sting.","commit_id":"4d324e6d76ec6e4fdf28cd53e1646181a857900a"}],"cyborg/agent/manager.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"eb80148a60d8f7758f737d328df9283a50763cf0","unresolved":true,"context_lines":[{"line_number":98,"context_line":"        self._rt \u003d ResourceTracker(self.resource_provider_name, self.cond_api)"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"    def init_host(self):"},{"line_number":101,"context_line":"        \"\"\"Hook called by RPCService.start() after the RPC server is up.\"\"\""},{"line_number":102,"context_line":"        pass"},{"line_number":103,"context_line":""},{"line_number":104,"context_line":"    def _get_resource_provider_name(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"3191e4e6_e3db510c","side":"PARENT","line":101,"range":{"start_line":101,"start_character":8,"end_line":101,"end_character":75},"updated":"2026-08-12 19:03:16.000000000","message":"the timing of this might be worth keeping i guess","commit_id":"270385fc3a1d3b8e71fc7aba92a46bacf3fce72d"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"eb80148a60d8f7758f737d328df9283a50763cf0","unresolved":true,"context_lines":[{"line_number":110,"context_line":"        \"\"\"Report resources once before periodic reporting starts.\"\"\""},{"line_number":111,"context_line":"        context \u003d cyborg_context.get_admin_context()"},{"line_number":112,"context_line":"        try:"},{"line_number":113,"context_line":"            self._rt.update_usage(context)"},{"line_number":114,"context_line":"        except _CONFIGURATION_EXCEPTIONS:"},{"line_number":115,"context_line":"            raise"},{"line_number":116,"context_line":"        except Exception:"}],"source_content_type":"text/x-python","patch_set":5,"id":"b0ee6d1f_35d7bf3e","line":113,"range":{"start_line":113,"start_character":10,"end_line":113,"end_character":42},"updated":"2026-08-12 19:03:16.000000000","message":"i feel like in the long run it might be better to call\nupdate_available_resource here instead.\niuts the same irght now but we proably dont wnat this to drift","commit_id":"4d324e6d76ec6e4fdf28cd53e1646181a857900a"}],"cyborg/common/attach_handle.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"eb80148a60d8f7758f737d328df9283a50763cf0","unresolved":true,"context_lines":[{"line_number":1,"context_line":"# Copyright 2026 Red Hat, Inc."},{"line_number":2,"context_line":"# All Rights Reserved."},{"line_number":3,"context_line":"#"},{"line_number":4,"context_line":"#    Licensed under the Apache License, Version 2.0 (the \"License\"); you may"}],"source_content_type":"text/x-python","patch_set":5,"id":"f5387f13_c36fc3ff","line":1,"range":{"start_line":1,"start_character":0,"end_line":1,"end_character":30},"updated":"2026-08-12 19:03:16.000000000","message":"i shoudl drop this","commit_id":"4d324e6d76ec6e4fdf28cd53e1646181a857900a"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"eb80148a60d8f7758f737d328df9283a50763cf0","unresolved":true,"context_lines":[{"line_number":19,"context_line":"from oslo_utils import strutils"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from cyborg.common import constants"},{"line_number":22,"context_line":""},{"line_number":23,"context_line":""},{"line_number":24,"context_line":"UNCHANGED \u003d \u0027unchanged\u0027"},{"line_number":25,"context_line":"APPLY \u003d \u0027apply\u0027"},{"line_number":26,"context_line":"REJECT_IN_USE \u003d \u0027reject_in_use\u0027"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"_MISSING \u003d object()"},{"line_number":29,"context_line":"_PCI_COMPONENT_WIDTHS \u003d {"}],"source_content_type":"text/x-python","patch_set":5,"id":"507b782e_cab1f406","line":26,"range":{"start_line":22,"start_character":1,"end_line":26,"end_character":31},"updated":"2026-08-12 19:03:16.000000000","message":"this should be an enum","commit_id":"4d324e6d76ec6e4fdf28cd53e1646181a857900a"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"eb80148a60d8f7758f737d328df9283a50763cf0","unresolved":true,"context_lines":[{"line_number":51,"context_line":"    return attach_info"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"def pci_address(attach_info):"},{"line_number":55,"context_line":"    \"\"\"Return the canonical PCI address from attach information.\"\"\""},{"line_number":56,"context_line":"    info \u003d load_attach_info(attach_info)"},{"line_number":57,"context_line":"    components \u003d {}"},{"line_number":58,"context_line":"    for field, width in _PCI_COMPONENT_WIDTHS.items():"},{"line_number":59,"context_line":"        try:"},{"line_number":60,"context_line":"            value \u003d str(info[field])"},{"line_number":61,"context_line":"        except KeyError:"},{"line_number":62,"context_line":"            raise ValueError(\u0027Missing PCI address field: %s\u0027 % field)"},{"line_number":63,"context_line":"        if not value or len(value) \u003e width:"},{"line_number":64,"context_line":"            raise ValueError(\u0027Invalid PCI %s: %s\u0027 % (field, value))"},{"line_number":65,"context_line":"        try:"},{"line_number":66,"context_line":"            number \u003d int(value, 16)"},{"line_number":67,"context_line":"        except ValueError:"},{"line_number":68,"context_line":"            raise ValueError(\u0027Invalid PCI %s: %s\u0027 % (field, value))"},{"line_number":69,"context_line":"        if field \u003d\u003d \u0027function\u0027 and number \u003e 7:"},{"line_number":70,"context_line":"            raise ValueError(\u0027Invalid PCI function: %s\u0027 % value)"},{"line_number":71,"context_line":"        components[field] \u003d value.zfill(width).lower()"},{"line_number":72,"context_line":"    return \u0027%(domain)s:%(bus)s:%(device)s.%(function)s\u0027 % components"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":""},{"line_number":75,"context_line":"def attach_handle_identity(attach_type, attach_info):"}],"source_content_type":"text/x-python","patch_set":5,"id":"eb32e437_f25213f2","line":72,"range":{"start_line":54,"start_character":0,"end_line":72,"end_character":68},"updated":"2026-08-12 19:03:16.000000000","message":"none of this is wrong, this is the correct way to validate and zeor extend a pci adres in the cannonical format\n\nbut lookign at this agisn this feels out of place.\n\nthe attachemnt handils is na ovo\n\nhttps://github.com/openstack/cyborg/blob/master/cyborg/objects/attach_handle.py\n\nand while the info file dis just a sting file containing a json blob\n\ni feel like these utils shoudl live with the obejct.","commit_id":"4d324e6d76ec6e4fdf28cd53e1646181a857900a"}],"cyborg/conductor/manager.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"e509456ceb0fbf4dd5b08088d33a618734ced2b8","unresolved":false,"context_lines":[{"line_number":134,"context_line":"        discovered device list."},{"line_number":135,"context_line":"        :param context: request context."},{"line_number":136,"context_line":"        :param hostname: agent\u0027s hostname."},{"line_number":137,"context_line":"        :param driver_device_list: a list of driver_device object"},{"line_number":138,"context_line":"        discovered by agent in the host."},{"line_number":139,"context_line":"        \"\"\""},{"line_number":140,"context_line":"        # Hold row locks across preflight and reconciliation so allocation"}],"source_content_type":"text/x-python","patch_set":5,"id":"b011582c_cc2ef21d","line":137,"updated":"2026-08-10 22:13:35.000000000","message":"The report_data method wraps the entire reconciliation flow (preflight plus drv_device_make_diff) in a single writer transaction with SELECT FOR UPDATE locks on attach_handle rows. During this locked scope, drv_device_make_diff invokes drv_deployable_make_diff and drv_attr_make_diff, both of whic...\n\n**Severity**: WARNING | **Confidence**: 0.8\n\n**Impact**: If the Placement service is slow or unreachable, the database transaction and its row locks remain open for the duration of the HTTP timeout. This can cause lock contention on attach_handle rows, block concurrent operations such as ARQ allocation, exhaust the database connection pool, and potenti...\n\n**Suggestion**:\nConsider separating preflight validation and lock acquisition from Placement API mutations. Acquire locks and run preflight within a short transaction, commit, then perform Placement API calls outside the transaction. Alternatively, move only the attach-handle reconciliation (drv_ah_make_diff) within the lock scope and perform deployable/attribute/Placement operations outside it.","commit_id":"4d324e6d76ec6e4fdf28cd53e1646181a857900a"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"eb80148a60d8f7758f737d328df9283a50763cf0","unresolved":true,"context_lines":[{"line_number":141,"context_line":"        # cannot race an accepted managed transition. Nested object DB calls"},{"line_number":142,"context_line":"        # reuse this transaction. This is a temporary conductor-side adapter"},{"line_number":143,"context_line":"        # until ResourceTracker owns authoritative allocation state."},{"line_number":144,"context_line":"        with sqlalchemy_api.main_context_manager.writer.using(context):"},{"line_number":145,"context_line":"            AttachHandle.dbapi.attach_handle_lock_by_hostname("},{"line_number":146,"context_line":"                context, hostname"},{"line_number":147,"context_line":"            )"}],"source_content_type":"text/x-python","patch_set":5,"id":"f8cc820d_84616a78","line":144,"range":{"start_line":144,"start_character":6,"end_line":144,"end_character":71},"updated":"2026-08-12 19:03:16.000000000","message":"i kind of hate how this turned out so i might retink this approch.","commit_id":"4d324e6d76ec6e4fdf28cd53e1646181a857900a"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"eb80148a60d8f7758f737d328df9283a50763cf0","unresolved":true,"context_lines":[{"line_number":217,"context_line":"                            value\u003dexc.value,"},{"line_number":218,"context_line":"                        )"},{"line_number":219,"context_line":""},{"line_number":220,"context_line":"    @classmethod"},{"line_number":221,"context_line":"    def _preflight_managed_transitions("},{"line_number":222,"context_line":"        cls, host, old_driver_device_list, new_driver_device_list"},{"line_number":223,"context_line":"    ):"}],"source_content_type":"text/x-python","patch_set":5,"id":"b62a3dbe_74fee204","line":220,"updated":"2026-08-12 19:03:16.000000000","message":"i kind of hate how this owrks\ni understand it but this feels alot more complciate then it needs to be.\n\nsepcilaly shicne thei really shoudl be done in the cyborg-aget but it doe snot have teh current usage info.","commit_id":"4d324e6d76ec6e4fdf28cd53e1646181a857900a"}],"cyborg/db/sqlalchemy/api.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"eb80148a60d8f7758f737d328df9283a50763cf0","unresolved":true,"context_lines":[{"line_number":256,"context_line":"        return _paginate_query(context, models.AttachHandle, query\u003dquery)"},{"line_number":257,"context_line":""},{"line_number":258,"context_line":"    @main_context_manager.writer"},{"line_number":259,"context_line":"    def attach_handle_lock_by_hostname(self, context, hostname):"},{"line_number":260,"context_line":"        \"\"\"Lock a host\u0027s attach handles for discovery reconciliation.\"\"\""},{"line_number":261,"context_line":"        query \u003d model_query(context, models.AttachHandle)"},{"line_number":262,"context_line":"        query \u003d query.join("}],"source_content_type":"text/x-python","patch_set":5,"id":"0156cc94_24252c41","line":259,"updated":"2026-08-12 19:03:16.000000000","message":"this is not correct either the lock shoudl be droped when we return","commit_id":"4d324e6d76ec6e4fdf28cd53e1646181a857900a"}],"cyborg/objects/attach_handle.py":[{"author":{"_account_id":28006,"name":"teim-ci","display_name":"teim-ci","email":"ci@seanmooney.info","username":"ci-sean-mooney","status":"this is a third-party ci account run by sean-k-mooney on irc\nhosted at zuul.teim.app"},"tag":"autogenerated:zuul:automatic-ci","change_message_id":"e509456ceb0fbf4dd5b08088d33a618734ced2b8","unresolved":false,"context_lines":[{"line_number":109,"context_line":"        for ah_obj in ah_obj_list:"},{"line_number":110,"context_line":"            current_info \u003d ("},{"line_number":111,"context_line":"                ah_obj.attach_info"},{"line_number":112,"context_line":"                if hasattr(ah_obj, \u0027attach_info\u0027)"},{"line_number":113,"context_line":"                else ah_obj[\u0027attach_info\u0027]"},{"line_number":114,"context_line":"            )"},{"line_number":115,"context_line":"            if current_info \u003d\u003d attach_info:"}],"source_content_type":"text/x-python","patch_set":5,"id":"8a084ea5_5ae2bdde","line":112,"updated":"2026-08-10 22:13:35.000000000","message":"The refactored get_ah_by_depid_attachinfo method uses hasattr(ah_obj, \u0027attach_info\u0027) to decide between attribute and dict-style access. Since ah_obj is always an AttachHandle versioned object with attach_info as a required non-nullable field, the hasattr check always returns True and the dict-acc...\n\n**Severity**: SUGGESTION | **Confidence**: 0.9\n\n**Benefit**: The dead branch is misleading to future maintainers who might assume dict-style access is a valid fallback path. The method can be simplified to a direct attribute access.\n\n**Recommendation**:\nReplace the conditional expression with a direct attribute access: `if ah_obj.attach_info \u003d\u003d attach_info:`. This removes the dead branch and makes the intent clearer.","commit_id":"4d324e6d76ec6e4fdf28cd53e1646181a857900a"}],"cyborg/tests/unit/accelerator/drivers/pci/pci/test_sysinfo.py":[{"author":{"_account_id":34452,"name":"Joan Gilabert","display_name":"jgilaber","email":"jgilaber@redhat.com","username":"jgilaber"},"change_message_id":"994e44fb43c02c4f51cdb56acd9483a2c8c7ec4d","unresolved":true,"context_lines":[{"line_number":305,"context_line":"        self.assertNotIn(\u0027managed\u0027, info)"},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"    @mock.patch(_MOCK_GET_PCI, autospec\u003dTrue)"},{"line_number":308,"context_line":"    def test_discover_managed_string_no(self, mock_pci):"},{"line_number":309,"context_line":"        \"\"\"Whitelist with managed\u003d\u0027no\u0027 stores \u0027false\u0027 in attach_info.\"\"\""},{"line_number":310,"context_line":"        mock_pci.return_value \u003d (NVIDIA_PCI_LINE, \u0027\u0027)"},{"line_number":311,"context_line":"        self._set_whitelist("}],"source_content_type":"text/x-python","patch_set":3,"id":"9b4c0609_fa641205","line":308,"updated":"2026-07-15 15:54:28.000000000","message":"as a minor improvement, we could add tests for the other stated supported string values (yes/1/0)","commit_id":"9103dec080d6a65fad4a98abf1393b0115ce4bee"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"eb80148a60d8f7758f737d328df9283a50763cf0","unresolved":true,"context_lines":[{"line_number":305,"context_line":"        self.assertNotIn(\u0027managed\u0027, info)"},{"line_number":306,"context_line":""},{"line_number":307,"context_line":"    @mock.patch(_MOCK_GET_PCI, autospec\u003dTrue)"},{"line_number":308,"context_line":"    def test_discover_managed_string_no(self, mock_pci):"},{"line_number":309,"context_line":"        \"\"\"Whitelist with managed\u003d\u0027no\u0027 stores \u0027false\u0027 in attach_info.\"\"\""},{"line_number":310,"context_line":"        mock_pci.return_value \u003d (NVIDIA_PCI_LINE, \u0027\u0027)"},{"line_number":311,"context_line":"        self._set_whitelist("}],"source_content_type":"text/x-python","patch_set":3,"id":"6d6f8326_3dfb1efb","line":308,"in_reply_to":"9b4c0609_fa641205","updated":"2026-08-12 19:03:16.000000000","message":"ill add yes and no but i dont want to docuemnt supprot for any of the other permuations\n\nim only adding yes/no because nova supproted those as well as true/false\n\nperhaps using ddt or subtest","commit_id":"9103dec080d6a65fad4a98abf1393b0115ce4bee"}],"cyborg/tests/unit/accelerator/drivers/pci/test_devspec.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"eb80148a60d8f7758f737d328df9283a50763cf0","unresolved":true,"context_lines":[{"line_number":14,"context_line":"from cyborg.common import exception"},{"line_number":15,"context_line":"from cyborg.tests import base"},{"line_number":16,"context_line":""},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"class TestPciDeviceSpecManaged(base.DietTestCase):"},{"line_number":19,"context_line":"    \"\"\"Tests for the managed tag in PciDeviceSpec.\"\"\""},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"    def _make_spec(self, **kwargs):"},{"line_number":22,"context_line":"        spec_dict \u003d {"},{"line_number":23,"context_line":"            \u0027vendor_id\u0027: \u002710de\u0027,"},{"line_number":24,"context_line":"            \u0027product_id\u0027: \u00271eb8\u0027,"},{"line_number":25,"context_line":"        }"},{"line_number":26,"context_line":"        spec_dict.update(kwargs)"},{"line_number":27,"context_line":"        return devspec.PciDeviceSpec(spec_dict)"},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"    def test_managed_default_when_absent(self):"},{"line_number":30,"context_line":"        \"\"\"managed is None when not specified.\"\"\""},{"line_number":31,"context_line":"        spec \u003d self._make_spec()"},{"line_number":32,"context_line":"        self.assertIsNone(spec.managed)"},{"line_number":33,"context_line":""},{"line_number":34,"context_line":"    def test_managed_json_bool_true(self):"},{"line_number":35,"context_line":"        spec \u003d self._make_spec(managed\u003dTrue)"},{"line_number":36,"context_line":"        self.assertEqual(\u0027true\u0027, spec.managed)"},{"line_number":37,"context_line":""},{"line_number":38,"context_line":"    def test_managed_json_bool_false(self):"},{"line_number":39,"context_line":"        spec \u003d self._make_spec(managed\u003dFalse)"},{"line_number":40,"context_line":"        self.assertEqual(\u0027false\u0027, spec.managed)"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def test_managed_string_true(self):"},{"line_number":43,"context_line":"        spec \u003d self._make_spec(managed\u003d\u0027true\u0027)"},{"line_number":44,"context_line":"        self.assertEqual(\u0027true\u0027, spec.managed)"},{"line_number":45,"context_line":""},{"line_number":46,"context_line":"    def test_managed_string_false(self):"},{"line_number":47,"context_line":"        spec \u003d self._make_spec(managed\u003d\u0027false\u0027)"},{"line_number":48,"context_line":"        self.assertEqual(\u0027false\u0027, spec.managed)"},{"line_number":49,"context_line":""},{"line_number":50,"context_line":"    def test_managed_string_uppercase_false(self):"},{"line_number":51,"context_line":"        spec \u003d self._make_spec(managed\u003d\u0027FALSE\u0027)"},{"line_number":52,"context_line":"        self.assertEqual(\u0027false\u0027, spec.managed)"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"    def test_managed_string_yes(self):"},{"line_number":55,"context_line":"        spec \u003d self._make_spec(managed\u003d\u0027yes\u0027)"},{"line_number":56,"context_line":"        self.assertEqual(\u0027true\u0027, spec.managed)"},{"line_number":57,"context_line":""},{"line_number":58,"context_line":"    def test_managed_string_no(self):"},{"line_number":59,"context_line":"        spec \u003d self._make_spec(managed\u003d\u0027no\u0027)"},{"line_number":60,"context_line":"        self.assertEqual(\u0027false\u0027, spec.managed)"},{"line_number":61,"context_line":""},{"line_number":62,"context_line":"    def test_managed_string_one(self):"},{"line_number":63,"context_line":"        spec \u003d self._make_spec(managed\u003d\u00271\u0027)"},{"line_number":64,"context_line":"        self.assertEqual(\u0027true\u0027, spec.managed)"},{"line_number":65,"context_line":""},{"line_number":66,"context_line":"    def test_managed_string_zero(self):"},{"line_number":67,"context_line":"        spec \u003d self._make_spec(managed\u003d\u00270\u0027)"},{"line_number":68,"context_line":"        self.assertEqual(\u0027false\u0027, spec.managed)"},{"line_number":69,"context_line":""},{"line_number":70,"context_line":"    def test_managed_integer_one(self):"},{"line_number":71,"context_line":"        spec \u003d self._make_spec(managed\u003d1)"},{"line_number":72,"context_line":"        self.assertEqual(\u0027true\u0027, spec.managed)"},{"line_number":73,"context_line":""},{"line_number":74,"context_line":"    def test_managed_integer_zero(self):"},{"line_number":75,"context_line":"        spec \u003d self._make_spec(managed\u003d0)"},{"line_number":76,"context_line":"        self.assertEqual(\u0027false\u0027, spec.managed)"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"    def test_managed_invalid_raises(self):"}],"source_content_type":"text/x-python","patch_set":5,"id":"349a2f9a_f9b23f61","line":75,"range":{"start_line":17,"start_character":1,"end_line":75,"end_character":41},"updated":"2026-08-12 19:03:16.000000000","message":"i need to decided on the internal type of managed\ni think it should be a bool but its stroed in a json blob in the db as part fo a list of tag strings  adn its returned in teh api as a sting.","commit_id":"4d324e6d76ec6e4fdf28cd53e1646181a857900a"}]}
