)]}'
{"openstackclient/tests/functional/compute/v2/test_server.py":[{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"e96cf16aff9837199cddfe08344f3c3c49e8c6d4","unresolved":false,"context_lines":[{"line_number":283,"context_line":"    def test_server_boot_from_volume(self):"},{"line_number":284,"context_line":"        \"\"\"Test server create from volume, server delete\"\"\""},{"line_number":285,"context_line":"        # get volume status wait function"},{"line_number":286,"context_line":"        volume_wait_for \u003d volume_common.BaseVolumeTests.wait_for_status"},{"line_number":287,"context_line":"        # Ensure to use Volume API v2"},{"line_number":288,"context_line":"        self.useFixture(fixtures.EnvironmentVariable("},{"line_number":289,"context_line":"            \u0027OS_VOLUME_API_VERSION\u0027, \u00272\u0027))"}],"source_content_type":"text/x-python","patch_set":3,"id":"ff0f0b1f_80f5c885","line":286,"range":{"start_line":286,"start_character":8,"end_line":286,"end_character":71},"updated":"2017-05-21 23:50:44.000000000","message":"nice","commit_id":"78f04bc8b3bc3d29e7d1b6889f1d219d07e324bb"},{"author":{"_account_id":8276,"name":"kiwik","email":"chenrui.momo@gmail.com","username":"kiwik"},"change_message_id":"774ae400dd7ea0c47c031d9aa1b2dd30138c9835","unresolved":false,"context_lines":[{"line_number":285,"context_line":"        # get volume status wait function"},{"line_number":286,"context_line":"        volume_wait_for \u003d volume_common.BaseVolumeTests.wait_for_status"},{"line_number":287,"context_line":"        # Ensure to use Volume API v2"},{"line_number":288,"context_line":"        self.useFixture(fixtures.EnvironmentVariable("},{"line_number":289,"context_line":"            \u0027OS_VOLUME_API_VERSION\u0027, \u00272\u0027))"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        # get image size"},{"line_number":292,"context_line":"        cmd_output \u003d json.loads(self.openstack("}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_9c43703f","line":289,"range":{"start_line":288,"start_character":8,"end_line":289,"end_character":42},"updated":"2017-05-25 12:46:31.000000000","message":"why add these? the following volume related commands should works in both v1 and v2.","commit_id":"5c21880dfa6f2d56e1bbe58d13d0c25578f00687"},{"author":{"_account_id":8276,"name":"kiwik","email":"chenrui.momo@gmail.com","username":"kiwik"},"change_message_id":"4cafd3036250b50ee2058325e6eaa9b5f0d1edae","unresolved":false,"context_lines":[{"line_number":285,"context_line":"        # get volume status wait function"},{"line_number":286,"context_line":"        volume_wait_for \u003d volume_common.BaseVolumeTests.wait_for_status"},{"line_number":287,"context_line":"        # Ensure to use Volume API v2"},{"line_number":288,"context_line":"        self.useFixture(fixtures.EnvironmentVariable("},{"line_number":289,"context_line":"            \u0027OS_VOLUME_API_VERSION\u0027, \u00272\u0027))"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        # get image size"},{"line_number":292,"context_line":"        cmd_output \u003d json.loads(self.openstack("}],"source_content_type":"text/x-python","patch_set":4,"id":"df140735_95b89c76","line":289,"range":{"start_line":288,"start_character":8,"end_line":289,"end_character":42},"in_reply_to":"df140735_5bfdb738","updated":"2017-05-31 11:27:57.000000000","message":"Sorry, reply late, wait_for_status and wait_for_delete should be common methods, no matter which version API, these methods should works fine, the latest implement looks good to me, thank you.","commit_id":"5c21880dfa6f2d56e1bbe58d13d0c25578f00687"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"8cba3482e461da21444873719d6dc60d13bc7e81","unresolved":false,"context_lines":[{"line_number":285,"context_line":"        # get volume status wait function"},{"line_number":286,"context_line":"        volume_wait_for \u003d volume_common.BaseVolumeTests.wait_for_status"},{"line_number":287,"context_line":"        # Ensure to use Volume API v2"},{"line_number":288,"context_line":"        self.useFixture(fixtures.EnvironmentVariable("},{"line_number":289,"context_line":"            \u0027OS_VOLUME_API_VERSION\u0027, \u00272\u0027))"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        # get image size"},{"line_number":292,"context_line":"        cmd_output \u003d json.loads(self.openstack("}],"source_content_type":"text/x-python","patch_set":4,"id":"df140735_5bfdb738","line":289,"range":{"start_line":288,"start_character":8,"end_line":289,"end_character":42},"in_reply_to":"df140735_b05bdb85","updated":"2017-05-30 00:45:49.000000000","message":"After thinking more, I merged tests.functional.volume.v1/2.common into tests.functional.volume.base to define wait_for variants. As you said, OSC tries to ensure the interface is compatible, so I think wait_for stuffs can be common. Thought?","commit_id":"5c21880dfa6f2d56e1bbe58d13d0c25578f00687"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"775246fa3c25396370d34c0228eb943445f9fb3d","unresolved":false,"context_lines":[{"line_number":285,"context_line":"        # get volume status wait function"},{"line_number":286,"context_line":"        volume_wait_for \u003d volume_common.BaseVolumeTests.wait_for_status"},{"line_number":287,"context_line":"        # Ensure to use Volume API v2"},{"line_number":288,"context_line":"        self.useFixture(fixtures.EnvironmentVariable("},{"line_number":289,"context_line":"            \u0027OS_VOLUME_API_VERSION\u0027, \u00272\u0027))"},{"line_number":290,"context_line":""},{"line_number":291,"context_line":"        # get image size"},{"line_number":292,"context_line":"        cmd_output \u003d json.loads(self.openstack("}],"source_content_type":"text/x-python","patch_set":4,"id":"df140735_b05bdb85","line":289,"range":{"start_line":288,"start_character":8,"end_line":289,"end_character":42},"in_reply_to":"ff0f0b1f_9c43703f","updated":"2017-05-29 13:19:56.000000000","message":"This is because we import wait_for_status from volume.v2.common.\nIf we do not specify the volume API version here, we should prepare volume.common which works for both v1 and v2 instead of using volume.v2.common.\n\nThis is the reason I specify volume v2 version.\n\nIMHO the test should be reproducable. I don\u0027t think it is a good idea if we depends on envvars outside of test env. \nShould tests.functional.volume.v2.common work even if OS_VOLUME_API_VERSION\u003d1 out side of the test env? It is not desirable but I believe we should avoid such dependency as much as possible.\n\nIf you prefer to volume.common (which is version independent), I am fine to do it.","commit_id":"5c21880dfa6f2d56e1bbe58d13d0c25578f00687"}],"openstackclient/tests/functional/volume/v1/common.py":[{"author":{"_account_id":8276,"name":"kiwik","email":"chenrui.momo@gmail.com","username":"kiwik"},"change_message_id":"774ae400dd7ea0c47c031d9aa1b2dd30138c9835","unresolved":false,"context_lines":[{"line_number":47,"context_line":"                                .format(current_status, failures))"},{"line_number":48,"context_line":"            time.sleep(interval)"},{"line_number":49,"context_line":"            total_sleep +\u003d interval"},{"line_number":50,"context_line":"        cls.assertOutput(desired_status, current_status)"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    @classmethod"},{"line_number":53,"context_line":"    def wait_for_delete(cls, check_type, check_name, wait\u003d120, interval\u003d5,"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_a61aa1c2","line":50,"range":{"start_line":50,"start_character":12,"end_line":50,"end_character":24},"updated":"2017-05-25 12:46:31.000000000","message":"please use assertEqual(), we can get more exact error reason about what\u0027s expected and actual value.","commit_id":"5c21880dfa6f2d56e1bbe58d13d0c25578f00687"},{"author":{"_account_id":8276,"name":"kiwik","email":"chenrui.momo@gmail.com","username":"kiwik"},"change_message_id":"4cafd3036250b50ee2058325e6eaa9b5f0d1edae","unresolved":false,"context_lines":[{"line_number":47,"context_line":"                                .format(current_status, failures))"},{"line_number":48,"context_line":"            time.sleep(interval)"},{"line_number":49,"context_line":"            total_sleep +\u003d interval"},{"line_number":50,"context_line":"        cls.assertOutput(desired_status, current_status)"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    @classmethod"},{"line_number":53,"context_line":"    def wait_for_delete(cls, check_type, check_name, wait\u003d120, interval\u003d5,"}],"source_content_type":"text/x-python","patch_set":4,"id":"df140735_ef849860","line":50,"range":{"start_line":50,"start_character":12,"end_line":50,"end_character":24},"in_reply_to":"df140735_b0987b6a","updated":"2017-05-31 11:27:57.000000000","message":"Thank you clarifying these, it looks good to me now.","commit_id":"5c21880dfa6f2d56e1bbe58d13d0c25578f00687"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"775246fa3c25396370d34c0228eb943445f9fb3d","unresolved":false,"context_lines":[{"line_number":47,"context_line":"                                .format(current_status, failures))"},{"line_number":48,"context_line":"            time.sleep(interval)"},{"line_number":49,"context_line":"            total_sleep +\u003d interval"},{"line_number":50,"context_line":"        cls.assertOutput(desired_status, current_status)"},{"line_number":51,"context_line":""},{"line_number":52,"context_line":"    @classmethod"},{"line_number":53,"context_line":"    def wait_for_delete(cls, check_type, check_name, wait\u003d120, interval\u003d5,"}],"source_content_type":"text/x-python","patch_set":4,"id":"df140735_b0987b6a","line":50,"range":{"start_line":50,"start_character":12,"end_line":50,"end_character":24},"in_reply_to":"ff0f0b1f_a61aa1c2","updated":"2017-05-29 13:19:56.000000000","message":"If we want to use this class method in tearDownClass, you will get an error like: TypeError: unbound method assertEqual() must be called with VolumeSnapshotTests instance as first argument (got str instance instead).\n\nI try to make this method callable from anywhere including tearDownClass.\n\nIf I follow your suggestion, this method can be called only from an instance object. Does this match your suggestion?","commit_id":"5c21880dfa6f2d56e1bbe58d13d0c25578f00687"}],"openstackclient/tests/functional/volume/v2/common.py":[{"author":{"_account_id":8276,"name":"kiwik","email":"chenrui.momo@gmail.com","username":"kiwik"},"change_message_id":"774ae400dd7ea0c47c031d9aa1b2dd30138c9835","unresolved":false,"context_lines":[{"line_number":48,"context_line":"                    .format(current_status, check_type, check_name, failures))"},{"line_number":49,"context_line":"            time.sleep(interval)"},{"line_number":50,"context_line":"            total_sleep +\u003d interval"},{"line_number":51,"context_line":"        cls.assertOutput(desired_status, current_status)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    @classmethod"},{"line_number":54,"context_line":"    def wait_for_delete(cls, check_type, check_name, wait\u003d120, interval\u003d5):"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_d9cc5a8a","line":51,"range":{"start_line":51,"start_character":12,"end_line":51,"end_character":24},"updated":"2017-05-25 12:46:31.000000000","message":"ditto in v1","commit_id":"5c21880dfa6f2d56e1bbe58d13d0c25578f00687"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"3426c5dc2b5a23dc06b0095393255edd996cf5e4","unresolved":false,"context_lines":[{"line_number":48,"context_line":"                    .format(current_status, check_type, check_name, failures))"},{"line_number":49,"context_line":"            time.sleep(interval)"},{"line_number":50,"context_line":"            total_sleep +\u003d interval"},{"line_number":51,"context_line":"        cls.assertOutput(desired_status, current_status)"},{"line_number":52,"context_line":""},{"line_number":53,"context_line":"    @classmethod"},{"line_number":54,"context_line":"    def wait_for_delete(cls, check_type, check_name, wait\u003d120, interval\u003d5):"}],"source_content_type":"text/x-python","patch_set":4,"id":"df140735_1b629f3f","line":51,"range":{"start_line":51,"start_character":12,"end_line":51,"end_character":24},"in_reply_to":"ff0f0b1f_d9cc5a8a","updated":"2017-05-30 00:34:17.000000000","message":"waiting for your response","commit_id":"5c21880dfa6f2d56e1bbe58d13d0c25578f00687"},{"author":{"_account_id":8276,"name":"kiwik","email":"chenrui.momo@gmail.com","username":"kiwik"},"change_message_id":"774ae400dd7ea0c47c031d9aa1b2dd30138c9835","unresolved":false,"context_lines":[{"line_number":62,"context_line":"            print(\u0027Checking {} {} Waiting for deleted\u0027"},{"line_number":63,"context_line":"                  .format(check_type, check_name))"},{"line_number":64,"context_line":"            time.sleep(interval)"},{"line_number":65,"context_line":"            total_sleep +\u003d interval"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_39e596dc","line":65,"updated":"2017-05-25 12:46:31.000000000","message":"please add a print if the resource can\u0027t be deleted in wait timeout, that help us to find root reason in functional tests.","commit_id":"5c21880dfa6f2d56e1bbe58d13d0c25578f00687"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"3426c5dc2b5a23dc06b0095393255edd996cf5e4","unresolved":false,"context_lines":[{"line_number":62,"context_line":"            print(\u0027Checking {} {} Waiting for deleted\u0027"},{"line_number":63,"context_line":"                  .format(check_type, check_name))"},{"line_number":64,"context_line":"            time.sleep(interval)"},{"line_number":65,"context_line":"            total_sleep +\u003d interval"}],"source_content_type":"text/x-python","patch_set":4,"id":"df140735_3b732318","line":65,"in_reply_to":"df140735_f3fefd03","updated":"2017-05-30 00:34:17.000000000","message":"Done","commit_id":"5c21880dfa6f2d56e1bbe58d13d0c25578f00687"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"775246fa3c25396370d34c0228eb943445f9fb3d","unresolved":false,"context_lines":[{"line_number":62,"context_line":"            print(\u0027Checking {} {} Waiting for deleted\u0027"},{"line_number":63,"context_line":"                  .format(check_type, check_name))"},{"line_number":64,"context_line":"            time.sleep(interval)"},{"line_number":65,"context_line":"            total_sleep +\u003d interval"}],"source_content_type":"text/x-python","patch_set":4,"id":"df140735_f3fefd03","line":65,"in_reply_to":"ff0f0b1f_39e596dc","updated":"2017-05-29 13:19:56.000000000","message":"will do","commit_id":"5c21880dfa6f2d56e1bbe58d13d0c25578f00687"}],"openstackclient/tests/functional/volume/v2/test_snapshot.py":[{"author":{"_account_id":8276,"name":"kiwik","email":"chenrui.momo@gmail.com","username":"kiwik"},"change_message_id":"774ae400dd7ea0c47c031d9aa1b2dd30138c9835","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    @classmethod"},{"line_number":37,"context_line":"    def tearDownClass(cls):"},{"line_number":38,"context_line":"        cls.wait_for_status(\u0027volume\u0027, cls.VOLLY, \u0027available\u0027)"},{"line_number":39,"context_line":"        raw_output \u003d cls.openstack(\u0027volume delete --force \u0027 + cls.VOLLY)"},{"line_number":40,"context_line":"        cls.assertOutput(\u0027\u0027, raw_output)"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def test_volume_snapshot__delete(self):"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_f96efe2c","line":39,"updated":"2017-05-25 12:46:31.000000000","message":"Just a suggestion, we can add \"--purge\" option at here, that\u0027s supported by volume v2 API to delete volume and the related snapshots, it\u0027s useful for the volume clean up case.","commit_id":"5c21880dfa6f2d56e1bbe58d13d0c25578f00687"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"3426c5dc2b5a23dc06b0095393255edd996cf5e4","unresolved":false,"context_lines":[{"line_number":36,"context_line":"    @classmethod"},{"line_number":37,"context_line":"    def tearDownClass(cls):"},{"line_number":38,"context_line":"        cls.wait_for_status(\u0027volume\u0027, cls.VOLLY, \u0027available\u0027)"},{"line_number":39,"context_line":"        raw_output \u003d cls.openstack(\u0027volume delete --force \u0027 + cls.VOLLY)"},{"line_number":40,"context_line":"        cls.assertOutput(\u0027\u0027, raw_output)"},{"line_number":41,"context_line":""},{"line_number":42,"context_line":"    def test_volume_snapshot__delete(self):"}],"source_content_type":"text/x-python","patch_set":4,"id":"df140735_fb7dabe7","line":39,"in_reply_to":"ff0f0b1f_f96efe2c","updated":"2017-05-30 00:34:17.000000000","message":"Done","commit_id":"5c21880dfa6f2d56e1bbe58d13d0c25578f00687"},{"author":{"_account_id":6482,"name":"Steve Martinelli","email":"s.martinelli@gmail.com","username":"stevemar"},"change_message_id":"10d97774340974ddf56c741c8667ef670dacea04","unresolved":false,"context_lines":[{"line_number":37,"context_line":"    def tearDownClass(cls):"},{"line_number":38,"context_line":"        cls.wait_for_status(\u0027volume\u0027, cls.VOLLY, \u0027available\u0027)"},{"line_number":39,"context_line":"        raw_output \u003d cls.openstack("},{"line_number":40,"context_line":"            \u0027volume delete --force \u0027 + cls.VOLLY)"},{"line_number":41,"context_line":"        cls.assertOutput(\u0027\u0027, raw_output)"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def test_volume_snapshot__delete(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"df140735_af541254","line":40,"range":{"start_line":40,"start_character":13,"end_line":40,"end_character":34},"updated":"2017-06-02 12:24:00.000000000","message":"--purge was not added, not a big deal","commit_id":"2e0d0c8b070252f688624f04086da4c89955c9a5"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"22dd50aa8cc329a0da9740bdf5069870d8b21466","unresolved":false,"context_lines":[{"line_number":37,"context_line":"    def tearDownClass(cls):"},{"line_number":38,"context_line":"        cls.wait_for_status(\u0027volume\u0027, cls.VOLLY, \u0027available\u0027)"},{"line_number":39,"context_line":"        raw_output \u003d cls.openstack("},{"line_number":40,"context_line":"            \u0027volume delete --force \u0027 + cls.VOLLY)"},{"line_number":41,"context_line":"        cls.assertOutput(\u0027\u0027, raw_output)"},{"line_number":42,"context_line":""},{"line_number":43,"context_line":"    def test_volume_snapshot__delete(self):"}],"source_content_type":"text/x-python","patch_set":7,"id":"df140735_31096895","line":40,"range":{"start_line":40,"start_character":13,"end_line":40,"end_character":34},"in_reply_to":"df140735_af541254","updated":"2017-06-04 16:30:22.000000000","message":"Ah.. I forgot to reply this. Unfortunately --force and --purge are mutually exclusive, so I cannot specify --purge.\n\nhttps://github.com/openstack/python-openstackclient/blob/master/openstackclient/volume/v2/volume.py#L262-L274","commit_id":"2e0d0c8b070252f688624f04086da4c89955c9a5"}],"openstackclient/tests/functional/volume/v2/test_volume.py":[{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"e8fe798bc93a1d5507eed95c08cf51825f2eefa5","unresolved":false,"context_lines":[{"line_number":259,"context_line":"                status \u003d self.openstack("},{"line_number":260,"context_line":"                    check_type + \u0027 show \u0027 + check_name + opts"},{"line_number":261,"context_line":"                )"},{"line_number":262,"context_line":"            except exceptions.CommandFailed:"},{"line_number":263,"context_line":"                # Show command raise Exception when object had been deleted"},{"line_number":264,"context_line":"                status \u003d \u0027disappear\u0027"},{"line_number":265,"context_line":"            status \u003d status.rstrip()"},{"line_number":266,"context_line":"            print(\u0027Checking {} {} Waiting for {} current status: {}\u0027"},{"line_number":267,"context_line":"                  .format(check_type, check_name, desired_status, status))"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_4dd8b279","side":"PARENT","line":264,"range":{"start_line":262,"start_character":11,"end_line":264,"end_character":36},"updated":"2017-05-24 08:08:52.000000000","message":"Note for reviewers:\n\nThis was used to check a given volume snapshot has gone, but it is not a good idea to use CommandFailed to detect a deletion. Instead, I use wait_for_delete in test_server.py. Thus there is no corresponding logic in volume.v2.common.py.","commit_id":"205d6e408a916e2df84c57d74bc5085aedd2866d"},{"author":{"_account_id":8276,"name":"kiwik","email":"chenrui.momo@gmail.com","username":"kiwik"},"change_message_id":"774ae400dd7ea0c47c031d9aa1b2dd30138c9835","unresolved":false,"context_lines":[{"line_number":259,"context_line":"                status \u003d self.openstack("},{"line_number":260,"context_line":"                    check_type + \u0027 show \u0027 + check_name + opts"},{"line_number":261,"context_line":"                )"},{"line_number":262,"context_line":"            except exceptions.CommandFailed:"},{"line_number":263,"context_line":"                # Show command raise Exception when object had been deleted"},{"line_number":264,"context_line":"                status \u003d \u0027disappear\u0027"},{"line_number":265,"context_line":"            status \u003d status.rstrip()"},{"line_number":266,"context_line":"            print(\u0027Checking {} {} Waiting for {} current status: {}\u0027"},{"line_number":267,"context_line":"                  .format(check_type, check_name, desired_status, status))"}],"source_content_type":"text/x-python","patch_set":4,"id":"ff0f0b1f_7c91bc46","side":"PARENT","line":264,"range":{"start_line":262,"start_character":11,"end_line":264,"end_character":36},"in_reply_to":"ff0f0b1f_4dd8b279","updated":"2017-05-25 12:46:31.000000000","message":"Make sense, thanks.","commit_id":"205d6e408a916e2df84c57d74bc5085aedd2866d"}]}
