)]}'
{"watcher/api/controllers/v1/audit.py":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"6b371bba8655643d108d3dd833e0c05d8aa0530f","unresolved":false,"context_lines":[{"line_number":563,"context_line":""},{"line_number":564,"context_line":"        initial_state \u003d audit_dict[\u0027state\u0027]"},{"line_number":565,"context_line":"        new_state \u003d api_utils.get_patch_value(patch, \u0027state\u0027)"},{"line_number":566,"context_line":"        check_transition \u003d objects.audit.AuditStateTransitionManager("},{"line_number":567,"context_line":"            ).check_transition(initial_state, new_state)"},{"line_number":568,"context_line":"        if new_state is not None and not check_transition:"},{"line_number":569,"context_line":"            error_message \u003d _(\"State transition not allowed: \""}],"source_content_type":"text/x-python","patch_set":2,"id":"9a30ddce_e682ad93","line":566,"range":{"start_line":566,"start_character":8,"end_line":566,"end_character":24},"updated":"2017-03-09 08:46:00.000000000","message":"nit: a variable with a verb looks like a function, which is slightly confusing: can you please rename it as something like \"transition_validated\"?","commit_id":"ee976f88e8f630fb94a922b8681d330c9adc91d0"},{"author":{"_account_id":13111,"name":"Hidekazu Nakamura","email":"hidekazuna@gmail.com","username":"hid-nakamura"},"change_message_id":"513ef8c1b96f4c36d6cc8ff7a68be5a457b25314","unresolved":false,"context_lines":[{"line_number":563,"context_line":""},{"line_number":564,"context_line":"        initial_state \u003d audit_dict[\u0027state\u0027]"},{"line_number":565,"context_line":"        new_state \u003d api_utils.get_patch_value(patch, \u0027state\u0027)"},{"line_number":566,"context_line":"        check_transition \u003d objects.audit.AuditStateTransitionManager("},{"line_number":567,"context_line":"            ).check_transition(initial_state, new_state)"},{"line_number":568,"context_line":"        if new_state is not None and not check_transition:"},{"line_number":569,"context_line":"            error_message \u003d _(\"State transition not allowed: \""}],"source_content_type":"text/x-python","patch_set":2,"id":"9a30ddce_464a6327","line":566,"range":{"start_line":566,"start_character":8,"end_line":566,"end_character":24},"in_reply_to":"9a30ddce_e682ad93","updated":"2017-03-10 09:00:41.000000000","message":"This part is refactored.","commit_id":"ee976f88e8f630fb94a922b8681d330c9adc91d0"},{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"6b371bba8655643d108d3dd833e0c05d8aa0530f","unresolved":false,"context_lines":[{"line_number":565,"context_line":"        new_state \u003d api_utils.get_patch_value(patch, \u0027state\u0027)"},{"line_number":566,"context_line":"        check_transition \u003d objects.audit.AuditStateTransitionManager("},{"line_number":567,"context_line":"            ).check_transition(initial_state, new_state)"},{"line_number":568,"context_line":"        if new_state is not None and not check_transition:"},{"line_number":569,"context_line":"            error_message \u003d _(\"State transition not allowed: \""},{"line_number":570,"context_line":"                              \"(%(initial_state)s -\u003e %(new_state)s)\")"},{"line_number":571,"context_line":"            raise exception.PatchError("}],"source_content_type":"text/x-python","patch_set":2,"id":"9a30ddce_091a726e","line":568,"range":{"start_line":568,"start_character":11,"end_line":568,"end_character":32},"updated":"2017-03-09 08:46:00.000000000","message":"\"new_state is not None\" is an api PATCH payload validation logic so IMO it should be moved into the AuditPatchType.validate() method.\n\nAs for the business logic that checks the validadity of the transition, it should IMO be done before event creating and patching the objects.Audit() instance (i.e. before lines 559-560).","commit_id":"ee976f88e8f630fb94a922b8681d330c9adc91d0"},{"author":{"_account_id":13111,"name":"Hidekazu Nakamura","email":"hidekazuna@gmail.com","username":"hid-nakamura"},"change_message_id":"513ef8c1b96f4c36d6cc8ff7a68be5a457b25314","unresolved":false,"context_lines":[{"line_number":565,"context_line":"        new_state \u003d api_utils.get_patch_value(patch, \u0027state\u0027)"},{"line_number":566,"context_line":"        check_transition \u003d objects.audit.AuditStateTransitionManager("},{"line_number":567,"context_line":"            ).check_transition(initial_state, new_state)"},{"line_number":568,"context_line":"        if new_state is not None and not check_transition:"},{"line_number":569,"context_line":"            error_message \u003d _(\"State transition not allowed: \""},{"line_number":570,"context_line":"                              \"(%(initial_state)s -\u003e %(new_state)s)\")"},{"line_number":571,"context_line":"            raise exception.PatchError("}],"source_content_type":"text/x-python","patch_set":2,"id":"9a30ddce_6653e7e2","line":568,"range":{"start_line":568,"start_character":11,"end_line":568,"end_character":32},"in_reply_to":"9a30ddce_091a726e","updated":"2017-03-10 09:00:41.000000000","message":"Done","commit_id":"ee976f88e8f630fb94a922b8681d330c9adc91d0"},{"author":{"_account_id":16277,"name":"Pradeep Kumar Singh","email":"ps4openstack@gmail.com","username":"pradeep_singh"},"change_message_id":"f182583fcd6a095e59a6f83648e6afdf6807c1a3","unresolved":false,"context_lines":[{"line_number":565,"context_line":"        new_state \u003d api_utils.get_patch_value(patch, \u0027state\u0027)"},{"line_number":566,"context_line":"        check_transition \u003d objects.audit.AuditStateTransitionManager("},{"line_number":567,"context_line":"            ).check_transition(initial_state, new_state)"},{"line_number":568,"context_line":"        if new_state is not None and not check_transition:"},{"line_number":569,"context_line":"            error_message \u003d _(\"State transition not allowed: \""},{"line_number":570,"context_line":"                              \"(%(initial_state)s -\u003e %(new_state)s)\")"},{"line_number":571,"context_line":"            raise exception.PatchError("},{"line_number":572,"context_line":"                patch\u003dpatch,"},{"line_number":573,"context_line":"                reason\u003derror_message % dict("},{"line_number":574,"context_line":"                    initial_state\u003dinitial_state, new_state\u003dnew_state))"},{"line_number":575,"context_line":""},{"line_number":576,"context_line":"        # Update only the fields that have changed"},{"line_number":577,"context_line":"        for field in objects.Audit.fields:"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a30ddce_ac8a59bd","line":574,"range":{"start_line":568,"start_character":8,"end_line":574,"end_character":70},"updated":"2017-03-09 06:35:20.000000000","message":"It may be my personal opinion, will it be good to move this logic to  check_transition method? Thoughts?","commit_id":"ee976f88e8f630fb94a922b8681d330c9adc91d0"},{"author":{"_account_id":13111,"name":"Hidekazu Nakamura","email":"hidekazuna@gmail.com","username":"hid-nakamura"},"change_message_id":"513ef8c1b96f4c36d6cc8ff7a68be5a457b25314","unresolved":false,"context_lines":[{"line_number":565,"context_line":"        new_state \u003d api_utils.get_patch_value(patch, \u0027state\u0027)"},{"line_number":566,"context_line":"        check_transition \u003d objects.audit.AuditStateTransitionManager("},{"line_number":567,"context_line":"            ).check_transition(initial_state, new_state)"},{"line_number":568,"context_line":"        if new_state is not None and not check_transition:"},{"line_number":569,"context_line":"            error_message \u003d _(\"State transition not allowed: \""},{"line_number":570,"context_line":"                              \"(%(initial_state)s -\u003e %(new_state)s)\")"},{"line_number":571,"context_line":"            raise exception.PatchError("},{"line_number":572,"context_line":"                patch\u003dpatch,"},{"line_number":573,"context_line":"                reason\u003derror_message % dict("},{"line_number":574,"context_line":"                    initial_state\u003dinitial_state, new_state\u003dnew_state))"},{"line_number":575,"context_line":""},{"line_number":576,"context_line":"        # Update only the fields that have changed"},{"line_number":577,"context_line":"        for field in objects.Audit.fields:"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a30ddce_26748f66","line":574,"range":{"start_line":568,"start_character":8,"end_line":574,"end_character":70},"in_reply_to":"9a30ddce_892ae22a","updated":"2017-03-10 09:00:41.000000000","message":"I like the first.","commit_id":"ee976f88e8f630fb94a922b8681d330c9adc91d0"},{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"6b371bba8655643d108d3dd833e0c05d8aa0530f","unresolved":false,"context_lines":[{"line_number":565,"context_line":"        new_state \u003d api_utils.get_patch_value(patch, \u0027state\u0027)"},{"line_number":566,"context_line":"        check_transition \u003d objects.audit.AuditStateTransitionManager("},{"line_number":567,"context_line":"            ).check_transition(initial_state, new_state)"},{"line_number":568,"context_line":"        if new_state is not None and not check_transition:"},{"line_number":569,"context_line":"            error_message \u003d _(\"State transition not allowed: \""},{"line_number":570,"context_line":"                              \"(%(initial_state)s -\u003e %(new_state)s)\")"},{"line_number":571,"context_line":"            raise exception.PatchError("},{"line_number":572,"context_line":"                patch\u003dpatch,"},{"line_number":573,"context_line":"                reason\u003derror_message % dict("},{"line_number":574,"context_line":"                    initial_state\u003dinitial_state, new_state\u003dnew_state))"},{"line_number":575,"context_line":""},{"line_number":576,"context_line":"        # Update only the fields that have changed"},{"line_number":577,"context_line":"        for field in objects.Audit.fields:"}],"source_content_type":"text/x-python","patch_set":2,"id":"9a30ddce_892ae22a","line":574,"range":{"start_line":568,"start_character":8,"end_line":574,"end_character":70},"in_reply_to":"9a30ddce_ac8a59bd","updated":"2017-03-09 08:46:00.000000000","message":"The PatchError Exception is an API-related exception type which means that we should not raise such exception from within the AuditStateTransitionManager.\n\nSo IMHO we have 2 options:\n\n- We return True or False whether or not it\u0027s valid and we manually raise the corresponding error everywhere needed\n- We raise a new TransitionError exception and then catch it in this block to re-raise our PatchError","commit_id":"ee976f88e8f630fb94a922b8681d330c9adc91d0"}],"watcher/api/controllers/v1/utils.py":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"612ff19a1a2a40a6d5fbdb2b3cf33cda50225140","unresolved":false,"context_lines":[{"line_number":80,"context_line":""},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"def check_audit_state_transition(patch, initial):"},{"line_number":83,"context_line":"    for p in patch:"},{"line_number":84,"context_line":"        if p[\u0027op\u0027] \u003d\u003d \u0027replace\u0027 and p[\u0027path\u0027] \u003d\u003d \u0027/state\u0027:"},{"line_number":85,"context_line":"            return (objects.audit.AuditStateTransitionManager()."},{"line_number":86,"context_line":"                    check_transition(initial, p[\u0027value\u0027]))"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    return True"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"def as_filters_dict(**filters):"}],"source_content_type":"text/x-python","patch_set":4,"id":"bff0334d_2d3d8f2a","line":88,"range":{"start_line":83,"start_character":0,"end_line":88,"end_character":15},"updated":"2017-04-11 07:35:36.000000000","message":"why not instead:\n\ndef check_audit_state_transition(patch, initial):\n    is_transition_valid \u003d True\n    state_value \u003d get_patch_value(patch, \"/state\")\n    if state_value is not None:\n        is_transition_valid \u003d objects.audit.AuditStateTransitionManager().\n                    check_transition(initial, state_value)\n    return is_transition_valid\n\nEven if my version is longer, I think it\u0027s more readable since it reuses the get_patch_value() function.","commit_id":"60796973061b58c95682c3665e2ec149f300908d"},{"author":{"_account_id":13111,"name":"Hidekazu Nakamura","email":"hidekazuna@gmail.com","username":"hid-nakamura"},"change_message_id":"5608545385823b3edab6321627a8d14241370e7c","unresolved":false,"context_lines":[{"line_number":80,"context_line":""},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"def check_audit_state_transition(patch, initial):"},{"line_number":83,"context_line":"    for p in patch:"},{"line_number":84,"context_line":"        if p[\u0027op\u0027] \u003d\u003d \u0027replace\u0027 and p[\u0027path\u0027] \u003d\u003d \u0027/state\u0027:"},{"line_number":85,"context_line":"            return (objects.audit.AuditStateTransitionManager()."},{"line_number":86,"context_line":"                    check_transition(initial, p[\u0027value\u0027]))"},{"line_number":87,"context_line":""},{"line_number":88,"context_line":"    return True"},{"line_number":89,"context_line":""},{"line_number":90,"context_line":""},{"line_number":91,"context_line":"def as_filters_dict(**filters):"}],"source_content_type":"text/x-python","patch_set":4,"id":"bff0334d_ea32e2f1","line":88,"range":{"start_line":83,"start_character":0,"end_line":88,"end_character":15},"in_reply_to":"bff0334d_2d3d8f2a","updated":"2017-04-11 11:51:54.000000000","message":"Done","commit_id":"60796973061b58c95682c3665e2ec149f300908d"}],"watcher/decision_engine/audit/continuous.py":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"83b74a07432210840439a4c7001d838013545780","unresolved":false,"context_lines":[{"line_number":46,"context_line":"            self._scheduler \u003d background.BackgroundScheduler()"},{"line_number":47,"context_line":"        return self._scheduler"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def _is_audit_inactive(self, audit):"},{"line_number":50,"context_line":"        audit \u003d objects.Audit.get_by_uuid("},{"line_number":51,"context_line":"            self.context_show_deleted, audit.uuid)"},{"line_number":52,"context_line":"        if audit.state in (objects.audit.State.CANCELLED,"},{"line_number":53,"context_line":"                           objects.audit.State.DELETED,"},{"line_number":54,"context_line":"                           objects.audit.State.FAILED,"},{"line_number":55,"context_line":"                           objects.audit.State.SUSPENDED):"},{"line_number":56,"context_line":"            # if audit isn\u0027t in active states, audit\u0027s job must be removed to"},{"line_number":57,"context_line":"            # prevent using of inactive audit in future."},{"line_number":58,"context_line":"            job_to_delete \u003d [job for job in self.jobs"}],"source_content_type":"text/x-python","patch_set":1,"id":"ba2be162_0df9a34d","line":55,"range":{"start_line":49,"start_character":0,"end_line":55,"end_character":58},"updated":"2017-03-02 13:54:18.000000000","message":"If you agree with my comment made in https://review.openstack.org/#/c/438800/1/watcher/tests/api/v1/test_audits.py, we should also move this piece of logic into AuditStateTransitionManager:\n\n    # in watcher/objects/audit.py\n    class AuditStateTransitionManager(object):\n        [...]\n        INACTIVE_STATES \u003d (State.CANCELLED, State.DELETED,\n                           State.FAILED, State.SUSPENDED)\n\n        def is_inactive(self, audit):\n            return audit.state in self.INACTIVE_STATES","commit_id":"508534840705b516f5767721f819646512f73f59"},{"author":{"_account_id":13111,"name":"Hidekazu Nakamura","email":"hidekazuna@gmail.com","username":"hid-nakamura"},"change_message_id":"5291c85b3a74c881d0f4380b30603a6ae00ec2a2","unresolved":false,"context_lines":[{"line_number":46,"context_line":"            self._scheduler \u003d background.BackgroundScheduler()"},{"line_number":47,"context_line":"        return self._scheduler"},{"line_number":48,"context_line":""},{"line_number":49,"context_line":"    def _is_audit_inactive(self, audit):"},{"line_number":50,"context_line":"        audit \u003d objects.Audit.get_by_uuid("},{"line_number":51,"context_line":"            self.context_show_deleted, audit.uuid)"},{"line_number":52,"context_line":"        if audit.state in (objects.audit.State.CANCELLED,"},{"line_number":53,"context_line":"                           objects.audit.State.DELETED,"},{"line_number":54,"context_line":"                           objects.audit.State.FAILED,"},{"line_number":55,"context_line":"                           objects.audit.State.SUSPENDED):"},{"line_number":56,"context_line":"            # if audit isn\u0027t in active states, audit\u0027s job must be removed to"},{"line_number":57,"context_line":"            # prevent using of inactive audit in future."},{"line_number":58,"context_line":"            job_to_delete \u003d [job for job in self.jobs"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a30ddce_51451f15","line":55,"range":{"start_line":49,"start_character":0,"end_line":55,"end_character":58},"in_reply_to":"ba2be162_0df9a34d","updated":"2017-03-08 07:14:18.000000000","message":"Done","commit_id":"508534840705b516f5767721f819646512f73f59"}],"watcher/tests/api/v1/test_audits.py":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"83b74a07432210840439a4c7001d838013545780","unresolved":false,"context_lines":[{"line_number":344,"context_line":"        self.assertTrue(response.json[\u0027error_message\u0027])"},{"line_number":345,"context_line":""},{"line_number":346,"context_line":""},{"line_number":347,"context_line":"ALLOWED_TRANSITIONS \u003d ["},{"line_number":348,"context_line":"    {\"original_state\": objects.audit.State.PENDING,"},{"line_number":349,"context_line":"     \"new_state\": objects.audit.State.ONGOING},"},{"line_number":350,"context_line":"    {\"original_state\": objects.audit.State.PENDING,"},{"line_number":351,"context_line":"     \"new_state\": objects.audit.State.CANCELLED},"},{"line_number":352,"context_line":"    {\"original_state\": objects.audit.State.ONGOING,"},{"line_number":353,"context_line":"     \"new_state\": objects.audit.State.FAILED},"},{"line_number":354,"context_line":"    {\"original_state\": objects.audit.State.ONGOING,"},{"line_number":355,"context_line":"     \"new_state\": objects.audit.State.SUCCEEDED},"},{"line_number":356,"context_line":"    {\"original_state\": objects.audit.State.ONGOING,"},{"line_number":357,"context_line":"     \"new_state\": objects.audit.State.CANCELLED},"},{"line_number":358,"context_line":"    {\"original_state\": objects.audit.State.ONGOING,"},{"line_number":359,"context_line":"     \"new_state\": objects.audit.State.SUSPENDED},"},{"line_number":360,"context_line":"    {\"original_state\": objects.audit.State.FAILED,"},{"line_number":361,"context_line":"     \"new_state\": objects.audit.State.DELETED},"},{"line_number":362,"context_line":"    {\"original_state\": objects.audit.State.SUCCEEDED,"},{"line_number":363,"context_line":"     \"new_state\": objects.audit.State.DELETED},"},{"line_number":364,"context_line":"    {\"original_state\": objects.audit.State.CANCELLED,"},{"line_number":365,"context_line":"     \"new_state\": objects.audit.State.DELETED},"},{"line_number":366,"context_line":"    {\"original_state\": objects.audit.State.SUSPENDED,"},{"line_number":367,"context_line":"     \"new_state\": objects.audit.State.ONGOING},"},{"line_number":368,"context_line":"    {\"original_state\": objects.audit.State.SUSPENDED,"},{"line_number":369,"context_line":"     \"new_state\": objects.audit.State.DELETED},"},{"line_number":370,"context_line":"]"},{"line_number":371,"context_line":""},{"line_number":372,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"ba2be162_a77276ab","line":369,"range":{"start_line":347,"start_character":0,"end_line":369,"end_character":47},"updated":"2017-03-02 13:54:18.000000000","message":"This is actually somewhat of a duplication from the ALLOWED_TRANSITION that is defined in https://review.openstack.org/#/c/438800/1/watcher/api/controllers/v1/audit.py although it is written in a different form.\n\nIMHO, we should factorize both so that the list of allowed transition is shared throughout the codebase to avoid discrepancies.\n\nHow about moving the API notation into the watcher/objects/audit.py in a new AuditStateTransitionManager that would encapsulate this catalog of transition like:\n\n\n    # in watcher/objects/audit.py\n    class AuditStateTransitionManager(object):\n\n        TRANSITIONS \u003d {\n            State.PENDING: [State.ONGOING, State.CANCELLED],\n            State.ONGOING: [State.FAILED, State.SUCCEEDED,\n                            State.CANCELLED, State.SUSPENDED],\n            State.FAILED: [State.DELETED],\n            State.SUCCEEDED: [State.DELETED],\n            State.CANCELLED: [State.DELETED],\n            State.SUSPENDED: [State.ONGOING, State.DELETED],\n        }\n\n        def check_transition(self, initial, new):\n            return new in self.TRANSITIONS.get(initial, [])\n\n\nYou could then rewrite this structure as:\n\n    ALLOWED_TRANSITIONS \u003d [\n        {\"original_state\": key, \"new_state\": value}\n        for key, values in AuditStateTransitionManager.TRANSITIONS.items()\n        for value in values]","commit_id":"508534840705b516f5767721f819646512f73f59"},{"author":{"_account_id":13111,"name":"Hidekazu Nakamura","email":"hidekazuna@gmail.com","username":"hid-nakamura"},"change_message_id":"5291c85b3a74c881d0f4380b30603a6ae00ec2a2","unresolved":false,"context_lines":[{"line_number":344,"context_line":"        self.assertTrue(response.json[\u0027error_message\u0027])"},{"line_number":345,"context_line":""},{"line_number":346,"context_line":""},{"line_number":347,"context_line":"ALLOWED_TRANSITIONS \u003d ["},{"line_number":348,"context_line":"    {\"original_state\": objects.audit.State.PENDING,"},{"line_number":349,"context_line":"     \"new_state\": objects.audit.State.ONGOING},"},{"line_number":350,"context_line":"    {\"original_state\": objects.audit.State.PENDING,"},{"line_number":351,"context_line":"     \"new_state\": objects.audit.State.CANCELLED},"},{"line_number":352,"context_line":"    {\"original_state\": objects.audit.State.ONGOING,"},{"line_number":353,"context_line":"     \"new_state\": objects.audit.State.FAILED},"},{"line_number":354,"context_line":"    {\"original_state\": objects.audit.State.ONGOING,"},{"line_number":355,"context_line":"     \"new_state\": objects.audit.State.SUCCEEDED},"},{"line_number":356,"context_line":"    {\"original_state\": objects.audit.State.ONGOING,"},{"line_number":357,"context_line":"     \"new_state\": objects.audit.State.CANCELLED},"},{"line_number":358,"context_line":"    {\"original_state\": objects.audit.State.ONGOING,"},{"line_number":359,"context_line":"     \"new_state\": objects.audit.State.SUSPENDED},"},{"line_number":360,"context_line":"    {\"original_state\": objects.audit.State.FAILED,"},{"line_number":361,"context_line":"     \"new_state\": objects.audit.State.DELETED},"},{"line_number":362,"context_line":"    {\"original_state\": objects.audit.State.SUCCEEDED,"},{"line_number":363,"context_line":"     \"new_state\": objects.audit.State.DELETED},"},{"line_number":364,"context_line":"    {\"original_state\": objects.audit.State.CANCELLED,"},{"line_number":365,"context_line":"     \"new_state\": objects.audit.State.DELETED},"},{"line_number":366,"context_line":"    {\"original_state\": objects.audit.State.SUSPENDED,"},{"line_number":367,"context_line":"     \"new_state\": objects.audit.State.ONGOING},"},{"line_number":368,"context_line":"    {\"original_state\": objects.audit.State.SUSPENDED,"},{"line_number":369,"context_line":"     \"new_state\": objects.audit.State.DELETED},"},{"line_number":370,"context_line":"]"},{"line_number":371,"context_line":""},{"line_number":372,"context_line":""}],"source_content_type":"text/x-python","patch_set":1,"id":"9a30ddce_b1565bd0","line":369,"range":{"start_line":347,"start_character":0,"end_line":369,"end_character":47},"in_reply_to":"ba2be162_a77276ab","updated":"2017-03-08 07:14:18.000000000","message":"Done","commit_id":"508534840705b516f5767721f819646512f73f59"}],"watcher/tests/db/test_audit.py":[{"author":{"_account_id":18971,"name":"Vincent Françoise","email":"Vincent.FRANCOISE@b-com.com","username":"v-francoise"},"change_message_id":"83b74a07432210840439a4c7001d838013545780","unresolved":false,"context_lines":[{"line_number":235,"context_line":"    def test_get_audit_list_filter_state_in(self):"},{"line_number":236,"context_line":"        res \u003d self.dbapi.get_audit_list("},{"line_number":237,"context_line":"            self.context,"},{"line_number":238,"context_line":"            filters\u003d{\u0027state__in\u0027: (objects.audit.State.FAILED,"},{"line_number":239,"context_line":"                                   objects.audit.State.CANCELLED,"},{"line_number":240,"context_line":"                                   objects.audit.State.SUSPENDED)})"},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"        self.assertEqual("},{"line_number":243,"context_line":"            [self.audit2[\u0027id\u0027], self.audit3[\u0027id\u0027], self.audit4[\u0027id\u0027]],"}],"source_content_type":"text/x-python","patch_set":1,"id":"ba2be162_92484e89","line":240,"range":{"start_line":238,"start_character":35,"end_line":240,"end_character":64},"updated":"2017-03-02 13:54:18.000000000","message":"following my previous comment about adding the AuditStateTransitionManager class, we could then extend it to simplify the writing of these tests:","commit_id":"508534840705b516f5767721f819646512f73f59"},{"author":{"_account_id":13111,"name":"Hidekazu Nakamura","email":"hidekazuna@gmail.com","username":"hid-nakamura"},"change_message_id":"5291c85b3a74c881d0f4380b30603a6ae00ec2a2","unresolved":false,"context_lines":[{"line_number":235,"context_line":"    def test_get_audit_list_filter_state_in(self):"},{"line_number":236,"context_line":"        res \u003d self.dbapi.get_audit_list("},{"line_number":237,"context_line":"            self.context,"},{"line_number":238,"context_line":"            filters\u003d{\u0027state__in\u0027: (objects.audit.State.FAILED,"},{"line_number":239,"context_line":"                                   objects.audit.State.CANCELLED,"},{"line_number":240,"context_line":"                                   objects.audit.State.SUSPENDED)})"},{"line_number":241,"context_line":""},{"line_number":242,"context_line":"        self.assertEqual("},{"line_number":243,"context_line":"            [self.audit2[\u0027id\u0027], self.audit3[\u0027id\u0027], self.audit4[\u0027id\u0027]],"}],"source_content_type":"text/x-python","patch_set":1,"id":"9a30ddce_1162c7ad","line":240,"range":{"start_line":238,"start_character":35,"end_line":240,"end_character":64},"in_reply_to":"ba2be162_92484e89","updated":"2017-03-08 07:14:18.000000000","message":"Done","commit_id":"508534840705b516f5767721f819646512f73f59"}]}
