)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8789c4b686c9fd607a9e860772076b49953c053a","unresolved":true,"context_lines":[{"line_number":9,"context_line":"Various parts of the relinker record the invoked action (\u0027relink\u0027,"},{"line_number":10,"context_line":"\u0027cleanup\u0027) in generated log messages, without utilizing a uniform"},{"line_number":11,"context_line":"format. In most cases the logged prefix was cleanup\u003d(True/False)."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes this by using a prefixed logger that prepends log"},{"line_number":14,"context_line":"messages with the invoked action\u0027s name, which seamlessly supports any"},{"line_number":15,"context_line":"actions added to the relinker in the future."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"32b17510_51e6c348","line":12,"updated":"2026-02-09 16:19:47.000000000","message":"I think the cleanup\u003d(True|False) tended to be logged as a suffix","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":false,"context_lines":[{"line_number":9,"context_line":"Various parts of the relinker record the invoked action (\u0027relink\u0027,"},{"line_number":10,"context_line":"\u0027cleanup\u0027) in generated log messages, without utilizing a uniform"},{"line_number":11,"context_line":"format. In most cases the logged prefix was cleanup\u003d(True/False)."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes this by using a prefixed logger that prepends log"},{"line_number":14,"context_line":"messages with the invoked action\u0027s name, which seamlessly supports any"},{"line_number":15,"context_line":"actions added to the relinker in the future."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"a0b3e49a_d1cbf6e4","line":12,"in_reply_to":"32b17510_51e6c348","updated":"2026-02-10 03:58:56.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":9,"context_line":"Various parts of the relinker record the invoked action (\u0027relink\u0027,"},{"line_number":10,"context_line":"\u0027cleanup\u0027) in generated log messages, without utilizing a uniform"},{"line_number":11,"context_line":"format. In most cases the logged prefix was cleanup\u003d(True/False)."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes this by using a prefixed logger that prepends log"},{"line_number":14,"context_line":"messages with the invoked action\u0027s name, which seamlessly supports any"},{"line_number":15,"context_line":"actions added to the relinker in the future."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"c10a528b_40319407","line":12,"in_reply_to":"32b17510_51e6c348","updated":"2026-02-10 03:58:56.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"f2ea961a90007c5e97ff6e91f1d4174e7aca7499","unresolved":false,"context_lines":[{"line_number":9,"context_line":"Various parts of the relinker record the invoked action (\u0027relink\u0027,"},{"line_number":10,"context_line":"\u0027cleanup\u0027) in generated log messages, without utilizing a uniform"},{"line_number":11,"context_line":"format. In most cases the logged prefix was cleanup\u003d(True/False)."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes this by using a prefixed logger that prepends log"},{"line_number":14,"context_line":"messages with the invoked action\u0027s name, which seamlessly supports any"},{"line_number":15,"context_line":"actions added to the relinker in the future."}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"cadea7bc_5e039287","line":12,"in_reply_to":"c10a528b_40319407","updated":"2026-02-10 04:01:42.000000000","message":"Done","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8789c4b686c9fd607a9e860772076b49953c053a","unresolved":true,"context_lines":[{"line_number":10,"context_line":"\u0027cleanup\u0027) in generated log messages, without utilizing a uniform"},{"line_number":11,"context_line":"format. In most cases the logged prefix was cleanup\u003d(True/False)."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes this by using a prefixed logger that prepends log"},{"line_number":14,"context_line":"messages with the invoked action\u0027s name, which seamlessly supports any"},{"line_number":15,"context_line":"actions added to the relinker in the future."},{"line_number":16,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"3cb909c0_0be0b19c","line":13,"updated":"2026-02-09 16:19:47.000000000","message":"s/fixes/improves","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":false,"context_lines":[{"line_number":10,"context_line":"\u0027cleanup\u0027) in generated log messages, without utilizing a uniform"},{"line_number":11,"context_line":"format. In most cases the logged prefix was cleanup\u003d(True/False)."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes this by using a prefixed logger that prepends log"},{"line_number":14,"context_line":"messages with the invoked action\u0027s name, which seamlessly supports any"},{"line_number":15,"context_line":"actions added to the relinker in the future."},{"line_number":16,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"6509fe36_e7297f85","line":13,"in_reply_to":"3cb909c0_0be0b19c","updated":"2026-02-10 03:58:56.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":10,"context_line":"\u0027cleanup\u0027) in generated log messages, without utilizing a uniform"},{"line_number":11,"context_line":"format. In most cases the logged prefix was cleanup\u003d(True/False)."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes this by using a prefixed logger that prepends log"},{"line_number":14,"context_line":"messages with the invoked action\u0027s name, which seamlessly supports any"},{"line_number":15,"context_line":"actions added to the relinker in the future."},{"line_number":16,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"ae7d9735_37332005","line":13,"in_reply_to":"3cb909c0_0be0b19c","updated":"2026-02-10 03:58:56.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"f2ea961a90007c5e97ff6e91f1d4174e7aca7499","unresolved":false,"context_lines":[{"line_number":10,"context_line":"\u0027cleanup\u0027) in generated log messages, without utilizing a uniform"},{"line_number":11,"context_line":"format. In most cases the logged prefix was cleanup\u003d(True/False)."},{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes this by using a prefixed logger that prepends log"},{"line_number":14,"context_line":"messages with the invoked action\u0027s name, which seamlessly supports any"},{"line_number":15,"context_line":"actions added to the relinker in the future."},{"line_number":16,"context_line":""}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"f9a55045_69111d90","line":13,"in_reply_to":"ae7d9735_37332005","updated":"2026-02-10 04:01:42.000000000","message":"Done","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8789c4b686c9fd607a9e860772076b49953c053a","unresolved":true,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes this by using a prefixed logger that prepends log"},{"line_number":14,"context_line":"messages with the invoked action\u0027s name, which seamlessly supports any"},{"line_number":15,"context_line":"actions added to the relinker in the future."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Change-Id: I046c4837a638d097649688db39455fb089fa7007"},{"line_number":18,"context_line":"Signed-off-by: Wael Halbawi \u003cwhalbawi@nvidia.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"ed7f959d_af9b6490","line":15,"updated":"2026-02-09 16:19:47.000000000","message":"foreshadowing - I like it!","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"f2ea961a90007c5e97ff6e91f1d4174e7aca7499","unresolved":false,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes this by using a prefixed logger that prepends log"},{"line_number":14,"context_line":"messages with the invoked action\u0027s name, which seamlessly supports any"},{"line_number":15,"context_line":"actions added to the relinker in the future."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Change-Id: I046c4837a638d097649688db39455fb089fa7007"},{"line_number":18,"context_line":"Signed-off-by: Wael Halbawi \u003cwhalbawi@nvidia.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"5a355362_ad6410d9","line":15,"in_reply_to":"d85c8ad6_475fec68","updated":"2026-02-10 04:01:42.000000000","message":"Done","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes this by using a prefixed logger that prepends log"},{"line_number":14,"context_line":"messages with the invoked action\u0027s name, which seamlessly supports any"},{"line_number":15,"context_line":"actions added to the relinker in the future."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Change-Id: I046c4837a638d097649688db39455fb089fa7007"},{"line_number":18,"context_line":"Signed-off-by: Wael Halbawi \u003cwhalbawi@nvidia.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"1bc987a6_a429b1d4","line":15,"in_reply_to":"ed7f959d_af9b6490","updated":"2026-02-10 03:58:56.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":12,"context_line":""},{"line_number":13,"context_line":"This patch fixes this by using a prefixed logger that prepends log"},{"line_number":14,"context_line":"messages with the invoked action\u0027s name, which seamlessly supports any"},{"line_number":15,"context_line":"actions added to the relinker in the future."},{"line_number":16,"context_line":""},{"line_number":17,"context_line":"Change-Id: I046c4837a638d097649688db39455fb089fa7007"},{"line_number":18,"context_line":"Signed-off-by: Wael Halbawi \u003cwhalbawi@nvidia.com\u003e"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":2,"id":"d85c8ad6_475fec68","line":15,"in_reply_to":"ed7f959d_af9b6490","updated":"2026-02-10 03:58:56.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"}],"/PATCHSET_LEVEL":[{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8789c4b686c9fd607a9e860772076b49953c053a","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"5906f36b_0822f7ab","updated":"2026-02-09 16:19:47.000000000","message":"This is a welcome cleanup, I think it makes swift better w/o making anything terribly worse.  However, as a first time contributor I\u0027d like to give Wael a chance to respond to Al\u0027s comments as I think all of them point to things that would make the change *better*.\n\nI don\u0027t think I spotted anything *new* that Al didn\u0027t already see; but I\u0027d encourage Wael to consider (possibly as a follow-up?) pushing the `step` argument all the way into the `Relinker` class itself as opposed to the `do_cleanup` boolean.  Alternatively we may find that treating step/devices as primary inputs to the `Relinker` class makes it more attractive to implement the consistent logging prefix there and decide it\u0027s worth doing once and for all in a single patch - dunno!","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a6d558f583a41ea7513d909cb2812477920dfc","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"110755dd_27abac17","updated":"2026-02-04 17:35:55.000000000","message":"This looks like a great improvement and I feel bad leaving a -1, but there\u0027s a few things that are worth fixing IMHO.\n\nWe get cleaner code and more consistent log message context 😊","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":2,"id":"a618252d_a511a5eb","in_reply_to":"5906f36b_0822f7ab","updated":"2026-02-10 03:58:56.000000000","message":"I do think there\u0027s value in pushing step/devices into the Relinker. I\u0027m not 100% sure that we\u0027d want prefix logging implemented there since prefix loggers don\u0027t compose.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"15a1ab086c5316761bc8c470f726abb72db0a1c6","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":2,"id":"55d676aa_4a0fe765","in_reply_to":"7787ee13_2244aced","updated":"2026-02-11 17:54:12.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":true,"context_lines":[],"source_content_type":"","patch_set":2,"id":"7787ee13_2244aced","in_reply_to":"a618252d_a511a5eb","updated":"2026-02-10 21:03:14.000000000","message":"you could do composition explicitly by inspecting the passed-in logger:\n\n```\nbase_prefix \u003d getattr(plogger, \u0027prefix\u0027, \u0027\u0027)\n```\n\nYou could also just HAVE all the information you need to create the `(step, pid, devs)` prefix from the passed in arguments regardless of the current prefix on the logger (if any) - Relinker already gets devs argument and calls `os.getpid`.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"f2ea961a90007c5e97ff6e91f1d4174e7aca7499","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"ca896686_e140670b","updated":"2026-02-10 04:01:42.000000000","message":"@clay.gerrard@gmail.com @alistairncoles@gmail.com - Thanks for the thorough review!","commit_id":"4afc5c580985e2fa1fe5cfcfe7b1a8cabb0ab2f2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7cb106f4c9afaa0b087b3a63f8ebb8ec86b9a62b","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"b771a55d_1c681d1f","updated":"2026-02-11 12:09:48.000000000","message":"@whalbawi@nvidia.com nice work!\n\nConsistently formatted log lines are incredibly helpful. I\u0027m happy to merge this. There\u0027s been some healthy debate on potential polishing, none of which is prevented by getting this improvement onto master.\n\nFor the record, here\u0027s what I see when running the relinker (with this patch) in a probe test:\n\n```\nvagrant@saio:~/swift$ pytest ./test/probe/test_object_partpower_increase.py -k test_main -s\n\nvagrant@saio:~/nv-swift-inventory$ cat /var/log/syslog |grep relinker\nFeb 11 11:23:25 saio object-relinker-6010: [step\u003drelink] Starting relinker using 1 workers: 11:23:25 02/11/26 GMT\nFeb 11 11:23:25 saio object-relinker-6010: [step\u003drelink, pid\u003d107776, devs\u003dsdb1,sdb5] Processing files for policy ec under /srv/node1\nFeb 11 11:23:25 saio object-relinker-6010: [step\u003drelink, pid\u003d107776, devs\u003dsdb1,sdb5] Relinking created link: /srv/node1/sdb5/objects-1/768/a30/c00469761a9679245694727eaa285a30/1770809001.74664#5#d.data to /srv/node1/sdb5/objects-1/1536/a30/c00469761a9679245694727eaa285a30/1770809001.74664#5#d.data\nFeb 11 11:23:25 saio object-relinker-6010: [step\u003drelink, pid\u003d107776, devs\u003dsdb1,sdb5] Run listdir on /srv/node1/sdb5/objects-1/1536\nFeb 11 11:23:25 saio object-relinker-6010: [step\u003drelink, pid\u003d107776, devs\u003dsdb1,sdb5] Device: sdb5 Policy: ec Partitions: 1/1\nFeb 11 11:23:25 saio object-relinker-6010: [step\u003drelink, pid\u003d107776, devs\u003dsdb1,sdb5] Updating recon for sdb5\nFeb 11 11:23:25 saio object-relinker-6010: [step\u003drelink, pid\u003d107776, devs\u003dsdb1,sdb5] Relinking created link: /srv/node1/sdb1/objects-1/768/a30/c00469761a9679245694727eaa285a30/1770809001.74664#1#d.data to /srv/node1/sdb1/objects-1/1536/a30/c00469761a9679245694727eaa285a30/1770809001.74664#1#d.data\nFeb 11 11:23:25 saio object-relinker-6010: [step\u003drelink, pid\u003d107776, devs\u003dsdb1,sdb5] Run listdir on /srv/node1/sdb1/objects-1/1536\nFeb 11 11:23:25 saio object-relinker-6010: [step\u003drelink, pid\u003d107776, devs\u003dsdb1,sdb5] Device: sdb1 Policy: ec Partitions: 1/1\nFeb 11 11:23:25 saio object-relinker-6010: [step\u003drelink, pid\u003d107776, devs\u003dsdb1,sdb5] Updating recon for sdb1\nFeb 11 11:23:25 saio object-relinker-6010: [step\u003drelink, pid\u003d107776, devs\u003dsdb1,sdb5] Updating recon\nFeb 11 11:23:25 saio object-relinker-6010: [step\u003drelink, pid\u003d107776, devs\u003dsdb1,sdb5] 2 hash dirs processed (2 files, 2 linked, 0 removed, 0 errors)\nFeb 11 11:23:25 saio object-relinker-6010: [step\u003drelink] Finished relinker: 11:23:25 02/11/26 GMT (0:00:00.014883 elapsed)\nFeb 11 11:23:26 saio object-relinker-6020: [step\u003drelink] Starting relinker using 1 workers: 11:23:26 02/11/26 GMT\nFeb 11 11:23:26 saio object-relinker-6020: [step\u003drelink, pid\u003d107802, devs\u003dsdb2,sdb6] Processing files for policy ec under /srv/node2\nFeb 11 11:23:26 saio object-relinker-6020: [step\u003drelink, pid\u003d107802, devs\u003dsdb2,sdb6] Relinking created link: /srv/node2/sdb2/objects-1/768/a30/c00469761a9679245694727eaa285a30/1770809001.74664#2#d.data to /srv/node2/sdb2/objects-1/1536/a30/c00469761a9679245694727eaa285a30/1770809001.74664#2#d.data\nFeb 11 11:23:26 saio object-relinker-6020: [step\u003drelink, pid\u003d107802, devs\u003dsdb2,sdb6] Run listdir on /srv/node2/sdb2/objects-1/1536\nFeb 11 11:23:26 saio object-relinker-6020: [step\u003drelink, pid\u003d107802, devs\u003dsdb2,sdb6] Device: sdb2 Policy: ec Partitions: 1/1\nFeb 11 11:23:26 saio object-relinker-6020: [step\u003drelink, pid\u003d107802, devs\u003dsdb2,sdb6] Updating recon for sdb2\nFeb 11 11:23:26 saio object-relinker-6020: [step\u003drelink, pid\u003d107802, devs\u003dsdb2,sdb6] Updating recon for sdb6\nFeb 11 11:23:26 saio object-relinker-6020: [step\u003drelink, pid\u003d107802, devs\u003dsdb2,sdb6] Updating recon\nFeb 11 11:23:26 saio object-relinker-6020: [step\u003drelink, pid\u003d107802, devs\u003dsdb2,sdb6] 1 hash dirs processed (1 files, 1 linked, 0 removed, 0 errors)\nFeb 11 11:23:26 saio object-relinker-6020: [step\u003drelink] Finished relinker: 11:23:26 02/11/26 GMT (0:00:00.012452 elapsed)\nFeb 11 11:23:26 saio object-relinker-6030: [step\u003drelink] Starting relinker using 1 workers: 11:23:26 02/11/26 GMT\nFeb 11 11:23:26 saio object-relinker-6030: [step\u003drelink, pid\u003d107828, devs\u003dsdb3,sdb7] Processing files for policy ec under /srv/node3\nFeb 11 11:23:26 saio object-relinker-6030: [step\u003drelink, pid\u003d107828, devs\u003dsdb3,sdb7] Updating recon for sdb3\nFeb 11 11:23:26 saio object-relinker-6030: [step\u003drelink, pid\u003d107828, devs\u003dsdb3,sdb7] Relinking created link: /srv/node3/sdb7/objects-1/768/a30/c00469761a9679245694727eaa285a30/1770809001.74664#3#d.data to /srv/node3/sdb7/objects-1/1536/a30/c00469761a9679245694727eaa285a30/1770809001.74664#3#d.data\nFeb 11 11:23:26 saio object-relinker-6030: [step\u003drelink, pid\u003d107828, devs\u003dsdb3,sdb7] Run listdir on /srv/node3/sdb7/objects-1/1536\nFeb 11 11:23:26 saio object-relinker-6030: [step\u003drelink, pid\u003d107828, devs\u003dsdb3,sdb7] Device: sdb7 Policy: ec Partitions: 1/1\nFeb 11 11:23:26 saio object-relinker-6030: [step\u003drelink, pid\u003d107828, devs\u003dsdb3,sdb7] Updating recon for sdb7\nFeb 11 11:23:26 saio object-relinker-6030: [step\u003drelink, pid\u003d107828, devs\u003dsdb3,sdb7] Updating recon\nFeb 11 11:23:26 saio object-relinker-6030: [step\u003drelink, pid\u003d107828, devs\u003dsdb3,sdb7] 1 hash dirs processed (1 files, 1 linked, 0 removed, 0 errors)\nFeb 11 11:23:26 saio object-relinker-6030: [step\u003drelink] Finished relinker: 11:23:26 02/11/26 GMT (0:00:00.011731 elapsed)\nFeb 11 11:23:27 saio object-relinker-6040: [step\u003drelink] Starting relinker using 1 workers: 11:23:27 02/11/26 GMT\nFeb 11 11:23:27 saio object-relinker-6040: [step\u003drelink, pid\u003d107854, devs\u003dsdb4,sdb8] Processing files for policy ec under /srv/node4\nFeb 11 11:23:27 saio object-relinker-6040: [step\u003drelink, pid\u003d107854, devs\u003dsdb4,sdb8] Relinking created link: /srv/node4/sdb8/objects-1/768/a30/c00469761a9679245694727eaa285a30/1770809001.74664#4#d.data to /srv/node4/sdb8/objects-1/1536/a30/c00469761a9679245694727eaa285a30/1770809001.74664#4#d.data\nFeb 11 11:23:27 saio object-relinker-6040: [step\u003drelink, pid\u003d107854, devs\u003dsdb4,sdb8] Run listdir on /srv/node4/sdb8/objects-1/1536\nFeb 11 11:23:27 saio object-relinker-6040: [step\u003drelink, pid\u003d107854, devs\u003dsdb4,sdb8] Device: sdb8 Policy: ec Partitions: 1/1\nFeb 11 11:23:27 saio object-relinker-6040: [step\u003drelink, pid\u003d107854, devs\u003dsdb4,sdb8] Updating recon for sdb8\nFeb 11 11:23:27 saio object-relinker-6040: [step\u003drelink, pid\u003d107854, devs\u003dsdb4,sdb8] Relinking created link: /srv/node4/sdb4/objects-1/768/a30/c00469761a9679245694727eaa285a30/1770809001.74664#0#d.data to /srv/node4/sdb4/objects-1/1536/a30/c00469761a9679245694727eaa285a30/1770809001.74664#0#d.data\nFeb 11 11:23:27 saio object-relinker-6040: [step\u003drelink, pid\u003d107854, devs\u003dsdb4,sdb8] Run listdir on /srv/node4/sdb4/objects-1/1536\nFeb 11 11:23:27 saio object-relinker-6040: [step\u003drelink, pid\u003d107854, devs\u003dsdb4,sdb8] Device: sdb4 Policy: ec Partitions: 1/1\nFeb 11 11:23:27 saio object-relinker-6040: [step\u003drelink, pid\u003d107854, devs\u003dsdb4,sdb8] Updating recon for sdb4\nFeb 11 11:23:27 saio object-relinker-6040: [step\u003drelink, pid\u003d107854, devs\u003dsdb4,sdb8] Updating recon\nFeb 11 11:23:27 saio object-relinker-6040: [step\u003drelink, pid\u003d107854, devs\u003dsdb4,sdb8] 2 hash dirs processed (2 files, 2 linked, 0 removed, 0 errors)\nFeb 11 11:23:27 saio object-relinker-6040: [step\u003drelink] Finished relinker: 11:23:27 02/11/26 GMT (0:00:00.014801 elapsed)\nFeb 11 11:23:31 saio object-relinker-6010: [step\u003dcleanup] Starting relinker using 1 workers: 11:23:31 02/11/26 GMT\nFeb 11 11:23:31 saio object-relinker-6010: [step\u003dcleanup, pid\u003d107897, devs\u003dsdb1,sdb5] Processing files for policy ec under /srv/node1\nFeb 11 11:23:31 saio object-relinker-6010: [step\u003dcleanup, pid\u003d107897, devs\u003dsdb1,sdb5] Removed /srv/node1/sdb5/objects-1/768/a30/c00469761a9679245694727eaa285a30/1770809007.83086#5#d.data\nFeb 11 11:23:31 saio object-relinker-6010: [step\u003dcleanup, pid\u003d107897, devs\u003dsdb1,sdb5] Run listdir on /srv/node1/sdb5/objects-1/768\nFeb 11 11:23:31 saio object-relinker-6010: [step\u003dcleanup, pid\u003d107897, devs\u003dsdb1,sdb5] Device: sdb5 Policy: ec Partitions: 1/2\nFeb 11 11:23:31 saio object-relinker-6010: [step\u003dcleanup, pid\u003d107897, devs\u003dsdb1,sdb5] Removed /srv/node1/sdb5/objects-1/648/d61/a23c4ee9d41214053e86a65b4a7a0d61/1770809007.77171#3#d.data\nFeb 11 11:23:31 saio object-relinker-6010: [step\u003dcleanup, pid\u003d107897, devs\u003dsdb1,sdb5] Run listdir on /srv/node1/sdb5/objects-1/648\nFeb 11 11:23:31 saio object-relinker-6010: [step\u003dcleanup, pid\u003d107897, devs\u003dsdb1,sdb5] Device: sdb5 Policy: ec Partitions: 2/2\nFeb 11 11:23:31 saio object-relinker-6010: [step\u003dcleanup, pid\u003d107897, devs\u003dsdb1,sdb5] Updating recon for sdb5\nFeb 11 11:23:31 saio object-relinker-6010: [step\u003dcleanup, pid\u003d107897, devs\u003dsdb1,sdb5] Removed /srv/node1/sdb1/objects-1/768/a30/c00469761a9679245694727eaa285a30/1770809007.83086#1#d.data\nFeb 11 11:23:31 saio object-relinker-6010: [step\u003dcleanup, pid\u003d107897, devs\u003dsdb1,sdb5] Run listdir on /srv/node1/sdb1/objects-1/768\nFeb 11 11:23:31 saio object-relinker-6010: [step\u003dcleanup, pid\u003d107897, devs\u003dsdb1,sdb5] Device: sdb1 Policy: ec Partitions: 1/1\nFeb 11 11:23:31 saio object-relinker-6010: [step\u003dcleanup, pid\u003d107897, devs\u003dsdb1,sdb5] Updating recon for sdb1\nFeb 11 11:23:31 saio object-relinker-6010: [step\u003dcleanup, pid\u003d107897, devs\u003dsdb1,sdb5] Updating recon\nFeb 11 11:23:31 saio object-relinker-6010: [step\u003dcleanup, pid\u003d107897, devs\u003dsdb1,sdb5] 3 hash dirs processed (1 files, 0 linked, 3 removed, 0 errors)\nFeb 11 11:23:31 saio object-relinker-6010: [step\u003dcleanup] Finished relinker: 11:23:31 02/11/26 GMT (0:00:00.020420 elapsed)\nFeb 11 11:23:32 saio object-relinker-6020: [step\u003dcleanup] Starting relinker using 1 workers: 11:23:32 02/11/26 GMT\nFeb 11 11:23:32 saio object-relinker-6020: [step\u003dcleanup, pid\u003d107923, devs\u003dsdb2,sdb6] Processing files for policy ec under /srv/node2\nFeb 11 11:23:32 saio object-relinker-6020: [step\u003dcleanup, pid\u003d107923, devs\u003dsdb2,sdb6] Removed /srv/node2/sdb2/objects-1/768/a30/c00469761a9679245694727eaa285a30/1770809007.83086#2#d.data\nFeb 11 11:23:32 saio object-relinker-6020: [step\u003dcleanup, pid\u003d107923, devs\u003dsdb2,sdb6] Run listdir on /srv/node2/sdb2/objects-1/768\nFeb 11 11:23:32 saio object-relinker-6020: [step\u003dcleanup, pid\u003d107923, devs\u003dsdb2,sdb6] Device: sdb2 Policy: ec Partitions: 1/2\nFeb 11 11:23:32 saio object-relinker-6020: [step\u003dcleanup, pid\u003d107923, devs\u003dsdb2,sdb6] Removed /srv/node2/sdb2/objects-1/648/d61/a23c4ee9d41214053e86a65b4a7a0d61/1770809007.77171#0#d.data\nFeb 11 11:23:32 saio object-relinker-6020: [step\u003dcleanup, pid\u003d107923, devs\u003dsdb2,sdb6] Run listdir on /srv/node2/sdb2/objects-1/648\nFeb 11 11:23:32 saio object-relinker-6020: [step\u003dcleanup, pid\u003d107923, devs\u003dsdb2,sdb6] Device: sdb2 Policy: ec Partitions: 2/2\nFeb 11 11:23:32 saio object-relinker-6020: [step\u003dcleanup, pid\u003d107923, devs\u003dsdb2,sdb6] Updating recon for sdb2\nFeb 11 11:23:32 saio object-relinker-6020: [step\u003dcleanup, pid\u003d107923, devs\u003dsdb2,sdb6] Removed /srv/node2/sdb6/objects-1/648/d61/a23c4ee9d41214053e86a65b4a7a0d61/1770809007.77171#4#d.data\nFeb 11 11:23:32 saio object-relinker-6020: [step\u003dcleanup, pid\u003d107923, devs\u003dsdb2,sdb6] Run listdir on /srv/node2/sdb6/objects-1/648\nFeb 11 11:23:32 saio object-relinker-6020: [step\u003dcleanup, pid\u003d107923, devs\u003dsdb2,sdb6] Device: sdb6 Policy: ec Partitions: 1/1\nFeb 11 11:23:32 saio object-relinker-6020: [step\u003dcleanup, pid\u003d107923, devs\u003dsdb2,sdb6] Updating recon for sdb6\nFeb 11 11:23:32 saio object-relinker-6020: [step\u003dcleanup, pid\u003d107923, devs\u003dsdb2,sdb6] Updating recon\nFeb 11 11:23:32 saio object-relinker-6020: [step\u003dcleanup, pid\u003d107923, devs\u003dsdb2,sdb6] 3 hash dirs processed (2 files, 0 linked, 3 removed, 0 errors)\nFeb 11 11:23:32 saio object-relinker-6020: [step\u003dcleanup] Finished relinker: 11:23:32 02/11/26 GMT (0:00:00.017435 elapsed)\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup] Starting relinker using 1 workers: 11:23:33 02/11/26 GMT\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup, pid\u003d107949, devs\u003dsdb3,sdb7] Processing files for policy ec under /srv/node3\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup, pid\u003d107949, devs\u003dsdb3,sdb7] Run listdir on /srv/node3/sdb3/objects-1/1297\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup, pid\u003d107949, devs\u003dsdb3,sdb7] Device: sdb3 Policy: ec Partitions: 1/2\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup, pid\u003d107949, devs\u003dsdb3,sdb7] Removed /srv/node3/sdb3/objects-1/648/d61/a23c4ee9d41214053e86a65b4a7a0d61/1770809007.77171#5#d.data\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup, pid\u003d107949, devs\u003dsdb3,sdb7] Run listdir on /srv/node3/sdb3/objects-1/648\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup, pid\u003d107949, devs\u003dsdb3,sdb7] Device: sdb3 Policy: ec Partitions: 2/2\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup, pid\u003d107949, devs\u003dsdb3,sdb7] Updating recon for sdb3\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup, pid\u003d107949, devs\u003dsdb3,sdb7] Removed /srv/node3/sdb7/objects-1/768/a30/c00469761a9679245694727eaa285a30/1770809007.83086#3#d.data\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup, pid\u003d107949, devs\u003dsdb3,sdb7] Run listdir on /srv/node3/sdb7/objects-1/768\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup, pid\u003d107949, devs\u003dsdb3,sdb7] Device: sdb7 Policy: ec Partitions: 1/2\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup, pid\u003d107949, devs\u003dsdb3,sdb7] Removed /srv/node3/sdb7/objects-1/648/d61/a23c4ee9d41214053e86a65b4a7a0d61/1770809007.77171#1#d.data\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup, pid\u003d107949, devs\u003dsdb3,sdb7] Run listdir on /srv/node3/sdb7/objects-1/648\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup, pid\u003d107949, devs\u003dsdb3,sdb7] Device: sdb7 Policy: ec Partitions: 2/2\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup, pid\u003d107949, devs\u003dsdb3,sdb7] Updating recon for sdb7\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup, pid\u003d107949, devs\u003dsdb3,sdb7] Updating recon\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup, pid\u003d107949, devs\u003dsdb3,sdb7] 3 hash dirs processed (2 files, 0 linked, 3 removed, 0 errors)\nFeb 11 11:23:33 saio object-relinker-6030: [step\u003dcleanup] Finished relinker: 11:23:33 02/11/26 GMT (0:00:00.020397 elapsed)\nFeb 11 11:23:33 saio object-relinker-6040: [step\u003dcleanup] Starting relinker using 1 workers: 11:23:33 02/11/26 GMT\nFeb 11 11:23:33 saio object-relinker-6040: [step\u003dcleanup, pid\u003d107977, devs\u003dsdb4,sdb8] Processing files for policy ec under /srv/node4\nFeb 11 11:23:33 saio object-relinker-6040: [step\u003dcleanup, pid\u003d107977, devs\u003dsdb4,sdb8] Removed /srv/node4/sdb8/objects-1/768/a30/c00469761a9679245694727eaa285a30/1770809007.83086#4#d.data\nFeb 11 11:23:33 saio object-relinker-6040: [step\u003dcleanup, pid\u003d107977, devs\u003dsdb4,sdb8] Run listdir on /srv/node4/sdb8/objects-1/768\nFeb 11 11:23:33 saio object-relinker-6040: [step\u003dcleanup, pid\u003d107977, devs\u003dsdb4,sdb8] Device: sdb8 Policy: ec Partitions: 1/2\nFeb 11 11:23:33 saio object-relinker-6040: [step\u003dcleanup, pid\u003d107977, devs\u003dsdb4,sdb8] Removed /srv/node4/sdb8/objects-1/648/d61/a23c4ee9d41214053e86a65b4a7a0d61/1770809007.77171#2#d.data\nFeb 11 11:23:33 saio object-relinker-6040: [step\u003dcleanup, pid\u003d107977, devs\u003dsdb4,sdb8] Run listdir on /srv/node4/sdb8/objects-1/648\nFeb 11 11:23:33 saio object-relinker-6040: [step\u003dcleanup, pid\u003d107977, devs\u003dsdb4,sdb8] Device: sdb8 Policy: ec Partitions: 2/2\nFeb 11 11:23:33 saio object-relinker-6040: [step\u003dcleanup, pid\u003d107977, devs\u003dsdb4,sdb8] Updating recon for sdb8\nFeb 11 11:23:33 saio object-relinker-6040: [step\u003dcleanup, pid\u003d107977, devs\u003dsdb4,sdb8] Removed /srv/node4/sdb4/objects-1/768/a30/c00469761a9679245694727eaa285a30/1770809007.83086#0#d.data\nFeb 11 11:23:33 saio object-relinker-6040: [step\u003dcleanup, pid\u003d107977, devs\u003dsdb4,sdb8] Run listdir on /srv/node4/sdb4/objects-1/768\nFeb 11 11:23:33 saio object-relinker-6040: [step\u003dcleanup, pid\u003d107977, devs\u003dsdb4,sdb8] Device: sdb4 Policy: ec Partitions: 1/1\nFeb 11 11:23:33 saio object-relinker-6040: [step\u003dcleanup, pid\u003d107977, devs\u003dsdb4,sdb8] Updating recon for sdb4\nFeb 11 11:23:33 saio object-relinker-6040: [step\u003dcleanup, pid\u003d107977, devs\u003dsdb4,sdb8] Updating recon\nFeb 11 11:23:33 saio object-relinker-6040: [step\u003dcleanup, pid\u003d107977, devs\u003dsdb4,sdb8] 3 hash dirs processed (1 files, 0 linked, 3 removed, 0 errors)\nFeb 11 11:23:33 saio object-relinker-6040: [step\u003dcleanup] Finished relinker: 11:23:33 02/11/26 GMT (0:00:00.016978 elapsed)\n```","commit_id":"4afc5c580985e2fa1fe5cfcfe7b1a8cabb0ab2f2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"b182ac0875f7a2dd6c127071d11d26ee0614f15f","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"08d2fa71_d430fc64","updated":"2026-02-11 12:15:54.000000000","message":"FWIW https://review.opendev.org/c/openstack/swift/+/976375 trivial: remove print statement in relinker unit test","commit_id":"4afc5c580985e2fa1fe5cfcfe7b1a8cabb0ab2f2"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"aa66249c_f18a0520","updated":"2026-02-10 21:03:14.000000000","message":"I think including the `step\u003d` consistently in relinker log messages is an improvement and despite any further refinements we might imagine making to this change I don\u0027t think merging it as is would make it any harder to continue to improve swift.","commit_id":"4afc5c580985e2fa1fe5cfcfe7b1a8cabb0ab2f2"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"9e106d34e3d39cb4c3ce6a4f3c40fc39c7b031b5","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"aab7444d_9905e528","updated":"2026-02-11 16:30:03.000000000","message":"recheck\n\nlooks like an unrelated test failure in another project\n```\ntempest.api.volume.test_volumes_snapshots.VolumesSnapshotTestJSON.test_snapshot_create_offline_delete_online[compute,id-5210a1de-85a0-11e6-bb21-641c676a5d61]\n-------------------------------------------------------------------------------------------------------------------------------------------------------------\n\nCaptured traceback:\n~~~~~~~~~~~~~~~~~~~\n    Traceback (most recent call last):\n\n      File \"/opt/stack/tempest/tempest/common/utils/__init__.py\", line 65, in wrapper\n    return f(*func_args, **func_kwargs)\n\n      File \"/opt/stack/tempest/tempest/api/volume/test_volumes_snapshots.py\", line 103, in test_snapshot_create_offline_delete_online\n    server \u003d self.create_server(wait_until\u003d\u0027SSHABLE\u0027)\n\n      File \"/opt/stack/tempest/tempest/api/volume/base.py\", line 270, in create_server\n    body, _ \u003d compute.create_test_server(\n\n      File \"/opt/stack/tempest/tempest/common/compute.py\", line 345, in create_test_server\n    with excutils.save_and_reraise_exception():\n\n      File \"/opt/stack/tempest/.tox/tempest/lib/python3.10/site-packages/oslo_utils/excutils.py\", line 256, in __exit__\n    self.force_reraise()\n\n      File \"/opt/stack/tempest/.tox/tempest/lib/python3.10/site-packages/oslo_utils/excutils.py\", line 222, in force_reraise\n    raise self.value\n\n      File \"/opt/stack/tempest/tempest/common/compute.py\", line 340, in create_test_server\n    wait_for_ssh_or_ping(\n\n      File \"/opt/stack/tempest/tempest/common/compute.py\", line 150, in wait_for_ssh_or_ping\n    waiters.wait_for_ssh(\n\n      File \"/opt/stack/tempest/tempest/common/waiters.py\", line 713, in wait_for_ssh\n    raise lib_exc.TimeoutException()\n\n    tempest.lib.exceptions.TimeoutException: Request timed out\nDetails: None\n```","commit_id":"4afc5c580985e2fa1fe5cfcfe7b1a8cabb0ab2f2"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"3f3bb6fd1c44359684862430a7abfcb16a260cbb","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"bef22d98_a801574a","updated":"2026-02-12 19:15:26.000000000","message":"Swift functional tests failing in [swift-multinode-rolling-upgrade](https://zuul.opendev.org/t/openstack/build/b0b724ec66d14d079ecfb87cd0083730/log/job-output.txt), e.g.:\n\n```\n{0} test.functional.tests.TestContainer.testListMultiCharDelimiter [0.718458s] ... FAILED\n\nCaptured traceback:\n~~~~~~~~~~~~~~~~~~~\n    Traceback (most recent call last):\n\n      File \"/home/zuul/src/opendev.org/openstack/swift/test/functional/tests.py\", line 718, in testListMultiCharDelimiter\n    self.assertEqual(results, [\"test-\u0027baz\", \u0027test-\u0026\u0027, \u0027test\u0027])\n\n      File \"/usr/lib64/python3.9/unittest/case.py\", line 837, in assertEqual\n    assertion_func(first, second, msg\u003dmsg)\n\n      File \"/usr/lib64/python3.9/unittest/case.py\", line 1043, in assertListEqual\n    self.assertSequenceEqual(list1, list2, msg, seq_type\u003dlist)\n\n      File \"/usr/lib64/python3.9/unittest/case.py\", line 1025, in assertSequenceEqual\n    self.fail(msg)\n\n      File \"/usr/lib64/python3.9/unittest/case.py\", line 676, in fail\n    raise self.failureException(msg)\n\n    AssertionError: Lists differ: [\"test-\u0027baz\", \u0027test-\u0026\u0027] !\u003d [\"test-\u0027baz\", \u0027test-\u0026\u0027, \u0027test\u0027]\n\nSecond list contains 1 additional elements.\nFirst extra element 2:\n\u0027test\u0027\n\n- [\"test-\u0027baz\", \u0027test-\u0026\u0027]\n+ [\"test-\u0027baz\", \u0027test-\u0026\u0027, \u0027test\u0027]\n?\n```","commit_id":"e14473f885778b8d23a064a863e0689200fe56f1"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"999913b07c1bf6e528425ea3b1ce1f4787e767eb","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"bd2494e1_4d0d33b3","updated":"2026-02-12 17:19:26.000000000","message":"Thanks @alistairncoles@gmail.com, @clay.gerrard@gmail.com and @tburke@nvidia.com for reviewing this patch!","commit_id":"e14473f885778b8d23a064a863e0689200fe56f1"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"cf430564019da24c445d6d1b096a63a9031dafd3","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"58a95bcb_1da8ca76","updated":"2026-02-12 19:42:11.000000000","message":"recheck","commit_id":"e14473f885778b8d23a064a863e0689200fe56f1"},{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"d3d4402127318f9e38975d58985596f3e8d2d766","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"87eb63f5_4a794a3d","updated":"2026-02-13 22:19:12.000000000","message":"recheck","commit_id":"e14473f885778b8d23a064a863e0689200fe56f1"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"fd39872ec18fcdc25a0c9764e3faada91d10fd37","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"d59768ed_feab1cbb","updated":"2026-02-12 03:48:27.000000000","message":"recheck","commit_id":"e14473f885778b8d23a064a863e0689200fe56f1"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"1350e21bf771cfbfe1ca0d60b5c9d16a10f9e89e","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":4,"id":"741ff3e0_860f3e2f","updated":"2026-02-12 07:35:09.000000000","message":"recheck - several tempest tests timed out, e.g.:\n```\n{3} tempest.api.volume.test_volumes_snapshots.VolumesSnapshotTestJSON.test_snapshot_create_offline_delete_online [240.531158s] ... FAILED\n\nCaptured traceback:\n~~~~~~~~~~~~~~~~~~~\n    Traceback (most recent call last):\n\n      File \"/opt/stack/tempest/tempest/common/utils/__init__.py\", line 65, in wrapper\n    return f(*func_args, **func_kwargs)\n\n      File \"/opt/stack/tempest/tempest/api/volume/test_volumes_snapshots.py\", line 103, in test_snapshot_create_offline_delete_online\n    server \u003d self.create_server(wait_until\u003d\u0027SSHABLE\u0027)\n\n      File \"/opt/stack/tempest/tempest/api/volume/base.py\", line 270, in create_server\n    body, _ \u003d compute.create_test_server(\n\n      File \"/opt/stack/tempest/tempest/common/compute.py\", line 345, in create_test_server\n    with excutils.save_and_reraise_exception():\n\n      File \"/opt/stack/tempest/.tox/tempest/lib/python3.10/site-packages/oslo_utils/excutils.py\", line 256, in __exit__\n    self.force_reraise()\n\n      File \"/opt/stack/tempest/.tox/tempest/lib/python3.10/site-packages/oslo_utils/excutils.py\", line 222, in force_reraise\n    raise self.value\n\n      File \"/opt/stack/tempest/tempest/common/compute.py\", line 340, in create_test_server\n    wait_for_ssh_or_ping(\n\n      File \"/opt/stack/tempest/tempest/common/compute.py\", line 150, in wait_for_ssh_or_ping\n    waiters.wait_for_ssh(\n\n      File \"/opt/stack/tempest/tempest/common/waiters.py\", line 713, in wait_for_ssh\n    raise lib_exc.TimeoutException()\n\n    tempest.lib.exceptions.TimeoutException: Request timed out\nDetails: None\n```","commit_id":"e14473f885778b8d23a064a863e0689200fe56f1"}],"swift/cli/relinker.py":[{"author":{"_account_id":15343,"name":"Tim Burke","email":"tburke@nvidia.com","username":"tburke"},"change_message_id":"5e6892aaa1a5ebe10c960952b0ccdfe166127db5","unresolved":true,"context_lines":[{"line_number":941,"context_line":"                                       \u0027false\u0027))),"},{"line_number":942,"context_line":"    })"},{"line_number":943,"context_line":"    step_prefixed_logger \u003d get_prefixed_logger(logger,"},{"line_number":944,"context_line":"                                               f\"(step\u003d{args.action}) \")"},{"line_number":945,"context_line":"    return parallel_process(args.action \u003d\u003d STEP_CLEANUP,"},{"line_number":946,"context_line":"                            conf, step_prefixed_logger, args.device_list)"}],"source_content_type":"text/x-python","patch_set":1,"id":"af566b80_792fdff9","line":944,"updated":"2026-02-03 19:10:05.000000000","message":"Looks like other `get_prefixed_logger` callers use brackets:\n```\n% grep -r \u0027\u003d get_prefixed_logger\u0027 swift -A 1\nswift/obj/replicator.py:        self.logger \u003d get_prefixed_logger(\nswift/obj/replicator.py-            self.logger, \"[worker %d/%d pid\u003d%d] \" % (\n--\nswift/obj/auditor.py:        self.logger \u003d get_prefixed_logger(\nswift/obj/auditor.py-            logger, \u0027[audit-watcher %s] \u0027 % watcher_name)\n--\nswift/obj/reconstructor.py:        self.logger \u003d get_prefixed_logger(\nswift/obj/reconstructor.py-            self.logger, \"[worker %d/%d pid\u003d%s] \" % (\n--\nswift/cli/relinker.py:            logger \u003d get_prefixed_logger(logger, \u0027[pid\u003d%s, devs\u003d%s] \u0027 % (\nswift/cli/relinker.py-                os.getpid(), \u0027,\u0027.join(worker_devs)))\n```\nSomething like `f\"[step {args.action}]\"` might be more in keeping with precedent -- or were you trying to differentiate from the prefixing done when distributing work across child processes around L794?\n\n(Hmm... I\u0027m not sure we have any test coverage of that child-process prefixing... I\u0027d kinda love to have a test that demonstrated the combined effect.)","commit_id":"bf4f4e83480ab31315c2592d81b503da9378f45f"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"2b79466277bdcb36f799462f5a2a9f92624c9af6","unresolved":true,"context_lines":[{"line_number":941,"context_line":"                                       \u0027false\u0027))),"},{"line_number":942,"context_line":"    })"},{"line_number":943,"context_line":"    step_prefixed_logger \u003d get_prefixed_logger(logger,"},{"line_number":944,"context_line":"                                               f\"(step\u003d{args.action}) \")"},{"line_number":945,"context_line":"    return parallel_process(args.action \u003d\u003d STEP_CLEANUP,"},{"line_number":946,"context_line":"                            conf, step_prefixed_logger, args.device_list)"}],"source_content_type":"text/x-python","patch_set":1,"id":"f30208c6_848132c0","line":944,"in_reply_to":"af566b80_792fdff9","updated":"2026-02-04 05:20:50.000000000","message":"Thanks for the suggestion. I\u0027ve made the change to use square brackets. I had mistakenly assumed that prefixed_loggers compose, so I had to combine the PID and step information in one prefixed logger. I added a test to demonstrate the behavior.","commit_id":"bf4f4e83480ab31315c2592d81b503da9378f45f"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"15a1ab086c5316761bc8c470f726abb72db0a1c6","unresolved":false,"context_lines":[{"line_number":941,"context_line":"                                       \u0027false\u0027))),"},{"line_number":942,"context_line":"    })"},{"line_number":943,"context_line":"    step_prefixed_logger \u003d get_prefixed_logger(logger,"},{"line_number":944,"context_line":"                                               f\"(step\u003d{args.action}) \")"},{"line_number":945,"context_line":"    return parallel_process(args.action \u003d\u003d STEP_CLEANUP,"},{"line_number":946,"context_line":"                            conf, step_prefixed_logger, args.device_list)"}],"source_content_type":"text/x-python","patch_set":1,"id":"3e5dc8f1_2e96cfe4","line":944,"in_reply_to":"f30208c6_848132c0","updated":"2026-02-11 17:54:12.000000000","message":"Acknowledged","commit_id":"bf4f4e83480ab31315c2592d81b503da9378f45f"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8789c4b686c9fd607a9e860772076b49953c053a","unresolved":true,"context_lines":[{"line_number":382,"context_line":"        step \u003d STEP_CLEANUP if self.do_cleanup else STEP_RELINK"},{"line_number":383,"context_line":"        num_total_parts \u003d len(self.states[\"state\"])"},{"line_number":384,"context_line":"        self.logger.info("},{"line_number":385,"context_line":"            \"Step: %s Device: %s Policy: %s Partitions: %d/%d\","},{"line_number":386,"context_line":"            step, device, self.policy.name, num_parts_done, num_total_parts)"},{"line_number":387,"context_line":"        self._update_recon(device)"},{"line_number":388,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"56b9fe63_19034da9","side":"PARENT","line":385,"updated":"2026-02-09 16:19:47.000000000","message":"oic, here\u0027s step as a prefix - so it really is quite inconsistent","commit_id":"c7bee623658b464072783096b98adaddfb1005bc"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":false,"context_lines":[{"line_number":382,"context_line":"        step \u003d STEP_CLEANUP if self.do_cleanup else STEP_RELINK"},{"line_number":383,"context_line":"        num_total_parts \u003d len(self.states[\"state\"])"},{"line_number":384,"context_line":"        self.logger.info("},{"line_number":385,"context_line":"            \"Step: %s Device: %s Policy: %s Partitions: %d/%d\","},{"line_number":386,"context_line":"            step, device, self.policy.name, num_parts_done, num_total_parts)"},{"line_number":387,"context_line":"        self._update_recon(device)"},{"line_number":388,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"727eed72_867c84d8","side":"PARENT","line":385,"in_reply_to":"56b9fe63_19034da9","updated":"2026-02-10 03:58:56.000000000","message":"Acknowledged","commit_id":"c7bee623658b464072783096b98adaddfb1005bc"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":382,"context_line":"        step \u003d STEP_CLEANUP if self.do_cleanup else STEP_RELINK"},{"line_number":383,"context_line":"        num_total_parts \u003d len(self.states[\"state\"])"},{"line_number":384,"context_line":"        self.logger.info("},{"line_number":385,"context_line":"            \"Step: %s Device: %s Policy: %s Partitions: %d/%d\","},{"line_number":386,"context_line":"            step, device, self.policy.name, num_parts_done, num_total_parts)"},{"line_number":387,"context_line":"        self._update_recon(device)"},{"line_number":388,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"a35e420d_5464d820","side":"PARENT","line":385,"in_reply_to":"56b9fe63_19034da9","updated":"2026-02-10 03:58:56.000000000","message":"Acknowledged","commit_id":"c7bee623658b464072783096b98adaddfb1005bc"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"f2ea961a90007c5e97ff6e91f1d4174e7aca7499","unresolved":false,"context_lines":[{"line_number":382,"context_line":"        step \u003d STEP_CLEANUP if self.do_cleanup else STEP_RELINK"},{"line_number":383,"context_line":"        num_total_parts \u003d len(self.states[\"state\"])"},{"line_number":384,"context_line":"        self.logger.info("},{"line_number":385,"context_line":"            \"Step: %s Device: %s Policy: %s Partitions: %d/%d\","},{"line_number":386,"context_line":"            step, device, self.policy.name, num_parts_done, num_total_parts)"},{"line_number":387,"context_line":"        self._update_recon(device)"},{"line_number":388,"context_line":""}],"source_content_type":"text/x-python","patch_set":2,"id":"d7d66c25_4c64ad66","side":"PARENT","line":385,"in_reply_to":"a35e420d_5464d820","updated":"2026-02-10 04:01:42.000000000","message":"Done","commit_id":"c7bee623658b464072783096b98adaddfb1005bc"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a6d558f583a41ea7513d909cb2812477920dfc","unresolved":true,"context_lines":[{"line_number":777,"context_line":"        workers \u003d min(workers, len(device_list))"},{"line_number":778,"context_line":""},{"line_number":779,"context_line":"    start \u003d time.time()"},{"line_number":780,"context_line":"    logger \u003d get_prefixed_logger(logger, f\"[step\u003d{step}] \")"},{"line_number":781,"context_line":"    logger.info(\u0027Starting relinker using %d workers: %s\u0027 %"},{"line_number":782,"context_line":"                (workers, time.strftime(\u0027%X %x %Z\u0027, time.gmtime(start))))"},{"line_number":783,"context_line":"    do_cleanup \u003d (step \u003d\u003d STEP_CLEANUP)"}],"source_content_type":"text/x-python","patch_set":2,"id":"7f243017_a447528f","line":780,"updated":"2026-02-04 17:35:55.000000000","message":"Please use ``swift.common.utils.logs.get_prefixed_swift_logger``\n\nThere\u0027s some history here....\n\nIn the beginning swift logged using logging.Logger instances wrapped in a LogAdapter.\n\nThen, swift wanted to emit statsd metrics. For convenience the StatsdClient was made an attribute of a Logger instance, since the Logger instance had already been passed around between methods. And for further convenience, the StatsdClient interface was monkey-patched onto the Logger instance, so that callers could write ``logger.increment(\u0027my-metric\u0027)`` to emit a statsd metric!\n\nThis was all implemented via a ``utils.get_logger`` function.\n\nThen, we started migrating to labeled statsd metrics, and the sins of overloading Logger to be a shim for StatsdClient were exposed. A new pattern was created for creating *separate* logger instance and statsd clients. \n\nAround the same time, much of the logging code was moved from utils to a logs.py module. For backwards compatibility, ``get_logger`` retained its existing behaviour, so new helper functions include ``_swift_`` in their names to distinguish them:\n\n``logs.get_swift_logger`` should now be preferred for creating swift logger instances.\n\n``logs.get_prefixed_swift_logger`` should now be preferred for prefixing a swift logger\n\nThe older functions ``get_logger`` and ``get_prefixed_logger`` still work, but they return loggers with statsd interfaces and we\u0027d like to move away from that being a thing.\n\nThe relinker has not been modernised, so we have the old-style ``get_logger`` at line 910. It\u0027s scope-creep, but we could change that to ``get_swift_logger`` in this patch. The relinker does not emit statsd metrics.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":777,"context_line":"        workers \u003d min(workers, len(device_list))"},{"line_number":778,"context_line":""},{"line_number":779,"context_line":"    start \u003d time.time()"},{"line_number":780,"context_line":"    logger \u003d get_prefixed_logger(logger, f\"[step\u003d{step}] \")"},{"line_number":781,"context_line":"    logger.info(\u0027Starting relinker using %d workers: %s\u0027 %"},{"line_number":782,"context_line":"                (workers, time.strftime(\u0027%X %x %Z\u0027, time.gmtime(start))))"},{"line_number":783,"context_line":"    do_cleanup \u003d (step \u003d\u003d STEP_CLEANUP)"}],"source_content_type":"text/x-python","patch_set":2,"id":"f7ebf3a5_43fe7114","line":780,"in_reply_to":"5d2330e7_cc4b4826","updated":"2026-02-10 03:58:56.000000000","message":"I went ahead with the drive-by. There was minimal disruption to the tests.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8789c4b686c9fd607a9e860772076b49953c053a","unresolved":true,"context_lines":[{"line_number":777,"context_line":"        workers \u003d min(workers, len(device_list))"},{"line_number":778,"context_line":""},{"line_number":779,"context_line":"    start \u003d time.time()"},{"line_number":780,"context_line":"    logger \u003d get_prefixed_logger(logger, f\"[step\u003d{step}] \")"},{"line_number":781,"context_line":"    logger.info(\u0027Starting relinker using %d workers: %s\u0027 %"},{"line_number":782,"context_line":"                (workers, time.strftime(\u0027%X %x %Z\u0027, time.gmtime(start))))"},{"line_number":783,"context_line":"    do_cleanup \u003d (step \u003d\u003d STEP_CLEANUP)"}],"source_content_type":"text/x-python","patch_set":2,"id":"5d2330e7_cc4b4826","line":780,"in_reply_to":"7f243017_a447528f","updated":"2026-02-09 16:19:47.000000000","message":"this is useful context for @whalbawi@nvidia.com to have regardless of what makes the most sense for this change 👍\n\n\u003e It\u0027s scope-creep\n\nAgree, I think the `get[_swift]_logger` cleanup should be optional.  But possibly welcome drive-by ... as long as is doesn\u0027t lead to too much churn or additional testing or distraction from the spirit of the change.  It\u0027s probably a \"nice to have\" since this change doesn\u0027t touch metrics.\n\nIMHO, even if we \"cleanup\" `get[_swift]_logger` \"as we go\" for 6mo it barely reduces the overhead of the one-time audit/fix-the-world change where we try to cleanup *everything on purpose* and then try to enforce regression-free separate logging/stats going forward by defending \"pls, follow the existing pattern\".  Right now it feels like \"add labeled stats metrics\" is the \"right\" time to \"fix\" `get[_swift]_logger` and would probably find `get_prefixed_swift_logger(patched_logger)` a little confusing.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":false,"context_lines":[{"line_number":777,"context_line":"        workers \u003d min(workers, len(device_list))"},{"line_number":778,"context_line":""},{"line_number":779,"context_line":"    start \u003d time.time()"},{"line_number":780,"context_line":"    logger \u003d get_prefixed_logger(logger, f\"[step\u003d{step}] \")"},{"line_number":781,"context_line":"    logger.info(\u0027Starting relinker using %d workers: %s\u0027 %"},{"line_number":782,"context_line":"                (workers, time.strftime(\u0027%X %x %Z\u0027, time.gmtime(start))))"},{"line_number":783,"context_line":"    do_cleanup \u003d (step \u003d\u003d STEP_CLEANUP)"}],"source_content_type":"text/x-python","patch_set":2,"id":"4c9ec0d2_dbf9ad74","line":780,"in_reply_to":"f7ebf3a5_43fe7114","updated":"2026-02-10 21:03:14.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8789c4b686c9fd607a9e860772076b49953c053a","unresolved":true,"context_lines":[{"line_number":780,"context_line":"    logger \u003d get_prefixed_logger(logger, f\"[step\u003d{step}] \")"},{"line_number":781,"context_line":"    logger.info(\u0027Starting relinker using %d workers: %s\u0027 %"},{"line_number":782,"context_line":"                (workers, time.strftime(\u0027%X %x %Z\u0027, time.gmtime(start))))"},{"line_number":783,"context_line":"    do_cleanup \u003d (step \u003d\u003d STEP_CLEANUP)"},{"line_number":784,"context_line":"    if workers \u003d\u003d 0 or len(device_list) in (0, 1):"},{"line_number":785,"context_line":"        ret \u003d Relinker("},{"line_number":786,"context_line":"            conf, logger, device_list, do_cleanup\u003ddo_cleanup).run()"}],"source_content_type":"text/x-python","patch_set":2,"id":"a513a4ed_122a5d61","line":783,"updated":"2026-02-09 16:19:47.000000000","message":"despite this change ostensibly being about fixing logging I think you could *consider* just moving this one layer deeper into the relinker module ... there\u0027s actually already a `step \u003d STEP_CLEANUP if self.do_cleanup else STEP_RELINK` in there just waiting to for the Relinker to have a `self.step` attribute.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"15a1ab086c5316761bc8c470f726abb72db0a1c6","unresolved":false,"context_lines":[{"line_number":780,"context_line":"    logger \u003d get_prefixed_logger(logger, f\"[step\u003d{step}] \")"},{"line_number":781,"context_line":"    logger.info(\u0027Starting relinker using %d workers: %s\u0027 %"},{"line_number":782,"context_line":"                (workers, time.strftime(\u0027%X %x %Z\u0027, time.gmtime(start))))"},{"line_number":783,"context_line":"    do_cleanup \u003d (step \u003d\u003d STEP_CLEANUP)"},{"line_number":784,"context_line":"    if workers \u003d\u003d 0 or len(device_list) in (0, 1):"},{"line_number":785,"context_line":"        ret \u003d Relinker("},{"line_number":786,"context_line":"            conf, logger, device_list, do_cleanup\u003ddo_cleanup).run()"}],"source_content_type":"text/x-python","patch_set":2,"id":"4402acf7_120fa192","line":783,"in_reply_to":"20ea981e_5641c45c","updated":"2026-02-11 17:54:12.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":true,"context_lines":[{"line_number":780,"context_line":"    logger \u003d get_prefixed_logger(logger, f\"[step\u003d{step}] \")"},{"line_number":781,"context_line":"    logger.info(\u0027Starting relinker using %d workers: %s\u0027 %"},{"line_number":782,"context_line":"                (workers, time.strftime(\u0027%X %x %Z\u0027, time.gmtime(start))))"},{"line_number":783,"context_line":"    do_cleanup \u003d (step \u003d\u003d STEP_CLEANUP)"},{"line_number":784,"context_line":"    if workers \u003d\u003d 0 or len(device_list) in (0, 1):"},{"line_number":785,"context_line":"        ret \u003d Relinker("},{"line_number":786,"context_line":"            conf, logger, device_list, do_cleanup\u003ddo_cleanup).run()"}],"source_content_type":"text/x-python","patch_set":2,"id":"20ea981e_5641c45c","line":783,"in_reply_to":"8d92b1f6_6ef651ec","updated":"2026-02-10 21:03:14.000000000","message":"IIRC the \"leave composition up to the caller\" had something to do with no clearly obvious preference for ordering of stacked prefixes.  i.e.\n\nIf you *want* to set a pid/devices prefix in the caller and then \"add\" a `step` prefix in `__init__` you could do that:\n\n```\n\u003e\u003e\u003e base_prefix \u003d getattr(plogger, \u0027prefix\u0027, \u0027\u0027)\n\u003e\u003e\u003e pplogger \u003d logs.get_prefixed_swift_logger(plogger, base_prefix + \u0027info\u003dextra \u0027)\n\u003e\u003e\u003e pplogger.info(\u0027test\u0027)\nswift: info\u003dbase info\u003dextra test\n```","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":780,"context_line":"    logger \u003d get_prefixed_logger(logger, f\"[step\u003d{step}] \")"},{"line_number":781,"context_line":"    logger.info(\u0027Starting relinker using %d workers: %s\u0027 %"},{"line_number":782,"context_line":"                (workers, time.strftime(\u0027%X %x %Z\u0027, time.gmtime(start))))"},{"line_number":783,"context_line":"    do_cleanup \u003d (step \u003d\u003d STEP_CLEANUP)"},{"line_number":784,"context_line":"    if workers \u003d\u003d 0 or len(device_list) in (0, 1):"},{"line_number":785,"context_line":"        ret \u003d Relinker("},{"line_number":786,"context_line":"            conf, logger, device_list, do_cleanup\u003ddo_cleanup).run()"}],"source_content_type":"text/x-python","patch_set":2,"id":"8d92b1f6_6ef651ec","line":783,"in_reply_to":"a513a4ed_122a5d61","updated":"2026-02-10 03:58:56.000000000","message":"Seems reasonable to move the step inside the relinker module but not clear to me that we should push the prefix logging change down there too. I would\u0027ve tended your way if prefix loggers _composed_ rather than replaced prefixes. Thoughts?","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8789c4b686c9fd607a9e860772076b49953c053a","unresolved":true,"context_lines":[{"line_number":783,"context_line":"    do_cleanup \u003d (step \u003d\u003d STEP_CLEANUP)"},{"line_number":784,"context_line":"    if workers \u003d\u003d 0 or len(device_list) in (0, 1):"},{"line_number":785,"context_line":"        ret \u003d Relinker("},{"line_number":786,"context_line":"            conf, logger, device_list, do_cleanup\u003ddo_cleanup).run()"},{"line_number":787,"context_line":"        logger.info(\u0027Finished relinker: %s (%s elapsed)\u0027 %"},{"line_number":788,"context_line":"                    (time.strftime(\u0027%X %x %Z\u0027, time.gmtime()),"},{"line_number":789,"context_line":"                     datetime.timedelta(seconds\u003dtime.time() - start)))"}],"source_content_type":"text/x-python","patch_set":2,"id":"5f8bd4fc_1209ae15","line":786,"updated":"2026-02-09 16:19:47.000000000","message":"I wonder how important it is that the inline worker case NOT log pid and device prefix.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"15a1ab086c5316761bc8c470f726abb72db0a1c6","unresolved":false,"context_lines":[{"line_number":783,"context_line":"    do_cleanup \u003d (step \u003d\u003d STEP_CLEANUP)"},{"line_number":784,"context_line":"    if workers \u003d\u003d 0 or len(device_list) in (0, 1):"},{"line_number":785,"context_line":"        ret \u003d Relinker("},{"line_number":786,"context_line":"            conf, logger, device_list, do_cleanup\u003ddo_cleanup).run()"},{"line_number":787,"context_line":"        logger.info(\u0027Finished relinker: %s (%s elapsed)\u0027 %"},{"line_number":788,"context_line":"                    (time.strftime(\u0027%X %x %Z\u0027, time.gmtime()),"},{"line_number":789,"context_line":"                     datetime.timedelta(seconds\u003dtime.time() - start)))"}],"source_content_type":"text/x-python","patch_set":2,"id":"190ba406_f30e502b","line":786,"in_reply_to":"5f8bd4fc_1209ae15","updated":"2026-02-11 17:54:12.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a6d558f583a41ea7513d909cb2812477920dfc","unresolved":true,"context_lines":[{"line_number":793,"context_line":"    for worker_devs in distribute_evenly(device_list, workers):"},{"line_number":794,"context_line":"        pid \u003d os.fork()"},{"line_number":795,"context_line":"        if pid \u003d\u003d 0:"},{"line_number":796,"context_line":"            pid_prefixed_logger \u003d get_prefixed_logger("},{"line_number":797,"context_line":"                logger,"},{"line_number":798,"context_line":"                \u0027[step\u003d%s, pid\u003d%s, devs\u003d%s] \u0027"},{"line_number":799,"context_line":"                % (step, os.getpid(), \u0027,\u0027.join(worker_devs)))"},{"line_number":800,"context_line":"            os._exit(Relinker(conf, pid_prefixed_logger, worker_devs,"}],"source_content_type":"text/x-python","patch_set":2,"id":"849cf52a_aef8cb85","line":797,"range":{"start_line":796,"start_character":12,"end_line":797,"end_character":22},"updated":"2026-02-04 17:35:55.000000000","message":"Same comment re modernising to use ``get_prefixed_swift_logger``.\n\nThis wraps the already prefixed logger with a new prefix, except it doesn\u0027t exactly \u0027wrap\u0027 the prefixed logger...instead it wraps the wrapped logger !!\n\nSo, the outcome is what you want: the existing \u0027step\u0027 prefix is *replaced* with the new \u0027step, pid, devs\u0027 prefix.\n\nHowever, it might be less confusing for each call to ``get_prefixed_swift_logger`` to be prefixing the same original ``logger``, either by renaming the instance at line 780 to ``prefixed_logger``, or changing the arg passed in at line 755 to something like ``bare_logger``. I think the first option is preferable because it serves as a reminder that the logger has a prefix.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":793,"context_line":"    for worker_devs in distribute_evenly(device_list, workers):"},{"line_number":794,"context_line":"        pid \u003d os.fork()"},{"line_number":795,"context_line":"        if pid \u003d\u003d 0:"},{"line_number":796,"context_line":"            pid_prefixed_logger \u003d get_prefixed_logger("},{"line_number":797,"context_line":"                logger,"},{"line_number":798,"context_line":"                \u0027[step\u003d%s, pid\u003d%s, devs\u003d%s] \u0027"},{"line_number":799,"context_line":"                % (step, os.getpid(), \u0027,\u0027.join(worker_devs)))"},{"line_number":800,"context_line":"            os._exit(Relinker(conf, pid_prefixed_logger, worker_devs,"}],"source_content_type":"text/x-python","patch_set":2,"id":"7c5e4bbd_2982c3ab","line":797,"range":{"start_line":796,"start_character":12,"end_line":797,"end_character":22},"in_reply_to":"6089cf42_6fb7db2b","updated":"2026-02-10 03:58:56.000000000","message":"\u003e However, it might be less confusing for each call to get_prefixed_swift_logger to be prefixing the same original logger\n\nI wanted to redefine `logger` as early as possible so we wouldn\u0027t \"mistakenly\" use it in the body of this method. However, I do see the confusion caused by not prefixing the original logger.\n\n\u003e this was not the behavior I expected:\n\nMe too. Hence, the duplicate the `step\u003d` field in the per-pid logger.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7cb106f4c9afaa0b087b3a63f8ebb8ec86b9a62b","unresolved":true,"context_lines":[{"line_number":793,"context_line":"    for worker_devs in distribute_evenly(device_list, workers):"},{"line_number":794,"context_line":"        pid \u003d os.fork()"},{"line_number":795,"context_line":"        if pid \u003d\u003d 0:"},{"line_number":796,"context_line":"            pid_prefixed_logger \u003d get_prefixed_logger("},{"line_number":797,"context_line":"                logger,"},{"line_number":798,"context_line":"                \u0027[step\u003d%s, pid\u003d%s, devs\u003d%s] \u0027"},{"line_number":799,"context_line":"                % (step, os.getpid(), \u0027,\u0027.join(worker_devs)))"},{"line_number":800,"context_line":"            os._exit(Relinker(conf, pid_prefixed_logger, worker_devs,"}],"source_content_type":"text/x-python","patch_set":2,"id":"f54c63dc_3fa60927","line":797,"range":{"start_line":796,"start_character":12,"end_line":797,"end_character":22},"in_reply_to":"7c5e4bbd_2982c3ab","updated":"2026-02-11 12:09:48.000000000","message":"Thanks for making the change.\n\nPrior to [1] the PrefixLoggerAdapter supported nested/stacked prefixes, but I don\u0027t think nested prefixes were actually used.\n\nIIRC we wanted (needed?) to simplify things so that a swift logger only ever had one SwiftLogAdapter wrapping a logging.Logger, rather than a nest of adapters.\n\nWe had experienced bugs/anti-patterns where adapter prefixes were being mutated, causing unintended non-local side-effects.\n\nSo IIRC we decided to simplify to:\n\n* a swift logger is always a single SwiftLogAdapter wrapping a logging.Logger\n* the SwiftLogAdapter supports a prefix arg to its constructor\n* if you want a different prefix, create a different SwiftLogAdapter to wrap the underlying logging.Logger\n\nMy memory is fuzzy so I\u0027m not sure I have accurately described or justified the changes. I do remember the legacy being an awful mess to untangle.\n\n[1] https://review.opendev.org/c/openstack/swift/+/931060","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8789c4b686c9fd607a9e860772076b49953c053a","unresolved":true,"context_lines":[{"line_number":793,"context_line":"    for worker_devs in distribute_evenly(device_list, workers):"},{"line_number":794,"context_line":"        pid \u003d os.fork()"},{"line_number":795,"context_line":"        if pid \u003d\u003d 0:"},{"line_number":796,"context_line":"            pid_prefixed_logger \u003d get_prefixed_logger("},{"line_number":797,"context_line":"                logger,"},{"line_number":798,"context_line":"                \u0027[step\u003d%s, pid\u003d%s, devs\u003d%s] \u0027"},{"line_number":799,"context_line":"                % (step, os.getpid(), \u0027,\u0027.join(worker_devs)))"},{"line_number":800,"context_line":"            os._exit(Relinker(conf, pid_prefixed_logger, worker_devs,"}],"source_content_type":"text/x-python","patch_set":2,"id":"6089cf42_6fb7db2b","line":797,"range":{"start_line":796,"start_character":12,"end_line":797,"end_character":22},"in_reply_to":"849cf52a_aef8cb85","updated":"2026-02-09 16:19:47.000000000","message":"\u003e it doesn\u0027t exactly \u0027wrap\u0027 the prefixed logger...instead it wraps the wrapped logger !!\n\nthis was not the behavior I expected:\n\n```\n\u003e\u003e\u003e from swift.common.utils import logs\n\u003e\u003e\u003e logger \u003d logs.get_swift_logger({}, log_to_console\u003dTrue)\n\u003e\u003e\u003e plogger \u003d logs.get_prefixed_swift_logger(logger, \u0027info\u003dbase \u0027)\n\u003e\u003e\u003e plogger.info(\u0027test\u0027)\nswift: info\u003dbase test\n\u003e\u003e\u003e pplogger \u003d logs.get_prefixed_swift_logger(plogger, \u0027info\u003dextra \u0027)\n\u003e\u003e\u003e pplogger.info(\u0027test\u0027)\nswift: info\u003dextra test\n```\n\n... but I sort of remember it now:\n\n```\n\u003e\u003e\u003e base_prefix \u003d getattr(plogger, \u0027prefix\u0027, \u0027\u0027)\n\u003e\u003e\u003e pplogger \u003d logs.get_prefixed_swift_logger(plogger, base_prefix + \u0027info\u003dextra \u0027)\n\u003e\u003e\u003e pplogger.info(\u0027test\u0027)\nswift: info\u003dbase info\u003dextra test\n```\n\n\u003e the outcome is what you want\n\nwell that\u0027s probably good 😜 oic, only because the 2nd `pid_prefixed_logger` *also* sets the `[step\u003dxxx, ...]` *explicitly*\n\n\u003e I think the first option is preferable because it serves as a reminder that the logger has a prefix.\n\n... and the trade off is updating all the `logger.msg` calls in this function; I think \"surprising but correct\" is worse than \"explicit and correct\" but give the most weight to the correct part.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"15a1ab086c5316761bc8c470f726abb72db0a1c6","unresolved":false,"context_lines":[{"line_number":793,"context_line":"    for worker_devs in distribute_evenly(device_list, workers):"},{"line_number":794,"context_line":"        pid \u003d os.fork()"},{"line_number":795,"context_line":"        if pid \u003d\u003d 0:"},{"line_number":796,"context_line":"            pid_prefixed_logger \u003d get_prefixed_logger("},{"line_number":797,"context_line":"                logger,"},{"line_number":798,"context_line":"                \u0027[step\u003d%s, pid\u003d%s, devs\u003d%s] \u0027"},{"line_number":799,"context_line":"                % (step, os.getpid(), \u0027,\u0027.join(worker_devs)))"},{"line_number":800,"context_line":"            os._exit(Relinker(conf, pid_prefixed_logger, worker_devs,"}],"source_content_type":"text/x-python","patch_set":2,"id":"5aaceb50_8ff30c37","line":797,"range":{"start_line":796,"start_character":12,"end_line":797,"end_character":22},"in_reply_to":"f54c63dc_3fa60927","updated":"2026-02-11 17:54:12.000000000","message":"This is extremely helpful. Thanks for paging in this context.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8789c4b686c9fd607a9e860772076b49953c053a","unresolved":true,"context_lines":[{"line_number":810,"context_line":"        status \u003d status \u003e\u003e 8"},{"line_number":811,"context_line":"        time_delta \u003d time.time() - start"},{"line_number":812,"context_line":"        devs \u003d children.pop(pid, [\u0027unknown device\u0027])"},{"line_number":813,"context_line":"        worker_desc \u003d \u0027(pid\u003d%s, devs\u003d%s)\u0027 % (pid, \u0027,\u0027.join(devs))"},{"line_number":814,"context_line":"        if sig !\u003d 0:"},{"line_number":815,"context_line":"            final_status \u003d EXIT_ERROR"},{"line_number":816,"context_line":"            final_messages.append("}],"source_content_type":"text/x-python","patch_set":2,"id":"e886bbbf_5a166925","line":813,"updated":"2026-02-09 16:19:47.000000000","message":"this sort of reminds me of the worker logging prefix\n\nI wonder if the map should be of `pid\u003d\u003eworker_labels`","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":false,"context_lines":[{"line_number":810,"context_line":"        status \u003d status \u003e\u003e 8"},{"line_number":811,"context_line":"        time_delta \u003d time.time() - start"},{"line_number":812,"context_line":"        devs \u003d children.pop(pid, [\u0027unknown device\u0027])"},{"line_number":813,"context_line":"        worker_desc \u003d \u0027(pid\u003d%s, devs\u003d%s)\u0027 % (pid, \u0027,\u0027.join(devs))"},{"line_number":814,"context_line":"        if sig !\u003d 0:"},{"line_number":815,"context_line":"            final_status \u003d EXIT_ERROR"},{"line_number":816,"context_line":"            final_messages.append("}],"source_content_type":"text/x-python","patch_set":2,"id":"0c7cfc1b_9fd25f51","line":813,"in_reply_to":"526a8db8_ae0758da","updated":"2026-02-10 21:03:14.000000000","message":"I was just noticing how the descriptive strings assinged to workers are so similar:\n\n```\n\u0027[step\u003d%s, pid\u003d%s, devs\u003d%s] \u0027\n\u0027(pid\u003d%s, devs\u003d%s)\u0027\n```\n\nand thinking instead of \"simply\"\n\n```\nchildren[pid] \u003d worker_devs\n```\n\nwe might want:\n\n```\ntemplate \u003d \u0027step\u003d%(step)s, pid\u003d%(pid)s, devs\u003d%(devs)s\u0027\n...\nworker_args \u003d {\n    \u0027devs\u0027: worker_devs,\n    \u0027step\u0027: step,\n}\nif pid \u003d\u003d 0:\n    worker_args[\u0027pid\u0027] \u003d os.getpid()\n    prefix_description \u003d template % worker_args\n    os.exit(...)\nelse:\n    worker_args[\u0027pid\u0027] \u003d pid\n    children[pid] \u003d worker_args\n...\npid \u003d os.wait()\ndescription \u003d template % children[pid]\n```\n\nbut in retrospect maybe it\u0027s over-unification - if for no other reason than despite both labeling templates existing in the same function w/ similarly named args - they\u0027re composed on opposite sides of a fork and the value of \u0027pid\u0027 in each context doesn\u0027t come from a single place.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":810,"context_line":"        status \u003d status \u003e\u003e 8"},{"line_number":811,"context_line":"        time_delta \u003d time.time() - start"},{"line_number":812,"context_line":"        devs \u003d children.pop(pid, [\u0027unknown device\u0027])"},{"line_number":813,"context_line":"        worker_desc \u003d \u0027(pid\u003d%s, devs\u003d%s)\u0027 % (pid, \u0027,\u0027.join(devs))"},{"line_number":814,"context_line":"        if sig !\u003d 0:"},{"line_number":815,"context_line":"            final_status \u003d EXIT_ERROR"},{"line_number":816,"context_line":"            final_messages.append("}],"source_content_type":"text/x-python","patch_set":2,"id":"526a8db8_ae0758da","line":813,"in_reply_to":"e886bbbf_5a166925","updated":"2026-02-10 03:58:56.000000000","message":"I don\u0027t see `worker_labels`. Can you elaborate please?","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":true,"context_lines":[{"line_number":121,"context_line":"        self.stats \u003d _zero_stats()"},{"line_number":122,"context_line":"        self.devices_data \u003d recursive_defaultdict()"},{"line_number":123,"context_line":"        self.policy_count \u003d 0"},{"line_number":124,"context_line":"        self.pid \u003d os.getpid()"},{"line_number":125,"context_line":"        self.linked_into_partitions \u003d set()"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"    def _aggregate_dev_policy_stats(self):"}],"source_content_type":"text/x-python","patch_set":3,"id":"bf7dc9ba_1e853266","line":124,"updated":"2026-02-10 21:03:14.000000000","message":"despite the pid being prefixed on the logger by the caller the relinker still needs to know it\u0027s own pid anyway (for stats aggregation)","commit_id":"4afc5c580985e2fa1fe5cfcfe7b1a8cabb0ab2f2"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"15a1ab086c5316761bc8c470f726abb72db0a1c6","unresolved":false,"context_lines":[{"line_number":121,"context_line":"        self.stats \u003d _zero_stats()"},{"line_number":122,"context_line":"        self.devices_data \u003d recursive_defaultdict()"},{"line_number":123,"context_line":"        self.policy_count \u003d 0"},{"line_number":124,"context_line":"        self.pid \u003d os.getpid()"},{"line_number":125,"context_line":"        self.linked_into_partitions \u003d set()"},{"line_number":126,"context_line":""},{"line_number":127,"context_line":"    def _aggregate_dev_policy_stats(self):"}],"source_content_type":"text/x-python","patch_set":3,"id":"47e2bbbb_5c981084","line":124,"in_reply_to":"bf7dc9ba_1e853266","updated":"2026-02-11 17:54:12.000000000","message":"Acknowledged","commit_id":"4afc5c580985e2fa1fe5cfcfe7b1a8cabb0ab2f2"}],"test/unit/cli/test_relinker.py":[{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a6d558f583a41ea7513d909cb2812477920dfc","unresolved":true,"context_lines":[{"line_number":128,"context_line":"            self.fail("},{"line_number":129,"context_line":"                \"Failed to setup object satisfying test preconditions %s\""},{"line_number":130,"context_line":"                % attempts"},{"line_number":131,"context_line":"            )"},{"line_number":132,"context_line":"        return _hash, part, next_part, obj_path"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"    def _create_object(self, policy, part, _hash, ext\u003d\u0027.data\u0027):"}],"source_content_type":"text/x-python","patch_set":2,"id":"f39886e0_a4cb9e00","line":131,"updated":"2026-02-04 17:35:55.000000000","message":"This looks like an unnecessary change which we tend to avoid so as not to dirty the git history (is your editor auto-formatting?)","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":true,"context_lines":[{"line_number":128,"context_line":"            self.fail("},{"line_number":129,"context_line":"                \"Failed to setup object satisfying test preconditions %s\""},{"line_number":130,"context_line":"                % attempts"},{"line_number":131,"context_line":"            )"},{"line_number":132,"context_line":"        return _hash, part, next_part, obj_path"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"    def _create_object(self, policy, part, _hash, ext\u003d\u0027.data\u0027):"}],"source_content_type":"text/x-python","patch_set":2,"id":"add39280_e1cd906b","line":131,"in_reply_to":"1130c1af_62d5798e","updated":"2026-02-10 21:03:14.000000000","message":"compared to master the full diff hunk reads as:\n\n```\ndiff --git a/test/unit/cli/test_relinker.py b/test/unit/cli/test_relinker.py\nindex b54959990..01935465f 100644\n--- a/test/unit/cli/test_relinker.py\n+++ b/test/unit/cli/test_relinker.py\n@@ -125,8 +125,10 @@ class TestRelinker(unittest.TestCase):\n                     (condition(part) if condition else True)):\n                 break\n         else:\n-            self.fail(\u0027Failed to setup object satisfying test preconditions %s\u0027\n-                      % attempts)\n+            self.fail(\n+                \u0027Failed to setup object satisfying test preconditions %s\u0027\n+                % attempts\n+            )\n         return _hash, part, next_part, obj_path\n \n     def _create_object(self, policy, part, _hash, ext\u003d\u0027.data\u0027):\n```\n\nI think the idea is that you should able to dump the whole thing w/o making `flake8` mad since master is currently happy with the existing formatting:\n\n```\n(vagrant-swift-all-in-one) cgerrard@NVStation:~/Workspace/vagrant-swift-all-in-one/swift$ flake8 test/unit/cli/test_relinker.py \n(vagrant-swift-all-in-one) cgerrard@NVStation:~/Workspace/vagrant-swift-all-in-one/swift$ flake8 --version\n7.1.2 (hacking: 7.0.0, mccabe: 0.7.0, pycodestyle: 2.12.1, pyflakes: 3.2.0) CPython 3.12.3 on Linux\n```","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":128,"context_line":"            self.fail("},{"line_number":129,"context_line":"                \"Failed to setup object satisfying test preconditions %s\""},{"line_number":130,"context_line":"                % attempts"},{"line_number":131,"context_line":"            )"},{"line_number":132,"context_line":"        return _hash, part, next_part, obj_path"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"    def _create_object(self, policy, part, _hash, ext\u003d\u0027.data\u0027):"}],"source_content_type":"text/x-python","patch_set":2,"id":"1130c1af_62d5798e","line":131,"in_reply_to":"92efaf51_98e00e00","updated":"2026-02-10 03:58:56.000000000","message":"single -\u003e double quote switch is a rogue change. Reverted. Apologies.\nTasteless break before % is an attempt to keep `flake8` happy.\n\n\u003e Maybe obviously better as:\nI don\u0027t have input on how to best represent `condition`, so I\u0027ve left the contents of the log message unchanged.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"15a1ab086c5316761bc8c470f726abb72db0a1c6","unresolved":false,"context_lines":[{"line_number":128,"context_line":"            self.fail("},{"line_number":129,"context_line":"                \"Failed to setup object satisfying test preconditions %s\""},{"line_number":130,"context_line":"                % attempts"},{"line_number":131,"context_line":"            )"},{"line_number":132,"context_line":"        return _hash, part, next_part, obj_path"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"    def _create_object(self, policy, part, _hash, ext\u003d\u0027.data\u0027):"}],"source_content_type":"text/x-python","patch_set":2,"id":"4b6f6c51_5825d191","line":131,"in_reply_to":"add39280_e1cd906b","updated":"2026-02-11 17:54:12.000000000","message":"Apologies for the confusion. Fixed.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8789c4b686c9fd607a9e860772076b49953c053a","unresolved":true,"context_lines":[{"line_number":128,"context_line":"            self.fail("},{"line_number":129,"context_line":"                \"Failed to setup object satisfying test preconditions %s\""},{"line_number":130,"context_line":"                % attempts"},{"line_number":131,"context_line":"            )"},{"line_number":132,"context_line":"        return _hash, part, next_part, obj_path"},{"line_number":133,"context_line":""},{"line_number":134,"context_line":"    def _create_object(self, policy, part, _hash, ext\u003d\u0027.data\u0027):"}],"source_content_type":"text/x-python","patch_set":2,"id":"92efaf51_98e00e00","line":131,"in_reply_to":"f39886e0_a4cb9e00","updated":"2026-02-09 16:19:47.000000000","message":"I find the break before `%` sort of annoying, and this message is somewhat haphazardly interpolating the attempts...\n\nMaybe obviously better as:\n\n```\n\"Failed to setup object satisfying test preconditions\"\nf\" ({condition!r}) after {attempts} attempts\"\n```\n\nwith the `fail()` parens wherever you want.  Although I\u0027m sure someone would have a better idea about the optimal rendering of `{condition}`\n\n\u003e unnecessary change which we tend to avoid\n\n^ this 💯 - core reviewers have been trained to consider every hunk of every change very carefully, your best bet for getting stuff merged is to have as few hunks in the change as possible and consider independently if each one can be made as \"obviously necessary\" as possible.  Simple \"drive-bys\" *often* turn out to be a matter of taste, and unless you happen to land on a style that the reviewer(s) also thinks is an obvious improvement it WILL become a distraction.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8789c4b686c9fd607a9e860772076b49953c053a","unresolved":true,"context_lines":[{"line_number":266,"context_line":"            self.assertEqual([], self.logger.get_lines_for_level(\u0027error\u0027))"},{"line_number":267,"context_line":"            warning_lines \u003d self.logger.get_lines_for_level(\u0027warning\u0027)"},{"line_number":268,"context_line":"            self.assertIn(\u0027[step\u003dcleanup] Worker (pid\u003d5, devs\u003d\u0027,"},{"line_number":269,"context_line":"                          warning_lines[0])"},{"line_number":270,"context_line":"            self.assertTrue("},{"line_number":271,"context_line":"                warning_lines[0].endswith(msg),"},{"line_number":272,"context_line":"                \u0027Expected log line to end with %r; got %r\u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"9b4d1544_d6a5d4c9","line":269,"updated":"2026-02-09 16:19:47.000000000","message":"FWIW the `assertTrue(startswith)` was both correct/stronger - but maybe not obviously *better* from a code maintenance PoV as had the assert been written as \"merely\" `assertIn` *to begin with* it wouldn\u0027t have failed wit this introduction of the `step\u003d` prefix","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":false,"context_lines":[{"line_number":266,"context_line":"            self.assertEqual([], self.logger.get_lines_for_level(\u0027error\u0027))"},{"line_number":267,"context_line":"            warning_lines \u003d self.logger.get_lines_for_level(\u0027warning\u0027)"},{"line_number":268,"context_line":"            self.assertIn(\u0027[step\u003dcleanup] Worker (pid\u003d5, devs\u003d\u0027,"},{"line_number":269,"context_line":"                          warning_lines[0])"},{"line_number":270,"context_line":"            self.assertTrue("},{"line_number":271,"context_line":"                warning_lines[0].endswith(msg),"},{"line_number":272,"context_line":"                \u0027Expected log line to end with %r; got %r\u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"7dcee947_cc65d235","line":269,"in_reply_to":"7f9f7d24_0cfd8e20","updated":"2026-02-10 21:03:14.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":266,"context_line":"            self.assertEqual([], self.logger.get_lines_for_level(\u0027error\u0027))"},{"line_number":267,"context_line":"            warning_lines \u003d self.logger.get_lines_for_level(\u0027warning\u0027)"},{"line_number":268,"context_line":"            self.assertIn(\u0027[step\u003dcleanup] Worker (pid\u003d5, devs\u003d\u0027,"},{"line_number":269,"context_line":"                          warning_lines[0])"},{"line_number":270,"context_line":"            self.assertTrue("},{"line_number":271,"context_line":"                warning_lines[0].endswith(msg),"},{"line_number":272,"context_line":"                \u0027Expected log line to end with %r; got %r\u0027"}],"source_content_type":"text/x-python","patch_set":2,"id":"7f9f7d24_0cfd8e20","line":269,"in_reply_to":"9b4d1544_d6a5d4c9","updated":"2026-02-10 03:58:56.000000000","message":"I\u0027m less happy with my change now that I see it here. Reverted.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a6d558f583a41ea7513d909cb2812477920dfc","unresolved":true,"context_lines":[{"line_number":278,"context_line":"                          info_lines[0])"},{"line_number":279,"context_line":"            self.assertIn(\u0027[step\u003dcleanup] Finished relinker:\u0027,"},{"line_number":280,"context_line":"                          info_lines[1])"},{"line_number":281,"context_line":"            print(info_lines)"},{"line_number":282,"context_line":"            self.logger.clear()"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":"        os.mkdir(os.path.join(self.devices, \u0027sda2\u0027))"}],"source_content_type":"text/x-python","patch_set":2,"id":"8450bcd8_2c9a03a5","line":281,"updated":"2026-02-04 17:35:55.000000000","message":"nit: could you delete this line as a drive-by 🙏","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"15a1ab086c5316761bc8c470f726abb72db0a1c6","unresolved":false,"context_lines":[{"line_number":278,"context_line":"                          info_lines[0])"},{"line_number":279,"context_line":"            self.assertIn(\u0027[step\u003dcleanup] Finished relinker:\u0027,"},{"line_number":280,"context_line":"                          info_lines[1])"},{"line_number":281,"context_line":"            print(info_lines)"},{"line_number":282,"context_line":"            self.logger.clear()"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":"        os.mkdir(os.path.join(self.devices, \u0027sda2\u0027))"}],"source_content_type":"text/x-python","patch_set":2,"id":"89b414fc_9a318b29","line":281,"in_reply_to":"531c54f5_50f34827","updated":"2026-02-11 17:54:12.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8789c4b686c9fd607a9e860772076b49953c053a","unresolved":true,"context_lines":[{"line_number":278,"context_line":"                          info_lines[0])"},{"line_number":279,"context_line":"            self.assertIn(\u0027[step\u003dcleanup] Finished relinker:\u0027,"},{"line_number":280,"context_line":"                          info_lines[1])"},{"line_number":281,"context_line":"            print(info_lines)"},{"line_number":282,"context_line":"            self.logger.clear()"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":"        os.mkdir(os.path.join(self.devices, \u0027sda2\u0027))"}],"source_content_type":"text/x-python","patch_set":2,"id":"b37ca64f_770c37fa","line":281,"in_reply_to":"8450bcd8_2c9a03a5","updated":"2026-02-09 16:19:47.000000000","message":"😂 the answer of \"should a change have drive-bys\" is surprisingly difficult to get strong consensus on.  Personally I\u0027d err on the side of \"avoid drive-bys at all costs\" while I was getting started.\n\nEven after years of working with swift core reviewers I feel like I\u0027m batting less than 500 on when a \"quick/minor/obvious cleanup\" will be welcomed or distracting.  IMHO this print isn\u0027t hurting much since I missed it in review some 5 years ago:\n\n785936: relinker: Add start/end logs to parallel_process | https://review.opendev.org/c/openstack/swift/+/785936","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":278,"context_line":"                          info_lines[0])"},{"line_number":279,"context_line":"            self.assertIn(\u0027[step\u003dcleanup] Finished relinker:\u0027,"},{"line_number":280,"context_line":"                          info_lines[1])"},{"line_number":281,"context_line":"            print(info_lines)"},{"line_number":282,"context_line":"            self.logger.clear()"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":"        os.mkdir(os.path.join(self.devices, \u0027sda2\u0027))"}],"source_content_type":"text/x-python","patch_set":2,"id":"b5c1d1c4_664de778","line":281,"in_reply_to":"b37ca64f_770c37fa","updated":"2026-02-10 03:58:56.000000000","message":"When is the overhead of a drive-by justified? Only when it\u0027s less than that of a distinct patch?","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7cb106f4c9afaa0b087b3a63f8ebb8ec86b9a62b","unresolved":true,"context_lines":[{"line_number":278,"context_line":"                          info_lines[0])"},{"line_number":279,"context_line":"            self.assertIn(\u0027[step\u003dcleanup] Finished relinker:\u0027,"},{"line_number":280,"context_line":"                          info_lines[1])"},{"line_number":281,"context_line":"            print(info_lines)"},{"line_number":282,"context_line":"            self.logger.clear()"},{"line_number":283,"context_line":""},{"line_number":284,"context_line":"        os.mkdir(os.path.join(self.devices, \u0027sda2\u0027))"}],"source_content_type":"text/x-python","patch_set":2,"id":"531c54f5_50f34827","line":281,"in_reply_to":"b5c1d1c4_664de778","updated":"2026-02-11 12:09:48.000000000","message":"\u003eWhen is the overhead of a drive-by justified? \nwhen it gets merged? ;-) \n\nFor me this particular case is a no-brainer: unit tests should not print output, it\u0027s clearly cruft left from the patch being debugged.\n\nThe print is distracting/confusing when you want to look at the debug logger output to sanity check the test and have a WTF moment:\n\n```\ntest_relinker.py::TestRelinker::test_workers_parent_bubbles_up_errors \n\n\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d 1 passed in 3.28s \u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\u003d\ntest INFO: Starting relinker (cleanup\u003dTrue) using 5 workers: 11:01:44 02/11/26 UTC\ntest WARNING: Worker (pid\u003d5, devs\u003dsda4) exited in 0.0s after receiving signal: 9\ntest INFO: Finished relinker (cleanup\u003dTrue): 11:01:44 02/11/26 UTC (0:00:00.008819 elapsed)\n[\u0027Starting relinker (cleanup\u003dTrue) using 5 workers: 11:01:44 02/11/26 UTC\u0027, \u0027Finished relinker (cleanup\u003dTrue): 11:01:44 02/11/26 UTC (0:00:00.008819 elapsed)\u0027]\ntest INFO: Starting relinker (cleanup\u003dTrue) using 5 workers: 11:01:44 02/11/26 UTC\ntest WARNING: Worker (pid\u003d5, devs\u003dsda4) completed in 0.0s with errors\ntest INFO: Finished relinker (cleanup\u003dTrue): 11:01:44 02/11/26 UTC (0:00:00.000124 elapsed)\n[\u0027Starting relinker (cleanup\u003dTrue) using 5 workers: 11:01:44 02/11/26 UTC\u0027, \u0027Finished relinker (cleanup\u003dTrue): 11:01:44 02/11/26 UTC (0:00:00.000124 elapsed)\u0027]\ntest INFO: Starting relinker (cleanup\u003dTrue) using 5 workers: 11:01:44 02/11/26 UTC\ntest WARNING: Worker (pid\u003d5, devs\u003dsda4) exited in 0.0s with unexpected status 42\ntest INFO: Finished relinker (cleanup\u003dTrue): 11:01:44 02/11/26 UTC (0:00:00.000145 elapsed)\n[\u0027Starting relinker (cleanup\u003dTrue) using 5 workers: 11:01:44 02/11/26 UTC\u0027, \u0027Finished relinker (cleanup\u003dTrue): 11:01:44 02/11/26 UTC (0:00:00.000145 elapsed)\u0027]\nPASSED\nProcess finished with exit code 0\n```\n\nSometimes \"you\u0027re damned if you do and damned if you don\u0027t\"...One reviewer might say \"please don\u0027t make an unrelated change\", another reviewer might say \"you\u0027ve touched this test and you really don\u0027t think it is worth making Swift better by cleaning it up while you\u0027re here?\" (although I\u0027d hope *no* reviewer would be quote so snarky!).\n\nSo, I think there is no hard and fast rule. But in general I would avoid all but the most obvious drive-bys. Now watch while I likely go and ignore my own advice in one of my patches... :D","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8789c4b686c9fd607a9e860772076b49953c053a","unresolved":true,"context_lines":[{"line_number":893,"context_line":"        other_next_part_dir \u003d os.path.join(self.objects, str(other_next_part))"},{"line_number":894,"context_line":"        self.assertFalse(os.path.exists(other_next_part_dir))"},{"line_number":895,"context_line":""},{"line_number":896,"context_line":"    def _do_link_test(self, command, old_file_specs, new_file_specs,"},{"line_number":897,"context_line":"                      conflict_file_specs, exp_old_specs, exp_new_specs,"},{"line_number":898,"context_line":"                      exp_ret_code\u003d0, relink_errors\u003dNone,"},{"line_number":899,"context_line":"                      mock_relink_paths\u003dNone, extra_options\u003dNone):"}],"source_content_type":"text/x-python","patch_set":2,"id":"158d79dc_18ddd63d","line":896,"updated":"2026-02-09 16:19:47.000000000","message":"oic, `command` is just getting interpolated into the argv","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":893,"context_line":"        other_next_part_dir \u003d os.path.join(self.objects, str(other_next_part))"},{"line_number":894,"context_line":"        self.assertFalse(os.path.exists(other_next_part_dir))"},{"line_number":895,"context_line":""},{"line_number":896,"context_line":"    def _do_link_test(self, command, old_file_specs, new_file_specs,"},{"line_number":897,"context_line":"                      conflict_file_specs, exp_old_specs, exp_new_specs,"},{"line_number":898,"context_line":"                      exp_ret_code\u003d0, relink_errors\u003dNone,"},{"line_number":899,"context_line":"                      mock_relink_paths\u003dNone, extra_options\u003dNone):"}],"source_content_type":"text/x-python","patch_set":2,"id":"edc788fb_264869b3","line":896,"in_reply_to":"158d79dc_18ddd63d","updated":"2026-02-10 03:58:56.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":false,"context_lines":[{"line_number":893,"context_line":"        other_next_part_dir \u003d os.path.join(self.objects, str(other_next_part))"},{"line_number":894,"context_line":"        self.assertFalse(os.path.exists(other_next_part_dir))"},{"line_number":895,"context_line":""},{"line_number":896,"context_line":"    def _do_link_test(self, command, old_file_specs, new_file_specs,"},{"line_number":897,"context_line":"                      conflict_file_specs, exp_old_specs, exp_new_specs,"},{"line_number":898,"context_line":"                      exp_ret_code\u003d0, relink_errors\u003dNone,"},{"line_number":899,"context_line":"                      mock_relink_paths\u003dNone, extra_options\u003dNone):"}],"source_content_type":"text/x-python","patch_set":2,"id":"1f9a4763_06300981","line":896,"in_reply_to":"edc788fb_264869b3","updated":"2026-02-10 21:03:14.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a6d558f583a41ea7513d909cb2812477920dfc","unresolved":true,"context_lines":[{"line_number":988,"context_line":"            error_lines \u003d self.logger.get_lines_for_level(\u0027error\u0027)"},{"line_number":989,"context_line":"            self.assertEqual(len(conflict_file_specs), len(error_lines))"},{"line_number":990,"context_line":"            for err_msg in error_lines:"},{"line_number":991,"context_line":"                self.assertIn(\"Error relinking\", err_msg)"},{"line_number":992,"context_line":"                self.assertIn(\"hardlink collision\", err_msg)"},{"line_number":993,"context_line":"                self.assertTrue(err_msg.endswith("},{"line_number":994,"context_line":"                    \"(consider enabling clobber_hardlink_collisions)\"))"}],"source_content_type":"text/x-python","patch_set":2,"id":"2fb20f06_317322d3","line":991,"updated":"2026-02-04 17:35:55.000000000","message":"this can assert the prefix:\n```\nself.assertIn(\"[step\u003d%s] Error relinking\" % command, err_msg)\n```","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":false,"context_lines":[{"line_number":988,"context_line":"            error_lines \u003d self.logger.get_lines_for_level(\u0027error\u0027)"},{"line_number":989,"context_line":"            self.assertEqual(len(conflict_file_specs), len(error_lines))"},{"line_number":990,"context_line":"            for err_msg in error_lines:"},{"line_number":991,"context_line":"                self.assertIn(\"Error relinking\", err_msg)"},{"line_number":992,"context_line":"                self.assertIn(\"hardlink collision\", err_msg)"},{"line_number":993,"context_line":"                self.assertTrue(err_msg.endswith("},{"line_number":994,"context_line":"                    \"(consider enabling clobber_hardlink_collisions)\"))"}],"source_content_type":"text/x-python","patch_set":2,"id":"afd019d9_94adbba0","line":991,"in_reply_to":"08e66767_bdcf8ece","updated":"2026-02-10 21:03:14.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":988,"context_line":"            error_lines \u003d self.logger.get_lines_for_level(\u0027error\u0027)"},{"line_number":989,"context_line":"            self.assertEqual(len(conflict_file_specs), len(error_lines))"},{"line_number":990,"context_line":"            for err_msg in error_lines:"},{"line_number":991,"context_line":"                self.assertIn(\"Error relinking\", err_msg)"},{"line_number":992,"context_line":"                self.assertIn(\"hardlink collision\", err_msg)"},{"line_number":993,"context_line":"                self.assertTrue(err_msg.endswith("},{"line_number":994,"context_line":"                    \"(consider enabling clobber_hardlink_collisions)\"))"}],"source_content_type":"text/x-python","patch_set":2,"id":"08e66767_bdcf8ece","line":991,"in_reply_to":"2fb20f06_317322d3","updated":"2026-02-10 03:58:56.000000000","message":"Done. Thanks.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a6d558f583a41ea7513d909cb2812477920dfc","unresolved":true,"context_lines":[{"line_number":1194,"context_line":""},{"line_number":1195,"context_line":"        error_lines \u003d self.logger.get_lines_for_level(\u0027error\u0027)"},{"line_number":1196,"context_line":"        self.assertEqual(["},{"line_number":1197,"context_line":"            \u0027[step\u003drelink] Error relinking: hardlink collision: %s to %s \u0027"},{"line_number":1198,"context_line":"            \u0027(consider enabling clobber_hardlink_collisions)\u0027 % ("},{"line_number":1199,"context_line":"                self.objname,"},{"line_number":1200,"context_line":"                self.expected_file,"}],"source_content_type":"text/x-python","patch_set":2,"id":"8c1fa243_9ea76ff9","line":1197,"updated":"2026-02-04 17:35:55.000000000","message":"👍","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"f2ea961a90007c5e97ff6e91f1d4174e7aca7499","unresolved":false,"context_lines":[{"line_number":1194,"context_line":""},{"line_number":1195,"context_line":"        error_lines \u003d self.logger.get_lines_for_level(\u0027error\u0027)"},{"line_number":1196,"context_line":"        self.assertEqual(["},{"line_number":1197,"context_line":"            \u0027[step\u003drelink] Error relinking: hardlink collision: %s to %s \u0027"},{"line_number":1198,"context_line":"            \u0027(consider enabling clobber_hardlink_collisions)\u0027 % ("},{"line_number":1199,"context_line":"                self.objname,"},{"line_number":1200,"context_line":"                self.expected_file,"}],"source_content_type":"text/x-python","patch_set":2,"id":"18cfdb93_4b6d1da8","line":1197,"in_reply_to":"0c6feda1_08013fce","updated":"2026-02-10 04:01:42.000000000","message":"Done","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":1194,"context_line":""},{"line_number":1195,"context_line":"        error_lines \u003d self.logger.get_lines_for_level(\u0027error\u0027)"},{"line_number":1196,"context_line":"        self.assertEqual(["},{"line_number":1197,"context_line":"            \u0027[step\u003drelink] Error relinking: hardlink collision: %s to %s \u0027"},{"line_number":1198,"context_line":"            \u0027(consider enabling clobber_hardlink_collisions)\u0027 % ("},{"line_number":1199,"context_line":"                self.objname,"},{"line_number":1200,"context_line":"                self.expected_file,"}],"source_content_type":"text/x-python","patch_set":2,"id":"0c6feda1_08013fce","line":1197,"in_reply_to":"8c1fa243_9ea76ff9","updated":"2026-02-10 03:58:56.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a6d558f583a41ea7513d909cb2812477920dfc","unresolved":true,"context_lines":[{"line_number":2870,"context_line":"        r.hook_post_partition(os.path.join(datadir_path, \u002796\u0027))"},{"line_number":2871,"context_line":"        self.assertEqual(r.states[\"state\"], {\u002796\u0027: True, \u0027227\u0027: False})"},{"line_number":2872,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\"info\"), ["},{"line_number":2873,"context_line":"            \"Device: sda1 Policy: %s \""},{"line_number":2874,"context_line":"            \"Partitions: 1/2\" % r.policy.name,"},{"line_number":2875,"context_line":"        ])"},{"line_number":2876,"context_line":"        with open(state_file, \u0027rt\u0027) as f:"}],"source_content_type":"text/x-python","patch_set":2,"id":"68ab0777_36381d38","line":2873,"updated":"2026-02-04 17:35:55.000000000","message":"this looks like a regression, but it\u0027s actually a consequence of the test calling Relinker directly.\n\nI think it would be worth \u0027fixing\u0027 the test by passing a prefixed self.logger to the Relinker at line 2824","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"999913b07c1bf6e528425ea3b1ce1f4787e767eb","unresolved":false,"context_lines":[{"line_number":2870,"context_line":"        r.hook_post_partition(os.path.join(datadir_path, \u002796\u0027))"},{"line_number":2871,"context_line":"        self.assertEqual(r.states[\"state\"], {\u002796\u0027: True, \u0027227\u0027: False})"},{"line_number":2872,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\"info\"), ["},{"line_number":2873,"context_line":"            \"Device: sda1 Policy: %s \""},{"line_number":2874,"context_line":"            \"Partitions: 1/2\" % r.policy.name,"},{"line_number":2875,"context_line":"        ])"},{"line_number":2876,"context_line":"        with open(state_file, \u0027rt\u0027) as f:"}],"source_content_type":"text/x-python","patch_set":2,"id":"5d8790cb_da3ac27c","line":2873,"in_reply_to":"310adfac_8283911d","updated":"2026-02-12 17:19:26.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"6f3ac189560a2f33364922fb43904712ab875a40","unresolved":true,"context_lines":[{"line_number":2870,"context_line":"        r.hook_post_partition(os.path.join(datadir_path, \u002796\u0027))"},{"line_number":2871,"context_line":"        self.assertEqual(r.states[\"state\"], {\u002796\u0027: True, \u0027227\u0027: False})"},{"line_number":2872,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\"info\"), ["},{"line_number":2873,"context_line":"            \"Device: sda1 Policy: %s \""},{"line_number":2874,"context_line":"            \"Partitions: 1/2\" % r.policy.name,"},{"line_number":2875,"context_line":"        ])"},{"line_number":2876,"context_line":"        with open(state_file, \u0027rt\u0027) as f:"}],"source_content_type":"text/x-python","patch_set":2,"id":"310adfac_8283911d","line":2873,"in_reply_to":"439d99ba_c2736441","updated":"2026-02-12 10:32:01.000000000","message":"My 2-cents worth: you chose one of at least 2 ways to address the problem. We stumbled across one test that needed assertions changing, which drew attention to the fact that there was another way that would have avoided that. BUT...you got two +2 votes and a +A (approve/merge) which doesn\u0027t come easily...so my advice would be \"take the win\" 😊\n\nWe often have a flurry of follow-ups after an initial patch to try to polish things. That\u0027s fine...\"better\" on master and \"perfect\" still in review often beats \"nothing\" on master. On the other hand, sometimes its worth getting something closer to perfect before merging because we\u0027re not going to revisit this for some time (a lot of follow up patches languish because reviewers and authors have moved on once \"better\" has merged).\n\nIt all comes down to per-case judgement. In this case I can see that you have pushed a follow-up. IMHO that\u0027s a good call - don\u0027t delay this patch by polishing the tests.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"15a1ab086c5316761bc8c470f726abb72db0a1c6","unresolved":true,"context_lines":[{"line_number":2870,"context_line":"        r.hook_post_partition(os.path.join(datadir_path, \u002796\u0027))"},{"line_number":2871,"context_line":"        self.assertEqual(r.states[\"state\"], {\u002796\u0027: True, \u0027227\u0027: False})"},{"line_number":2872,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\"info\"), ["},{"line_number":2873,"context_line":"            \"Device: sda1 Policy: %s \""},{"line_number":2874,"context_line":"            \"Partitions: 1/2\" % r.policy.name,"},{"line_number":2875,"context_line":"        ])"},{"line_number":2876,"context_line":"        with open(state_file, \u0027rt\u0027) as f:"}],"source_content_type":"text/x-python","patch_set":2,"id":"439d99ba_c2736441","line":2873,"in_reply_to":"4a3b0cd9_3f10e39e","updated":"2026-02-11 17:54:12.000000000","message":"The spirit of the change was centered around: \"the CLI driver is choosing to do prefix logging, rather than the `Relinker` module\". As such, I decided to go with `assertIn` to be less dependent on the test input (`logger`).\n\nI\u0027m less convinced about this approach after seeing your and Clay\u0027s feedback on this patch. A possible path is to re-strengthen the assertions so that they test the expected invariant: \"Log lines are prefixed\". Ideally, this invariant is a upheld via approach 3 but to limit the scope of this patch I will go with approach 1.\n\nThoughts?","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8789c4b686c9fd607a9e860772076b49953c053a","unresolved":true,"context_lines":[{"line_number":2870,"context_line":"        r.hook_post_partition(os.path.join(datadir_path, \u002796\u0027))"},{"line_number":2871,"context_line":"        self.assertEqual(r.states[\"state\"], {\u002796\u0027: True, \u0027227\u0027: False})"},{"line_number":2872,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\"info\"), ["},{"line_number":2873,"context_line":"            \"Device: sda1 Policy: %s \""},{"line_number":2874,"context_line":"            \"Partitions: 1/2\" % r.policy.name,"},{"line_number":2875,"context_line":"        ])"},{"line_number":2876,"context_line":"        with open(state_file, \u0027rt\u0027) as f:"}],"source_content_type":"text/x-python","patch_set":2,"id":"ecb274c7_6088ec07","line":2873,"in_reply_to":"68ab0777_36381d38","updated":"2026-02-09 16:19:47.000000000","message":"\u003e passing a prefixed self.logger to the Relinker at line 2824\n\non using one of the \"main\" functions in the cli as the entrypoint like the other `_do_link_test` helpers - most of the `r.attr \u003d xyz` setup could be achived with moneky-patching.\n\nOR \n\npush the logger prefixing down a layer *into* the Relinker itself - it already calls getpid and has a list of devices","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"7cb106f4c9afaa0b087b3a63f8ebb8ec86b9a62b","unresolved":true,"context_lines":[{"line_number":2870,"context_line":"        r.hook_post_partition(os.path.join(datadir_path, \u002796\u0027))"},{"line_number":2871,"context_line":"        self.assertEqual(r.states[\"state\"], {\u002796\u0027: True, \u0027227\u0027: False})"},{"line_number":2872,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\"info\"), ["},{"line_number":2873,"context_line":"            \"Device: sda1 Policy: %s \""},{"line_number":2874,"context_line":"            \"Partitions: 1/2\" % r.policy.name,"},{"line_number":2875,"context_line":"        ])"},{"line_number":2876,"context_line":"        with open(state_file, \u0027rt\u0027) as f:"}],"source_content_type":"text/x-python","patch_set":2,"id":"4a3b0cd9_3f10e39e","line":2873,"in_reply_to":"b580aea4_235dd072","updated":"2026-02-11 12:09:48.000000000","message":"On reflection I might have prefixed my original comment \"nit:\". Yes, the diff looks like a regression, but \u0027fixing\u0027 that is either 1) somewhat artificial, or 2) creates churn just to get coverage we already have elsewhere, or 3) requires a different design.\n\nOf those, approach 3 (Clay\u0027s suggestion for different design, prefixing the logger inside Relinker) seems like the one with most return on investment.\n\nThe change from ``assertEqual`` to ``assertIn`` intrigues me though. It\u0027s not necessary, I think the ``assertEqual`` worked, so why choose a less precise assertion? I understand that ``assertIn`` leads to less maintenance (i.e. someone can tinker with the log line without breaking this test), but on the other hand if the log line is significant enough to be asserted, why wouldn\u0027t we want to know if it has been changed?\n\nI know that opinions will differ on this! FWIW, I have found myself moving away from ``assertIn(expected, log_line)`` to ``assertEqual(expected, log_line)`` *when possible* (it\u0027s not always possible). IIRC maybe I discovered some log line with unexpected content not caught by ``assertIn``??\n\nThat said, it\u0027s not a blocker IMO for the patch to merge, I\u0027m just sharing my thoughts.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":true,"context_lines":[{"line_number":2870,"context_line":"        r.hook_post_partition(os.path.join(datadir_path, \u002796\u0027))"},{"line_number":2871,"context_line":"        self.assertEqual(r.states[\"state\"], {\u002796\u0027: True, \u0027227\u0027: False})"},{"line_number":2872,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\"info\"), ["},{"line_number":2873,"context_line":"            \"Device: sda1 Policy: %s \""},{"line_number":2874,"context_line":"            \"Partitions: 1/2\" % r.policy.name,"},{"line_number":2875,"context_line":"        ])"},{"line_number":2876,"context_line":"        with open(state_file, \u0027rt\u0027) as f:"}],"source_content_type":"text/x-python","patch_set":2,"id":"b580aea4_235dd072","line":2873,"in_reply_to":"d674b98d_cefc3e87","updated":"2026-02-10 21:03:14.000000000","message":"I don\u0027t think \"assert this line appears in the list of log lines\" vs \"assert this sub-string appears in this log line\" difference is relevant to the `step\u003d` claim \"disappearing\" in the asserted log message.\n\nThe red part of the diff says `step\u003drelink` the green part of the diff notably does *not* mention the `step\u003d` in the assertion (b/c the step in fact *no longer* appears in the test\u0027s log message)\n\nThe possible ways to improve this offered have been:\n\n1) pass in a prefix\u0027d logger when you create the Relinker at L2824\n2) use a higher level entrypoint so that the Relinker is created by `parallel_process` (and therefore is passed a `step\u003d` prefix\u0027d logger)\n3) establish a consistent log prefix via `Relinker.__init__` instead of relying on the caller to do so\n\nI don\u0027t think \"rephrase the assert\" directly addresses the problem of \"the test setup no longer supports making assertion about the behavior we want to maintain\"","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":2870,"context_line":"        r.hook_post_partition(os.path.join(datadir_path, \u002796\u0027))"},{"line_number":2871,"context_line":"        self.assertEqual(r.states[\"state\"], {\u002796\u0027: True, \u0027227\u0027: False})"},{"line_number":2872,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\"info\"), ["},{"line_number":2873,"context_line":"            \"Device: sda1 Policy: %s \""},{"line_number":2874,"context_line":"            \"Partitions: 1/2\" % r.policy.name,"},{"line_number":2875,"context_line":"        ])"},{"line_number":2876,"context_line":"        with open(state_file, \u0027rt\u0027) as f:"}],"source_content_type":"text/x-python","patch_set":2,"id":"d674b98d_cefc3e87","line":2873,"in_reply_to":"ecb274c7_6088ec07","updated":"2026-02-10 03:58:56.000000000","message":"There seem\u0027s to be an inconsistency for this assertion across this file. In other cases, we have:\n```\nself.assertIn(\"Device: sda1 Policy: %s \"\n              \"Partitions: 2/2\" % r.policy.name,\n              self.logger.get_lines_for_level(\"info\")\n```\nI went with the above approach because its less code maintenance.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a6d558f583a41ea7513d909cb2812477920dfc","unresolved":true,"context_lines":[{"line_number":2925,"context_line":"        r.stats[\u0027errors\u0027] +\u003d 1"},{"line_number":2926,"context_line":"        r.hook_post_partition(os.path.join(datadir_path, \u0027227\u0027))"},{"line_number":2927,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\"info\"), ["},{"line_number":2928,"context_line":"            \"Device: sda1 Policy: %s \""},{"line_number":2929,"context_line":"            \"Partitions: 1/2\" % r.policy.name,"},{"line_number":2930,"context_line":"        ])"},{"line_number":2931,"context_line":"        self.assertEqual(r.states[\"state\"], {\u002796\u0027: True, \u0027227\u0027: False})"}],"source_content_type":"text/x-python","patch_set":2,"id":"0748fba2_e5997218","line":2928,"updated":"2026-02-04 17:35:55.000000000","message":"ditto, and below...","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":2925,"context_line":"        r.stats[\u0027errors\u0027] +\u003d 1"},{"line_number":2926,"context_line":"        r.hook_post_partition(os.path.join(datadir_path, \u0027227\u0027))"},{"line_number":2927,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\"info\"), ["},{"line_number":2928,"context_line":"            \"Device: sda1 Policy: %s \""},{"line_number":2929,"context_line":"            \"Partitions: 1/2\" % r.policy.name,"},{"line_number":2930,"context_line":"        ])"},{"line_number":2931,"context_line":"        self.assertEqual(r.states[\"state\"], {\u002796\u0027: True, \u0027227\u0027: False})"}],"source_content_type":"text/x-python","patch_set":2,"id":"bf231c0a_922de22d","line":2928,"in_reply_to":"0748fba2_e5997218","updated":"2026-02-10 03:58:56.000000000","message":"Went ahead with approach listed above.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":false,"context_lines":[{"line_number":2925,"context_line":"        r.stats[\u0027errors\u0027] +\u003d 1"},{"line_number":2926,"context_line":"        r.hook_post_partition(os.path.join(datadir_path, \u0027227\u0027))"},{"line_number":2927,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\"info\"), ["},{"line_number":2928,"context_line":"            \"Device: sda1 Policy: %s \""},{"line_number":2929,"context_line":"            \"Partitions: 1/2\" % r.policy.name,"},{"line_number":2930,"context_line":"        ])"},{"line_number":2931,"context_line":"        self.assertEqual(r.states[\"state\"], {\u002796\u0027: True, \u0027227\u0027: False})"}],"source_content_type":"text/x-python","patch_set":2,"id":"711bbeff_17ba654e","line":2928,"in_reply_to":"bf231c0a_922de22d","updated":"2026-02-10 21:03:14.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a6d558f583a41ea7513d909cb2812477920dfc","unresolved":true,"context_lines":[{"line_number":3681,"context_line":"        self.assertFalse(os.path.isfile(self.expected_file))"},{"line_number":3682,"context_line":"        self.assertTrue(os.path.isfile(self.objname))  # old file intact"},{"line_number":3683,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\u0027error\u0027), ["},{"line_number":3684,"context_line":"            \u0027[step\u003dcleanup] Error relinking: failed to relink %s to %s: os-error!\u0027 # noqa 501"},{"line_number":3685,"context_line":"            % (self.objname, self.expected_file),"},{"line_number":3686,"context_line":"        ])"},{"line_number":3687,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\u0027warning\u0027), ["}],"source_content_type":"text/x-python","patch_set":2,"id":"36aa2de7_59afff4d","line":3684,"updated":"2026-02-04 17:35:55.000000000","message":"please wrap the line rather than using a flake8 exception","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":false,"context_lines":[{"line_number":3681,"context_line":"        self.assertFalse(os.path.isfile(self.expected_file))"},{"line_number":3682,"context_line":"        self.assertTrue(os.path.isfile(self.objname))  # old file intact"},{"line_number":3683,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\u0027error\u0027), ["},{"line_number":3684,"context_line":"            \u0027[step\u003dcleanup] Error relinking: failed to relink %s to %s: os-error!\u0027 # noqa 501"},{"line_number":3685,"context_line":"            % (self.objname, self.expected_file),"},{"line_number":3686,"context_line":"        ])"},{"line_number":3687,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\u0027warning\u0027), ["}],"source_content_type":"text/x-python","patch_set":2,"id":"0a1304ed_62a9ac08","line":3684,"in_reply_to":"1eed7d98_b6239e12","updated":"2026-02-10 21:03:14.000000000","message":"Done","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":3681,"context_line":"        self.assertFalse(os.path.isfile(self.expected_file))"},{"line_number":3682,"context_line":"        self.assertTrue(os.path.isfile(self.objname))  # old file intact"},{"line_number":3683,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\u0027error\u0027), ["},{"line_number":3684,"context_line":"            \u0027[step\u003dcleanup] Error relinking: failed to relink %s to %s: os-error!\u0027 # noqa 501"},{"line_number":3685,"context_line":"            % (self.objname, self.expected_file),"},{"line_number":3686,"context_line":"        ])"},{"line_number":3687,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\u0027warning\u0027), ["}],"source_content_type":"text/x-python","patch_set":2,"id":"1eed7d98_b6239e12","line":3684,"in_reply_to":"36aa2de7_59afff4d","updated":"2026-02-10 03:58:56.000000000","message":"Done","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a6d558f583a41ea7513d909cb2812477920dfc","unresolved":true,"context_lines":[{"line_number":3719,"context_line":"        self.assertFalse(os.path.isfile(self.expected_file))"},{"line_number":3720,"context_line":"        self.assertTrue(os.path.isfile(self.objname))  # old file intact"},{"line_number":3721,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\"error\"), ["},{"line_number":3722,"context_line":"            \"[step\u003dcleanup] Error relinking: failed to relink %s to %s: kaboom!\"  # noqa 501"},{"line_number":3723,"context_line":"            % (self.objname, self.expected_file)"},{"line_number":3724,"context_line":"        ])"},{"line_number":3725,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\u0027warning\u0027), ["}],"source_content_type":"text/x-python","patch_set":2,"id":"c8a76144_58bcf3b7","line":3722,"updated":"2026-02-04 17:35:55.000000000","message":"ditto","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":false,"context_lines":[{"line_number":3719,"context_line":"        self.assertFalse(os.path.isfile(self.expected_file))"},{"line_number":3720,"context_line":"        self.assertTrue(os.path.isfile(self.objname))  # old file intact"},{"line_number":3721,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\"error\"), ["},{"line_number":3722,"context_line":"            \"[step\u003dcleanup] Error relinking: failed to relink %s to %s: kaboom!\"  # noqa 501"},{"line_number":3723,"context_line":"            % (self.objname, self.expected_file)"},{"line_number":3724,"context_line":"        ])"},{"line_number":3725,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\u0027warning\u0027), ["}],"source_content_type":"text/x-python","patch_set":2,"id":"c713a8e3_dbb2ab10","line":3722,"in_reply_to":"51dac11d_29444171","updated":"2026-02-10 21:03:14.000000000","message":"Done","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":3719,"context_line":"        self.assertFalse(os.path.isfile(self.expected_file))"},{"line_number":3720,"context_line":"        self.assertTrue(os.path.isfile(self.objname))  # old file intact"},{"line_number":3721,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\"error\"), ["},{"line_number":3722,"context_line":"            \"[step\u003dcleanup] Error relinking: failed to relink %s to %s: kaboom!\"  # noqa 501"},{"line_number":3723,"context_line":"            % (self.objname, self.expected_file)"},{"line_number":3724,"context_line":"        ])"},{"line_number":3725,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\u0027warning\u0027), ["}],"source_content_type":"text/x-python","patch_set":2,"id":"51dac11d_29444171","line":3722,"in_reply_to":"c8a76144_58bcf3b7","updated":"2026-02-10 03:58:56.000000000","message":"Done","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a6d558f583a41ea7513d909cb2812477920dfc","unresolved":true,"context_lines":[{"line_number":3931,"context_line":"            self.assertEqual(calls, expected)"},{"line_number":3932,"context_line":"            self.assertEqual([], self.logger.get_lines_for_level(\u0027error\u0027))"},{"line_number":3933,"context_line":""},{"line_number":3934,"context_line":"    # tests prefix logging for relinker runs with multiple workers"},{"line_number":3935,"context_line":"    def test_prefix_loggers(self):"},{"line_number":3936,"context_line":"        devices \u003d set([\u0027sda2\u0027, \u0027sda3\u0027, \u0027sda4\u0027])"},{"line_number":3937,"context_line":"        for device in devices:"}],"source_content_type":"text/x-python","patch_set":2,"id":"5d3bf9ae_08f4f981","line":3934,"updated":"2026-02-04 17:35:55.000000000","message":"nit: IME of swift tests this kind of comment tends to come inside the method (i.e. line 3935)\n\nHowever, I love comments that help me understand why a test exists 😊","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":false,"context_lines":[{"line_number":3931,"context_line":"            self.assertEqual(calls, expected)"},{"line_number":3932,"context_line":"            self.assertEqual([], self.logger.get_lines_for_level(\u0027error\u0027))"},{"line_number":3933,"context_line":""},{"line_number":3934,"context_line":"    # tests prefix logging for relinker runs with multiple workers"},{"line_number":3935,"context_line":"    def test_prefix_loggers(self):"},{"line_number":3936,"context_line":"        devices \u003d set([\u0027sda2\u0027, \u0027sda3\u0027, \u0027sda4\u0027])"},{"line_number":3937,"context_line":"        for device in devices:"}],"source_content_type":"text/x-python","patch_set":2,"id":"46444528_e0858429","line":3934,"in_reply_to":"229bb3bb_ca7bbe64","updated":"2026-02-10 21:03:14.000000000","message":"Done","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":3931,"context_line":"            self.assertEqual(calls, expected)"},{"line_number":3932,"context_line":"            self.assertEqual([], self.logger.get_lines_for_level(\u0027error\u0027))"},{"line_number":3933,"context_line":""},{"line_number":3934,"context_line":"    # tests prefix logging for relinker runs with multiple workers"},{"line_number":3935,"context_line":"    def test_prefix_loggers(self):"},{"line_number":3936,"context_line":"        devices \u003d set([\u0027sda2\u0027, \u0027sda3\u0027, \u0027sda4\u0027])"},{"line_number":3937,"context_line":"        for device in devices:"}],"source_content_type":"text/x-python","patch_set":2,"id":"229bb3bb_ca7bbe64","line":3934,"in_reply_to":"5d3bf9ae_08f4f981","updated":"2026-02-10 03:58:56.000000000","message":"Done!","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a6d558f583a41ea7513d909cb2812477920dfc","unresolved":true,"context_lines":[{"line_number":3933,"context_line":""},{"line_number":3934,"context_line":"    # tests prefix logging for relinker runs with multiple workers"},{"line_number":3935,"context_line":"    def test_prefix_loggers(self):"},{"line_number":3936,"context_line":"        devices \u003d set([\u0027sda2\u0027, \u0027sda3\u0027, \u0027sda4\u0027])"},{"line_number":3937,"context_line":"        for device in devices:"},{"line_number":3938,"context_line":"            os.mkdir(os.path.join(self.devices, device))"},{"line_number":3939,"context_line":"        devices.add(self.existing_device)"}],"source_content_type":"text/x-python","patch_set":2,"id":"bad60e2e_5444ddc9","line":3936,"updated":"2026-02-04 17:35:55.000000000","message":"nit: ``devices \u003d {\u0027sda2\u0027, \u0027sda3\u0027, \u0027sda4\u0027}``","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":3933,"context_line":""},{"line_number":3934,"context_line":"    # tests prefix logging for relinker runs with multiple workers"},{"line_number":3935,"context_line":"    def test_prefix_loggers(self):"},{"line_number":3936,"context_line":"        devices \u003d set([\u0027sda2\u0027, \u0027sda3\u0027, \u0027sda4\u0027])"},{"line_number":3937,"context_line":"        for device in devices:"},{"line_number":3938,"context_line":"            os.mkdir(os.path.join(self.devices, device))"},{"line_number":3939,"context_line":"        devices.add(self.existing_device)"}],"source_content_type":"text/x-python","patch_set":2,"id":"c02df4dd_ad05096d","line":3936,"in_reply_to":"bad60e2e_5444ddc9","updated":"2026-02-10 03:58:56.000000000","message":"Fixed. Thanks.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":false,"context_lines":[{"line_number":3933,"context_line":""},{"line_number":3934,"context_line":"    # tests prefix logging for relinker runs with multiple workers"},{"line_number":3935,"context_line":"    def test_prefix_loggers(self):"},{"line_number":3936,"context_line":"        devices \u003d set([\u0027sda2\u0027, \u0027sda3\u0027, \u0027sda4\u0027])"},{"line_number":3937,"context_line":"        for device in devices:"},{"line_number":3938,"context_line":"            os.mkdir(os.path.join(self.devices, device))"},{"line_number":3939,"context_line":"        devices.add(self.existing_device)"}],"source_content_type":"text/x-python","patch_set":2,"id":"89fd4d5f_f0678b2b","line":3936,"in_reply_to":"c02df4dd_ad05096d","updated":"2026-02-10 21:03:14.000000000","message":"Done","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a6d558f583a41ea7513d909cb2812477920dfc","unresolved":true,"context_lines":[{"line_number":3945,"context_line":""},{"line_number":3946,"context_line":"        calls \u003d []"},{"line_number":3947,"context_line":""},{"line_number":3948,"context_line":"        def mock_run(self):"},{"line_number":3949,"context_line":"            calls.append((\u0027run\u0027, self.device_list))"},{"line_number":3950,"context_line":"            self.logger.info(\"relinker run\")"},{"line_number":3951,"context_line":"            return 0"}],"source_content_type":"text/x-python","patch_set":2,"id":"6e9f9f64_77f512fb","line":3948,"range":{"start_line":3948,"start_character":21,"end_line":3948,"end_character":25},"updated":"2026-02-04 17:35:55.000000000","message":"nit: ``self`` works but can be confusing w.r.t. the ``self`` in the outer scope. IIRC I\u0027ve seen ``this`` or ``inst`` (instance) used as an alternative.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":false,"context_lines":[{"line_number":3945,"context_line":""},{"line_number":3946,"context_line":"        calls \u003d []"},{"line_number":3947,"context_line":""},{"line_number":3948,"context_line":"        def mock_run(self):"},{"line_number":3949,"context_line":"            calls.append((\u0027run\u0027, self.device_list))"},{"line_number":3950,"context_line":"            self.logger.info(\"relinker run\")"},{"line_number":3951,"context_line":"            return 0"}],"source_content_type":"text/x-python","patch_set":2,"id":"be53e233_0282dec5","line":3948,"range":{"start_line":3948,"start_character":21,"end_line":3948,"end_character":25},"in_reply_to":"3f7bc808_548829db","updated":"2026-02-10 21:03:14.000000000","message":"Done","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":3945,"context_line":""},{"line_number":3946,"context_line":"        calls \u003d []"},{"line_number":3947,"context_line":""},{"line_number":3948,"context_line":"        def mock_run(self):"},{"line_number":3949,"context_line":"            calls.append((\u0027run\u0027, self.device_list))"},{"line_number":3950,"context_line":"            self.logger.info(\"relinker run\")"},{"line_number":3951,"context_line":"            return 0"}],"source_content_type":"text/x-python","patch_set":2,"id":"3f7bc808_548829db","line":3948,"range":{"start_line":3948,"start_character":21,"end_line":3948,"end_character":25},"in_reply_to":"6e9f9f64_77f512fb","updated":"2026-02-10 03:58:56.000000000","message":"Fixed. Thanks.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"8789c4b686c9fd607a9e860772076b49953c053a","unresolved":true,"context_lines":[{"line_number":3968,"context_line":"        with mock.patch(\u0027os.fork\u0027, mock_fork), \\"},{"line_number":3969,"context_line":"                mock.patch(\u0027os._exit\u0027, mock_exit), \\"},{"line_number":3970,"context_line":"                mock.patch(\u0027os.getpid\u0027, mock_getpid), \\"},{"line_number":3971,"context_line":"                mock.patch(\u0027swift.cli.relinker.Relinker.run\u0027, mock_run), \\"},{"line_number":3972,"context_line":"                self._mock_relinker():"},{"line_number":3973,"context_line":"            self.assertEqual(0, relinker.main(["},{"line_number":3974,"context_line":"                step,"}],"source_content_type":"text/x-python","patch_set":2,"id":"f7eb7c1a_19506f1a","line":3971,"updated":"2026-02-09 16:19:47.000000000","message":"this is a rather complex test, it\u0027s really hard to get good coverage around code that uses fork and we\u0027re not always very good at it - KUDOS.","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"f2ea961a90007c5e97ff6e91f1d4174e7aca7499","unresolved":false,"context_lines":[{"line_number":3968,"context_line":"        with mock.patch(\u0027os.fork\u0027, mock_fork), \\"},{"line_number":3969,"context_line":"                mock.patch(\u0027os._exit\u0027, mock_exit), \\"},{"line_number":3970,"context_line":"                mock.patch(\u0027os.getpid\u0027, mock_getpid), \\"},{"line_number":3971,"context_line":"                mock.patch(\u0027swift.cli.relinker.Relinker.run\u0027, mock_run), \\"},{"line_number":3972,"context_line":"                self._mock_relinker():"},{"line_number":3973,"context_line":"            self.assertEqual(0, relinker.main(["},{"line_number":3974,"context_line":"                step,"}],"source_content_type":"text/x-python","patch_set":2,"id":"76b3f516_2fc9f044","line":3971,"in_reply_to":"d12d35b3_c1335b8f","updated":"2026-02-10 04:01:42.000000000","message":"Done","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":3968,"context_line":"        with mock.patch(\u0027os.fork\u0027, mock_fork), \\"},{"line_number":3969,"context_line":"                mock.patch(\u0027os._exit\u0027, mock_exit), \\"},{"line_number":3970,"context_line":"                mock.patch(\u0027os.getpid\u0027, mock_getpid), \\"},{"line_number":3971,"context_line":"                mock.patch(\u0027swift.cli.relinker.Relinker.run\u0027, mock_run), \\"},{"line_number":3972,"context_line":"                self._mock_relinker():"},{"line_number":3973,"context_line":"            self.assertEqual(0, relinker.main(["},{"line_number":3974,"context_line":"                step,"}],"source_content_type":"text/x-python","patch_set":2,"id":"d12d35b3_c1335b8f","line":3971,"in_reply_to":"f7eb7c1a_19506f1a","updated":"2026-02-10 03:58:56.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a6d558f583a41ea7513d909cb2812477920dfc","unresolved":true,"context_lines":[{"line_number":3985,"context_line":"        log_lines \u003d self.logger.get_lines_for_level(\u0027info\u0027)"},{"line_number":3986,"context_line":"        start_log \u003d log_lines[0]"},{"line_number":3987,"context_line":"        self.assertTrue(start_log.startswith("},{"line_number":3988,"context_line":"            f\"[step\u003d{step}] Starting relinker using {len(devices)} workers\"))"},{"line_number":3989,"context_line":""},{"line_number":3990,"context_line":"        self.assertEqual(pid, len(devices))"},{"line_number":3991,"context_line":"        for idx, dev in enumerate(devices):"}],"source_content_type":"text/x-python","patch_set":2,"id":"44ca37da_527c0468","line":3988,"updated":"2026-02-04 17:35:55.000000000","message":"ok, so startswith is needed because of the unknown timings 👍","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"f2ea961a90007c5e97ff6e91f1d4174e7aca7499","unresolved":false,"context_lines":[{"line_number":3985,"context_line":"        log_lines \u003d self.logger.get_lines_for_level(\u0027info\u0027)"},{"line_number":3986,"context_line":"        start_log \u003d log_lines[0]"},{"line_number":3987,"context_line":"        self.assertTrue(start_log.startswith("},{"line_number":3988,"context_line":"            f\"[step\u003d{step}] Starting relinker using {len(devices)} workers\"))"},{"line_number":3989,"context_line":""},{"line_number":3990,"context_line":"        self.assertEqual(pid, len(devices))"},{"line_number":3991,"context_line":"        for idx, dev in enumerate(devices):"}],"source_content_type":"text/x-python","patch_set":2,"id":"0baf41dc_9a67e9d8","line":3988,"in_reply_to":"3b5b0bd9_ea84d83b","updated":"2026-02-10 04:01:42.000000000","message":"Done","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":3985,"context_line":"        log_lines \u003d self.logger.get_lines_for_level(\u0027info\u0027)"},{"line_number":3986,"context_line":"        start_log \u003d log_lines[0]"},{"line_number":3987,"context_line":"        self.assertTrue(start_log.startswith("},{"line_number":3988,"context_line":"            f\"[step\u003d{step}] Starting relinker using {len(devices)} workers\"))"},{"line_number":3989,"context_line":""},{"line_number":3990,"context_line":"        self.assertEqual(pid, len(devices))"},{"line_number":3991,"context_line":"        for idx, dev in enumerate(devices):"}],"source_content_type":"text/x-python","patch_set":2,"id":"3b5b0bd9_ea84d83b","line":3988,"in_reply_to":"44ca37da_527c0468","updated":"2026-02-10 03:58:56.000000000","message":"Acknowledged","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":7847,"name":"Alistair Coles","email":"alistairncoles@gmail.com","username":"acoles"},"change_message_id":"56a6d558f583a41ea7513d909cb2812477920dfc","unresolved":true,"context_lines":[{"line_number":3990,"context_line":"        self.assertEqual(pid, len(devices))"},{"line_number":3991,"context_line":"        for idx, dev in enumerate(devices):"},{"line_number":3992,"context_line":"            pid_log \u003d f\"[step\u003d{step}, pid\u003d{idx + 1}, devs\u003d{dev}] relinker run\""},{"line_number":3993,"context_line":"            self.assertEqual(log_lines.count(pid_log), 1)"},{"line_number":3994,"context_line":""},{"line_number":3995,"context_line":"        finish_line \u003d log_lines[-1]"},{"line_number":3996,"context_line":"        self.assertTrue(finish_line.startswith("}],"source_content_type":"text/x-python","patch_set":2,"id":"5a0d0a8d_3279a2bb","line":3993,"updated":"2026-02-04 17:35:55.000000000","message":"nit: this is ok, but if the test fails it doesn\u0027t give us much info.\n\nAn alternative would be to compare ``sorted(log_lines[1:-1])`` with an order list of expectations","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":false,"context_lines":[{"line_number":3990,"context_line":"        self.assertEqual(pid, len(devices))"},{"line_number":3991,"context_line":"        for idx, dev in enumerate(devices):"},{"line_number":3992,"context_line":"            pid_log \u003d f\"[step\u003d{step}, pid\u003d{idx + 1}, devs\u003d{dev}] relinker run\""},{"line_number":3993,"context_line":"            self.assertEqual(log_lines.count(pid_log), 1)"},{"line_number":3994,"context_line":""},{"line_number":3995,"context_line":"        finish_line \u003d log_lines[-1]"},{"line_number":3996,"context_line":"        self.assertTrue(finish_line.startswith("}],"source_content_type":"text/x-python","patch_set":2,"id":"402c956c_d63f950a","line":3993,"in_reply_to":"24c2a1fa_4ab49abf","updated":"2026-02-10 21:03:14.000000000","message":"Done","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"53cc69cd66ae6a05672264684b2b0779abd60def","unresolved":true,"context_lines":[{"line_number":3990,"context_line":"        self.assertEqual(pid, len(devices))"},{"line_number":3991,"context_line":"        for idx, dev in enumerate(devices):"},{"line_number":3992,"context_line":"            pid_log \u003d f\"[step\u003d{step}, pid\u003d{idx + 1}, devs\u003d{dev}] relinker run\""},{"line_number":3993,"context_line":"            self.assertEqual(log_lines.count(pid_log), 1)"},{"line_number":3994,"context_line":""},{"line_number":3995,"context_line":"        finish_line \u003d log_lines[-1]"},{"line_number":3996,"context_line":"        self.assertTrue(finish_line.startswith("}],"source_content_type":"text/x-python","patch_set":2,"id":"24c2a1fa_4ab49abf","line":3993,"in_reply_to":"5a0d0a8d_3279a2bb","updated":"2026-02-10 03:58:56.000000000","message":"Done!","commit_id":"220555ee2ed7261cf68e0b4502d2ad01ead4a9d5"},{"author":{"_account_id":1179,"name":"Clay Gerrard","email":"clay.gerrard@gmail.com","username":"clay-gerrard"},"change_message_id":"9ea23580ca0a320dfa63ecc32621d2a1debd8890","unresolved":true,"context_lines":[{"line_number":2918,"context_line":"        r.stats[\u0027errors\u0027] +\u003d 1"},{"line_number":2919,"context_line":"        r.hook_post_partition(os.path.join(datadir_path, \u0027227\u0027))"},{"line_number":2920,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\"info\"), ["},{"line_number":2921,"context_line":"            \"Step: relink Device: sda1 Policy: %s \""},{"line_number":2922,"context_line":"            \"Partitions: 1/2\" % r.policy.name,"},{"line_number":2923,"context_line":"        ])"},{"line_number":2924,"context_line":"        self.assertEqual(r.states[\"state\"], {\u002796\u0027: True, \u0027227\u0027: False})"}],"source_content_type":"text/x-python","patch_set":3,"id":"4d210754_8d5afcab","side":"PARENT","line":2921,"updated":"2026-02-10 21:03:14.000000000","message":"N.B. if you pause in a debugger here this line *no longer* has \"relink\" in it:\n\n```\n(Pdb) self.logger.get_lines_for_level(\u0027info\u0027)\n[\u0027Device: sda1 Policy: platinum Partitions: 1/2\u0027]\n```\n\ncompared to master:\n\n```\n(Pdb) self.logger.get_lines_for_level(\"info\")\n[\u0027Step: relink Device: sda1 Policy: platinum Partitions: 1/2\u0027]\n```\n\ni.e. this test diff hunk taken on it\u0027s own still *looks* like a regression.","commit_id":"c7bee623658b464072783096b98adaddfb1005bc"},{"author":{"_account_id":38767,"name":"Wael Halbawi","display_name":"Wael Halbawi","email":"whalbawi@nvidia.com","username":"whalbawi"},"change_message_id":"7c1e65fbdba95b4dd6364b2b972a4303af75259b","unresolved":false,"context_lines":[{"line_number":2918,"context_line":"        r.stats[\u0027errors\u0027] +\u003d 1"},{"line_number":2919,"context_line":"        r.hook_post_partition(os.path.join(datadir_path, \u0027227\u0027))"},{"line_number":2920,"context_line":"        self.assertEqual(self.logger.get_lines_for_level(\"info\"), ["},{"line_number":2921,"context_line":"            \"Step: relink Device: sda1 Policy: %s \""},{"line_number":2922,"context_line":"            \"Partitions: 1/2\" % r.policy.name,"},{"line_number":2923,"context_line":"        ])"},{"line_number":2924,"context_line":"        self.assertEqual(r.states[\"state\"], {\u002796\u0027: True, \u0027227\u0027: False})"}],"source_content_type":"text/x-python","patch_set":3,"id":"38f8a7e3_63d28633","side":"PARENT","line":2921,"in_reply_to":"4d210754_8d5afcab","updated":"2026-02-11 22:52:12.000000000","message":"Acknowledged","commit_id":"c7bee623658b464072783096b98adaddfb1005bc"}]}
