)]}'
{"/PATCHSET_LEVEL":[{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"8dcf8ba6ff14f002f5ec876cb158e5ff3965f322","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"aa1c8807_6b434153","updated":"2026-01-29 14:47:54.000000000","message":"recheck unrelated failure","commit_id":"685bc766b7a1edcf9a9847b110fbbb5c95397323"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"5973f19a86eedd3b56263414b92f98fa729e9c09","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"f58eb18c_18cdc2f3","updated":"2026-06-02 15:20:02.000000000","message":"A few comments/questions.\n\n\nThese locking issues with native threadings, they only happen in testing, right?","commit_id":"628c0df9154dfdbfedfeef8ffcffe5d0d63c8e6a"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"50d6c2491059b74fe5a2717cade7bf679b3aeff6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"67a8001a_abb4f7c4","updated":"2026-06-03 05:26:01.000000000","message":"Thank you for review cycril, tried to address your comments.","commit_id":"628c0df9154dfdbfedfeef8ffcffe5d0d63c8e6a"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"50d6c2491059b74fe5a2717cade7bf679b3aeff6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":6,"id":"69285ac3_eec4ab27","in_reply_to":"f58eb18c_18cdc2f3","updated":"2026-06-03 05:26:01.000000000","message":"The races we are fixing are not test-only artifacts. uWSGI deployments already use native threading for Glance\u0027s thread pools and TaskFlow-based imports. What was test-only was running the functional suite under eventlet, which hid those races. The get_queued_images() fix and import-lock timing handling apply to real uWSGI production behavior; only the futurist atexit workaround is strictly test-process cleanup.","commit_id":"628c0df9154dfdbfedfeef8ffcffe5d0d63c8e6a"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"f71adb6f4badf19e51b47257a59c47d7783669bc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":7,"id":"8f469415_251e660f","updated":"2026-06-03 08:14:19.000000000","message":"recheck","commit_id":"52805acd31293fa82c25bd8c4a23b49a801fd693"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"4342653fc6d156150306cc5e1c1cd62105f1c84f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":9,"id":"cc1df3fa_c1e5c2f2","updated":"2026-06-05 11:27:44.000000000","message":"Thanks for the review Dan ! I tried to address your comments.","commit_id":"ea6036ff509051d61ae63d9c39120ee329a7e6dc"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"54f62926c198d66ecfddf6358b83b18693debd7c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"78b6a5b2_30f61d4b","updated":"2026-06-08 14:48:25.000000000","message":"OK, I\u0027ll +2 this though I really dont like relying on the internals of the futurist library.\n\nIdeally we can fix this once we remove eventlet completely, or use concurrent.futures instead.","commit_id":"c4998d6ffeb79fb66bca67e690d4ab849ca59674"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"0d83d085e505ba6a1a353bc24bdc8b0acfa40115","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"1b24b1a5_f58dfab6","updated":"2026-06-08 10:18:44.000000000","message":"recheck on nova-ceph-multistore for etcd download infra failure and timeouting issue functional-py311","commit_id":"c4998d6ffeb79fb66bca67e690d4ab849ca59674"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"00bb135bb436ad69a9d0a404fce788abadf0eee0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"97d9606f_06ebc9e1","in_reply_to":"6b32ac6c_5cd87c4d","updated":"2026-06-10 12:35:56.000000000","message":"Done - tried to remove the futurist atexit hack, switched glance.async_ to\nconcurrent.futures in the follow-up 992633 at the end of the stack","commit_id":"c4998d6ffeb79fb66bca67e690d4ab849ca59674"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"694916c885d4d3ecf3bbae9fa6972bc4589d76be","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":10,"id":"6b32ac6c_5cd87c4d","in_reply_to":"78b6a5b2_30f61d4b","updated":"2026-06-08 15:13:03.000000000","message":"I agree, extreme code smell. Perhaps before we merge this we start on a \"full removal\" patch at the end that nukes this and eventlet? A sort of tombstone where we collect on the debt we\u0027re adding here to make sure we don\u0027t forget?","commit_id":"c4998d6ffeb79fb66bca67e690d4ab849ca59674"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"85a30e04a50941231b1cf591b9433d4467d55dc7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"4cce5247_9ad5a7d6","updated":"2026-06-10 17:45:14.000000000","message":"Okay, at least the removal tombstone is in place at the end of the series here.","commit_id":"6ea226a2cd214e96006a54f9af4567fa0c37a2a0"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"335cec783497104ca8e09783974349dc8756835f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"000a662e_2e937bb8","updated":"2026-06-14 17:42:39.000000000","message":"recheck","commit_id":"6ea226a2cd214e96006a54f9af4567fa0c37a2a0"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"ea9b20b400886bfe13d26d2cf7b91ac8eda75c36","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"252918e9_b6e4aeb6","updated":"2026-06-12 06:23:08.000000000","message":"recheck","commit_id":"6ea226a2cd214e96006a54f9af4567fa0c37a2a0"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"3c9b9ad65d7816ed0bd3d90855d7f04d181368b5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"5b475280_59ee0da5","updated":"2026-06-11 08:13:35.000000000","message":"recheck","commit_id":"6ea226a2cd214e96006a54f9af4567fa0c37a2a0"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"ac2a34c5cfc18cdec38b86772ae5ecffa95228bb","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"9567d51f_eed2921d","updated":"2026-06-16 05:46:19.000000000","message":"recheck","commit_id":"6ea226a2cd214e96006a54f9af4567fa0c37a2a0"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"80d4fca93aaf41753264236f58172fec31f53052","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"b96658f3_3726a513","updated":"2026-06-14 08:06:15.000000000","message":"recheck","commit_id":"6ea226a2cd214e96006a54f9af4567fa0c37a2a0"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"f6995d52c5109fe9b68f84015ecee0a9d5522a79","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"a887f91a_66fb861f","updated":"2026-06-14 05:34:11.000000000","message":"recheck another timeout error","commit_id":"6ea226a2cd214e96006a54f9af4567fa0c37a2a0"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"5546df4f6d884a7cb74a62a6be877888ee159a9f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"7f8cead4_292149d9","updated":"2026-06-13 16:53:09.000000000","message":"recheck failing test skippped.","commit_id":"6ea226a2cd214e96006a54f9af4567fa0c37a2a0"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"1677ac7f4907aa78afc60bf9865425ec8c0e1f8a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"e79d361c_9b529779","updated":"2026-06-12 10:08:19.000000000","message":"recheck on tempest-integrated-storage Timeout","commit_id":"6ea226a2cd214e96006a54f9af4567fa0c37a2a0"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"af4d7f1718c37ebc213cb5f9a86785a87d2418c4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"46c7c793_cef8a9cf","updated":"2026-06-11 12:41:24.000000000","message":"recheck on time out for import failure","commit_id":"6ea226a2cd214e96006a54f9af4567fa0c37a2a0"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"1e508262a84bffe7530cfa471a06a5f3ecde5cb0","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"79d9169c_735e1821","updated":"2026-06-11 04:54:50.000000000","message":"recheck on timeouting issue on import failure","commit_id":"6ea226a2cd214e96006a54f9af4567fa0c37a2a0"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"1bafe325554e865501786a8ecda8675c0ca8bc09","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":12,"id":"f8387865_c060c164","updated":"2026-06-14 13:05:14.000000000","message":"recheck test_web_download_redirect_validation timedout","commit_id":"6ea226a2cd214e96006a54f9af4567fa0c37a2a0"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"44a16206478549ccce3151fd1ea54e720f9fb7e4","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"53bcab5d_a4261529","updated":"2026-06-16 11:40:23.000000000","message":"recheck","commit_id":"bd03794f1090e483233538f707a24b533b7a68d5"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"7652947222c7aaf438eaab5e61bf9ac5d2965e7c","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"be82a359_e2c77289","updated":"2026-06-17 17:17:25.000000000","message":"recheck","commit_id":"bd03794f1090e483233538f707a24b533b7a68d5"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"090af347ad66c841346df3663648b01fc788ad02","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"daa495c3_d873e98b","updated":"2026-06-17 13:40:54.000000000","message":"recheck","commit_id":"bd03794f1090e483233538f707a24b533b7a68d5"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"7c329cebe7aca1f473f341f7e2e4d873bec41030","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"ea3e9ab5_bd4af76d","updated":"2026-06-17 03:33:36.000000000","message":"recheck","commit_id":"bd03794f1090e483233538f707a24b533b7a68d5"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"3457bbed5888f31b09363f22debab58ea13cff4a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"c9c1dc21_3d1cae58","updated":"2026-06-18 07:30:14.000000000","message":"recheck similar failures","commit_id":"bd03794f1090e483233538f707a24b533b7a68d5"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"3030564c6ca80149d75a2938ec582bd93bf88918","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"cf0fb6c5_8ea602a9","updated":"2026-06-16 16:59:50.000000000","message":"recheck timeout while importing image","commit_id":"bd03794f1090e483233538f707a24b533b7a68d5"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"2fcca7d126a02dbcba5c0e8e88fceabba676beb8","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":14,"id":"afc1f537_deb65c02","updated":"2026-06-18 05:14:06.000000000","message":"restoring +w as it\u0027s rebased after approved.","commit_id":"bd03794f1090e483233538f707a24b533b7a68d5"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"9b4e0b8ccfdf0d26927f0a604237b5e71c08d39d","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":15,"id":"81ad63ad_e9419920","updated":"2026-06-18 14:04:54.000000000","message":"restoring +w after rebase","commit_id":"2f3393b8362aae64363ddb82b1f7d7f7a7385ec2"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"b67f83845b4435d0969cb0da6b7837a175d6a8a6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":16,"id":"8089c181_93cadc04","updated":"2026-06-18 17:43:26.000000000","message":"recheck","commit_id":"c5ad2013898f2deb151ef0070a60004fadee2b6d"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"e8c3cb65b07230df4edbfa331e2d6d6e8a837c2f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":16,"id":"ebb8ab83_3353b23a","updated":"2026-06-19 01:45:31.000000000","message":"recheck","commit_id":"c5ad2013898f2deb151ef0070a60004fadee2b6d"}],"glance/image_cache/drivers/centralized_db.py":[{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"5973f19a86eedd3b56263414b92f98fa729e9c09","unresolved":true,"context_lines":[{"line_number":383,"context_line":"                # File was processed/deleted by CacheWorker, skip it"},{"line_number":384,"context_line":"                continue"},{"line_number":385,"context_line":""},{"line_number":386,"context_line":"        items.sort()"},{"line_number":387,"context_line":"        return [image_id for (modtime, image_id) in items]"},{"line_number":388,"context_line":""},{"line_number":389,"context_line":"    def get_cache_files(self, basepath):"}],"source_content_type":"text/x-python","patch_set":6,"id":"1f46e917_a9576984","line":386,"range":{"start_line":386,"start_character":0,"end_line":386,"end_character":20},"updated":"2026-06-02 15:20:02.000000000","message":"So here we might return outdated info to the caller (if the cache entry has been deleted and we handled and OSError/FileNotFoundError), but I guess it\u0027s fine?","commit_id":"628c0df9154dfdbfedfeef8ffcffe5d0d63c8e6a"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"50d6c2491059b74fe5a2717cade7bf679b3aeff6","unresolved":false,"context_lines":[{"line_number":383,"context_line":"                # File was processed/deleted by CacheWorker, skip it"},{"line_number":384,"context_line":"                continue"},{"line_number":385,"context_line":""},{"line_number":386,"context_line":"        items.sort()"},{"line_number":387,"context_line":"        return [image_id for (modtime, image_id) in items]"},{"line_number":388,"context_line":""},{"line_number":389,"context_line":"    def get_cache_files(self, basepath):"}],"source_content_type":"text/x-python","patch_set":6,"id":"da1926d2_6749757d","line":386,"range":{"start_line":386,"start_character":0,"end_line":386,"end_character":20},"in_reply_to":"1f46e917_a9576984","updated":"2026-06-03 05:26:01.000000000","message":"Skipped files are gone so here list is current.","commit_id":"628c0df9154dfdbfedfeef8ffcffe5d0d63c8e6a"}],"glance/tests/__init__.py":[{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"5973f19a86eedd3b56263414b92f98fa729e9c09","unresolved":true,"context_lines":[{"line_number":20,"context_line":"import futurist._thread as futurist_thread"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"import glance.async_"},{"line_number":23,"context_line":"# NOTE(danms): Default to native threading for tests"},{"line_number":24,"context_line":"glance.async_.set_threadpool_model(\u0027native\u0027)"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"8e71f313_4f86dd07","line":23,"range":{"start_line":23,"start_character":12,"end_line":23,"end_character":13},"updated":"2026-06-02 15:20:02.000000000","message":"s/danms/pdeore/ or s/danms/akekane/ :)","commit_id":"628c0df9154dfdbfedfeef8ffcffe5d0d63c8e6a"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"50d6c2491059b74fe5a2717cade7bf679b3aeff6","unresolved":false,"context_lines":[{"line_number":20,"context_line":"import futurist._thread as futurist_thread"},{"line_number":21,"context_line":""},{"line_number":22,"context_line":"import glance.async_"},{"line_number":23,"context_line":"# NOTE(danms): Default to native threading for tests"},{"line_number":24,"context_line":"glance.async_.set_threadpool_model(\u0027native\u0027)"},{"line_number":25,"context_line":""},{"line_number":26,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"4259086b_d48b9124","line":23,"range":{"start_line":23,"start_character":12,"end_line":23,"end_character":13},"in_reply_to":"8e71f313_4f86dd07","updated":"2026-06-03 05:26:01.000000000","message":"Done","commit_id":"628c0df9154dfdbfedfeef8ffcffe5d0d63c8e6a"},{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"5973f19a86eedd3b56263414b92f98fa729e9c09","unresolved":true,"context_lines":[{"line_number":52,"context_line":"    pass"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"# Register our patched version that uses timeouts to prevent hangs"},{"line_number":55,"context_line":"atexit.register(_patched_clean_up)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"# See http://code.google.com/p/python-nose/issues/detail?id\u003d373"},{"line_number":58,"context_line":"# The code below enables tests to work with i18n _() blocks"}],"source_content_type":"text/x-python","patch_set":6,"id":"0ec2ab44_b55dc4e3","line":55,"range":{"start_line":55,"start_character":0,"end_line":55,"end_character":15},"updated":"2026-06-02 15:20:02.000000000","message":"About this whole _patched_clean_up thing.\n\n1) Do we have actual issues with threads blocking forever?\n2) Once we remove eventlet, could we switch to concurrent.futures?","commit_id":"628c0df9154dfdbfedfeef8ffcffe5d0d63c8e6a"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"50d6c2491059b74fe5a2717cade7bf679b3aeff6","unresolved":false,"context_lines":[{"line_number":52,"context_line":"    pass"},{"line_number":53,"context_line":""},{"line_number":54,"context_line":"# Register our patched version that uses timeouts to prevent hangs"},{"line_number":55,"context_line":"atexit.register(_patched_clean_up)"},{"line_number":56,"context_line":""},{"line_number":57,"context_line":"# See http://code.google.com/p/python-nose/issues/detail?id\u003d373"},{"line_number":58,"context_line":"# The code below enables tests to work with i18n _() blocks"}],"source_content_type":"text/x-python","patch_set":6,"id":"72791bdc_25477359","line":55,"range":{"start_line":55,"start_character":0,"end_line":55,"end_character":15},"in_reply_to":"0ec2ab44_b55dc4e3","updated":"2026-06-03 05:26:01.000000000","message":"Expanded comments explaining observed hangs and that this is test-only until eventlet removal","commit_id":"628c0df9154dfdbfedfeef8ffcffe5d0d63c8e6a"}],"glance/tests/functional/__init__.py":[{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"5973f19a86eedd3b56263414b92f98fa729e9c09","unresolved":true,"context_lines":[{"line_number":766,"context_line":"        # With native threading, the import task may still hold database locks"},{"line_number":767,"context_line":"        # briefly after completion. Add a small delay to ensure locks are"},{"line_number":768,"context_line":"        # fully released before proceeding with operations like delete."},{"line_number":769,"context_line":"        time.sleep(0.2)"},{"line_number":770,"context_line":""},{"line_number":771,"context_line":"        return image"},{"line_number":772,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"bdb27e0c_7a650b18","line":769,"range":{"start_line":769,"start_character":22,"end_line":769,"end_character":23},"updated":"2026-06-02 15:20:02.000000000","message":"This does not feel very robust.\n\nIs there no other way to do this? Like maybe locking/unlocking ourselves?","commit_id":"628c0df9154dfdbfedfeef8ffcffe5d0d63c8e6a"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"50d6c2491059b74fe5a2717cade7bf679b3aeff6","unresolved":false,"context_lines":[{"line_number":766,"context_line":"        # With native threading, the import task may still hold database locks"},{"line_number":767,"context_line":"        # briefly after completion. Add a small delay to ensure locks are"},{"line_number":768,"context_line":"        # fully released before proceeding with operations like delete."},{"line_number":769,"context_line":"        time.sleep(0.2)"},{"line_number":770,"context_line":""},{"line_number":771,"context_line":"        return image"},{"line_number":772,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"192ac15a_48b2a782","line":769,"range":{"start_line":769,"start_character":22,"end_line":769,"end_character":23},"in_reply_to":"bdb27e0c_7a650b18","updated":"2026-06-03 05:26:01.000000000","message":"Replaced with waiting mechanism","commit_id":"628c0df9154dfdbfedfeef8ffcffe5d0d63c8e6a"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"44428589e1c5f3b89010b066533b5cdfdd11248b","unresolved":true,"context_lines":[{"line_number":796,"context_line":"        self.assertGreater(len(tasks), 0)"},{"line_number":797,"context_line":"        return tasks[-1]"},{"line_number":798,"context_line":""},{"line_number":799,"context_line":"    def _get_import_task(self, image_id, task_id\u003dNone, exclude_task_ids\u003dNone,"},{"line_number":800,"context_line":"                         max_sec\u003d2, delay_sec\u003d0.1):"},{"line_number":801,"context_line":"        \"\"\"Get import task for image. Retry if task is not ready yet.\"\"\""},{"line_number":802,"context_line":"        if task_id is not None:"}],"source_content_type":"text/x-python","patch_set":8,"id":"bfa65a13_fb2e8db2","line":799,"updated":"2026-06-04 14:58:36.000000000","message":"Is this used?","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"4342653fc6d156150306cc5e1c1cd62105f1c84f","unresolved":true,"context_lines":[{"line_number":796,"context_line":"        self.assertGreater(len(tasks), 0)"},{"line_number":797,"context_line":"        return tasks[-1]"},{"line_number":798,"context_line":""},{"line_number":799,"context_line":"    def _get_import_task(self, image_id, task_id\u003dNone, exclude_task_ids\u003dNone,"},{"line_number":800,"context_line":"                         max_sec\u003d2, delay_sec\u003d0.1):"},{"line_number":801,"context_line":"        \"\"\"Get import task for image. Retry if task is not ready yet.\"\"\""},{"line_number":802,"context_line":"        if task_id is not None:"}],"source_content_type":"text/x-python","patch_set":8,"id":"fb680655_461ba49f","line":799,"in_reply_to":"bfa65a13_fb2e8db2","updated":"2026-06-05 11:27:44.000000000","message":"Yes — it’s used by test_images_import_locking.py via _get_image_import_task(). Needed for retry logic when finding the second import task after lock bust.","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"01cfed2a617c83659f56b0645553535f644cdf1d","unresolved":false,"context_lines":[{"line_number":796,"context_line":"        self.assertGreater(len(tasks), 0)"},{"line_number":797,"context_line":"        return tasks[-1]"},{"line_number":798,"context_line":""},{"line_number":799,"context_line":"    def _get_import_task(self, image_id, task_id\u003dNone, exclude_task_ids\u003dNone,"},{"line_number":800,"context_line":"                         max_sec\u003d2, delay_sec\u003d0.1):"},{"line_number":801,"context_line":"        \"\"\"Get import task for image. Retry if task is not ready yet.\"\"\""},{"line_number":802,"context_line":"        if task_id is not None:"}],"source_content_type":"text/x-python","patch_set":8,"id":"27f037a3_8a7eb847","line":799,"in_reply_to":"fb680655_461ba49f","updated":"2026-06-05 15:52:49.000000000","message":"Acknowledged","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"44428589e1c5f3b89010b066533b5cdfdd11248b","unresolved":true,"context_lines":[{"line_number":824,"context_line":""},{"line_number":825,"context_line":"        self.fail(\u0027Timed out waiting for import task on image %s\u0027 % image_id)"},{"line_number":826,"context_line":""},{"line_number":827,"context_line":"    def _wait_for_task_status(self, task_id, expected_status, max_sec\u003d2,"},{"line_number":828,"context_line":"                              delay_sec\u003d0.1):"},{"line_number":829,"context_line":"        \"\"\"Wait until task has expected status.\"\"\""},{"line_number":830,"context_line":"        done_time \u003d time.time() + max_sec"}],"source_content_type":"text/x-python","patch_set":8,"id":"a199cc69_4b451e79","line":827,"updated":"2026-06-04 14:58:36.000000000","message":"Am I missing where this is used?","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"4342653fc6d156150306cc5e1c1cd62105f1c84f","unresolved":true,"context_lines":[{"line_number":824,"context_line":""},{"line_number":825,"context_line":"        self.fail(\u0027Timed out waiting for import task on image %s\u0027 % image_id)"},{"line_number":826,"context_line":""},{"line_number":827,"context_line":"    def _wait_for_task_status(self, task_id, expected_status, max_sec\u003d2,"},{"line_number":828,"context_line":"                              delay_sec\u003d0.1):"},{"line_number":829,"context_line":"        \"\"\"Wait until task has expected status.\"\"\""},{"line_number":830,"context_line":"        done_time \u003d time.time() + max_sec"}],"source_content_type":"text/x-python","patch_set":8,"id":"cb19fcad_fbe7a9fa","line":827,"in_reply_to":"a199cc69_4b451e79","updated":"2026-06-05 11:27:44.000000000","message":"This is used in test_images_import_locking.py when warp_time\u003dTrue, to wait for the second task to reach processing.","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"01cfed2a617c83659f56b0645553535f644cdf1d","unresolved":false,"context_lines":[{"line_number":824,"context_line":""},{"line_number":825,"context_line":"        self.fail(\u0027Timed out waiting for import task on image %s\u0027 % image_id)"},{"line_number":826,"context_line":""},{"line_number":827,"context_line":"    def _wait_for_task_status(self, task_id, expected_status, max_sec\u003d2,"},{"line_number":828,"context_line":"                              delay_sec\u003d0.1):"},{"line_number":829,"context_line":"        \"\"\"Wait until task has expected status.\"\"\""},{"line_number":830,"context_line":"        done_time \u003d time.time() + max_sec"}],"source_content_type":"text/x-python","patch_set":8,"id":"325263ad_2de942d3","line":827,"in_reply_to":"cb19fcad_fbe7a9fa","updated":"2026-06-05 15:52:49.000000000","message":"Acknowledged","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"44428589e1c5f3b89010b066533b5cdfdd11248b","unresolved":true,"context_lines":[{"line_number":839,"context_line":"                         \u0027Timed out waiting for task %s status\u0027 % task_id)"},{"line_number":840,"context_line":"        return task"},{"line_number":841,"context_line":""},{"line_number":842,"context_line":"    def _wait_for_latest_task_terminal(self, image_id, max_sec\u003d5,"},{"line_number":843,"context_line":"                                       delay_sec\u003d0.1):"},{"line_number":844,"context_line":"        \"\"\"Wait until latest task is success or failure.\"\"\""},{"line_number":845,"context_line":"        done_time \u003d time.time() + max_sec"}],"source_content_type":"text/x-python","patch_set":8,"id":"1e45739c_b1d14ecb","line":842,"range":{"start_line":842,"start_character":30,"end_line":842,"end_character":38},"updated":"2026-06-04 14:58:36.000000000","message":"\"termination\" would make more sense here.","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"4342653fc6d156150306cc5e1c1cd62105f1c84f","unresolved":false,"context_lines":[{"line_number":839,"context_line":"                         \u0027Timed out waiting for task %s status\u0027 % task_id)"},{"line_number":840,"context_line":"        return task"},{"line_number":841,"context_line":""},{"line_number":842,"context_line":"    def _wait_for_latest_task_terminal(self, image_id, max_sec\u003d5,"},{"line_number":843,"context_line":"                                       delay_sec\u003d0.1):"},{"line_number":844,"context_line":"        \"\"\"Wait until latest task is success or failure.\"\"\""},{"line_number":845,"context_line":"        done_time \u003d time.time() + max_sec"}],"source_content_type":"text/x-python","patch_set":8,"id":"350a223d_49af9fda","line":842,"range":{"start_line":842,"start_character":30,"end_line":842,"end_character":38},"in_reply_to":"1e45739c_b1d14ecb","updated":"2026-06-05 11:27:44.000000000","message":"Done","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"44428589e1c5f3b89010b066533b5cdfdd11248b","unresolved":true,"context_lines":[{"line_number":854,"context_line":"            time.sleep(delay_sec)"},{"line_number":855,"context_line":""},{"line_number":856,"context_line":"        task \u003d self._get_latest_task(image_id)"},{"line_number":857,"context_line":"        self.assertIn(task[\u0027status\u0027], (\u0027success\u0027, \u0027failure\u0027),"},{"line_number":858,"context_line":"                      \u0027Timed out waiting for task to finish\u0027)"},{"line_number":859,"context_line":"        return task"},{"line_number":860,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"b65ae7c9_cf8b8961","line":857,"updated":"2026-06-04 14:58:36.000000000","message":"Will we ever pass this? Only if we time out in the loop and happen to have finished successfully right? I would think we should just make falling out of the timeout loop mean we raise a timed-out error...","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"01cfed2a617c83659f56b0645553535f644cdf1d","unresolved":false,"context_lines":[{"line_number":854,"context_line":"            time.sleep(delay_sec)"},{"line_number":855,"context_line":""},{"line_number":856,"context_line":"        task \u003d self._get_latest_task(image_id)"},{"line_number":857,"context_line":"        self.assertIn(task[\u0027status\u0027], (\u0027success\u0027, \u0027failure\u0027),"},{"line_number":858,"context_line":"                      \u0027Timed out waiting for task to finish\u0027)"},{"line_number":859,"context_line":"        return task"},{"line_number":860,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"cbafdcf6_0579032d","line":857,"in_reply_to":"6f9fe944_d49385f1","updated":"2026-06-05 15:52:49.000000000","message":"Acknowledged","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"4342653fc6d156150306cc5e1c1cd62105f1c84f","unresolved":true,"context_lines":[{"line_number":854,"context_line":"            time.sleep(delay_sec)"},{"line_number":855,"context_line":""},{"line_number":856,"context_line":"        task \u003d self._get_latest_task(image_id)"},{"line_number":857,"context_line":"        self.assertIn(task[\u0027status\u0027], (\u0027success\u0027, \u0027failure\u0027),"},{"line_number":858,"context_line":"                      \u0027Timed out waiting for task to finish\u0027)"},{"line_number":859,"context_line":"        return task"},{"line_number":860,"context_line":""}],"source_content_type":"text/x-python","patch_set":8,"id":"6f9fe944_d49385f1","line":857,"in_reply_to":"b65ae7c9_cf8b8961","updated":"2026-06-05 11:27:44.000000000","message":"Good point. Falling out of the loop now raises an explicit timeout via self.fail() with the last known status, instead of a post-loop assert.","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"}],"glance/tests/functional/image_cache/drivers/test_centralized_db.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"44428589e1c5f3b89010b066533b5cdfdd11248b","unresolved":true,"context_lines":[{"line_number":347,"context_line":"            self.driver.delete_queued_image(images[\u0027public\u0027])"},{"line_number":348,"context_line":"            self.assertFalse(self.driver.is_queued(images[\u0027public\u0027]))"},{"line_number":349,"context_line":"            if self.driver.is_cached(images[\u0027public\u0027]):"},{"line_number":350,"context_line":"                self.driver.delete_cached_image(images[\u0027public\u0027])"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def test_delete_all_queued_images(self):"},{"line_number":353,"context_line":"        self.start_server(enable_cache\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":8,"id":"bf4ccf48_bd6b7e0f","line":350,"updated":"2026-06-04 14:58:36.000000000","message":"I understand why you need to do this, but it seems like a bad idea to have a test that has two completely different assertion patterns. Why would we not set the cache worker to run extremely infrequently and keep just the queued part? We could also make it run twice, so that if we got super unlucky and it cached while we were watching, a second attempt won\u0027t if the worker won\u0027t run again for ten minutes. Alternately, we could make some way to disable the cache worker, either with a mock or a config interval set to zero?","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"694916c885d4d3ecf3bbae9fa6972bc4589d76be","unresolved":false,"context_lines":[{"line_number":347,"context_line":"            self.driver.delete_queued_image(images[\u0027public\u0027])"},{"line_number":348,"context_line":"            self.assertFalse(self.driver.is_queued(images[\u0027public\u0027]))"},{"line_number":349,"context_line":"            if self.driver.is_cached(images[\u0027public\u0027]):"},{"line_number":350,"context_line":"                self.driver.delete_cached_image(images[\u0027public\u0027])"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def test_delete_all_queued_images(self):"},{"line_number":353,"context_line":"        self.start_server(enable_cache\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":8,"id":"66604c80_151f0608","line":350,"in_reply_to":"5ee1490f_171fa531","updated":"2026-06-08 15:13:03.000000000","message":"Done","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"4342653fc6d156150306cc5e1c1cd62105f1c84f","unresolved":true,"context_lines":[{"line_number":347,"context_line":"            self.driver.delete_queued_image(images[\u0027public\u0027])"},{"line_number":348,"context_line":"            self.assertFalse(self.driver.is_queued(images[\u0027public\u0027]))"},{"line_number":349,"context_line":"            if self.driver.is_cached(images[\u0027public\u0027]):"},{"line_number":350,"context_line":"                self.driver.delete_cached_image(images[\u0027public\u0027])"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def test_delete_all_queued_images(self):"},{"line_number":353,"context_line":"        self.start_server(enable_cache\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":8,"id":"f698996f_f6b846bc","line":350,"in_reply_to":"bf4ccf48_bd6b7e0f","updated":"2026-06-05 11:27:44.000000000","message":"Agreed — the if/else path is not ideal. This is fixed in the follow-up patch 987156 by mocking WORKER.submit so the image stays queued and we keep strict assertions.","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"ba95cbbcfb05f039c822e7b7bd356877748a79b2","unresolved":true,"context_lines":[{"line_number":347,"context_line":"            self.driver.delete_queued_image(images[\u0027public\u0027])"},{"line_number":348,"context_line":"            self.assertFalse(self.driver.is_queued(images[\u0027public\u0027]))"},{"line_number":349,"context_line":"            if self.driver.is_cached(images[\u0027public\u0027]):"},{"line_number":350,"context_line":"                self.driver.delete_cached_image(images[\u0027public\u0027])"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def test_delete_all_queued_images(self):"},{"line_number":353,"context_line":"        self.start_server(enable_cache\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":8,"id":"5ee1490f_171fa531","line":350,"in_reply_to":"de5095b1_bed559c7","updated":"2026-06-08 07:18:10.000000000","message":"Sorry for the confusion. I tried to fix this only in the follow-up cache patch, but the if/else workaround was introduced in this change, so the mock belongs here. PS10 mocks WORKER.submit on the queue PUT and removes the if/else branches in both queued-image tests.","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"01cfed2a617c83659f56b0645553535f644cdf1d","unresolved":true,"context_lines":[{"line_number":347,"context_line":"            self.driver.delete_queued_image(images[\u0027public\u0027])"},{"line_number":348,"context_line":"            self.assertFalse(self.driver.is_queued(images[\u0027public\u0027]))"},{"line_number":349,"context_line":"            if self.driver.is_cached(images[\u0027public\u0027]):"},{"line_number":350,"context_line":"                self.driver.delete_cached_image(images[\u0027public\u0027])"},{"line_number":351,"context_line":""},{"line_number":352,"context_line":"    def test_delete_all_queued_images(self):"},{"line_number":353,"context_line":"        self.start_server(enable_cache\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":8,"id":"de5095b1_bed559c7","line":350,"in_reply_to":"f698996f_f6b846bc","updated":"2026-06-05 15:52:49.000000000","message":"It\u0027s not fixed because (as I noted there) you still have the if/else. Why not just move that worker mock here and avoid making it wrong for one commit?","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"44428589e1c5f3b89010b066533b5cdfdd11248b","unresolved":true,"context_lines":[{"line_number":382,"context_line":""},{"line_number":383,"context_line":"        self.assertEqual(0, len(self.driver.get_queued_images()))"},{"line_number":384,"context_line":"        self.assertFalse(self.driver.is_queued(images[\u0027public\u0027]))"},{"line_number":385,"context_line":"        self.assertFalse(self.driver.is_queued(images[\u0027private\u0027]))"},{"line_number":386,"context_line":""},{"line_number":387,"context_line":"    def test_clean(self):"},{"line_number":388,"context_line":"        self.start_server(enable_cache\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":8,"id":"01f03749_ea32c90f","line":385,"updated":"2026-06-04 14:58:36.000000000","message":"Why does this not suffer the same race as you\u0027re attempting to work around in the test above?","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"4342653fc6d156150306cc5e1c1cd62105f1c84f","unresolved":true,"context_lines":[{"line_number":382,"context_line":""},{"line_number":383,"context_line":"        self.assertEqual(0, len(self.driver.get_queued_images()))"},{"line_number":384,"context_line":"        self.assertFalse(self.driver.is_queued(images[\u0027public\u0027]))"},{"line_number":385,"context_line":"        self.assertFalse(self.driver.is_queued(images[\u0027private\u0027]))"},{"line_number":386,"context_line":""},{"line_number":387,"context_line":"    def test_clean(self):"},{"line_number":388,"context_line":"        self.start_server(enable_cache\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":8,"id":"94d57ae9_a5d7c50d","line":385,"in_reply_to":"01f03749_ea32c90f","updated":"2026-06-05 11:27:44.000000000","message":"Yes, same race. Also fixed in 987156 with the same WORKER.submit mock for both queue PUTs.","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"694916c885d4d3ecf3bbae9fa6972bc4589d76be","unresolved":false,"context_lines":[{"line_number":382,"context_line":""},{"line_number":383,"context_line":"        self.assertEqual(0, len(self.driver.get_queued_images()))"},{"line_number":384,"context_line":"        self.assertFalse(self.driver.is_queued(images[\u0027public\u0027]))"},{"line_number":385,"context_line":"        self.assertFalse(self.driver.is_queued(images[\u0027private\u0027]))"},{"line_number":386,"context_line":""},{"line_number":387,"context_line":"    def test_clean(self):"},{"line_number":388,"context_line":"        self.start_server(enable_cache\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":8,"id":"64f781d6_72bd0961","line":385,"in_reply_to":"94d57ae9_a5d7c50d","updated":"2026-06-08 15:13:03.000000000","message":"Done","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"}],"glance/tests/functional/v2/test_cache_api.py":[{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"44428589e1c5f3b89010b066533b5cdfdd11248b","unresolved":true,"context_lines":[{"line_number":104,"context_line":"                   (expected_code, response.status_code))"},{"line_number":105,"context_line":"            self.assertIn(response.status_code, expected_code, msg)"},{"line_number":106,"context_line":"        else:"},{"line_number":107,"context_line":"            self.assertEqual(expected_code, response.status_code)"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def cache_clear(self, target\u003d\u0027\u0027, expected_code\u003d204):"},{"line_number":110,"context_line":"        path \u003d \u0027/v2/cache\u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"efccbd2e_42bbe3e7","line":107,"updated":"2026-06-04 14:58:36.000000000","message":"Hmm, why do we need this change? Maybe some comment here to explain?","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"01cfed2a617c83659f56b0645553535f644cdf1d","unresolved":true,"context_lines":[{"line_number":104,"context_line":"                   (expected_code, response.status_code))"},{"line_number":105,"context_line":"            self.assertIn(response.status_code, expected_code, msg)"},{"line_number":106,"context_line":"        else:"},{"line_number":107,"context_line":"            self.assertEqual(expected_code, response.status_code)"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def cache_clear(self, target\u003d\u0027\u0027, expected_code\u003d204):"},{"line_number":110,"context_line":"        path \u003d \u0027/v2/cache\u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"c2c4b4b4_7bcc5e41","line":107,"in_reply_to":"582ce64d_263a3b4e","updated":"2026-06-05 15:52:49.000000000","message":"Thanks, but the comment doesn\u0027t explain it other than what is obvious from the code. *why* is a tuple returned sometimes? Is it because something returns 204 on success or (404, \u0027error message\u0027) on error? That seems like terrible behavior for a utility method, if so.","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"ba95cbbcfb05f039c822e7b7bd356877748a79b2","unresolved":true,"context_lines":[{"line_number":104,"context_line":"                   (expected_code, response.status_code))"},{"line_number":105,"context_line":"            self.assertIn(response.status_code, expected_code, msg)"},{"line_number":106,"context_line":"        else:"},{"line_number":107,"context_line":"            self.assertEqual(expected_code, response.status_code)"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def cache_clear(self, target\u003d\u0027\u0027, expected_code\u003d204):"},{"line_number":110,"context_line":"        path \u003d \u0027/v2/cache\u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"e7b3c8e2_83aac0e2","line":107,"in_reply_to":"c2c4b4b4_7bcc5e41","updated":"2026-06-08 07:18:10.000000000","message":"Yeah, removed tuple support from the helper. In test_cache_image_queue_delete, after we delete the image we call list_cache() first. If the cache entry is still there, we call cache_delete(). If it is already gone, we skip that and just check the cache is empty. The race is handled in the test, not in the helper.","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":4393,"name":"Dan Smith","email":"dms@danplanet.com","username":"danms"},"change_message_id":"694916c885d4d3ecf3bbae9fa6972bc4589d76be","unresolved":false,"context_lines":[{"line_number":104,"context_line":"                   (expected_code, response.status_code))"},{"line_number":105,"context_line":"            self.assertIn(response.status_code, expected_code, msg)"},{"line_number":106,"context_line":"        else:"},{"line_number":107,"context_line":"            self.assertEqual(expected_code, response.status_code)"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def cache_clear(self, target\u003d\u0027\u0027, expected_code\u003d204):"},{"line_number":110,"context_line":"        path \u003d \u0027/v2/cache\u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"cf2684f2_88f3fbc0","line":107,"in_reply_to":"e7b3c8e2_83aac0e2","updated":"2026-06-08 15:13:03.000000000","message":"Done","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"},{"author":{"_account_id":19138,"name":"Pranali Deore","email":"pdeore@redhat.com","username":"PranaliD"},"change_message_id":"4342653fc6d156150306cc5e1c1cd62105f1c84f","unresolved":true,"context_lines":[{"line_number":104,"context_line":"                   (expected_code, response.status_code))"},{"line_number":105,"context_line":"            self.assertIn(response.status_code, expected_code, msg)"},{"line_number":106,"context_line":"        else:"},{"line_number":107,"context_line":"            self.assertEqual(expected_code, response.status_code)"},{"line_number":108,"context_line":""},{"line_number":109,"context_line":"    def cache_clear(self, target\u003d\u0027\u0027, expected_code\u003d204):"},{"line_number":110,"context_line":"        path \u003d \u0027/v2/cache\u0027"}],"source_content_type":"text/x-python","patch_set":8,"id":"582ce64d_263a3b4e","line":107,"in_reply_to":"efccbd2e_42bbe3e7","updated":"2026-06-05 11:27:44.000000000","message":"Needed because under native threading the image may already be gone from cache when we call cache_delete after deleting the original image (204 or 404 are both valid). Added a comment to explain this.","commit_id":"f3e0479a8f29487da3db28716b203f77d9166351"}],"glance/tests/functional/v2/test_images_import_locking.py":[{"author":{"_account_id":8122,"name":"Cyril Roelandt","email":"cyril@redhat.com","username":"cyril.roelandt.enovance"},"change_message_id":"5973f19a86eedd3b56263414b92f98fa729e9c09","unresolved":true,"context_lines":[{"line_number":44,"context_line":"                time.sleep(0.1)"},{"line_number":45,"context_line":"            else:"},{"line_number":46,"context_line":"                raise Exception(\"Image %s has no import task after waiting\" %"},{"line_number":47,"context_line":"                                image_id)"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"        return self.api_get(\u0027/v2/tasks/%s\u0027 % task_id).json"},{"line_number":50,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"06b3b5a5_813c8527","line":47,"range":{"start_line":47,"start_character":32,"end_line":47,"end_character":40},"updated":"2026-06-02 15:20:02.000000000","message":"Yes, this is a bit weird as well. Is there no way to do better than retrying 20 times?","commit_id":"628c0df9154dfdbfedfeef8ffcffe5d0d63c8e6a"},{"author":{"_account_id":9303,"name":"Abhishek Kekane","email":"akekane@redhat.com","username":"abhishekkekane"},"change_message_id":"50d6c2491059b74fe5a2717cade7bf679b3aeff6","unresolved":false,"context_lines":[{"line_number":44,"context_line":"                time.sleep(0.1)"},{"line_number":45,"context_line":"            else:"},{"line_number":46,"context_line":"                raise Exception(\"Image %s has no import task after waiting\" %"},{"line_number":47,"context_line":"                                image_id)"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"        return self.api_get(\u0027/v2/tasks/%s\u0027 % task_id).json"},{"line_number":50,"context_line":""}],"source_content_type":"text/x-python","patch_set":6,"id":"1ed834bd_42d33b84","line":47,"range":{"start_line":47,"start_character":32,"end_line":47,"end_character":40},"in_reply_to":"06b3b5a5_813c8527","updated":"2026-06-03 05:26:01.000000000","message":"replaced with helper methods.","commit_id":"628c0df9154dfdbfedfeef8ffcffe5d0d63c8e6a"}]}
