)]}'
{"neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py":[{"author":{"_account_id":1131,"name":"Brian Haley","email":"haleyb.dev@gmail.com","username":"brian-haley"},"change_message_id":"5b111c0d890e70678bcbf929edc33523e91e119c","unresolved":false,"context_lines":[{"line_number":1069,"context_line":"        last_ping \u003d self._nb_ovn.nb_global.external_ids.get("},{"line_number":1070,"context_line":"            ovn_const.OVN_LIVENESS_CHECK_EXT_ID_KEY)"},{"line_number":1071,"context_line":"        if last_ping:"},{"line_number":1072,"context_line":"            interval \u003d max(cfg.CONF.agent_down_time / 2, 1)"},{"line_number":1073,"context_line":"            next_ping \u003d (timeutils.parse_isotime(last_ping) +"},{"line_number":1074,"context_line":"                         datetime.timedelta(seconds\u003dinterval))"},{"line_number":1075,"context_line":"            if timeutils.utcnow(with_timezone\u003dTrue) \u003c next_ping:"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_d497689b","line":1072,"range":{"start_line":1072,"start_character":52,"end_line":1072,"end_character":53},"updated":"2020-01-28 14:17:37.000000000","message":"Can you change to // ?  There\u0027s a py3 incompatibility where using / will result in a float.\n\n\u003e\u003e\u003e type(75 // 2)\n\u003cclass \u0027int\u0027\u003e\n\u003e\u003e\u003e type(75 / 2)\n\u003cclass \u0027float\u0027\u003e\n\nI only know this because we fixed another case recently.","commit_id":"a49bfab4ae82eb605f2fec82c8970bd7a83f4f1e"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"be80cc2a517514b6036d0eca4f6394ee39183833","unresolved":false,"context_lines":[{"line_number":1069,"context_line":"        last_ping \u003d self._nb_ovn.nb_global.external_ids.get("},{"line_number":1070,"context_line":"            ovn_const.OVN_LIVENESS_CHECK_EXT_ID_KEY)"},{"line_number":1071,"context_line":"        if last_ping:"},{"line_number":1072,"context_line":"            interval \u003d max(cfg.CONF.agent_down_time / 2, 1)"},{"line_number":1073,"context_line":"            next_ping \u003d (timeutils.parse_isotime(last_ping) +"},{"line_number":1074,"context_line":"                         datetime.timedelta(seconds\u003dinterval))"},{"line_number":1075,"context_line":"            if timeutils.utcnow(with_timezone\u003dTrue) \u003c next_ping:"}],"source_content_type":"text/x-python","patch_set":3,"id":"3fa7e38b_54e37806","line":1072,"range":{"start_line":1072,"start_character":52,"end_line":1072,"end_character":53},"in_reply_to":"3fa7e38b_d497689b","updated":"2020-01-28 14:27:51.000000000","message":"Ops... Good point. I will change it.","commit_id":"a49bfab4ae82eb605f2fec82c8970bd7a83f4f1e"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"8a1e783b4b68be9d48dfc33d3d3a2e546468f144","unresolved":false,"context_lines":[{"line_number":1073,"context_line":"            next_ping \u003d (timeutils.parse_isotime(last_ping) +"},{"line_number":1074,"context_line":"                         datetime.timedelta(seconds\u003dinterval))"},{"line_number":1075,"context_line":"            if timeutils.utcnow(with_timezone\u003dTrue) \u003c next_ping:"},{"line_number":1076,"context_line":"                return"},{"line_number":1077,"context_line":""},{"line_number":1078,"context_line":"        with self._nb_ovn.create_transaction(check_error\u003dTrue,"},{"line_number":1079,"context_line":"                                             bump_nb_cfg\u003dTrue) as txn:"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_8f01dd05","line":1076,"updated":"2020-01-28 14:46:56.000000000","message":"I\u0027m wondering if we can re-use throttler here: https://github.com/openstack/neutron/blob/master/neutron/common/utils.py#L90\n\nIts purpose exactly fits this scenario. The idea is that even if you call once function several times very quickly, throttler ensures it\u0027ll be called just once in the given time.","commit_id":"647b7f63f9dafedfa9fb6e09e3d92d66fb512f0b"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"1b064e3fc329f63eb27c0086bb8c8010ece5ccf0","unresolved":false,"context_lines":[{"line_number":1073,"context_line":"            next_ping \u003d (timeutils.parse_isotime(last_ping) +"},{"line_number":1074,"context_line":"                         datetime.timedelta(seconds\u003dinterval))"},{"line_number":1075,"context_line":"            if timeutils.utcnow(with_timezone\u003dTrue) \u003c next_ping:"},{"line_number":1076,"context_line":"                return"},{"line_number":1077,"context_line":""},{"line_number":1078,"context_line":"        with self._nb_ovn.create_transaction(check_error\u003dTrue,"},{"line_number":1079,"context_line":"                                             bump_nb_cfg\u003dTrue) as txn:"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_cfcef5b5","line":1076,"in_reply_to":"3fa7e38b_8f01dd05","updated":"2020-01-28 14:56:35.000000000","message":"Ah cool, I can take a look to see if it\u0027s fit.\n\nOne thing tho, this ^ is distributed because the last ping value is stored in the OVN database. So, once the \"agent list\" is handled by a specific API worker and the last ping is set, every other API worker (in any controller) will see it as well.\n\nI wonder if with throttler we can have something like it (I haven\u0027t looked at the code yet).","commit_id":"647b7f63f9dafedfa9fb6e09e3d92d66fb512f0b"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"e3cd7ff731c68d758b45bdf00c3f1f3c3ada5ccb","unresolved":false,"context_lines":[{"line_number":1073,"context_line":"            next_ping \u003d (timeutils.parse_isotime(last_ping) +"},{"line_number":1074,"context_line":"                         datetime.timedelta(seconds\u003dinterval))"},{"line_number":1075,"context_line":"            if timeutils.utcnow(with_timezone\u003dTrue) \u003c next_ping:"},{"line_number":1076,"context_line":"                return"},{"line_number":1077,"context_line":""},{"line_number":1078,"context_line":"        with self._nb_ovn.create_transaction(check_error\u003dTrue,"},{"line_number":1079,"context_line":"                                             bump_nb_cfg\u003dTrue) as txn:"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_5ac2c187","line":1076,"in_reply_to":"3fa7e38b_cfcef5b5","updated":"2020-01-28 15:45:01.000000000","message":"Ok I took a look at it and also talked to Kuba via IRC.\n\nUnfortunately @throttler won\u0027t fit here given the distributed scenario. The idea of re-using the \"last ping\" timestamp stored in the OVN NB DB is so that we avoid periodics in another neutron-server (on other controllers) from pinging it again.\n\nAs is, neutron will spawn one health check periodic task per neutron server and we need to coordinate them.\n\nThanks Kuba, @throttler still pretty useful. I\u0027m sure I will be using it somewhere else soon.","commit_id":"647b7f63f9dafedfa9fb6e09e3d92d66fb512f0b"},{"author":{"_account_id":8655,"name":"Jakub Libosvar","email":"libosvar@redhat.com","username":"jlibosva"},"change_message_id":"2075a8502770cbc481e7514487e66c154234bbd6","unresolved":false,"context_lines":[{"line_number":1073,"context_line":"            next_ping \u003d (timeutils.parse_isotime(last_ping) +"},{"line_number":1074,"context_line":"                         datetime.timedelta(seconds\u003dinterval))"},{"line_number":1075,"context_line":"            if timeutils.utcnow(with_timezone\u003dTrue) \u003c next_ping:"},{"line_number":1076,"context_line":"                return"},{"line_number":1077,"context_line":""},{"line_number":1078,"context_line":"        with self._nb_ovn.create_transaction(check_error\u003dTrue,"},{"line_number":1079,"context_line":"                                             bump_nb_cfg\u003dTrue) as txn:"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_5aaba1d5","line":1076,"in_reply_to":"3fa7e38b_cfcef5b5","updated":"2020-01-28 15:41:34.000000000","message":"Yes, you\u0027re right :) We can\u0027t use throttler here, sorry for taking your time.","commit_id":"647b7f63f9dafedfa9fb6e09e3d92d66fb512f0b"}],"neutron/tests/unit/fake_resources.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"d6a39ecf95e8bb253a65b234fa795ffefb5c3b87","unresolved":false,"context_lines":[{"line_number":50,"context_line":"        self._tables[\u0027NAT\u0027] \u003d self.nat_table"},{"line_number":51,"context_line":"        self._tables[\u0027Port_Group\u0027] \u003d self.port_group_table"},{"line_number":52,"context_line":"        self.transaction \u003d mock.MagicMock()"},{"line_number":53,"context_line":"        self.create_transaction \u003d mock.MagicMock()"},{"line_number":54,"context_line":"        self.ls_add \u003d mock.Mock()"},{"line_number":55,"context_line":"        self.set_lswitch_ext_ids \u003d mock.Mock()"},{"line_number":56,"context_line":"        self.ls_del \u003d mock.Mock()"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_23156895","line":53,"updated":"2020-01-28 12:08:42.000000000","message":"Why do you need this one?","commit_id":"7fe86a65224ba1a2a88b2f1e2903bd62fbd07481"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"8310da4a47cb520ff440db9a27f973da7914920f","unresolved":false,"context_lines":[{"line_number":50,"context_line":"        self._tables[\u0027NAT\u0027] \u003d self.nat_table"},{"line_number":51,"context_line":"        self._tables[\u0027Port_Group\u0027] \u003d self.port_group_table"},{"line_number":52,"context_line":"        self.transaction \u003d mock.MagicMock()"},{"line_number":53,"context_line":"        self.create_transaction \u003d mock.MagicMock()"},{"line_number":54,"context_line":"        self.ls_add \u003d mock.Mock()"},{"line_number":55,"context_line":"        self.set_lswitch_ext_ids \u003d mock.Mock()"},{"line_number":56,"context_line":"        self.ls_del \u003d mock.Mock()"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_432184b4","line":53,"in_reply_to":"3fa7e38b_23156895","updated":"2020-01-28 12:21:34.000000000","message":"Because we use \"create_transaction\" for the ping_chassis() method [0].\n\novsdbapp offers transaction() and create_transaction() the difference between these is that transaction() allows subtransctions (nesteding) when committing to the db and create_transaction() does not (I know the API naming choices is not great there) :D\n\n[0] https://github.com/openstack/neutron/blob/master/neutron/plugins/ml2/drivers/ovn/mech_driver/mech_driver.py#L1069","commit_id":"7fe86a65224ba1a2a88b2f1e2903bd62fbd07481"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"90d88d35432a5b73b03ba3c0927dba3e5f8a06d7","unresolved":false,"context_lines":[{"line_number":50,"context_line":"        self._tables[\u0027NAT\u0027] \u003d self.nat_table"},{"line_number":51,"context_line":"        self._tables[\u0027Port_Group\u0027] \u003d self.port_group_table"},{"line_number":52,"context_line":"        self.transaction \u003d mock.MagicMock()"},{"line_number":53,"context_line":"        self.create_transaction \u003d mock.MagicMock()"},{"line_number":54,"context_line":"        self.ls_add \u003d mock.Mock()"},{"line_number":55,"context_line":"        self.set_lswitch_ext_ids \u003d mock.Mock()"},{"line_number":56,"context_line":"        self.ls_del \u003d mock.Mock()"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_893ebde0","line":53,"in_reply_to":"3fa7e38b_432184b4","updated":"2020-01-28 14:10:30.000000000","message":"Thanks!","commit_id":"7fe86a65224ba1a2a88b2f1e2903bd62fbd07481"}],"neutron/tests/unit/plugins/ml2/drivers/ovn/mech_driver/test_mech_driver.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"d6a39ecf95e8bb253a65b234fa795ffefb5c3b87","unresolved":false,"context_lines":[{"line_number":1639,"context_line":"        self._test_update_network_fragmentation(new_mtu, expected_opts)"},{"line_number":1640,"context_line":""},{"line_number":1641,"context_line":"    def test_ping_chassis(self):"},{"line_number":1642,"context_line":"        cmd_mock \u003d mock.patch.object(self.nb_ovn, \u0027check_liveness\u0027).start()"},{"line_number":1643,"context_line":"        self.nb_ovn.nb_global.external_ids \u003d {}"},{"line_number":1644,"context_line":"        self.mech_driver.ping_chassis()"},{"line_number":1645,"context_line":"        cmd_mock.assert_called_once_with()"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_e313d0b5","line":1642,"updated":"2020-01-28 12:08:42.000000000","message":"You don\u0027t need to mock something that is already a mock. You can call directly to self.nb_ovn.check_liveness.assert_called_once_with()","commit_id":"7fe86a65224ba1a2a88b2f1e2903bd62fbd07481"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"8310da4a47cb520ff440db9a27f973da7914920f","unresolved":false,"context_lines":[{"line_number":1639,"context_line":"        self._test_update_network_fragmentation(new_mtu, expected_opts)"},{"line_number":1640,"context_line":""},{"line_number":1641,"context_line":"    def test_ping_chassis(self):"},{"line_number":1642,"context_line":"        cmd_mock \u003d mock.patch.object(self.nb_ovn, \u0027check_liveness\u0027).start()"},{"line_number":1643,"context_line":"        self.nb_ovn.nb_global.external_ids \u003d {}"},{"line_number":1644,"context_line":"        self.mech_driver.ping_chassis()"},{"line_number":1645,"context_line":"        cmd_mock.assert_called_once_with()"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_03270cca","line":1642,"in_reply_to":"3fa7e38b_e313d0b5","updated":"2020-01-28 12:21:34.000000000","message":"Ops that\u0027s true! My bad","commit_id":"7fe86a65224ba1a2a88b2f1e2903bd62fbd07481"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"d6a39ecf95e8bb253a65b234fa795ffefb5c3b87","unresolved":false,"context_lines":[{"line_number":1647,"context_line":"    def test_ping_chassis_interval_expired(self):"},{"line_number":1648,"context_line":"        timeout \u003d 10"},{"line_number":1649,"context_line":"        ovn_conf.cfg.CONF.set_override(\u0027agent_down_time\u0027, timeout)"},{"line_number":1650,"context_line":"        cmd_mock \u003d mock.patch.object(self.nb_ovn, \u0027check_liveness\u0027).start()"},{"line_number":1651,"context_line":""},{"line_number":1652,"context_line":"        # Pretend the interval is already expired"},{"line_number":1653,"context_line":"        time \u003d (timeutils.utcnow(with_timezone\u003dTrue) -"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_031aacc5","line":1650,"updated":"2020-01-28 12:08:42.000000000","message":"ditto","commit_id":"7fe86a65224ba1a2a88b2f1e2903bd62fbd07481"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"d6a39ecf95e8bb253a65b234fa795ffefb5c3b87","unresolved":false,"context_lines":[{"line_number":1662,"context_line":""},{"line_number":1663,"context_line":"    def test_ping_chassis_interval_not_expired(self):"},{"line_number":1664,"context_line":"        ovn_conf.cfg.CONF.set_override(\u0027agent_down_time\u0027, 10)"},{"line_number":1665,"context_line":"        cmd_mock \u003d mock.patch.object(self.nb_ovn, \u0027check_liveness\u0027).start()"},{"line_number":1666,"context_line":""},{"line_number":1667,"context_line":"        # Pretend the interval has NOT yet expired"},{"line_number":1668,"context_line":"        time \u003d timeutils.utcnow(with_timezone\u003dTrue)"}],"source_content_type":"text/x-python","patch_set":2,"id":"3fa7e38b_c3757401","line":1665,"updated":"2020-01-28 12:08:42.000000000","message":"ditto","commit_id":"7fe86a65224ba1a2a88b2f1e2903bd62fbd07481"},{"author":{"_account_id":11952,"name":"Flavio Fernandes","email":"flavio@flaviof.com","username":"ffernand"},"change_message_id":"6f28960d9c8ee538f00803ad5276e44667785b10","unresolved":false,"context_lines":[{"line_number":1668,"context_line":""},{"line_number":1669,"context_line":"        # Assert that \"check_liveness\" wasn\u0027t invoked"},{"line_number":1670,"context_line":"        self.mech_driver.ping_chassis()"},{"line_number":1671,"context_line":"        self.assertFalse(self.nb_ovn.check_liveness.called)"},{"line_number":1672,"context_line":""},{"line_number":1673,"context_line":""},{"line_number":1674,"context_line":"class OVNMechanismDriverTestCase(test_plugin.Ml2PluginV2TestCase):"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_d4020872","line":1671,"range":{"start_line":1671,"start_character":8,"end_line":1671,"end_character":59},"updated":"2020-01-28 14:35:36.000000000","message":"nit (please do not change patchset just for this):\ncould also use   assert_not_called()  \nhttps://docs.python.org/3/library/unittest.mock.html#unittest.mock.Mock.assert_not_called","commit_id":"647b7f63f9dafedfa9fb6e09e3d92d66fb512f0b"},{"author":{"_account_id":6773,"name":"Lucas Alvares Gomes","email":"lucasagomes@gmail.com","username":"lucasagomes"},"change_message_id":"066dd747112bf97cf46f0ee01a64cce4ba5bf1fb","unresolved":false,"context_lines":[{"line_number":1668,"context_line":""},{"line_number":1669,"context_line":"        # Assert that \"check_liveness\" wasn\u0027t invoked"},{"line_number":1670,"context_line":"        self.mech_driver.ping_chassis()"},{"line_number":1671,"context_line":"        self.assertFalse(self.nb_ovn.check_liveness.called)"},{"line_number":1672,"context_line":""},{"line_number":1673,"context_line":""},{"line_number":1674,"context_line":"class OVNMechanismDriverTestCase(test_plugin.Ml2PluginV2TestCase):"}],"source_content_type":"text/x-python","patch_set":4,"id":"3fa7e38b_3486fcb8","line":1671,"range":{"start_line":1671,"start_character":8,"end_line":1671,"end_character":59},"in_reply_to":"3fa7e38b_d4020872","updated":"2020-01-28 14:41:29.000000000","message":"Ah good point! Thanks\n\nIf I happen to send a new patch-set I will change this.","commit_id":"647b7f63f9dafedfa9fb6e09e3d92d66fb512f0b"}]}
