)]}'
{"/COMMIT_MSG":[{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"625e30be7464f7372e58d6613e2e2553d5e68e98","unresolved":false,"context_lines":[{"line_number":10,"context_line":"until it can no longer find a child. However, the intention is"},{"line_number":11,"context_line":"not to find the deepest child, but to strip away root helpers."},{"line_number":12,"context_line":"For example \u0027sudo neutron-rootwrap x\u0027 is supposed to find the"},{"line_number":13,"context_line":"pid of x. However, in cases \u0027x\u0027 spawned quick lived children of"},{"line_number":14,"context_line":"its own (For example: ip / brctl / ovs invocations),"},{"line_number":15,"context_line":"get_root_helper_child_pid returned those pids if called in"},{"line_number":16,"context_line":"the wrong time."},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"Change-Id: I582aa5c931c8bfe57f49df6899445698270bb33e"},{"line_number":19,"context_line":"Closes-Bug: #1558819"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"fa0719c6_009f2a04","line":16,"range":{"start_line":13,"start_character":10,"end_line":16,"end_character":15},"updated":"2016-03-20 10:08:47.000000000","message":"Does it mean if we\u0027ll have a process spawned that would spawn another process that will keep living, we\u0027ll have a reproducer? Maybe functional test for that would be good to prove the fix.","commit_id":"7e75747d04b5a8b11872e550493cb0a218bf1b37"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"0260ca5f28b40d9ee535261a108a9713e06d9f0b","unresolved":false,"context_lines":[{"line_number":10,"context_line":"until it can no longer find a child. However, the intention is"},{"line_number":11,"context_line":"not to find the deepest child, but to strip away root helpers."},{"line_number":12,"context_line":"For example \u0027sudo neutron-rootwrap x\u0027 is supposed to find the"},{"line_number":13,"context_line":"pid of x. However, in cases \u0027x\u0027 spawned quick lived children of"},{"line_number":14,"context_line":"its own (For example: ip / brctl / ovs invocations),"},{"line_number":15,"context_line":"get_root_helper_child_pid returned those pids if called in"},{"line_number":16,"context_line":"the wrong time."},{"line_number":17,"context_line":""},{"line_number":18,"context_line":"Change-Id: I582aa5c931c8bfe57f49df6899445698270bb33e"},{"line_number":19,"context_line":"Closes-Bug: #1558819"}],"source_content_type":"text/x-gerrit-commit-message","patch_set":1,"id":"ba0121b8_34f13e96","line":16,"range":{"start_line":13,"start_character":10,"end_line":16,"end_character":15},"in_reply_to":"fa0719c6_009f2a04","updated":"2016-04-01 19:31:22.000000000","message":"\u003e Does it mean if we\u0027ll have a process spawned that would spawn another process that will keep living, we\u0027ll have a reproducer?\n\nYes. Reading the implementation of get_root_helper_child_pid it\u0027s clear why.\n\n\u003e Maybe functional test for that would be good to prove the fix.\n\nI had a long reply written up, but I never sent it. I just noticed it\u0027s still a draft \u003d/","commit_id":"7e75747d04b5a8b11872e550493cb0a218bf1b37"}],"neutron/agent/linux/utils.py":[{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"3b6affd913b9f5c88d1951e3599b8979f2280e3c","unresolved":false,"context_lines":[{"line_number":239,"context_line":""},{"line_number":240,"context_line":"def get_root_helper_child_pid(pid, expected_cmd, run_as_root\u003dFalse):"},{"line_number":241,"context_line":"    \"\"\""},{"line_number":242,"context_line":"    Get the lowest child pid in the process hierarchy"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"    If root helper was used, two or more processes would be created:"},{"line_number":245,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"fa0719c6_479b2318","line":242,"updated":"2016-03-24 12:47:16.000000000","message":"This line probably needs refinement to reflect the change","commit_id":"7e75747d04b5a8b11872e550493cb0a218bf1b37"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"0260ca5f28b40d9ee535261a108a9713e06d9f0b","unresolved":false,"context_lines":[{"line_number":239,"context_line":""},{"line_number":240,"context_line":"def get_root_helper_child_pid(pid, expected_cmd, run_as_root\u003dFalse):"},{"line_number":241,"context_line":"    \"\"\""},{"line_number":242,"context_line":"    Get the lowest child pid in the process hierarchy"},{"line_number":243,"context_line":""},{"line_number":244,"context_line":"    If root helper was used, two or more processes would be created:"},{"line_number":245,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"ba0121b8_c0b48483","line":242,"in_reply_to":"fa0719c6_479b2318","updated":"2016-04-01 19:31:22.000000000","message":"Done","commit_id":"7e75747d04b5a8b11872e550493cb0a218bf1b37"},{"author":{"_account_id":8124,"name":"cbrandily","email":"zzelle@gmail.com","username":"cbrandily"},"change_message_id":"bdd9c033fa2e4db95ddab1b5d94f7542f5a6bdfb","unresolved":false,"context_lines":[{"line_number":269,"context_line":"                # so keep getting the children of the first one"},{"line_number":270,"context_line":"                pid \u003d find_child_pids(pid)[0]"},{"line_number":271,"context_line":"            except IndexError:"},{"line_number":272,"context_line":"                # Last process in the tree, return it"},{"line_number":273,"context_line":"                break"},{"line_number":274,"context_line":"    return pid"},{"line_number":275,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"1af94dfe_a75cae19","line":272,"updated":"2016-03-18 21:20:48.000000000","message":"What if a child process die while visiting child pids? get_root_helper_child will assume wrongly we found the \"child pid\".\n\nIt seems safer to verify the pid with pid_invoked_with_cmdline: \n\n\n while True:\n  try:\n   ...\n  except IndexError:\n    return pid if pid_invoked_with_cmdline(...) else None","commit_id":"7e75747d04b5a8b11872e550493cb0a218bf1b37"},{"author":{"_account_id":9044,"name":"Will","email":"wangjian.ika@bytedance.com","username":"Will"},"change_message_id":"f080e628a4fd8f6a2bdcd5a02a67bcbad20a116a","unresolved":false,"context_lines":[{"line_number":269,"context_line":"                # so keep getting the children of the first one"},{"line_number":270,"context_line":"                pid \u003d find_child_pids(pid)[0]"},{"line_number":271,"context_line":"            except IndexError:"},{"line_number":272,"context_line":"                # Last process in the tree, return it"},{"line_number":273,"context_line":"                break"},{"line_number":274,"context_line":"    return pid"},{"line_number":275,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"da0c15f0_1d3c58e1","line":272,"in_reply_to":"1af94dfe_a75cae19","updated":"2016-03-28 08:45:57.000000000","message":"Good point. And I think if we add a log could be better when pid is None.","commit_id":"7e75747d04b5a8b11872e550493cb0a218bf1b37"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"78b2737184932bceb0c06470d5d65532424de7d6","unresolved":false,"context_lines":[{"line_number":269,"context_line":"                # so keep getting the children of the first one"},{"line_number":270,"context_line":"                pid \u003d find_child_pids(pid)[0]"},{"line_number":271,"context_line":"            except IndexError:"},{"line_number":272,"context_line":"                # Last process in the tree, return it"},{"line_number":273,"context_line":"                break"},{"line_number":274,"context_line":"    return pid"},{"line_number":275,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"ba0121b8_011f305c","line":272,"in_reply_to":"1af94dfe_a75cae19","updated":"2016-04-01 19:47:03.000000000","message":"You\u0027re right. Also, I think we can just return None if we catch IndexError since if you do find the process you return earlier in line 266.","commit_id":"7e75747d04b5a8b11872e550493cb0a218bf1b37"}],"neutron/tests/contrib/functional-testing.filters":[{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"c1bd38054fd4b0497fbac728dd571862c4651079","unresolved":false,"context_lines":[{"line_number":40,"context_line":""},{"line_number":41,"context_line":"# needed for test creating more child processes"},{"line_number":42,"context_line":"bash_filter: RegExpFilter, /bin/bash, root, bash, -c, \\(sleep 100\\)"},{"line_number":43,"context_line":"bash_kill: KillFilter, root, bash, -9"}],"source_content_type":"application/octet-stream","patch_set":5,"id":"ba0121b8_35460e7b","line":43,"range":{"start_line":43,"start_character":0,"end_line":43,"end_character":9},"updated":"2016-04-01 09:26:21.000000000","message":"Uhm, this should be probably sleep_kill","commit_id":"1b10ade7031ce154b6b594724acfd7c5099034b2"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"da2d5145e28be99b6b8669d1c890b1cfa6023efe","unresolved":false,"context_lines":[{"line_number":40,"context_line":""},{"line_number":41,"context_line":"# needed for test creating more child processes"},{"line_number":42,"context_line":"bash_filter: RegExpFilter, /bin/bash, root, bash, -c, \\(sleep 100\\)"},{"line_number":43,"context_line":"bash_kill: KillFilter, root, bash, -9"}],"source_content_type":"application/octet-stream","patch_set":5,"id":"ba0121b8_3b53836e","line":43,"range":{"start_line":43,"start_character":0,"end_line":43,"end_character":9},"in_reply_to":"ba0121b8_35460e7b","updated":"2016-04-01 19:11:49.000000000","message":"The new functional test doesn\u0027t inherit from the functional tests base class in the current patch, so it doesn\u0027t use rootwrap, which is why it passed at the gate without a proper filter.","commit_id":"1b10ade7031ce154b6b594724acfd7c5099034b2"}],"neutron/tests/functional/agent/linux/test_utils.py":[{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"68c2c4435b9818e215216e5a4058fc444383eb67","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        proc.start(block\u003dTrue)"},{"line_number":63,"context_line":"        self.addCleanup(proc.stop)"},{"line_number":64,"context_line":"        child_pid \u003d utils.get_root_helper_child_pid("},{"line_number":65,"context_line":"            proc._process.pid, cmd, run_as_root\u003dTrue)"},{"line_number":66,"context_line":"        with open(\u0027/proc/%s/cmdline\u0027 % child_pid, \u0027r\u0027) as f_proc_cmdline:"},{"line_number":67,"context_line":"            cmdline \u003d f_proc_cmdline.readline().split(\u0027\\0\u0027)[0]"},{"line_number":68,"context_line":"        self.assertEqual(\u0027bash\u0027, cmdline)"}],"source_content_type":"text/x-python","patch_set":3,"id":"ba0121b8_b0441ab7","line":65,"updated":"2016-03-31 14:00:18.000000000","message":"Ah ha, you bypassed AsyncProcess.pid. I\u0027ll add a comment saying that AsyncProcess.pid uses get_root_helper_child_pid (Which is the method under test), so we go directly to _process.pid, which returns the top most process (sudo).","commit_id":"24bcd78a30407a291578d1916efb16f8e5fdeeb2"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"157c3a10df53476da0a15e7b1b41868abb2eec16","unresolved":false,"context_lines":[{"line_number":62,"context_line":"        proc.start(block\u003dTrue)"},{"line_number":63,"context_line":"        self.addCleanup(proc.stop)"},{"line_number":64,"context_line":"        child_pid \u003d utils.get_root_helper_child_pid("},{"line_number":65,"context_line":"            proc._process.pid, cmd, run_as_root\u003dTrue)"},{"line_number":66,"context_line":"        with open(\u0027/proc/%s/cmdline\u0027 % child_pid, \u0027r\u0027) as f_proc_cmdline:"},{"line_number":67,"context_line":"            cmdline \u003d f_proc_cmdline.readline().split(\u0027\\0\u0027)[0]"},{"line_number":68,"context_line":"        self.assertEqual(\u0027bash\u0027, cmdline)"}],"source_content_type":"text/x-python","patch_set":3,"id":"ba0121b8_2bea5fac","line":65,"in_reply_to":"ba0121b8_b0441ab7","updated":"2016-03-31 14:07:17.000000000","message":"Yep :)","commit_id":"24bcd78a30407a291578d1916efb16f8e5fdeeb2"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"68c2c4435b9818e215216e5a4058fc444383eb67","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        self.addCleanup(proc.stop)"},{"line_number":64,"context_line":"        child_pid \u003d utils.get_root_helper_child_pid("},{"line_number":65,"context_line":"            proc._process.pid, cmd, run_as_root\u003dTrue)"},{"line_number":66,"context_line":"        with open(\u0027/proc/%s/cmdline\u0027 % child_pid, \u0027r\u0027) as f_proc_cmdline:"},{"line_number":67,"context_line":"            cmdline \u003d f_proc_cmdline.readline().split(\u0027\\0\u0027)[0]"},{"line_number":68,"context_line":"        self.assertEqual(\u0027bash\u0027, cmdline)"}],"source_content_type":"text/x-python","patch_set":3,"id":"ba0121b8_104ce69c","line":66,"updated":"2016-03-31 14:00:18.000000000","message":"If the method under test is misbehaving, \"/proc/%s/cmdline\u0027 % child_pid\" might not exist, which will raise some IOError and will fail the test appropriately but the error message will be very confusing.","commit_id":"24bcd78a30407a291578d1916efb16f8e5fdeeb2"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"157c3a10df53476da0a15e7b1b41868abb2eec16","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        self.addCleanup(proc.stop)"},{"line_number":64,"context_line":"        child_pid \u003d utils.get_root_helper_child_pid("},{"line_number":65,"context_line":"            proc._process.pid, cmd, run_as_root\u003dTrue)"},{"line_number":66,"context_line":"        with open(\u0027/proc/%s/cmdline\u0027 % child_pid, \u0027r\u0027) as f_proc_cmdline:"},{"line_number":67,"context_line":"            cmdline \u003d f_proc_cmdline.readline().split(\u0027\\0\u0027)[0]"},{"line_number":68,"context_line":"        self.assertEqual(\u0027bash\u0027, cmdline)"}],"source_content_type":"text/x-python","patch_set":3,"id":"ba0121b8_abedcfb8","line":66,"in_reply_to":"ba0121b8_104ce69c","updated":"2016-03-31 14:07:17.000000000","message":"If IOError is raised then we will see the trace, won\u0027t we? If the process doesn\u0027t exist then child_pid is None, so we can check on that.","commit_id":"24bcd78a30407a291578d1916efb16f8e5fdeeb2"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"c5283e586e80b7b51c19fb0de1a83875d0e8f59b","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        proc \u003d async_process.AsyncProcess(cmd, run_as_root\u003dTrue)"},{"line_number":64,"context_line":"        proc.start()"},{"line_number":65,"context_line":"        utils.wait_until_true("},{"line_number":66,"context_line":"            functools.partial("},{"line_number":67,"context_line":"                utils.execute,"},{"line_number":68,"context_line":"                [\u0027pgrep\u0027, \u0027-f\u0027, \u0027^sleep 100\u0027],"},{"line_number":69,"context_line":"                check_exit_code\u003dFalse),"},{"line_number":70,"context_line":"            sleep\u003d0.2)"},{"line_number":71,"context_line":"        self.addCleanup(proc.stop)"},{"line_number":72,"context_line":"        child_pid \u003d utils.get_root_helper_child_pid("}],"source_content_type":"text/x-python","patch_set":4,"id":"ba0121b8_b698886b","line":69,"range":{"start_line":66,"start_character":0,"end_line":69,"end_character":39},"updated":"2016-03-31 16:55:09.000000000","message":"I still think we can do better than this :)","commit_id":"3117765c61b7524108898257833769ac7c582624"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"0f2bda163a49b941ada3d7833425069b17d841c7","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        proc \u003d async_process.AsyncProcess(cmd, run_as_root\u003dTrue)"},{"line_number":64,"context_line":"        proc.start()"},{"line_number":65,"context_line":"        utils.wait_until_true("},{"line_number":66,"context_line":"            functools.partial("},{"line_number":67,"context_line":"                utils.execute,"},{"line_number":68,"context_line":"                [\u0027pgrep\u0027, \u0027-f\u0027, \u0027^sleep 100\u0027],"},{"line_number":69,"context_line":"                check_exit_code\u003dFalse),"},{"line_number":70,"context_line":"            sleep\u003d0.2)"},{"line_number":71,"context_line":"        self.addCleanup(proc.stop)"},{"line_number":72,"context_line":"        child_pid \u003d utils.get_root_helper_child_pid("}],"source_content_type":"text/x-python","patch_set":4,"id":"ba0121b8_f605e045","line":69,"range":{"start_line":66,"start_character":0,"end_line":69,"end_character":39},"in_reply_to":"ba0121b8_b698886b","updated":"2016-03-31 16:59:36.000000000","message":"How about\n\n  \u0027sleep\u0027 in utils.execute([\u0027pstree\u0027, proc._process.pid])","commit_id":"3117765c61b7524108898257833769ac7c582624"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"f8909fe9a7f95a5199d3d8e0d1f3773caa3cb6ba","unresolved":false,"context_lines":[{"line_number":63,"context_line":"        proc \u003d async_process.AsyncProcess(cmd, run_as_root\u003dTrue)"},{"line_number":64,"context_line":"        proc.start()"},{"line_number":65,"context_line":"        utils.wait_until_true("},{"line_number":66,"context_line":"            functools.partial("},{"line_number":67,"context_line":"                utils.execute,"},{"line_number":68,"context_line":"                [\u0027pgrep\u0027, \u0027-f\u0027, \u0027^sleep 100\u0027],"},{"line_number":69,"context_line":"                check_exit_code\u003dFalse),"},{"line_number":70,"context_line":"            sleep\u003d0.2)"},{"line_number":71,"context_line":"        self.addCleanup(proc.stop)"},{"line_number":72,"context_line":"        child_pid \u003d utils.get_root_helper_child_pid("}],"source_content_type":"text/x-python","patch_set":4,"id":"ba0121b8_f6de80db","line":69,"range":{"start_line":66,"start_character":0,"end_line":69,"end_character":39},"in_reply_to":"ba0121b8_b698886b","updated":"2016-03-31 16:58:19.000000000","message":"Jakub and I had a video conversation about this - Jakub\u0027s suggestion here is to verify that the process that we find here is indeed the child of proc._process.pid (sudo). Otherwise there\u0027s a chance that the process we find was not spawned by this test run.","commit_id":"3117765c61b7524108898257833769ac7c582624"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"7dc8d68a6c693eaa413ca0b8a5cc8b2acff2d4bb","unresolved":false,"context_lines":[{"line_number":42,"context_line":"            utils.wait_until_true(lambda: False, 2)"},{"line_number":43,"context_line":""},{"line_number":44,"context_line":""},{"line_number":45,"context_line":"class TestGetRootHelperChildPid(base.BaseTestCase):"},{"line_number":46,"context_line":"    def _cleanup_sleep_process(self, parent_pid):"},{"line_number":47,"context_line":"        sleep_pid \u003d utils.execute("},{"line_number":48,"context_line":"            [\u0027ps\u0027, \u0027--ppid\u0027, parent_pid, \u0027-o\u0027, \u0027pid\u003d\u0027]).strip()"}],"source_content_type":"text/x-python","patch_set":5,"id":"ba0121b8_5e30e5e8","line":45,"updated":"2016-04-01 19:21:20.000000000","message":"Should inherit from the functional tests base class instead to run the test with rootwrap.","commit_id":"1b10ade7031ce154b6b594724acfd7c5099034b2"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"7dc8d68a6c693eaa413ca0b8a5cc8b2acff2d4bb","unresolved":false,"context_lines":[{"line_number":48,"context_line":"            [\u0027ps\u0027, \u0027--ppid\u0027, parent_pid, \u0027-o\u0027, \u0027pid\u003d\u0027]).strip()"},{"line_number":49,"context_line":"        self.addCleanup("},{"line_number":50,"context_line":"            utils.execute,"},{"line_number":51,"context_line":"            [\u0027kill\u0027, sleep_pid],"},{"line_number":52,"context_line":"            check_exit_code\u003dFalse,"},{"line_number":53,"context_line":"            run_as_root\u003dTrue)"},{"line_number":54,"context_line":""}],"source_content_type":"text/x-python","patch_set":5,"id":"ba0121b8_3e39b1d9","line":51,"updated":"2016-04-01 19:21:20.000000000","message":"The kill signal needs to match the rootwrap filter to work (Currently using default of 15, with a filter of 9).","commit_id":"1b10ade7031ce154b6b594724acfd7c5099034b2"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"555f5f3ca124e9838e91e8f2c150668f3138851f","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        def wait_for_sleep_is_spawned(parent_pid):"},{"line_number":72,"context_line":"            proc_tree \u003d utils.execute("},{"line_number":73,"context_line":"                [\u0027pstree\u0027, parent_pid], check_exit_code\u003dFalse)"},{"line_number":74,"context_line":"            processes \u003d [command.strip() for command in proc_tree.split(\u0027-\u0027)"},{"line_number":75,"context_line":"                         if command]"},{"line_number":76,"context_line":"            return \u0027sleep\u0027 \u003d\u003d processes[-1]"},{"line_number":77,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"ba0121b8_40a909df","line":74,"updated":"2016-04-03 15:38:32.000000000","message":"When neutron-rootwrap is used, I think the output of pstree will be:\n\n  sudo---neutron-rootwra---bash---sleep\n\nsplit(\u0027-\u0027) works but I think split(\u0027---\u0027) is better and accurate.","commit_id":"f5c387bad8ada171fc1a85a86187eabbb075c590"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"edc6bb90325d079bc2b0ff18f6157cef41d33228","unresolved":false,"context_lines":[{"line_number":71,"context_line":"        def wait_for_sleep_is_spawned(parent_pid):"},{"line_number":72,"context_line":"            proc_tree \u003d utils.execute("},{"line_number":73,"context_line":"                [\u0027pstree\u0027, parent_pid], check_exit_code\u003dFalse)"},{"line_number":74,"context_line":"            processes \u003d [command.strip() for command in proc_tree.split(\u0027-\u0027)"},{"line_number":75,"context_line":"                         if command]"},{"line_number":76,"context_line":"            return \u0027sleep\u0027 \u003d\u003d processes[-1]"},{"line_number":77,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"9a061dce_1af679d7","line":74,"in_reply_to":"ba0121b8_40a909df","updated":"2016-04-04 08:24:39.000000000","message":"L98 adds pid of bash, so output is\n bash---sleep\n\nYep, \u0027---\u0027 is better.","commit_id":"f5c387bad8ada171fc1a85a86187eabbb075c590"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"555f5f3ca124e9838e91e8f2c150668f3138851f","unresolved":false,"context_lines":[{"line_number":95,"context_line":"            child_pid,"},{"line_number":96,"context_line":"            \"get_root_helper_child_pid is expected to return the pid of the \""},{"line_number":97,"context_line":"            \"bash process\")"},{"line_number":98,"context_line":"        self._cleanup_sleep_process(child_pid)"},{"line_number":99,"context_line":"        with open(\u0027/proc/%s/cmdline\u0027 % child_pid, \u0027r\u0027) as f_proc_cmdline:"},{"line_number":100,"context_line":"            cmdline \u003d f_proc_cmdline.readline().split(\u0027\\0\u0027)[0]"},{"line_number":101,"context_line":"        self.assertIn(\u0027bash\u0027, cmdline)"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba0121b8_2081754e","line":98,"range":{"start_line":98,"start_character":13,"end_line":98,"end_character":35},"updated":"2016-04-03 15:38:32.000000000","message":"This method does not do cleanup, but it adds an entry to addCleanup.\n\u0027cleanup\u0027 is a bit confusing. It is better to \u0027_addcleanup_sleep_process\u0027.","commit_id":"f5c387bad8ada171fc1a85a86187eabbb075c590"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"edc6bb90325d079bc2b0ff18f6157cef41d33228","unresolved":false,"context_lines":[{"line_number":95,"context_line":"            child_pid,"},{"line_number":96,"context_line":"            \"get_root_helper_child_pid is expected to return the pid of the \""},{"line_number":97,"context_line":"            \"bash process\")"},{"line_number":98,"context_line":"        self._cleanup_sleep_process(child_pid)"},{"line_number":99,"context_line":"        with open(\u0027/proc/%s/cmdline\u0027 % child_pid, \u0027r\u0027) as f_proc_cmdline:"},{"line_number":100,"context_line":"            cmdline \u003d f_proc_cmdline.readline().split(\u0027\\0\u0027)[0]"},{"line_number":101,"context_line":"        self.assertIn(\u0027bash\u0027, cmdline)"}],"source_content_type":"text/x-python","patch_set":7,"id":"9a061dce_7a0335b9","line":98,"range":{"start_line":98,"start_character":13,"end_line":98,"end_character":35},"in_reply_to":"ba0121b8_2081754e","updated":"2016-04-04 08:24:39.000000000","message":"Done","commit_id":"f5c387bad8ada171fc1a85a86187eabbb075c590"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"047399986612e7c7a01be077251783e4229e0d00","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        \"\"\""},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"        def wait_for_sleep_is_spawned(parent_pid):"},{"line_number":72,"context_line":"            proc_tree \u003d utils.execute("},{"line_number":73,"context_line":"                [\u0027pstree\u0027, parent_pid], check_exit_code\u003dFalse)"},{"line_number":74,"context_line":"            processes \u003d [command.strip() for command in proc_tree.split(\u0027---\u0027)"},{"line_number":75,"context_line":"                         if command]"},{"line_number":76,"context_line":"            return \u0027sleep\u0027 \u003d\u003d processes[-1]"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        cmd \u003d [\u0027bash\u0027, \u0027-c\u0027, \u0027(sleep 100)\u0027]"}],"source_content_type":"text/x-python","patch_set":9,"id":"9a061dce_a486ef10","line":75,"range":{"start_line":72,"start_character":12,"end_line":75,"end_character":36},"updated":"2016-04-05 20:11:26.000000000","message":"there are actually better ways to interact with process tree, like psutil.","commit_id":"fd93e19f2a415b3803700fc491749daba01a4390"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"4a7e2487bf651c1e2e1a4a7a3612e05f8ea342a0","unresolved":false,"context_lines":[{"line_number":69,"context_line":"        \"\"\""},{"line_number":70,"context_line":""},{"line_number":71,"context_line":"        def wait_for_sleep_is_spawned(parent_pid):"},{"line_number":72,"context_line":"            proc_tree \u003d utils.execute("},{"line_number":73,"context_line":"                [\u0027pstree\u0027, parent_pid], check_exit_code\u003dFalse)"},{"line_number":74,"context_line":"            processes \u003d [command.strip() for command in proc_tree.split(\u0027---\u0027)"},{"line_number":75,"context_line":"                         if command]"},{"line_number":76,"context_line":"            return \u0027sleep\u0027 \u003d\u003d processes[-1]"},{"line_number":77,"context_line":""},{"line_number":78,"context_line":"        cmd \u003d [\u0027bash\u0027, \u0027-c\u0027, \u0027(sleep 100)\u0027]"}],"source_content_type":"text/x-python","patch_set":9,"id":"9a061dce_672a1980","line":75,"range":{"start_line":72,"start_character":12,"end_line":75,"end_character":36},"in_reply_to":"9a061dce_a486ef10","updated":"2016-04-05 20:24:03.000000000","message":"That\u0027s interesting. It\u0027s possible to replace get_root_helper_child_pid with something like (Pseudocode / Writing this directly in Gerrit):\n\ndef get_root_helper_child_pid(pid, cmd):\n    children \u003d [psutil.Process(child_pid) for child_pid in psutil.Process(pid).children(recursive\u003dTrue)]\n    return next(child.pid for child in children if child.cmd \u003d\u003d cmd, None)\n\nBut that\u0027s for another time.","commit_id":"fd93e19f2a415b3803700fc491749daba01a4390"}],"neutron/tests/unit/agent/linux/test_utils.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"555f5f3ca124e9838e91e8f2c150668f3138851f","unresolved":false,"context_lines":[{"line_number":244,"context_line":"                                             run_as_root\u003dTrue,"},{"line_number":245,"context_line":"                                             cmds\u003d[False, True])"},{"line_number":246,"context_line":""},{"line_number":247,"context_line":"    def test_does_not_return_transient_child(self):"},{"line_number":248,"context_line":"        self._test_get_root_helper_child_pid("},{"line_number":249,"context_line":"                expected\u003d\u00272\u0027,"},{"line_number":250,"context_line":"                pids\u003d[\u00271\u0027, \u00272\u0027, \u00273\u0027],"}],"source_content_type":"text/x-python","patch_set":7,"id":"ba0121b8_c74533b4","line":247,"range":{"start_line":247,"start_character":8,"end_line":247,"end_character":44},"updated":"2016-04-03 15:38:32.000000000","message":"This checks if the first non-root-helper child is returned. Is there more appropriate test name?","commit_id":"f5c387bad8ada171fc1a85a86187eabbb075c590"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"71d97a5cd597ed6bb08e82c1c25c3a1d5395d764","unresolved":false,"context_lines":[{"line_number":244,"context_line":"                                             run_as_root\u003dTrue,"},{"line_number":245,"context_line":"                                             cmds\u003d[False, True])"},{"line_number":246,"context_line":""},{"line_number":247,"context_line":"    def test_does_not_return_transient_child(self):"},{"line_number":248,"context_line":"        self._test_get_root_helper_child_pid("},{"line_number":249,"context_line":"                expected\u003d\u00272\u0027,"},{"line_number":250,"context_line":"                pids\u003d[\u00271\u0027, \u00272\u0027, \u00273\u0027],"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a061dce_ddf7dbf3","line":247,"range":{"start_line":247,"start_character":8,"end_line":247,"end_character":44},"updated":"2016-04-04 08:28:00.000000000","message":"There is still undiscussed comment in PS7 from Akihiro.","commit_id":"10a50e787f2d7b8e2ff507d51496903fb22e826b"},{"author":{"_account_id":8873,"name":"Assaf Muller","email":"amuller@redhat.com","username":"amuller"},"change_message_id":"4d412beef3e33d8c6bd52fd6483fb42485f30c44","unresolved":false,"context_lines":[{"line_number":244,"context_line":"                                             run_as_root\u003dTrue,"},{"line_number":245,"context_line":"                                             cmds\u003d[False, True])"},{"line_number":246,"context_line":""},{"line_number":247,"context_line":"    def test_does_not_return_transient_child(self):"},{"line_number":248,"context_line":"        self._test_get_root_helper_child_pid("},{"line_number":249,"context_line":"                expected\u003d\u00272\u0027,"},{"line_number":250,"context_line":"                pids\u003d[\u00271\u0027, \u00272\u0027, \u00273\u0027],"}],"source_content_type":"text/x-python","patch_set":8,"id":"9a061dce_c1e23f9f","line":247,"range":{"start_line":247,"start_character":8,"end_line":247,"end_character":44},"in_reply_to":"9a061dce_ddf7dbf3","updated":"2016-04-04 16:15:50.000000000","message":"Done","commit_id":"10a50e787f2d7b8e2ff507d51496903fb22e826b"}]}
