)]}'
{"neutron/plugins/ml2/drivers/openvswitch/agent/openflow/br_cookie.py":[{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"100712aa9465e2b03bb0db4f348fc23d0c7ff7e8","unresolved":false,"context_lines":[{"line_number":75,"context_line":""},{"line_number":76,"context_line":"        cookie_bridge \u003d copy.copy(self)"},{"line_number":77,"context_line":"        cookie_bridge.set_agent_uuid_stamp(self.request_cookie())"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        class CookieBridgeDyn(OVSCookieBridge, self.__class__):"},{"line_number":80,"context_line":"            pass"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"        cookie_bridge.__class__ \u003d CookieBridgeDyn"},{"line_number":83,"context_line":"        return cookie_bridge"}],"source_content_type":"text/x-python","patch_set":5,"id":"3a461143_b9eb74af","line":82,"range":{"start_line":78,"start_character":0,"end_line":82,"end_character":49},"updated":"2017-01-27 13:43:55.000000000","message":"You don\u0027t need to make this class. You can remove these lines, just returning the copy of the bridge with a different cookie","commit_id":"17cfb28e32f321c26ac240ed6341742aa9ff42a3"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"14917eef02e34ef27a4d5a1ba76e0936645c63b0","unresolved":false,"context_lines":[{"line_number":75,"context_line":""},{"line_number":76,"context_line":"        cookie_bridge \u003d copy.copy(self)"},{"line_number":77,"context_line":"        cookie_bridge.set_agent_uuid_stamp(self.request_cookie())"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        class CookieBridgeDyn(OVSCookieBridge, self.__class__):"},{"line_number":80,"context_line":"            pass"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"        cookie_bridge.__class__ \u003d CookieBridgeDyn"},{"line_number":83,"context_line":"        return cookie_bridge"}],"source_content_type":"text/x-python","patch_set":5,"id":"3a461143_d43ba5cf","line":82,"range":{"start_line":78,"start_character":0,"end_line":82,"end_character":49},"in_reply_to":"3a461143_b9eb74af","updated":"2017-01-27 13:54:32.000000000","message":"I think we need to.\n\nIf we don\u0027t do this, then the object returned will not be an OVSCookieBridge (and it won\u0027t have the delete_flows implementation restricting the delete_flows to the flow carrying the specific cookie).","commit_id":"17cfb28e32f321c26ac240ed6341742aa9ff42a3"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"f2a47065d6e7d18b2f653264074823447b11e1e8","unresolved":false,"context_lines":[{"line_number":75,"context_line":""},{"line_number":76,"context_line":"        cookie_bridge \u003d copy.copy(self)"},{"line_number":77,"context_line":"        cookie_bridge.set_agent_uuid_stamp(self.request_cookie())"},{"line_number":78,"context_line":""},{"line_number":79,"context_line":"        class CookieBridgeDyn(OVSCookieBridge, self.__class__):"},{"line_number":80,"context_line":"            pass"},{"line_number":81,"context_line":""},{"line_number":82,"context_line":"        cookie_bridge.__class__ \u003d CookieBridgeDyn"},{"line_number":83,"context_line":"        return cookie_bridge"}],"source_content_type":"text/x-python","patch_set":5,"id":"3a461143_74083192","line":82,"range":{"start_line":78,"start_character":0,"end_line":82,"end_character":49},"in_reply_to":"3a461143_d43ba5cf","updated":"2017-01-27 14:09:22.000000000","message":"Oh, yes yes, sorry. This is the whole point of this patch!!","commit_id":"17cfb28e32f321c26ac240ed6341742aa9ff42a3"},{"author":{"_account_id":18051,"name":"David Shaughnessy","email":"david.shaughnessy@intel.com","username":"davidsha"},"change_message_id":"12593ba09bd2465695781ccd3887c63e7e21cf86","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        a distinct cookie reserved from this bridge."},{"line_number":58,"context_line":"        \u0027\u0027\u0027"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"        cookie_bridge \u003d copy.copy(self)"},{"line_number":61,"context_line":"        cookie_bridge.set_agent_uuid_stamp(self.request_cookie())"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"        class CookieBridgeDyn(ovs_agent_extension_api.OVSCookieBridge,"}],"source_content_type":"text/x-python","patch_set":7,"id":"3a461143_600bde2a","line":60,"range":{"start_line":60,"start_character":8,"end_line":60,"end_character":39},"updated":"2017-01-30 13:17:55.000000000","message":"Is a copy ok for the deferred bridge or would a deep copy be better?","commit_id":"a17d59ae43f4b75e7ce7ee33e839b6172b145f64"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"5389334132388cd54fe969d17047abf7ee7fd3fa","unresolved":false,"context_lines":[{"line_number":57,"context_line":"        a distinct cookie reserved from this bridge."},{"line_number":58,"context_line":"        \u0027\u0027\u0027"},{"line_number":59,"context_line":""},{"line_number":60,"context_line":"        cookie_bridge \u003d copy.copy(self)"},{"line_number":61,"context_line":"        cookie_bridge.set_agent_uuid_stamp(self.request_cookie())"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"        class CookieBridgeDyn(ovs_agent_extension_api.OVSCookieBridge,"}],"source_content_type":"text/x-python","patch_set":7,"id":"3a461143_962ac58e","line":60,"range":{"start_line":60,"start_character":8,"end_line":60,"end_character":39},"in_reply_to":"3a461143_600bde2a","updated":"2017-01-30 15:44:12.000000000","message":"I looked both in ovs_lib and native/ovs_ofctl implementations, and I haven\u0027t identified any bridge instance attribute that would need to not be shared between a bridge and the cookie bridges derived from it, so I think a shallow copy is enough.","commit_id":"a17d59ae43f4b75e7ce7ee33e839b6172b145f64"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"12b69c341470bf6567bc9ca45a979d438527eff4","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        cookie_bridge \u003d copy.copy(self)"},{"line_number":61,"context_line":"        cookie_bridge.set_agent_uuid_stamp(self.request_cookie())"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"        class CookieBridgeDyn(ovs_agent_extension_api.OVSCookieBridge,"},{"line_number":64,"context_line":"                              self.__class__):"},{"line_number":65,"context_line":"            pass"},{"line_number":66,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"1a430d35_31030d0f","line":63,"updated":"2017-02-07 02:15:27.000000000","message":"Can you provide some context as to why this is being done this way? It seems like it would be much clearer to construct a cookie bridge explicitly with a new UUID stamp rather than this dynamically created class with copying.","commit_id":"a17d59ae43f4b75e7ce7ee33e839b6172b145f64"},{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"5409290c2cb6ac00611079b7813ad736b4f4238f","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        cookie_bridge \u003d copy.copy(self)"},{"line_number":61,"context_line":"        cookie_bridge.set_agent_uuid_stamp(self.request_cookie())"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"        class CookieBridgeDyn(ovs_agent_extension_api.OVSCookieBridge,"},{"line_number":64,"context_line":"                              self.__class__):"},{"line_number":65,"context_line":"            pass"},{"line_number":66,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"1a430d35_6db847c9","line":63,"updated":"2017-02-07 12:24:40.000000000","message":"I understand what you are doing now. If do_action_flows is really the only thing that needs to be overridden, wouldn\u0027t a decorator be a little clearer? That would avoid the use of dynamic class creation and changing the class of existing instances.\n\nhttp://paste.openstack.org/show/597934/","commit_id":"a17d59ae43f4b75e7ce7ee33e839b6172b145f64"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"ab609704dced268aa9a07bf26c22c2f50336c235","unresolved":false,"context_lines":[{"line_number":60,"context_line":"        cookie_bridge \u003d copy.copy(self)"},{"line_number":61,"context_line":"        cookie_bridge.set_agent_uuid_stamp(self.request_cookie())"},{"line_number":62,"context_line":""},{"line_number":63,"context_line":"        class CookieBridgeDyn(ovs_agent_extension_api.OVSCookieBridge,"},{"line_number":64,"context_line":"                              self.__class__):"},{"line_number":65,"context_line":"            pass"},{"line_number":66,"context_line":""}],"source_content_type":"text/x-python","patch_set":7,"id":"1a430d35_9023d2a6","line":63,"in_reply_to":"1a430d35_31030d0f","updated":"2017-02-07 08:45:04.000000000","message":"(I won\u0027t claim there is no better way, but here is my context:)\n\nThe bridge from which we want to derive a cookie bridge may be of many different classes (OVSTunnelBridge or OVSIntegrationBridge, in both native and ovs_ofctl variants). We could find out which class we want to instantiate by looking at the underlying class, but we have two other issues:\n- for native variants we would have to introspect into the underlying bridge to get ryu_app and pass it to __init__ the cookie bridge\n- we need the cookie bridge to behave differently than the underlying bridge so we need it to be of a different class overriding (at least) delete_flows; it means that for each of the possible underlying-bridge class we would need to define a cookiebridge class, and then define a mapping between the two\n\nThese constraints had been solved with a design based on factories (see I55835a34d8fba7a139dce93f99cbff54584d695c), but in the process of taking it over from the initial author, I thought I could do something simpler.\n\nOverall the code above is the most elegant I came up with, but I\u0027ll be very happy to make it less convoluted.\n\n(to avoid copy.copy, I also considered a design combining a passthrough behavior based on __getattribute__ voodoo - remotely similar to [1] - and the use of a dynamic class, but found that  dynamic class was convoluted enough and that copy.copy was probably fine).\n\n\n[1] https://github.com/openstack/networking-bgpvpn/blob/master/networking_bgpvpn/neutron/services/service_drivers/bagpipe/agent_extension.py#L72","commit_id":"a17d59ae43f4b75e7ce7ee33e839b6172b145f64"}],"neutron/plugins/ml2/drivers/openvswitch/agent/ovs_agent_extension_api.py":[{"author":{"_account_id":7787,"name":"Kevin Benton","email":"kevin@benton.pub","username":"blak111"},"change_message_id":"29c961f05b5e0c6be1fa7023c828a5f7f2cf5356","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"        # change the class so that isinstance(OVSCookieBridge, x)"},{"line_number":33,"context_line":"        # is True, with x \u003d OVSCookieBridge(...)"},{"line_number":34,"context_line":"        class OVSCookieBridgeDyn(OVSCookieBridge, bridge.__class__):"},{"line_number":35,"context_line":"            pass"},{"line_number":36,"context_line":"        cookie_bridge.__class__ \u003d OVSCookieBridgeDyn"},{"line_number":37,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"fa31d9ce_502004f8","line":34,"updated":"2017-02-09 21:45:00.000000000","message":"This is a dynamic class created on every call to this method. This results in behavior where two bridge of the same type can be passed into OVSCookieBridge have results of different types. Even worse, the same bridge passed into OVSCookieBridge multiple times results in a different type every time. http://paste.openstack.org/show/598307/\n\nA class is supposed to give you an expectation of the interface you can expect. It\u0027s not really supposed to be something that changes on every object instantiation with the same parameters (e.g. I expect type(str(43)) \u003d\u003d type(str(43)) \u003d\u003d type(str(42)) ).\n\n\nWhy don\u0027t we just force them all to inherit from OVSCookieBridge in the first place if its only being used as a way to logically encapsulate the method? Then we can just have a method of get_new_cookie_bridge() that calls self.clone(), sets a new cookie on the result and returns it.\n\nNo more dynamic types or changing classes on existing objects. Will that work?","commit_id":"6d402d4046e536adcf5c1b9f87a51cc93c8d2330"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"ee8392de38e9fe40d0fe8883a65098728b2c648a","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"        # change the class so that isinstance(OVSCookieBridge, x)"},{"line_number":33,"context_line":"        # is True, with x \u003d OVSCookieBridge(...)"},{"line_number":34,"context_line":"        class OVSCookieBridgeDyn(OVSCookieBridge, bridge.__class__):"},{"line_number":35,"context_line":"            pass"},{"line_number":36,"context_line":"        cookie_bridge.__class__ \u003d OVSCookieBridgeDyn"},{"line_number":37,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"fa31d9ce_53764e3f","line":34,"in_reply_to":"fa31d9ce_502004f8","updated":"2017-02-09 22:11:25.000000000","message":"Inheriting from OVSCookieBridge would mean that the base integration bridge used by the agent would get a delete_flows implementation only touching the flows setup by the agent, but would not let the agent remove all flows with a plain delete_flows.  I was trying to avoid changing the behavior of bridge instances used by base agent code, and change only the behavior seen by extensions.\n\nA possibility change the agent code so that when it really needs to delete flows from extension, passes cookie\u003d1/-1. Then all brides could have the same delete_flows implementation.  But again, I would rather avoid risking side effects on base code to fix/improve the bridges that extensions see.\n\nOn the issue you describe of having a different class on different instantiations: why about avoiding this by caching/reusing the class used for a given mother class ?","commit_id":"6d402d4046e536adcf5c1b9f87a51cc93c8d2330"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"5eac52a0d21d24f42e271d91c3bbcd0ce815cfbd","unresolved":false,"context_lines":[{"line_number":31,"context_line":""},{"line_number":32,"context_line":"        # change the class so that isinstance(OVSCookieBridge, x)"},{"line_number":33,"context_line":"        # is True, with x \u003d OVSCookieBridge(...)"},{"line_number":34,"context_line":"        class OVSCookieBridgeDyn(OVSCookieBridge, bridge.__class__):"},{"line_number":35,"context_line":"            pass"},{"line_number":36,"context_line":"        cookie_bridge.__class__ \u003d OVSCookieBridgeDyn"},{"line_number":37,"context_line":""}],"source_content_type":"text/x-python","patch_set":12,"id":"da36d5c6_a0f4c75a","line":34,"in_reply_to":"fa31d9ce_53764e3f","updated":"2017-02-24 14:46:15.000000000","message":"(Keeping track here of what we discussed during PTG:)\n* do a separate change so that the default behavior for delete_flows is to only remove flows matching the bridge default cookie  (this avoids having to change/patch the delete_flows implementation in OVSCookieBridge and the drawbacks of a dynamic class)\n* in OVSCookieBridge.__new__ copy the underlying bridge, give it a new cookie, and that\u0027s it","commit_id":"6d402d4046e536adcf5c1b9f87a51cc93c8d2330"}],"neutron/tests/unit/plugins/ml2/drivers/openvswitch/agent/test_ovs_agent_extension_api.py":[{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"b0fdc94e411520d86de490e2a3a46a9523d9c72c","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        self.bridge \u003d self.br_int_cls(\"br-int\")"},{"line_number":67,"context_line":"        self.tested_bridge \u003d self.bridge.get_cookie_bridge()"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"        patcher \u003d mock.patch.object(self.bridge, \u0027do_action_flows\u0027)"},{"line_number":70,"context_line":"        self.mock_do_action_flows \u003d patcher.start()"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def test_cookie(self):"},{"line_number":73,"context_line":"        self.assertNotEqual(self.bridge.default_cookie,"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a430d35_c510275c","line":70,"range":{"start_line":69,"start_character":0,"end_line":70,"end_character":51},"updated":"2017-02-07 16:47:53.000000000","message":"This does not work: six.wrap in the decorator tries to wrap do_action_flows and fails because since this is a mock it does not have __name__ nor __self__ .\n\nI don\u0027t know how to solve this elegantly.","commit_id":"aee494b42c5b602ccc8e88936e770f799e69b563"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"c540b89dd4780b882748151fa2a885e0af5dbc81","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        self.bridge \u003d self.br_int_cls(\"br-int\")"},{"line_number":67,"context_line":"        self.tested_bridge \u003d self.bridge.get_cookie_bridge()"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"        patcher \u003d mock.patch.object(self.bridge, \u0027do_action_flows\u0027)"},{"line_number":70,"context_line":"        self.mock_do_action_flows \u003d patcher.start()"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def test_cookie(self):"},{"line_number":73,"context_line":"        self.assertNotEqual(self.bridge.default_cookie,"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a430d35_4e5b58f6","line":70,"range":{"start_line":69,"start_character":0,"end_line":70,"end_character":51},"in_reply_to":"1a430d35_13bdf9b6","updated":"2017-02-08 10:10:36.000000000","message":"Agreed, the situation is unclean: we moved out of the ovs_agent_extension the core functionality required to pass a bridge with the right behavior to extensions, and the OVSCookieBridge with its tests do not relate to that anymore.\n\nOn the other hand, looking back at the bug as recorded in LP, to really Close it we need not only to fix the behavior of what is returned by the extension API, but also the behavior of the OVSCookieBridge class.  So I guess the right thing to do is indeed to fix this class as well.\n\nI\u0027ll see what I can do to make the things more consistent.","commit_id":"aee494b42c5b602ccc8e88936e770f799e69b563"},{"author":{"_account_id":16688,"name":"Rodolfo Alonso","email":"ralonsoh@redhat.com","username":"rodolfo-alonso-hernandez"},"change_message_id":"e864e98e2ceeba1eab9fff3f435620a31ee86b22","unresolved":false,"context_lines":[{"line_number":66,"context_line":"        self.bridge \u003d self.br_int_cls(\"br-int\")"},{"line_number":67,"context_line":"        self.tested_bridge \u003d self.bridge.get_cookie_bridge()"},{"line_number":68,"context_line":""},{"line_number":69,"context_line":"        patcher \u003d mock.patch.object(self.bridge, \u0027do_action_flows\u0027)"},{"line_number":70,"context_line":"        self.mock_do_action_flows \u003d patcher.start()"},{"line_number":71,"context_line":""},{"line_number":72,"context_line":"    def test_cookie(self):"},{"line_number":73,"context_line":"        self.assertNotEqual(self.bridge.default_cookie,"}],"source_content_type":"text/x-python","patch_set":9,"id":"1a430d35_13bdf9b6","line":70,"range":{"start_line":69,"start_character":0,"end_line":70,"end_character":51},"in_reply_to":"1a430d35_c510275c","updated":"2017-02-08 09:52:12.000000000","message":"Why are you modifying this class? You didn\u0027t make any change in the code.\n\nYou should test only OVSCookieBridge, using a fake brigde as input parameter, faking the \"request_cookie()\" call and then faking the bridge \"do_action_flows\" call in add/mod/delete\n\nBut TestOVSCookieBridgeOFCtl and TestOVSCookieBridgeRyu shouldn\u0027t be tested here.","commit_id":"aee494b42c5b602ccc8e88936e770f799e69b563"},{"author":{"_account_id":18051,"name":"David Shaughnessy","email":"david.shaughnessy@intel.com","username":"davidsha"},"change_message_id":"da8036567d458f4d67dc60a4f9879c74eeb0a37e","unresolved":false,"context_lines":[{"line_number":26,"context_line":"    import ovs_test_base"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"class TestOVSAgentExtensionAPI(ovs_test_base.OVSOFCtlTestBase):"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    def setUp(self):"},{"line_number":32,"context_line":"        super(TestOVSAgentExtensionAPI, self).setUp()"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a430d35_f49d690b","line":29,"updated":"2017-02-09 17:06:31.000000000","message":"It seems like Jenkins is failing because you haven\u0027t mocked all the add/mod/delete_flow calls, maybe just put a mock around do_action here for br-int and br-tun to see if this is where they\u0027re getting through.","commit_id":"afc80a6edf86abc017eb1ae9cd226c64abf08239"},{"author":{"_account_id":18051,"name":"David Shaughnessy","email":"david.shaughnessy@intel.com","username":"davidsha"},"change_message_id":"9a5c2d024e22b8ddf10838e9b254f2cff369f95b","unresolved":false,"context_lines":[{"line_number":26,"context_line":"    import ovs_test_base"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"class TestOVSAgentExtensionAPI(ovs_test_base.OVSOFCtlTestBase):"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    def setUp(self):"},{"line_number":32,"context_line":"        super(TestOVSAgentExtensionAPI, self).setUp()"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a430d35_aa5c5af1","line":29,"in_reply_to":"1a430d35_575abf51","updated":"2017-02-09 17:34:28.000000000","message":"I don\u0027t know how to enabled the warning, but running the NeutronAgent tests and the Cookie bridge tests seperately and having a watch on br-int\u0027s flow table maybe useful.","commit_id":"afc80a6edf86abc017eb1ae9cd226c64abf08239"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"67cce05c620974fd0fa62a9c503b1955227ef6a3","unresolved":false,"context_lines":[{"line_number":26,"context_line":"    import ovs_test_base"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"class TestOVSAgentExtensionAPI(ovs_test_base.OVSOFCtlTestBase):"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    def setUp(self):"},{"line_number":32,"context_line":"        super(TestOVSAgentExtensionAPI, self).setUp()"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a430d35_ad29d4f4","line":29,"in_reply_to":"1a430d35_aa5c5af1","updated":"2017-02-09 20:28:29.000000000","message":"I don\u0027t even have ovs installed on my development box; but these tests run perfectly fine (tox -e test_ovs_agent_extension), so I don\u0027t get what is not mocked like it should.","commit_id":"afc80a6edf86abc017eb1ae9cd226c64abf08239"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"61d86f7a9a266b9e91206fcb9db25e389bdc5cf6","unresolved":false,"context_lines":[{"line_number":26,"context_line":"    import ovs_test_base"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"class TestOVSAgentExtensionAPI(ovs_test_base.OVSOFCtlTestBase):"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    def setUp(self):"},{"line_number":32,"context_line":"        super(TestOVSAgentExtensionAPI, self).setUp()"}],"source_content_type":"text/x-python","patch_set":11,"id":"fa31d9ce_6de4513b","line":29,"in_reply_to":"1a430d35_ad29d4f4","updated":"2017-02-09 20:57:50.000000000","message":"Err...\n\nThe broken mocking was due to an obvious bug (missing .start())\n\nThe test suite worked without complaining locally on my machine without ovs, because run_ofctl does only very limited error check [1]...\n\n[1] https://github.com/openstack/neutron/blob/master/neutron/agent/common/ovs_lib.py#L269-L272","commit_id":"afc80a6edf86abc017eb1ae9cd226c64abf08239"},{"author":{"_account_id":12021,"name":"Thomas Morin","email":"tmmorin.orange@gmail.com","username":"tmorin"},"change_message_id":"6a9d836d104bc5d93f19e829f2d6dc6527cafc0e","unresolved":false,"context_lines":[{"line_number":26,"context_line":"    import ovs_test_base"},{"line_number":27,"context_line":""},{"line_number":28,"context_line":""},{"line_number":29,"context_line":"class TestOVSAgentExtensionAPI(ovs_test_base.OVSOFCtlTestBase):"},{"line_number":30,"context_line":""},{"line_number":31,"context_line":"    def setUp(self):"},{"line_number":32,"context_line":"        super(TestOVSAgentExtensionAPI, self).setUp()"}],"source_content_type":"text/x-python","patch_set":11,"id":"1a430d35_575abf51","line":29,"in_reply_to":"1a430d35_f49d690b","updated":"2017-02-09 17:27:58.000000000","message":"This class had no test ending up with add/del/mod flows (AFAICT), but the next class, TestOVSCookieBridgeOFCtl (L652) has many. However, L67 is supposed to mock run_ofctl, which I thought would do the job. I have to see what is missing (and what I need to do to be able to check against sudo calls on my local setup).","commit_id":"afc80a6edf86abc017eb1ae9cd226c64abf08239"},{"author":{"_account_id":9656,"name":"Ihar Hrachyshka","email":"ihrachys@redhat.com","username":"ihrachys","status":"Red Hat Networking Systems Engineer"},"change_message_id":"64fa1d451e07be10d0ab69347cc66ccf8a78ceea","unresolved":false,"context_lines":[{"line_number":197,"context_line":"            mock.call._send_msg("},{"line_number":198,"context_line":"                ofpp.OFPFlowMod("},{"line_number":199,"context_line":"                    dp,"},{"line_number":200,"context_line":"                    # this is the interesting part of the check:"},{"line_number":201,"context_line":"                    cookie\u003dself.tested_bridge._default_cookie,"},{"line_number":202,"context_line":"                    instructions\u003d[],"},{"line_number":203,"context_line":"                    match\u003dofpp.OFPMatch(in_port\u003din_port),"}],"source_content_type":"text/x-python","patch_set":19,"id":"3a1ff146_c7e4233d","line":200,"range":{"start_line":200,"start_character":22,"end_line":200,"end_character":64},"updated":"2017-03-15 04:58:26.000000000","message":"not interesting parts could be skipped with mock.ANY","commit_id":"64e2e10fcf5e8884c50d4eba91642ea8e281dbe0"}]}
