)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"a5e61bcff2dc92897ba23d9ce7544888a82c8062","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"648485f5_84ed7326","updated":"2024-05-31 09:42:12.000000000","message":"Okay, let\u0027s try to recheck it then.\n\nNo other problems here.","commit_id":"44c1b48b3121682cf959c90b3adaf2a3f92e318c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"9a6cbec549e19cc7a6e58c1552ddfc29e96f5c51","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"5e468ae5_f448b0cb","updated":"2024-05-28 07:06:54.000000000","message":"recheck \nlvm job failed due to failed image upload in shelve_offload test:\nnova-compute:\n```\nMay 27 18:18:46.467071 np0037607070 nova-compute[83840]: ERROR oslo_messaging.rpc.server glanceclient.exc.HTTPInternalServerError: HTTP 500 Internal Server Error: The server has either erred or is incapable of performing the requested operation.\nMay 27 18:18:46.467071 np0037607070 nova-compute[83840]: ERROR oslo_messaging.rpc.server \n```\nglance-api:\n```\nMay 27 18:18:42.438384 np0037607070 devstack@g-api.service[86565]: ERROR glance_store._drivers.swift.store [None req-87234191-65a2-4973-8ea5-84142818e4cd tempest-ServerActionsTestOtherB-39775779 tempest-ServerActionsTestOtherB-39775779-project-member] Error during chunked upload to backend, deleting stale chunks.: swiftclient.exceptions.ClientException: put_object(\u0027glance\u0027, \u00270b2d1d6d-7e89-4348-ba2a-b6688e95dd19-00001\u0027, ...) failure and no ability to reset contents for reupload.\nMay 27 18:18:42.439875 np0037607070 devstack@g-api.service[86565]: ERROR glance_store._drivers.swift.store [None req-87234191-65a2-4973-8ea5-84142818e4cd tempest-ServerActionsTestOtherB-39775779 tempest-ServerActionsTestOtherB-39775779-project-member] Failed to add object to Swift.\nMay 27 18:18:42.439875 np0037607070 devstack@g-api.service[86565]: Got error from Swift: put_object(\u0027glance\u0027, \u00270b2d1d6d-7e89-4348-ba2a-b6688e95dd19-00001\u0027, ...) failure and no ability to reset contents for reupload..: swiftclient.exceptions.ClientException: put_object(\u0027glance\u0027, \u00270b2d1d6d-7e89-4348-ba2a-b6688e95dd19-00001\u0027, ...) failure and no ability to reset contents for reupload.\nMay 27 18:18:42.497362 np0037607070 devstack@g-api.service[86565]: ERROR glance.api.v2.image_data [None req-87234191-65a2-4973-8ea5-84142818e4cd tempest-ServerActionsTestOtherB-39775779 tempest-ServerActionsTestOtherB-39775779-project-member] Failed to upload image data due to internal error: glance_store.exceptions.BackendException: Failed to add object to Swift.\nMay 27 18:18:42.612582 np0037607070 devstack@g-api.service[86565]: ERROR glance.common.wsgi [None req-87234191-65a2-4973-8ea5-84142818e4cd tempest-ServerActionsTestOtherB-39775779 tempest-ServerActionsTestOtherB-39775779-project-member] Caught error: Failed to add object to Swift.\n```","commit_id":"44c1b48b3121682cf959c90b3adaf2a3f92e318c"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"22af85b66e5a2390ef312769b0aa92e318be3a99","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"9dd75fe0_333fbe88","updated":"2024-06-04 19:25:15.000000000","message":"recheck  openstack.tests.functional.compute.v2.test_volume_attachment.TestServerVolumeAttachment.test_volume_attachment failed to delete the volume","commit_id":"44c1b48b3121682cf959c90b3adaf2a3f92e318c"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"a562c9330553689b231e36b617f40b7675ce6b89","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"bf1c7f43_c329728a","updated":"2024-06-27 15:15:51.000000000","message":"recheck .... test_image_defined_boot_from_volume failed...","commit_id":"44c1b48b3121682cf959c90b3adaf2a3f92e318c"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"b085355237d6ce057733ca7d9462efcbd885f49f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"1f6c2485_1930c5a4","updated":"2024-06-27 10:10:44.000000000","message":"recheck https://review.opendev.org/c/openstack/devstack/+/881580 fixed nova-next","commit_id":"44c1b48b3121682cf959c90b3adaf2a3f92e318c"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"bf555aacf665d006d6b9ca0fdad32f57cdfca3b2","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"69fb5872_f47ec8d4","updated":"2024-06-25 18:01:37.000000000","message":"recheck https://review.opendev.org/c/openstack/devstack/+/922630 shoudl fix the timeouts","commit_id":"44c1b48b3121682cf959c90b3adaf2a3f92e318c"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"cd8abe030351010bd62583a94ca7263b19cbc98b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"c4469ee4_becdc32c","updated":"2024-06-13 07:15:48.000000000","message":"recheck kernel panic in ceph job","commit_id":"44c1b48b3121682cf959c90b3adaf2a3f92e318c"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"49e1c1008867bbec719573bb471875e6113ce2c8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"e5296f15_e41644ac","updated":"2024-06-12 16:09:13.000000000","message":"recheck openstacksdk-functional-devstack failed with an unrelated volume detach failure openstack.tests.functional.compute.v2.test_volume_attachment.TestServerVolumeAttachment.test_volume_attachment","commit_id":"44c1b48b3121682cf959c90b3adaf2a3f92e318c"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"fbcd3001d55a1870f73b8e080eb290576f3ad5b1","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"df08b1c9_a9799361","updated":"2024-06-04 16:36:09.000000000","message":"recheck tempest-integrated-compute timedout with no failing tests https://storage.bhs.cloud.ovh.net/v1/AUTH_dcaab5e32b234d56b626f72581e3644c/zuul_opendev_logs_14b/920203/4/gate/tempest-integrated-compute/14b3485/testr_results.html","commit_id":"44c1b48b3121682cf959c90b3adaf2a3f92e318c"},{"author":{"_account_id":7730,"name":"Sahid Orentino Ferdjaoui","email":"sahid.ferdjaoui@industrialdiscipline.com","username":"sahid"},"change_message_id":"d2c734969cd8bd3568e5aa5195a7b7f345034709","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"5e530abd_db6eb47d","updated":"2024-06-13 13:42:47.000000000","message":"recheck timeout","commit_id":"44c1b48b3121682cf959c90b3adaf2a3f92e318c"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"e8920166414cbf5cfb795dfc135c80ec9980a450","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"4154d7a4_52c5438b","updated":"2024-05-28 06:59:01.000000000","message":"still looks good.","commit_id":"44c1b48b3121682cf959c90b3adaf2a3f92e318c"}],"nova/filesystem.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"b5c15aefe24d419d20d9a06e51f08a73eca56848","unresolved":true,"context_lines":[{"line_number":25,"context_line":""},{"line_number":26,"context_line":"SYS \u003d \u0027/sys\u0027"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"# NOTE(bauzas): this method is deliberately not wrapped in a privsep entrypoint"},{"line_number":30,"context_line":"def read_sys(path: str) -\u003e str:"},{"line_number":31,"context_line":"    \"\"\"Reads the content of a file in the sys filesystem."}],"source_content_type":"text/x-python","patch_set":1,"id":"4b83bf0c_0707e40c","line":28,"updated":"2024-05-22 18:05:01.000000000","message":"i proably should add it here too.\nim not sure if we can get a device busy error on read but it wont hurt to be able to retry.","commit_id":"447d869be49154ae4666e9bd47cc7509f845a867"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"201d549267715b403c1573f530f41db41036456c","unresolved":false,"context_lines":[{"line_number":25,"context_line":""},{"line_number":26,"context_line":"SYS \u003d \u0027/sys\u0027"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"# NOTE(bauzas): this method is deliberately not wrapped in a privsep entrypoint"},{"line_number":30,"context_line":"def read_sys(path: str) -\u003e str:"},{"line_number":31,"context_line":"    \"\"\"Reads the content of a file in the sys filesystem."}],"source_content_type":"text/x-python","patch_set":1,"id":"6555541e_9ca511e9","line":28,"in_reply_to":"4b83bf0c_0707e40c","updated":"2024-05-27 12:26:05.000000000","message":"Done","commit_id":"447d869be49154ae4666e9bd47cc7509f845a867"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"b5c15aefe24d419d20d9a06e51f08a73eca56848","unresolved":true,"context_lines":[{"line_number":52,"context_line":"            except OSError as e:"},{"line_number":53,"context_line":"                if e.errno \u003d\u003d 16:"},{"line_number":54,"context_line":"                    LOG.debug(\u0027File is busy, retrying\u0027)"},{"line_number":55,"context_line":"                    time.sleep(i)"},{"line_number":56,"context_line":"                    continue"},{"line_number":57,"context_line":"                raise"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"83872842_6bc6f550","line":55,"updated":"2024-05-22 18:05:01.000000000","message":"time is monkey-patched by eventlet so thhe time.sleep is actuly an eventlet.sleep\nhowever we dont want to use eventlet.sleep directly so we dont add addtional tech debt.\n\nas with time.sleep evetlet.sleep is just a hint for how long to sleep for but thats fine we just wan to have a slight backoff below to allow the device to be ready.","commit_id":"447d869be49154ae4666e9bd47cc7509f845a867"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"201d549267715b403c1573f530f41db41036456c","unresolved":false,"context_lines":[{"line_number":52,"context_line":"            except OSError as e:"},{"line_number":53,"context_line":"                if e.errno \u003d\u003d 16:"},{"line_number":54,"context_line":"                    LOG.debug(\u0027File is busy, retrying\u0027)"},{"line_number":55,"context_line":"                    time.sleep(i)"},{"line_number":56,"context_line":"                    continue"},{"line_number":57,"context_line":"                raise"},{"line_number":58,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"d9e51c08_a440eb8d","line":55,"in_reply_to":"83872842_6bc6f550","updated":"2024-05-27 12:26:05.000000000","message":"Acknowledged","commit_id":"447d869be49154ae4666e9bd47cc7509f845a867"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"30e90d45657a76a9011e83c62c2b53b3757b5bca","unresolved":true,"context_lines":[{"line_number":55,"context_line":"                    time.sleep(i)"},{"line_number":56,"context_line":"                    continue"},{"line_number":57,"context_line":"                raise"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    return wrapper"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"f0a8d87f_dba1570d","line":58,"updated":"2024-05-23 07:44:08.000000000","message":"I think this decorator will ignore the OSError 16 if it happens 6 times in a row instead of signalling error in that case.","commit_id":"447d869be49154ae4666e9bd47cc7509f845a867"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"201d549267715b403c1573f530f41db41036456c","unresolved":false,"context_lines":[{"line_number":55,"context_line":"                    time.sleep(i)"},{"line_number":56,"context_line":"                    continue"},{"line_number":57,"context_line":"                raise"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    return wrapper"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"e621c2a0_3aab5ee8","line":58,"in_reply_to":"ef5f8163_a9d67c38","updated":"2024-05-27 12:26:05.000000000","message":"Done","commit_id":"447d869be49154ae4666e9bd47cc7509f845a867"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"e37f864c6e4dda694d1a06ca8e2534d805a6b0e1","unresolved":true,"context_lines":[{"line_number":55,"context_line":"                    time.sleep(i)"},{"line_number":56,"context_line":"                    continue"},{"line_number":57,"context_line":"                raise"},{"line_number":58,"context_line":""},{"line_number":59,"context_line":"    return wrapper"},{"line_number":60,"context_line":""},{"line_number":61,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"ef5f8163_a9d67c38","line":58,"in_reply_to":"f0a8d87f_dba1570d","updated":"2024-05-23 11:03:54.000000000","message":"oh your correct i was expecting it to hit the raise on line 57 but it wont ill fix that.","commit_id":"447d869be49154ae4666e9bd47cc7509f845a867"},{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"30e90d45657a76a9011e83c62c2b53b3757b5bca","unresolved":true,"context_lines":[{"line_number":75,"context_line":"        # The path can be absolute with a /sys prefix but that\u0027s fine."},{"line_number":76,"context_line":"        with open(os.path.join(SYS, path), mode\u003d\u0027w\u0027) as fd:"},{"line_number":77,"context_line":"            fd.write(data)"},{"line_number":78,"context_line":"    except OSError as exc:"},{"line_number":79,"context_line":"        # errno 16 is EBUSY, which means the file is busy."},{"line_number":80,"context_line":"        if exc.errno \u003d\u003d 16:"},{"line_number":81,"context_line":"            LOG.debug(\u0027File %s is busy, retrying\u0027, path)"},{"line_number":82,"context_line":"            raise"},{"line_number":83,"context_line":"        raise exception.FileNotFound(file_path\u003dpath) from exc"},{"line_number":84,"context_line":"    except ValueError as exc:"},{"line_number":85,"context_line":"        raise exception.FileNotFound(file_path\u003dpath) from exc"}],"source_content_type":"text/x-python","patch_set":1,"id":"0f1a798f_776c99b4","line":83,"range":{"start_line":78,"start_character":0,"end_line":83,"end_character":61},"updated":"2024-05-23 07:44:08.000000000","message":"I don\u0027t super happy about duplicating the logging and the errno checking between this place and the decorator.\n\nThe logging can be dropped from one of the places easily but the errno checking is harder to dedupe. I think we need to create another indirection (function) to have a layer where the error translation can be separate from the retry.","commit_id":"447d869be49154ae4666e9bd47cc7509f845a867"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"e37f864c6e4dda694d1a06ca8e2534d805a6b0e1","unresolved":true,"context_lines":[{"line_number":75,"context_line":"        # The path can be absolute with a /sys prefix but that\u0027s fine."},{"line_number":76,"context_line":"        with open(os.path.join(SYS, path), mode\u003d\u0027w\u0027) as fd:"},{"line_number":77,"context_line":"            fd.write(data)"},{"line_number":78,"context_line":"    except OSError as exc:"},{"line_number":79,"context_line":"        # errno 16 is EBUSY, which means the file is busy."},{"line_number":80,"context_line":"        if exc.errno \u003d\u003d 16:"},{"line_number":81,"context_line":"            LOG.debug(\u0027File %s is busy, retrying\u0027, path)"},{"line_number":82,"context_line":"            raise"},{"line_number":83,"context_line":"        raise exception.FileNotFound(file_path\u003dpath) from exc"},{"line_number":84,"context_line":"    except ValueError as exc:"},{"line_number":85,"context_line":"        raise exception.FileNotFound(file_path\u003dpath) from exc"}],"source_content_type":"text/x-python","patch_set":1,"id":"eb138f88_d57bfa35","line":83,"range":{"start_line":78,"start_character":0,"end_line":83,"end_character":61},"in_reply_to":"0f1a798f_776c99b4","updated":"2024-05-23 11:03:54.000000000","message":"ok ill thnk on that for a bit.\n\ni can see a few ways to do that\nim debating btween a decorator vs a function vs converting the EBUSY to a diffent nova excption and having the decorator catch that instead.","commit_id":"447d869be49154ae4666e9bd47cc7509f845a867"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"201d549267715b403c1573f530f41db41036456c","unresolved":false,"context_lines":[{"line_number":75,"context_line":"        # The path can be absolute with a /sys prefix but that\u0027s fine."},{"line_number":76,"context_line":"        with open(os.path.join(SYS, path), mode\u003d\u0027w\u0027) as fd:"},{"line_number":77,"context_line":"            fd.write(data)"},{"line_number":78,"context_line":"    except OSError as exc:"},{"line_number":79,"context_line":"        # errno 16 is EBUSY, which means the file is busy."},{"line_number":80,"context_line":"        if exc.errno \u003d\u003d 16:"},{"line_number":81,"context_line":"            LOG.debug(\u0027File %s is busy, retrying\u0027, path)"},{"line_number":82,"context_line":"            raise"},{"line_number":83,"context_line":"        raise exception.FileNotFound(file_path\u003dpath) from exc"},{"line_number":84,"context_line":"    except ValueError as exc:"},{"line_number":85,"context_line":"        raise exception.FileNotFound(file_path\u003dpath) from exc"}],"source_content_type":"text/x-python","patch_set":1,"id":"59b36dc7_866f1518","line":83,"range":{"start_line":78,"start_character":0,"end_line":83,"end_character":61},"in_reply_to":"eb138f88_d57bfa35","updated":"2024-05-27 12:26:05.000000000","message":"Done","commit_id":"447d869be49154ae4666e9bd47cc7509f845a867"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"a5e61bcff2dc92897ba23d9ce7544888a82c8062","unresolved":false,"context_lines":[{"line_number":22,"context_line":""},{"line_number":23,"context_line":"LOG \u003d logging.getLogger(__name__)"},{"line_number":24,"context_line":"SYS \u003d \u0027/sys\u0027"},{"line_number":25,"context_line":"RETRY_LIMIT \u003d 5"},{"line_number":26,"context_line":""},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"# a retry decorator to handle EBUSY"}],"source_content_type":"text/x-python","patch_set":4,"id":"cb160af5_d865eabe","line":25,"updated":"2024-05-31 09:42:12.000000000","message":"Cool with 5","commit_id":"44c1b48b3121682cf959c90b3adaf2a3f92e318c"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"a5e61bcff2dc92897ba23d9ce7544888a82c8062","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        for i in range(RETRY_LIMIT):"},{"line_number":42,"context_line":"            try:"},{"line_number":43,"context_line":"                return func(*args, **kwargs)"},{"line_number":44,"context_line":"            except exception.DeviceBusy as e:"},{"line_number":45,"context_line":"                # if we have retried RETRY_LIMIT times, raise the exception"},{"line_number":46,"context_line":"                # otherwise, sleep and retry, i is 0-based so we need"},{"line_number":47,"context_line":"                # to add 1 to it"}],"source_content_type":"text/x-python","patch_set":4,"id":"25f4ca64_6455b9a3","line":44,"updated":"2024-05-31 09:42:12.000000000","message":"okay, fine to only check this exception","commit_id":"44c1b48b3121682cf959c90b3adaf2a3f92e318c"},{"author":{"_account_id":7166,"name":"Sylvain Bauza","email":"sbauza@redhat.com","username":"sbauza"},"change_message_id":"a5e61bcff2dc92897ba23d9ce7544888a82c8062","unresolved":false,"context_lines":[{"line_number":73,"context_line":"            return data.read()"},{"line_number":74,"context_line":"    except OSError as exc:"},{"line_number":75,"context_line":"        # errno 16 is EBUSY, which means the file is busy."},{"line_number":76,"context_line":"        if exc.errno \u003d\u003d 16:"},{"line_number":77,"context_line":"            raise exception.DeviceBusy(file_path\u003dpath) from exc"},{"line_number":78,"context_line":"        # convert permission denied to file not found"},{"line_number":79,"context_line":"        raise exception.FileNotFound(file_path\u003dpath) from exc"}],"source_content_type":"text/x-python","patch_set":4,"id":"315f857e_0ab0f285","line":76,"updated":"2024-05-31 09:42:12.000000000","message":"Well, maybe later the Python community will create a specific OSError subclass for device busy but for the moment, we don\u0027t have it https://docs.python.org/3/library/exceptions.html#os-exceptions","commit_id":"44c1b48b3121682cf959c90b3adaf2a3f92e318c"}],"nova/tests/functional/libvirt/test_power_manage.py":[{"author":{"_account_id":9708,"name":"Balazs Gibizer","display_name":"gibi","email":"gibizer@gmail.com","username":"gibi"},"change_message_id":"66e4283a3ea24f438739d83b3cc277ea44f8943d","unresolved":true,"context_lines":[{"line_number":281,"context_line":"        instance_pcpus \u003d inst.numa_topology.cpu_pinning"},{"line_number":282,"context_line":"        self._assert_cpu_set_state(instance_pcpus, expected\u003d\u0027online\u0027)"},{"line_number":283,"context_line":"        with mock.patch("},{"line_number":284,"context_line":"            \u0027nova.filesystem.write_sys.__wrapped__\u0027,"},{"line_number":285,"context_line":"            side_effect\u003d["},{"line_number":286,"context_line":"                exception.DeviceBusy(file_path\u003d\u0027fake\u0027),"},{"line_number":287,"context_line":"                None]):"}],"source_content_type":"text/x-python","patch_set":3,"id":"2ab8d7db_3b68a70b","line":284,"updated":"2024-05-27 15:01:21.000000000","message":"I went into the rabbit hole to try to mock on the builtins.open level to test the OSError translation as well but it become too complicated for the functional test:\n```diff\ndiff --git a/nova/tests/functional/libvirt/test_power_manage.py b/nova/tests/functional/libvirt/test_power_manage.py\nindex f4c861576c..57309b2c5a 100644\n--- a/nova/tests/functional/libvirt/test_power_manage.py\n+++ b/nova/tests/functional/libvirt/test_power_manage.py\n@@ -9,6 +9,7 @@\n #    WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the\n #    License for the specific language governing permissions and limitations\n #    under the License.\n+import collections\n \n import fixtures\n \n@@ -280,13 +281,23 @@ class PowerManagementTests(PowerManagementTestsBase):\n         inst \u003d objects.Instance.get_by_uuid(self.ctxt, server[\u0027id\u0027])\n         instance_pcpus \u003d inst.numa_topology.cpu_pinning\n         self._assert_cpu_set_state(instance_pcpus, expected\u003d\u0027online\u0027)\n-        with mock.patch(\n-            \u0027nova.filesystem.write_sys.__wrapped__\u0027,\n-            side_effect\u003d[\n-                exception.DeviceBusy(file_path\u003d\u0027fake\u0027),\n-                None]):\n \n+        builtin_open \u003d open  # save the unpatched version\n+        calls \u003d collections.Counter()\n+\n+        def mock_open(*args, **kwargs):\n+            if args[0].endswith(\"/online\") and kwargs[\"mode\"] \u003d\u003d \"w\":\n+                calls.update([args[0]])\n+                # raise EBUSY for each CPU offlining once otherwise succeed\n+                if dict(calls)[args[0]] \u003c 2:\n+                    raise OSError(16, \"busy\", args[0])\n+            return builtin_open(*args, **kwargs)\n+\n+        with mock.patch(\u0027builtins.open\u0027, mock_open) as m:\n             self._delete_server(server)\n+\n+        # flavor has 4 cpus to offline and each cpu needed a retry\n+        self.assertEqual(2 * 4, calls.total(), dict(calls))\n\n```\n\nSo let\u0027s not overcomplicate this test. It is good as is.","commit_id":"74b507805489671bbb57197fb8ee30aadbc068ff"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"e7c1ba75bd8dfa2d268e98c06c2990a0a3e6ed75","unresolved":false,"context_lines":[{"line_number":281,"context_line":"        instance_pcpus \u003d inst.numa_topology.cpu_pinning"},{"line_number":282,"context_line":"        self._assert_cpu_set_state(instance_pcpus, expected\u003d\u0027online\u0027)"},{"line_number":283,"context_line":"        with mock.patch("},{"line_number":284,"context_line":"            \u0027nova.filesystem.write_sys.__wrapped__\u0027,"},{"line_number":285,"context_line":"            side_effect\u003d["},{"line_number":286,"context_line":"                exception.DeviceBusy(file_path\u003d\u0027fake\u0027),"},{"line_number":287,"context_line":"                None]):"}],"source_content_type":"text/x-python","patch_set":3,"id":"885b21ad_2fa24af2","line":284,"in_reply_to":"2ab8d7db_3b68a70b","updated":"2024-05-27 16:41:35.000000000","message":"ya i had consider something similar but differnt and equally complicated.\nif we are generally happy with the current behavior of the funtional test ill mark this as resolved.","commit_id":"74b507805489671bbb57197fb8ee30aadbc068ff"}],"nova/tests/unit/test_filesystem.py":[{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"e7c1ba75bd8dfa2d268e98c06c2990a0a3e6ed75","unresolved":true,"context_lines":[{"line_number":41,"context_line":"        with mock.patch(\u0027builtins.open\u0027, open_mock) as m_open:"},{"line_number":42,"context_line":"            m_open.side_effect \u003d ["},{"line_number":43,"context_line":"                OSError(16, \u0027Device or resource busy\u0027),"},{"line_number":44,"context_line":"                mock.mock_open(read_data\u003d\u0027bar\u0027)(),"},{"line_number":45,"context_line":"            ]"},{"line_number":46,"context_line":"            self.assertEqual(\u0027bar\u0027, filesystem.read_sys(\u0027foo\u0027))"},{"line_number":47,"context_line":"        expected_path \u003d os.path.join(filesystem.SYS, \u0027foo\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"86d0a57a_5a36ad1c","line":44,"range":{"start_line":44,"start_character":16,"end_line":44,"end_character":49},"updated":"2024-05-27 16:41:35.000000000","message":"py39 is not happy with this\ni think this coudl be a string otherwise i need to do mock.MagicMock(spec\u003dfile_spec)\nand set the returnvalue for read.","commit_id":"74b507805489671bbb57197fb8ee30aadbc068ff"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"afb765b727d4500675b16b94e7922e0013768a75","unresolved":false,"context_lines":[{"line_number":41,"context_line":"        with mock.patch(\u0027builtins.open\u0027, open_mock) as m_open:"},{"line_number":42,"context_line":"            m_open.side_effect \u003d ["},{"line_number":43,"context_line":"                OSError(16, \u0027Device or resource busy\u0027),"},{"line_number":44,"context_line":"                mock.mock_open(read_data\u003d\u0027bar\u0027)(),"},{"line_number":45,"context_line":"            ]"},{"line_number":46,"context_line":"            self.assertEqual(\u0027bar\u0027, filesystem.read_sys(\u0027foo\u0027))"},{"line_number":47,"context_line":"        expected_path \u003d os.path.join(filesystem.SYS, \u0027foo\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"cbe622ec_8f8aa1a1","line":44,"range":{"start_line":44,"start_character":16,"end_line":44,"end_character":49},"in_reply_to":"86d0a57a_5a36ad1c","updated":"2024-05-27 17:37:29.000000000","message":"i just replaced this with io.StringIO(\u0027bar\u0027)\n\nhere i was tryign to delegate to mock_open but at this point the object that is returned via the sideefect shoudl be a file_spec compatiable object that we will call read on\n\nan io.StringIO instance is perfectly serviciable for that and we dont need to complicate things with creating a mock.","commit_id":"74b507805489671bbb57197fb8ee30aadbc068ff"},{"author":{"_account_id":11604,"name":"sean mooney","email":"smooney@redhat.com","username":"sean-k-mooney"},"change_message_id":"afb765b727d4500675b16b94e7922e0013768a75","unresolved":false,"context_lines":[{"line_number":82,"context_line":"        with mock.patch(\u0027builtins.open\u0027, open_mock) as m_open:"},{"line_number":83,"context_line":"            m_open.side_effect \u003d ["},{"line_number":84,"context_line":"                OSError(16, \u0027Device or resource busy\u0027),"},{"line_number":85,"context_line":"                mock.MagicMock(spec\u003dfile_spec),"},{"line_number":86,"context_line":"            ]"},{"line_number":87,"context_line":"            self.assertIsNone(filesystem.write_sys(\u0027foo\u0027, \u0027bar\u0027))"},{"line_number":88,"context_line":"        expected_path \u003d os.path.join(filesystem.SYS, \u0027foo\u0027)"}],"source_content_type":"text/x-python","patch_set":3,"id":"37baa5d4_6e34b294","line":85,"updated":"2024-05-27 17:37:29.000000000","message":"i realsied while fixing the ohter issue above that we can just use an io.StringIO object here too so i removed the use of the _io module\n\ni was orginaly using that to emulate the internal implemenmation of mock.mock_open\n\nit uses the filespec ectra because it needs to be generic where as i just need this to not raise an error","commit_id":"74b507805489671bbb57197fb8ee30aadbc068ff"}]}
