)]}'
{"neutron/api/rpc/agentnotifiers/l3_rpc_agent_api.py":[{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"435483e78bcdc3867a1b192095ec0bed3d200ca7","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"9a061dce_63a597a0","updated":"2016-04-07 08:52:01.000000000","message":"I\u0027d add retry logic wrapping rpc call() (smth like  call_with_retries()) and use it in _notification_host() and _notification() if use_call parameter is True. Then specify use_call\u003dTrue where needed in l3 plugin (when rescheduling or router creation)","commit_id":"e50332049d0200980184841c38b275bb205bbcb9"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"9531e95c00d71ae17ce4bd8c89e792d5e0fd5a21","unresolved":false,"context_lines":[],"source_content_type":"","patch_set":3,"id":"9a061dce_5d9f7e5e","in_reply_to":"9a061dce_63a597a0","updated":"2016-04-07 12:48:09.000000000","message":"Sure, I had the same idea, will be done once I get the tests fixed. Just want to make sure my refactor doesn\u0027t break the tests first.","commit_id":"e50332049d0200980184841c38b275bb205bbcb9"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"471c2f8000782038a4464d073864de7f627639f1","unresolved":false,"context_lines":[{"line_number":97,"context_line":"                                        version\u003d\u00271.2\u0027)"},{"line_number":98,"context_line":"            cctxt.cast(context, method, payload\u003ddvr_arptable)"},{"line_number":99,"context_line":""},{"line_number":100,"context_line":"    @ag_utils.call_with_retry(AGENT_NOTIFY_MAX_ATTEMPTS)"},{"line_number":101,"context_line":"    def _notification(self, context, method, router_ids, operation,"},{"line_number":102,"context_line":"                      shuffle_agents, schedule_routers\u003dTrue, use_call\u003dTrue):"},{"line_number":103,"context_line":"        \"\"\"Notify all the agents that are hosting the routers.\"\"\""}],"source_content_type":"text/x-python","patch_set":6,"id":"9a061dce_de085fdc","line":100,"range":{"start_line":100,"start_character":4,"end_line":100,"end_character":56},"updated":"2016-04-08 13:42:02.000000000","message":"this will retry the whole method in case call() fails - it seems an overkill. Can we retry only call()? Smth like _call_with_retries(*args, **kwargs)..","commit_id":"1ba5d8ffecdfb62a3579fcfd7ca5fa9c6d6bccce"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"23e8eee9f6a1037610022fd4014e792b548e3e5d","unresolved":false,"context_lines":[{"line_number":171,"context_line":"        if router_ids:"},{"line_number":172,"context_line":"            self._notification(context, \u0027routers_updated\u0027, router_ids,"},{"line_number":173,"context_line":"                               operation, shuffle_agents, schedule_routers,"},{"line_number":174,"context_line":"                               use_call\u003dFalse)"},{"line_number":175,"context_line":""},{"line_number":176,"context_line":"    def add_arp_entry(self, context, router_id, arp_table, operation\u003dNone):"},{"line_number":177,"context_line":"        self._agent_notification_arp(context, \u0027add_arp_entry\u0027, router_id,"}],"source_content_type":"text/x-python","patch_set":6,"id":"9a061dce_cf61d3d5","line":174,"range":{"start_line":174,"start_character":31,"end_line":174,"end_character":39},"updated":"2016-04-08 12:28:56.000000000","message":"use_call\u003dFalse will be removed in the next PS.","commit_id":"1ba5d8ffecdfb62a3579fcfd7ca5fa9c6d6bccce"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"23e8eee9f6a1037610022fd4014e792b548e3e5d","unresolved":false,"context_lines":[{"line_number":201,"context_line":"    def routers_updated_on_host(self, context, router_ids, host):"},{"line_number":202,"context_line":"        # use call here to make sure agents do receive update notification"},{"line_number":203,"context_line":"        self._notification_host(context, \u0027routers_updated\u0027, host,"},{"line_number":204,"context_line":"                                routers\u003drouter_ids, use_call\u003dFalse)"}],"source_content_type":"text/x-python","patch_set":6,"id":"9a061dce_4f6dc3cb","line":204,"range":{"start_line":204,"start_character":61,"end_line":204,"end_character":66},"updated":"2016-04-08 12:28:56.000000000","message":"use_call\u003dFalse will be removed in the next PS.","commit_id":"1ba5d8ffecdfb62a3579fcfd7ca5fa9c6d6bccce"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"76c138e633211e3668b693bbf922cc97432c770f","unresolved":false,"context_lines":[{"line_number":145,"context_line":"        self._notification_host(context, \u0027agent_updated\u0027, host,"},{"line_number":146,"context_line":"                                payload\u003d{\u0027admin_state_up\u0027: admin_state_up})"},{"line_number":147,"context_line":""},{"line_number":148,"context_line":"    def router_rescheduled(self, context, router_id, old_agents, new_agents):"},{"line_number":149,"context_line":"        \"\"\""},{"line_number":150,"context_line":"        Notifies agents about router resceduling."},{"line_number":151,"context_line":"        In case of failure tries to add a router to an agent, raises an"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a1b2928_07ff3602","line":148,"range":{"start_line":148,"start_character":8,"end_line":148,"end_character":26},"updated":"2016-04-11 09:31:45.000000000","message":"I think this should not be moved. Please only move retrying logic to limit the scope of the patch","commit_id":"684d1bc15348b2748f26e7763d73e1f3114ae764"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"b8f7bb5635f80fe8dbb2fe03932313628d567a9b","unresolved":false,"context_lines":[{"line_number":145,"context_line":"        self._notification_host(context, \u0027agent_updated\u0027, host,"},{"line_number":146,"context_line":"                                payload\u003d{\u0027admin_state_up\u0027: admin_state_up})"},{"line_number":147,"context_line":""},{"line_number":148,"context_line":"    def router_rescheduled(self, context, router_id, old_agents, new_agents):"},{"line_number":149,"context_line":"        \"\"\""},{"line_number":150,"context_line":"        Notifies agents about router resceduling."},{"line_number":151,"context_line":"        In case of failure tries to add a router to an agent, raises an"}],"source_content_type":"text/x-python","patch_set":8,"id":"7a1b2928_fa860864","line":148,"range":{"start_line":148,"start_character":8,"end_line":148,"end_character":26},"in_reply_to":"7a1b2928_07ff3602","updated":"2016-04-11 13:00:50.000000000","message":"Ok, will be done.","commit_id":"684d1bc15348b2748f26e7763d73e1f3114ae764"},{"author":{"_account_id":14605,"name":"vikram.choudhary","email":"vikschw@gmail.com","username":"vikram.choudhary"},"change_message_id":"221262606e43660f849f07e083231acbf5063e2a","unresolved":false,"context_lines":[{"line_number":19,"context_line":"import oslo_messaging"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from neutron._i18n import _LE"},{"line_number":22,"context_line":"from neutron.api.rpc.agentnotifiers import utils as ag_utils"},{"line_number":23,"context_line":"from neutron.common import constants"},{"line_number":24,"context_line":"from neutron.common import rpc as n_rpc"},{"line_number":25,"context_line":"from neutron.common import topics"}],"source_content_type":"text/x-python","patch_set":13,"id":"1a122d0e_1f428f3e","line":22,"updated":"2016-04-24 04:25:26.000000000","message":"IMO, lets use \u0027agt\u0027 as suffix for agent instead of \u0027ag\u0027","commit_id":"59916c5b451de8426b30f519d49427d3bbfe64d0"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"004386da0abadde357c36abb0798abb0b60f543e","unresolved":false,"context_lines":[{"line_number":19,"context_line":"import oslo_messaging"},{"line_number":20,"context_line":""},{"line_number":21,"context_line":"from neutron._i18n import _LE"},{"line_number":22,"context_line":"from neutron.api.rpc.agentnotifiers import utils as ag_utils"},{"line_number":23,"context_line":"from neutron.common import constants"},{"line_number":24,"context_line":"from neutron.common import rpc as n_rpc"},{"line_number":25,"context_line":"from neutron.common import topics"}],"source_content_type":"text/x-python","patch_set":13,"id":"1a122d0e_136e0896","line":22,"in_reply_to":"1a122d0e_1f428f3e","updated":"2016-04-24 16:06:18.000000000","message":"I prefer ag_utils as a more natural way of reduction of the word \u0027agent\u0027 (by the first vowel).","commit_id":"59916c5b451de8426b30f519d49427d3bbfe64d0"}],"neutron/api/rpc/agentnotifiers/utils.py":[{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"471c2f8000782038a4464d073864de7f627639f1","unresolved":false,"context_lines":[{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"def call_with_retry(max_attempts):"},{"line_number":26,"context_line":"    \"\"\"A wrapper to retry rpc call in case of failure for k times."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    Retries the decorated function in case of failure. If maximum attempts"},{"line_number":29,"context_line":"    exceeded, NotifyFailedInMaxAttempts exception is raised."}],"source_content_type":"text/x-python","patch_set":6,"id":"9a061dce_fd03adbc","line":26,"range":{"start_line":26,"start_character":58,"end_line":26,"end_character":59},"updated":"2016-04-08 13:42:02.000000000","message":"max_attempts","commit_id":"1ba5d8ffecdfb62a3579fcfd7ca5fa9c6d6bccce"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"471c2f8000782038a4464d073864de7f627639f1","unresolved":false,"context_lines":[{"line_number":25,"context_line":"def call_with_retry(max_attempts):"},{"line_number":26,"context_line":"    \"\"\"A wrapper to retry rpc call in case of failure for k times."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    Retries the decorated function in case of failure. If maximum attempts"},{"line_number":29,"context_line":"    exceeded, NotifyFailedInMaxAttempts exception is raised."},{"line_number":30,"context_line":"    \"\"\""},{"line_number":31,"context_line":"    def wrapper(f):"}],"source_content_type":"text/x-python","patch_set":6,"id":"9a061dce_1de141ff","line":28,"range":{"start_line":28,"start_character":46,"end_line":28,"end_character":53},"updated":"2016-04-08 13:42:02.000000000","message":"MessagingTimeout","commit_id":"1ba5d8ffecdfb62a3579fcfd7ca5fa9c6d6bccce"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"23e8eee9f6a1037610022fd4014e792b548e3e5d","unresolved":false,"context_lines":[{"line_number":33,"context_line":"            if kwargs.get(\u0027use_call\u0027, False):"},{"line_number":34,"context_line":"                # XXX FIXME have to think of a more informative data to log"},{"line_number":35,"context_line":"                # there is no func_name in python 3, using __name__ instead"},{"line_number":36,"context_line":"                action \u003d \u0027%(func)s\u0027 % {\u0027func\u0027: f.__name__}"},{"line_number":37,"context_line":"                for attempt in range(max_attempts):"},{"line_number":38,"context_line":"                    try:"},{"line_number":39,"context_line":"                        return f(*args, **kwargs)"}],"source_content_type":"text/x-python","patch_set":6,"id":"9a061dce_ef9e57b7","line":36,"range":{"start_line":36,"start_character":15,"end_line":36,"end_character":58},"updated":"2016-04-08 12:28:56.000000000","message":"Any suggestions on log message?","commit_id":"1ba5d8ffecdfb62a3579fcfd7ca5fa9c6d6bccce"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"76c138e633211e3668b693bbf922cc97432c770f","unresolved":false,"context_lines":[{"line_number":25,"context_line":"def call_with_retry(max_attempts):"},{"line_number":26,"context_line":"    \"\"\"A wrapper to retry function in case of MessagingTimeout."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    Retries the decorated function in case of timeout. If maximum attempts"},{"line_number":29,"context_line":"    exceeded, NotifyFailedInMaxAttempts exception is raised."},{"line_number":30,"context_line":"    Should be used on functions containing rpc call logic."},{"line_number":31,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":8,"id":"7a1b2928_c481bc91","line":28,"range":{"start_line":28,"start_character":12,"end_line":28,"end_character":34},"updated":"2016-04-11 09:31:45.000000000","message":"I\u0027d like to understand what else would make sense to decorate with this except rpc call()?","commit_id":"684d1bc15348b2748f26e7763d73e1f3114ae764"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"639d8a34210f94214b363ff4c78ff205081f88c2","unresolved":false,"context_lines":[{"line_number":25,"context_line":"def call_with_retry(max_attempts):"},{"line_number":26,"context_line":"    \"\"\"A wrapper to retry function in case of MessagingTimeout."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    Retries the decorated function in case of timeout. If maximum attempts"},{"line_number":29,"context_line":"    exceeded, NotifyFailedInMaxAttempts exception is raised."},{"line_number":30,"context_line":"    Should be used on functions containing rpc call logic."},{"line_number":31,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":8,"id":"7a1b2928_cee4270f","line":28,"range":{"start_line":28,"start_character":12,"end_line":28,"end_character":34},"in_reply_to":"7a1b2928_9aaf14e3","updated":"2016-04-11 14:39:21.000000000","message":"Ok, I get it now - you are generally concerned that I\u0027m introducing a decorator that won\u0027t be used on its own, as long as the common use case will be to repeat one single call using retry().\n\nIn my defense I can say that, imo, decorator version looks neat and the implementation details of retry() should not matter much, but I don\u0027t want to violate YAGNI and will produce an alternative, non-decorator based retry() implementation in next PS.","commit_id":"684d1bc15348b2748f26e7763d73e1f3114ae764"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"b8f7bb5635f80fe8dbb2fe03932313628d567a9b","unresolved":false,"context_lines":[{"line_number":25,"context_line":"def call_with_retry(max_attempts):"},{"line_number":26,"context_line":"    \"\"\"A wrapper to retry function in case of MessagingTimeout."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    Retries the decorated function in case of timeout. If maximum attempts"},{"line_number":29,"context_line":"    exceeded, NotifyFailedInMaxAttempts exception is raised."},{"line_number":30,"context_line":"    Should be used on functions containing rpc call logic."},{"line_number":31,"context_line":"    \"\"\""}],"source_content_type":"text/x-python","patch_set":8,"id":"7a1b2928_9aaf14e3","line":28,"range":{"start_line":28,"start_character":12,"end_line":28,"end_character":34},"in_reply_to":"7a1b2928_c481bc91","updated":"2016-04-11 13:00:50.000000000","message":"I meant that any notification function which uses rpc call may be decorated.","commit_id":"684d1bc15348b2748f26e7763d73e1f3114ae764"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"8970b386d488e5953f1134bf524913731d260a97","unresolved":false,"context_lines":[{"line_number":42,"context_line":"                        {\u0027attempt\u0027: attempt + 1,"},{"line_number":43,"context_line":"                            \u0027max_attempts\u0027: max_attempts,"},{"line_number":44,"context_line":"                            \u0027action\u0027: action})"},{"line_number":45,"context_line":"            raise exc.NotifyFailedInMaxAttempts("},{"line_number":46,"context_line":"                action\u003daction, max_attempts\u003dmax_attempts)"},{"line_number":47,"context_line":"        return func_wrapper"},{"line_number":48,"context_line":"    return wrapper"}],"source_content_type":"text/x-python","patch_set":9,"id":"5a18252c_fab08fdf","line":45,"updated":"2016-04-13 11:09:22.000000000","message":"might be simpler to just re-raise the messaging timeout exception on retry exceeded. that way we don\u0027t have to introduce a new exception and the callers don\u0027t have to worry about which exception type to catch. what do you think?","commit_id":"f669556cabb4f5934e31535d109a63dcc6f666c6"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"cb74a0506681129d7990664bccba964986c78a65","unresolved":false,"context_lines":[{"line_number":42,"context_line":"                        {\u0027attempt\u0027: attempt + 1,"},{"line_number":43,"context_line":"                            \u0027max_attempts\u0027: max_attempts,"},{"line_number":44,"context_line":"                            \u0027action\u0027: action})"},{"line_number":45,"context_line":"            raise exc.NotifyFailedInMaxAttempts("},{"line_number":46,"context_line":"                action\u003daction, max_attempts\u003dmax_attempts)"},{"line_number":47,"context_line":"        return func_wrapper"},{"line_number":48,"context_line":"    return wrapper"}],"source_content_type":"text/x-python","patch_set":9,"id":"5a18252c_cc565d29","line":45,"in_reply_to":"5a18252c_fab08fdf","updated":"2016-04-14 19:07:50.000000000","message":"I think the simpler the better. Will change to MessagingTimeout in next PS, thanks!","commit_id":"f669556cabb4f5934e31535d109a63dcc6f666c6"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"a3f8869a6369c0f0aaafc0bcef6313fb63106010","unresolved":false,"context_lines":[{"line_number":42,"context_line":"                        {\u0027attempt\u0027: attempt + 1,"},{"line_number":43,"context_line":"                            \u0027max_attempts\u0027: max_attempts,"},{"line_number":44,"context_line":"                            \u0027action\u0027: action})"},{"line_number":45,"context_line":"                    last_exc \u003d e"},{"line_number":46,"context_line":"            raise last_exc if last_exc else oslo_messaging.MessagingTimeout()"},{"line_number":47,"context_line":"        return func_wrapper"},{"line_number":48,"context_line":"    return wrapper"}],"source_content_type":"text/x-python","patch_set":13,"id":"1a122d0e_a2bc2edc","line":45,"updated":"2016-04-23 07:25:41.000000000","message":"I think you need to use excutils.save_and_reraise_exception when reraising an exception with potentially eventlet green thread switch.\n\n  from oslo_utils import excutils\n\n  except oslo_messaging.MessagingTimeout as e:\n    with excutils.save_and_reraise_exception(reraise\u003dFalse) as ctxt:\n        LOG.warning(....)\n        if attempt \u003d\u003d max_attempt - 1:  # final attempt\n            ctxt.reraise \u003d True","commit_id":"59916c5b451de8426b30f519d49427d3bbfe64d0"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"004386da0abadde357c36abb0798abb0b60f543e","unresolved":false,"context_lines":[{"line_number":42,"context_line":"                        {\u0027attempt\u0027: attempt + 1,"},{"line_number":43,"context_line":"                            \u0027max_attempts\u0027: max_attempts,"},{"line_number":44,"context_line":"                            \u0027action\u0027: action})"},{"line_number":45,"context_line":"                    last_exc \u003d e"},{"line_number":46,"context_line":"            raise last_exc if last_exc else oslo_messaging.MessagingTimeout()"},{"line_number":47,"context_line":"        return func_wrapper"},{"line_number":48,"context_line":"    return wrapper"}],"source_content_type":"text/x-python","patch_set":13,"id":"1a122d0e_93bdf8d9","line":45,"in_reply_to":"1a122d0e_a2bc2edc","updated":"2016-04-24 16:06:18.000000000","message":"Oh, dear, I forgot about save_and_reraise_exception. I\u0027ll definitely do it this way, thanks!","commit_id":"59916c5b451de8426b30f519d49427d3bbfe64d0"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"a3f8869a6369c0f0aaafc0bcef6313fb63106010","unresolved":false,"context_lines":[{"line_number":43,"context_line":"                            \u0027max_attempts\u0027: max_attempts,"},{"line_number":44,"context_line":"                            \u0027action\u0027: action})"},{"line_number":45,"context_line":"                    last_exc \u003d e"},{"line_number":46,"context_line":"            raise last_exc if last_exc else oslo_messaging.MessagingTimeout()"},{"line_number":47,"context_line":"        return func_wrapper"},{"line_number":48,"context_line":"    return wrapper"},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"1a122d0e_42cefa83","line":46,"updated":"2016-04-23 07:25:41.000000000","message":"Is there a case where last_exc is None?","commit_id":"59916c5b451de8426b30f519d49427d3bbfe64d0"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"004386da0abadde357c36abb0798abb0b60f543e","unresolved":false,"context_lines":[{"line_number":43,"context_line":"                            \u0027max_attempts\u0027: max_attempts,"},{"line_number":44,"context_line":"                            \u0027action\u0027: action})"},{"line_number":45,"context_line":"                    last_exc \u003d e"},{"line_number":46,"context_line":"            raise last_exc if last_exc else oslo_messaging.MessagingTimeout()"},{"line_number":47,"context_line":"        return func_wrapper"},{"line_number":48,"context_line":"    return wrapper"},{"line_number":49,"context_line":""}],"source_content_type":"text/x-python","patch_set":13,"id":"1a122d0e_b3a114ac","line":46,"in_reply_to":"1a122d0e_42cefa83","updated":"2016-04-24 16:06:18.000000000","message":"I think that was done to make pep8 happy as it argued about raising None exception at some point. I\u0027ll restructure the code, thanks.","commit_id":"59916c5b451de8426b30f519d49427d3bbfe64d0"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"b80d044614c83f66ddadaaafcd97e585d1925e95","unresolved":false,"context_lines":[{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"def _call_with_retry(max_attempts):"},{"line_number":26,"context_line":"    \"\"\"A wrapper to retry function using rpc call in case of MessagingTimeout."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    Retries the decorated function in case of timeout. If maximum attempts"},{"line_number":29,"context_line":"    exceeded, MessagingTimeout exception is raised."}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_3f0bb925","line":26,"range":{"start_line":26,"start_character":61,"end_line":26,"end_character":77},"updated":"2016-04-27 15:37:32.000000000","message":"I believe we should care about any messaging exception, what matters is that recipient didn\u0027t get the notification and we need to retry. So originally it was handling MessagingException, why changing to timeout?","commit_id":"b70249ca8e4a86670d8fed425b60d2828f169b33"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"6fddb277e91d16a5b509952a94bfbec394894d79","unresolved":false,"context_lines":[{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"def _call_with_retry(max_attempts):"},{"line_number":26,"context_line":"    \"\"\"A wrapper to retry function using rpc call in case of MessagingTimeout."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    Retries the decorated function in case of timeout. If maximum attempts"},{"line_number":29,"context_line":"    exceeded, MessagingTimeout exception is raised."}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_85d27bfe","line":26,"range":{"start_line":26,"start_character":61,"end_line":26,"end_character":77},"in_reply_to":"1a122d0e_3f0bb925","updated":"2016-04-27 20:26:53.000000000","message":"Good catch! If there is a reason you need to change to catch MessagingTimeout, could you describe more detail description in the commit message or the bug report?\n\nChanging the exception to be caught is not a part of refactoring. A bug report should be filed if there is a problem.","commit_id":"b70249ca8e4a86670d8fed425b60d2828f169b33"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"0dcb4bd0f00c8a84be8cc4f6123d5409bc9d2d4f","unresolved":false,"context_lines":[{"line_number":23,"context_line":""},{"line_number":24,"context_line":""},{"line_number":25,"context_line":"def _call_with_retry(max_attempts):"},{"line_number":26,"context_line":"    \"\"\"A wrapper to retry function using rpc call in case of MessagingTimeout."},{"line_number":27,"context_line":""},{"line_number":28,"context_line":"    Retries the decorated function in case of timeout. If maximum attempts"},{"line_number":29,"context_line":"    exceeded, MessagingTimeout exception is raised."}],"source_content_type":"text/x-python","patch_set":16,"id":"1a122d0e_386aaaed","line":26,"range":{"start_line":26,"start_character":61,"end_line":26,"end_character":77},"in_reply_to":"1a122d0e_85d27bfe","updated":"2016-04-27 21:23:34.000000000","message":"You are right, it sure has to be more general case.","commit_id":"b70249ca8e4a86670d8fed425b60d2828f169b33"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"0cbc452122bc6a009bbfbbad2a7d8cbdf9f816aa","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        def func_wrapper(*args, **kwargs):"},{"line_number":36,"context_line":"            # (ivasilevskaya) think of a more informative data to log"},{"line_number":37,"context_line":"            action \u003d \u0027%(func)s\u0027 % {\u0027func\u0027: getattr(f, \u0027__name__\u0027, f)}"},{"line_number":38,"context_line":"            for attempt in range(1, max_attempts + 1):"},{"line_number":39,"context_line":"                try:"},{"line_number":40,"context_line":"                    return f(*args, **kwargs)"},{"line_number":41,"context_line":"                except oslo_messaging.MessagingException:"}],"source_content_type":"text/x-python","patch_set":18,"id":"dab17558_f3520866","line":38,"range":{"start_line":38,"start_character":36,"end_line":38,"end_character":52},"updated":"2016-05-11 07:57:05.000000000","message":"seems this can be just max_attempts given line #50","commit_id":"495f417c8c34fcd75d1dd6449d19082ad6f67160"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"fd3d97111cfe92650d186424e2236505bbc1106d","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        def func_wrapper(*args, **kwargs):"},{"line_number":36,"context_line":"            # (ivasilevskaya) think of a more informative data to log"},{"line_number":37,"context_line":"            action \u003d \u0027%(func)s\u0027 % {\u0027func\u0027: getattr(f, \u0027__name__\u0027, f)}"},{"line_number":38,"context_line":"            for attempt in range(1, max_attempts + 1):"},{"line_number":39,"context_line":"                try:"},{"line_number":40,"context_line":"                    return f(*args, **kwargs)"},{"line_number":41,"context_line":"                except oslo_messaging.MessagingException:"}],"source_content_type":"text/x-python","patch_set":18,"id":"dab17558_6e0aab8b","line":38,"range":{"start_line":38,"start_character":36,"end_line":38,"end_character":52},"in_reply_to":"dab17558_eee5fb08","updated":"2016-05-11 08:19:10.000000000","message":"you\u0027re right, my bad :)","commit_id":"495f417c8c34fcd75d1dd6449d19082ad6f67160"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"18a871f94888cf8513f2cf711169557e576b4ed5","unresolved":false,"context_lines":[{"line_number":35,"context_line":"        def func_wrapper(*args, **kwargs):"},{"line_number":36,"context_line":"            # (ivasilevskaya) think of a more informative data to log"},{"line_number":37,"context_line":"            action \u003d \u0027%(func)s\u0027 % {\u0027func\u0027: getattr(f, \u0027__name__\u0027, f)}"},{"line_number":38,"context_line":"            for attempt in range(1, max_attempts + 1):"},{"line_number":39,"context_line":"                try:"},{"line_number":40,"context_line":"                    return f(*args, **kwargs)"},{"line_number":41,"context_line":"                except oslo_messaging.MessagingException:"}],"source_content_type":"text/x-python","patch_set":18,"id":"dab17558_eee5fb08","line":38,"range":{"start_line":38,"start_character":36,"end_line":38,"end_character":52},"in_reply_to":"dab17558_f3520866","updated":"2016-05-11 08:14:07.000000000","message":"hm, doubt it: \nrange(1, max_attempts + 1) is [1, ... max_attempts]\n\nif changed to range(1, max_attempts) if condition (line #50) will never be matched as long as the greatest \"attempt\" value will be max_attempt - 1.\n\nCorrect me if I got that wrong.","commit_id":"495f417c8c34fcd75d1dd6449d19082ad6f67160"}],"neutron/db/l3_agentschedulers_db.py":[{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"8970b386d488e5953f1134bf524913731d260a97","unresolved":false,"context_lines":[{"line_number":311,"context_line":"            for agent in new_agents:"},{"line_number":312,"context_line":"                # XXX(ivasilevskaya) the original version called unbind_router"},{"line_number":313,"context_line":"                # only on last agent in new_agents list. Was it a bug or am"},{"line_number":314,"context_line":"                # I missing smth?"},{"line_number":315,"context_line":"                self._unbind_router(context, router_id, agent[\u0027id\u0027])"},{"line_number":316,"context_line":"            raise l3agentscheduler.RouterReschedulingFailed("},{"line_number":317,"context_line":"                router_id\u003drouter_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"5a18252c_3a6e872f","line":314,"updated":"2016-04-13 11:09:22.000000000","message":"your indentation changed the logic here. notice that the original one would iterate over each agent and do a full attempt set and catch the timeout and then unbind from the agent that failed. Now that you put the catch logic further out, you don\u0027t know which one failed to notify so you are forced to unbind them all.\n\nMove the except statement into the inner loop so you only unbind from the ones that fail to preserve previous behavior.","commit_id":"f669556cabb4f5934e31535d109a63dcc6f666c6"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"cb74a0506681129d7990664bccba964986c78a65","unresolved":false,"context_lines":[{"line_number":311,"context_line":"            for agent in new_agents:"},{"line_number":312,"context_line":"                # XXX(ivasilevskaya) the original version called unbind_router"},{"line_number":313,"context_line":"                # only on last agent in new_agents list. Was it a bug or am"},{"line_number":314,"context_line":"                # I missing smth?"},{"line_number":315,"context_line":"                self._unbind_router(context, router_id, agent[\u0027id\u0027])"},{"line_number":316,"context_line":"            raise l3agentscheduler.RouterReschedulingFailed("},{"line_number":317,"context_line":"                router_id\u003drouter_id)"}],"source_content_type":"text/x-python","patch_set":9,"id":"5a18252c_8098a9c1","line":314,"in_reply_to":"5a18252c_3a6e872f","updated":"2016-04-14 19:07:50.000000000","message":"Thanks a lot, I missed this.","commit_id":"f669556cabb4f5934e31535d109a63dcc6f666c6"},{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"e971d977a6e8b70d8f1b8a70e82bffc40352c9ed","unresolved":false,"context_lines":[{"line_number":296,"context_line":"                                          old_agents, new_agents):"},{"line_number":297,"context_line":"        l3_notifier \u003d self.agent_notifiers.get(constants.AGENT_TYPE_L3)"},{"line_number":298,"context_line":"        if not l3_notifier:"},{"line_number":299,"context_line":"            return"},{"line_number":300,"context_line":"        old_hosts \u003d [agent[\u0027host\u0027] for agent in old_agents]"},{"line_number":301,"context_line":"        new_hosts \u003d [agent[\u0027host\u0027] for agent in new_agents]"},{"line_number":302,"context_line":"        for host in set(old_hosts) - set(new_hosts):"}],"source_content_type":"text/x-python","patch_set":10,"id":"5a18252c_4255e8c3","line":299,"updated":"2016-04-15 04:00:03.000000000","message":"nit: unrelated change to remove this line","commit_id":"ca3a7c3f9ae1b9130fe79895c8b8bd9d3239da71"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"579a0e3b3ea954dd539fdadb3ae589e628cc2630","unresolved":false,"context_lines":[{"line_number":296,"context_line":"                                          old_agents, new_agents):"},{"line_number":297,"context_line":"        l3_notifier \u003d self.agent_notifiers.get(constants.AGENT_TYPE_L3)"},{"line_number":298,"context_line":"        if not l3_notifier:"},{"line_number":299,"context_line":"            return"},{"line_number":300,"context_line":"        old_hosts \u003d [agent[\u0027host\u0027] for agent in old_agents]"},{"line_number":301,"context_line":"        new_hosts \u003d [agent[\u0027host\u0027] for agent in new_agents]"},{"line_number":302,"context_line":"        for host in set(old_hosts) - set(new_hosts):"}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_5be39b05","line":299,"in_reply_to":"5a18252c_4255e8c3","updated":"2016-04-18 12:28:44.000000000","message":"Done","commit_id":"ca3a7c3f9ae1b9130fe79895c8b8bd9d3239da71"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"086bcff0a0de412f240e66f76d98d7723407187c","unresolved":false,"context_lines":[{"line_number":301,"context_line":"        old_hosts \u003d [agent[\u0027host\u0027] for agent in old_agents]"},{"line_number":302,"context_line":"        new_hosts \u003d [agent[\u0027host\u0027] for agent in new_agents]"},{"line_number":303,"context_line":"        for host in set(old_hosts) - set(new_hosts):"},{"line_number":304,"context_line":"            l3_notifier.router_removed_from_agent(context, router_id, host)"},{"line_number":305,"context_line":""},{"line_number":306,"context_line":"        for agent in new_agents:"},{"line_number":307,"context_line":"            try:"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a122d0e_4878ca2a","line":304,"range":{"start_line":304,"start_character":12,"end_line":304,"end_character":75},"updated":"2016-04-19 00:36:39.000000000","message":"nit: unrelated change","commit_id":"44d94b73098242dc45a157a8bb13ddb48a09fe79"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"086bcff0a0de412f240e66f76d98d7723407187c","unresolved":false,"context_lines":[{"line_number":305,"context_line":""},{"line_number":306,"context_line":"        for agent in new_agents:"},{"line_number":307,"context_line":"            try:"},{"line_number":308,"context_line":"                l3_notifier.router_added_to_agent(context,"},{"line_number":309,"context_line":"                                                  [router_id], agent[\u0027host\u0027])"},{"line_number":310,"context_line":"            except oslo_messaging.MessagingTimeout:"},{"line_number":311,"context_line":"                self._unbind_router(context, router_id, agent[\u0027id\u0027])"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a122d0e_8805c27b","line":308,"updated":"2016-04-19 00:36:39.000000000","message":"style nit: new line after opening bracket so all parameters are on the same line","commit_id":"44d94b73098242dc45a157a8bb13ddb48a09fe79"}],"neutron/tests/unit/db/test_agentschedulers_db.py":[{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"e971d977a6e8b70d8f1b8a70e82bffc40352c9ed","unresolved":false,"context_lines":[{"line_number":817,"context_line":""},{"line_number":818,"context_line":"                notification_mock.side_effect \u003d _side_effect"},{"line_number":819,"context_line":"                self._take_down_agent_and_run_reschedule(L3_HOSTA)"},{"line_number":820,"context_line":"                self.assertEqual("},{"line_number":821,"context_line":"                    2, len([e for e in notification_mock.call_args_list"},{"line_number":822,"context_line":"                            if e[0][1] \u003d\u003d \u0027router_added_to_agent\u0027]))"},{"line_number":823,"context_line":"                # make sure router was rescheduled even when first attempt"},{"line_number":824,"context_line":"                # failed to notify l3 agent"},{"line_number":825,"context_line":"                l3_agents \u003d self._list_l3_agents_hosting_router("}],"source_content_type":"text/x-python","patch_set":10,"id":"5a18252c_16069551","line":822,"range":{"start_line":820,"start_character":0,"end_line":822,"end_character":68},"updated":"2016-04-15 04:00:03.000000000","message":"With the code in this patch, _notification_host will be called once in actual code running, while cctxt.call will be called twice. If I am right with this, the test here might not be appropriate. The call_count of notification_mock is 2, is because you retry it at line 805~807. But that is not a real case.","commit_id":"ca3a7c3f9ae1b9130fe79895c8b8bd9d3239da71"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"579a0e3b3ea954dd539fdadb3ae589e628cc2630","unresolved":false,"context_lines":[{"line_number":817,"context_line":""},{"line_number":818,"context_line":"                notification_mock.side_effect \u003d _side_effect"},{"line_number":819,"context_line":"                self._take_down_agent_and_run_reschedule(L3_HOSTA)"},{"line_number":820,"context_line":"                self.assertEqual("},{"line_number":821,"context_line":"                    2, len([e for e in notification_mock.call_args_list"},{"line_number":822,"context_line":"                            if e[0][1] \u003d\u003d \u0027router_added_to_agent\u0027]))"},{"line_number":823,"context_line":"                # make sure router was rescheduled even when first attempt"},{"line_number":824,"context_line":"                # failed to notify l3 agent"},{"line_number":825,"context_line":"                l3_agents \u003d self._list_l3_agents_hosting_router("}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_d35e6711","line":822,"range":{"start_line":820,"start_character":0,"end_line":822,"end_character":68},"in_reply_to":"5a18252c_16069551","updated":"2016-04-18 12:28:44.000000000","message":"Thanks, will be fixed","commit_id":"ca3a7c3f9ae1b9130fe79895c8b8bd9d3239da71"},{"author":{"_account_id":11159,"name":"Hong Hui Xiao","email":"honghui_xiao@yeah.net","username":"HongHuiXiao"},"change_message_id":"e971d977a6e8b70d8f1b8a70e82bffc40352c9ed","unresolved":false,"context_lines":[{"line_number":853,"context_line":""},{"line_number":854,"context_line":"                notification_mock.side_effect \u003d _side_effect"},{"line_number":855,"context_line":"                self._take_down_agent_and_run_reschedule(L3_HOSTA)"},{"line_number":856,"context_line":"                self.assertEqual("},{"line_number":857,"context_line":"                    l3_rpc_agent_api.AGENT_NOTIFY_MAX_ATTEMPTS,"},{"line_number":858,"context_line":"                    # here [0][1] means second positional argument of"},{"line_number":859,"context_line":"                    # function mocked"},{"line_number":860,"context_line":"                    len([e for e in notification_mock.call_args_list"},{"line_number":861,"context_line":"                         if e[0][1] \u003d\u003d \u0027router_added_to_agent\u0027]))"},{"line_number":862,"context_line":"                l3_agents \u003d self._list_l3_agents_hosting_router("},{"line_number":863,"context_line":"                    router[\u0027router\u0027][\u0027id\u0027])[\u0027agents\u0027]"},{"line_number":864,"context_line":"                self.assertEqual(0, len(l3_agents))"}],"source_content_type":"text/x-python","patch_set":10,"id":"5a18252c_56aacd19","line":861,"range":{"start_line":856,"start_character":0,"end_line":861,"end_character":65},"updated":"2016-04-15 04:00:03.000000000","message":"ditto","commit_id":"ca3a7c3f9ae1b9130fe79895c8b8bd9d3239da71"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"579a0e3b3ea954dd539fdadb3ae589e628cc2630","unresolved":false,"context_lines":[{"line_number":853,"context_line":""},{"line_number":854,"context_line":"                notification_mock.side_effect \u003d _side_effect"},{"line_number":855,"context_line":"                self._take_down_agent_and_run_reschedule(L3_HOSTA)"},{"line_number":856,"context_line":"                self.assertEqual("},{"line_number":857,"context_line":"                    l3_rpc_agent_api.AGENT_NOTIFY_MAX_ATTEMPTS,"},{"line_number":858,"context_line":"                    # here [0][1] means second positional argument of"},{"line_number":859,"context_line":"                    # function mocked"},{"line_number":860,"context_line":"                    len([e for e in notification_mock.call_args_list"},{"line_number":861,"context_line":"                         if e[0][1] \u003d\u003d \u0027router_added_to_agent\u0027]))"},{"line_number":862,"context_line":"                l3_agents \u003d self._list_l3_agents_hosting_router("},{"line_number":863,"context_line":"                    router[\u0027router\u0027][\u0027id\u0027])[\u0027agents\u0027]"},{"line_number":864,"context_line":"                self.assertEqual(0, len(l3_agents))"}],"source_content_type":"text/x-python","patch_set":10,"id":"1a122d0e_339cfbbf","line":861,"range":{"start_line":856,"start_character":0,"end_line":861,"end_character":65},"in_reply_to":"5a18252c_56aacd19","updated":"2016-04-18 12:28:44.000000000","message":"Done","commit_id":"ca3a7c3f9ae1b9130fe79895c8b8bd9d3239da71"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"086bcff0a0de412f240e66f76d98d7723407187c","unresolved":false,"context_lines":[{"line_number":228,"context_line":"    l3_plugin \u003d (\u0027neutron.tests.unit.extensions.test_l3.\u0027"},{"line_number":229,"context_line":"                 \u0027TestL3NatAgentSchedulingServicePlugin\u0027)"},{"line_number":230,"context_line":""},{"line_number":231,"context_line":"    @mock.patch(\u0027neutron.common.rpc.get_client\u0027)"},{"line_number":232,"context_line":"    def setUp(self, get_client_mock):"},{"line_number":233,"context_line":"        self.useFixture(tools.AttributeMapMemento())"},{"line_number":234,"context_line":"        if self.l3_plugin:"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a122d0e_3cc5cc5a","line":231,"range":{"start_line":231,"start_character":4,"end_line":231,"end_character":48},"updated":"2016-04-19 00:36:39.000000000","message":"won\u0027t the mocking be scoped to only setUp()? I see tests passing but still..","commit_id":"44d94b73098242dc45a157a8bb13ddb48a09fe79"},{"author":{"_account_id":5948,"name":"Oleg Bondarev","email":"obondarev@mirantis.com","username":"obondarev"},"change_message_id":"086bcff0a0de412f240e66f76d98d7723407187c","unresolved":false,"context_lines":[{"line_number":238,"context_line":"        # (ivasilevskaya) mocking this way allows some control over mocked"},{"line_number":239,"context_line":"        # client like further method mocking with asserting calls"},{"line_number":240,"context_line":"        self.client_mock \u003d mock.MagicMock(name\u003d\"mocked client\")"},{"line_number":241,"context_line":"        get_client_mock.return_value \u003d self.client_mock"},{"line_number":242,"context_line":"        super(OvsAgentSchedulerTestCaseBase, self).setUp("},{"line_number":243,"context_line":"            self.plugin_str, service_plugins\u003dservice_plugins)"},{"line_number":244,"context_line":"        mock.patch.object("}],"source_content_type":"text/x-python","patch_set":11,"id":"1a122d0e_dcac98a2","line":241,"range":{"start_line":241,"start_character":8,"end_line":241,"end_character":55},"updated":"2016-04-19 00:36:39.000000000","message":"this can be:\nmock.patch(\u0027neutron.common.rpc.get_client\u0027).start().return_value \u003d self.client_mock\n\nand not mocking at method level","commit_id":"44d94b73098242dc45a157a8bb13ddb48a09fe79"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"a3f8869a6369c0f0aaafc0bcef6313fb63106010","unresolved":false,"context_lines":[{"line_number":804,"context_line":"            ctxt_mock.call \u003d call_mock"},{"line_number":805,"context_line":"            self.client_mock.prepare \u003d mock.MagicMock(return_value\u003dctxt_mock)"},{"line_number":806,"context_line":"            self._take_down_agent_and_run_reschedule(L3_HOSTA)"},{"line_number":807,"context_line":"            self.assertEqual(2, len(call_mock.call_args_list))"},{"line_number":808,"context_line":"            # make sure router was rescheduled even when first attempt"},{"line_number":809,"context_line":"            # failed to notify l3 agent"},{"line_number":810,"context_line":"            l3_agents \u003d self._list_l3_agents_hosting_router("}],"source_content_type":"text/x-python","patch_set":13,"id":"1a122d0e_02824200","line":807,"range":{"start_line":807,"start_character":32,"end_line":807,"end_character":61},"updated":"2016-04-23 07:25:41.000000000","message":"call_mock.call_count is simpler way.","commit_id":"59916c5b451de8426b30f519d49427d3bbfe64d0"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"004386da0abadde357c36abb0798abb0b60f543e","unresolved":false,"context_lines":[{"line_number":804,"context_line":"            ctxt_mock.call \u003d call_mock"},{"line_number":805,"context_line":"            self.client_mock.prepare \u003d mock.MagicMock(return_value\u003dctxt_mock)"},{"line_number":806,"context_line":"            self._take_down_agent_and_run_reschedule(L3_HOSTA)"},{"line_number":807,"context_line":"            self.assertEqual(2, len(call_mock.call_args_list))"},{"line_number":808,"context_line":"            # make sure router was rescheduled even when first attempt"},{"line_number":809,"context_line":"            # failed to notify l3 agent"},{"line_number":810,"context_line":"            l3_agents \u003d self._list_l3_agents_hosting_router("}],"source_content_type":"text/x-python","patch_set":13,"id":"1a122d0e_f3ab8c87","line":807,"range":{"start_line":807,"start_character":32,"end_line":807,"end_character":61},"in_reply_to":"1a122d0e_02824200","updated":"2016-04-24 16:06:18.000000000","message":"It sure is, thanks!","commit_id":"59916c5b451de8426b30f519d49427d3bbfe64d0"},{"author":{"_account_id":841,"name":"Akihiro Motoki","email":"amotoki@gmail.com","username":"amotoki"},"change_message_id":"a3f8869a6369c0f0aaafc0bcef6313fb63106010","unresolved":false,"context_lines":[{"line_number":828,"context_line":"            self._take_down_agent_and_run_reschedule(L3_HOSTA)"},{"line_number":829,"context_line":"            self.assertEqual("},{"line_number":830,"context_line":"                l3_rpc_agent_api.AGENT_NOTIFY_MAX_ATTEMPTS,"},{"line_number":831,"context_line":"                len(call_mock.call_args_list))"},{"line_number":832,"context_line":"            l3_agents \u003d self._list_l3_agents_hosting_router("},{"line_number":833,"context_line":"                router[\u0027router\u0027][\u0027id\u0027])[\u0027agents\u0027]"},{"line_number":834,"context_line":"            self.assertEqual(0, len(l3_agents))"}],"source_content_type":"text/x-python","patch_set":13,"id":"1a122d0e_22777e3c","line":831,"range":{"start_line":831,"start_character":16,"end_line":831,"end_character":45},"updated":"2016-04-23 07:25:41.000000000","message":"Can\u0027t call_count be used?","commit_id":"59916c5b451de8426b30f519d49427d3bbfe64d0"},{"author":{"_account_id":13717,"name":"Inessa Vasilevskaya","email":"ivasilevskaya@mirantis.com","username":"ivasilevskaya"},"change_message_id":"004386da0abadde357c36abb0798abb0b60f543e","unresolved":false,"context_lines":[{"line_number":828,"context_line":"            self._take_down_agent_and_run_reschedule(L3_HOSTA)"},{"line_number":829,"context_line":"            self.assertEqual("},{"line_number":830,"context_line":"                l3_rpc_agent_api.AGENT_NOTIFY_MAX_ATTEMPTS,"},{"line_number":831,"context_line":"                len(call_mock.call_args_list))"},{"line_number":832,"context_line":"            l3_agents \u003d self._list_l3_agents_hosting_router("},{"line_number":833,"context_line":"                router[\u0027router\u0027][\u0027id\u0027])[\u0027agents\u0027]"},{"line_number":834,"context_line":"            self.assertEqual(0, len(l3_agents))"}],"source_content_type":"text/x-python","patch_set":13,"id":"1a122d0e_d3ae5097","line":831,"range":{"start_line":831,"start_character":16,"end_line":831,"end_character":45},"in_reply_to":"1a122d0e_22777e3c","updated":"2016-04-24 16:06:18.000000000","message":"Will be done.","commit_id":"59916c5b451de8426b30f519d49427d3bbfe64d0"}]}
